|
@@ -96,12 +96,41 @@ static int scsi_write ( struct block_device *blockdev, uint64_t block,
|
96
|
96
|
}
|
97
|
97
|
|
98
|
98
|
/**
|
99
|
|
- * Read capacity of SCSI device
|
|
99
|
+ * Read capacity of SCSI device via READ CAPACITY (10)
|
100
|
100
|
*
|
101
|
101
|
* @v blockdev Block device
|
102
|
102
|
* @ret rc Return status code
|
103
|
103
|
*/
|
104
|
|
-static int scsi_read_capacity ( struct block_device *blockdev ) {
|
|
104
|
+static int scsi_read_capacity_10 ( struct block_device *blockdev ) {
|
|
105
|
+ struct scsi_device *scsi = block_to_scsi ( blockdev );
|
|
106
|
+ struct scsi_command command;
|
|
107
|
+ struct scsi_cdb_read_capacity_10 *cdb = &command.cdb.readcap10;
|
|
108
|
+ struct scsi_capacity_10 capacity;
|
|
109
|
+ int rc;
|
|
110
|
+
|
|
111
|
+ /* Issue READ CAPACITY (10) */
|
|
112
|
+ memset ( &command, 0, sizeof ( command ) );
|
|
113
|
+ cdb->opcode = SCSI_OPCODE_READ_CAPACITY_10;
|
|
114
|
+ command.data_in = virt_to_user ( &capacity );
|
|
115
|
+ command.data_in_len = sizeof ( capacity );
|
|
116
|
+
|
|
117
|
+ if ( ( rc = scsi_command ( scsi, &command ) ) != 0 )
|
|
118
|
+ return rc;
|
|
119
|
+
|
|
120
|
+ /* Fill in block device fields */
|
|
121
|
+ blockdev->blksize = be32_to_cpu ( capacity.blksize );
|
|
122
|
+ blockdev->blocks = ( be32_to_cpu ( capacity.lba ) + 1 );
|
|
123
|
+
|
|
124
|
+ return 0;
|
|
125
|
+}
|
|
126
|
+
|
|
127
|
+/**
|
|
128
|
+ * Read capacity of SCSI device via READ CAPACITY (16)
|
|
129
|
+ *
|
|
130
|
+ * @v blockdev Block device
|
|
131
|
+ * @ret rc Return status code
|
|
132
|
+ */
|
|
133
|
+static int scsi_read_capacity_16 ( struct block_device *blockdev ) {
|
105
|
134
|
struct scsi_device *scsi = block_to_scsi ( blockdev );
|
106
|
135
|
struct scsi_command command;
|
107
|
136
|
struct scsi_cdb_read_capacity_16 *cdb = &command.cdb.readcap16;
|
|
@@ -125,6 +154,32 @@ static int scsi_read_capacity ( struct block_device *blockdev ) {
|
125
|
154
|
return 0;
|
126
|
155
|
}
|
127
|
156
|
|
|
157
|
+/**
|
|
158
|
+ * Read capacity of SCSI device
|
|
159
|
+ *
|
|
160
|
+ * @v blockdev Block device
|
|
161
|
+ * @ret rc Return status code
|
|
162
|
+ */
|
|
163
|
+static int scsi_read_capacity ( struct block_device *blockdev ) {
|
|
164
|
+ int rc;
|
|
165
|
+
|
|
166
|
+ /* Try READ CAPACITY (10), which is a mandatory command, first. */
|
|
167
|
+ if ( ( rc = scsi_read_capacity_10 ( blockdev ) ) != 0 )
|
|
168
|
+ return rc;
|
|
169
|
+
|
|
170
|
+ /* If capacity range was exceeded (i.e. capacity.lba was
|
|
171
|
+ * 0xffffffff, meaning that blockdev->blocks is now zero), use
|
|
172
|
+ * READ CAPACITY (16) instead. READ CAPACITY (16) is not
|
|
173
|
+ * mandatory, so we can't just use it straight off.
|
|
174
|
+ */
|
|
175
|
+ if ( blockdev->blocks == 0 ) {
|
|
176
|
+ if ( ( rc = scsi_read_capacity_16 ( blockdev ) ) != 0 )
|
|
177
|
+ return rc;
|
|
178
|
+ }
|
|
179
|
+
|
|
180
|
+ return 0;
|
|
181
|
+}
|
|
182
|
+
|
128
|
183
|
/**
|
129
|
184
|
* Initialise SCSI device
|
130
|
185
|
*
|