Changeset bd5f3b7 in mainline for uspace/drv/bus/usb/usbmast/scsi_ms.c
- Timestamp:
- 2011-08-21T13:07:35Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 00aece0, f1a9e87
- Parents:
- 86a34d3e (diff), a6480d5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbmast/scsi_ms.c
r86a34d3e rbd5f3b7 46 46 #include <scsi/sbc.h> 47 47 #include <scsi/spc.h> 48 #include "cmd s.h"49 #include " mast.h"48 #include "cmdw.h" 49 #include "bo_trans.h" 50 50 #include "scsi_ms.h" 51 #include "usbmast.h" 51 52 52 53 /** Get string representation for SCSI peripheral device type. … … 60 61 } 61 62 63 static void usbmast_dump_sense(scsi_sense_data_t *sense_buf) 64 { 65 unsigned sense_key; 66 67 sense_key = sense_buf->flags_key & 0x0f; 68 printf("Got sense data. Sense key: 0x%x (%s), ASC 0x%02x, " 69 "ASCQ 0x%02x.\n", sense_key, 70 scsi_get_sense_key_str(sense_key), 71 sense_buf->additional_code, 72 sense_buf->additional_cqual); 73 } 74 75 /** Run SCSI command. 76 * 77 * Run command and repeat in case of unit attention. 78 * XXX This is too simplified. 79 */ 80 static int usbmast_run_cmd(usbmast_fun_t *mfun, scsi_cmd_t *cmd) 81 { 82 uint8_t sense_key; 83 scsi_sense_data_t sense_buf; 84 int rc; 85 86 do { 87 rc = usb_massstor_cmd(mfun, 0xDEADBEEF, cmd); 88 if (rc != EOK) { 89 usb_log_error("Inquiry transport failed, device %s: %s.\n", 90 mfun->mdev->ddf_dev->name, str_error(rc)); 91 return rc; 92 } 93 94 if (cmd->status == CMDS_GOOD) 95 return EOK; 96 97 usb_log_error("SCSI command failed, device %s.\n", 98 mfun->mdev->ddf_dev->name); 99 100 rc = usbmast_request_sense(mfun, &sense_buf, sizeof(sense_buf)); 101 if (rc != EOK) { 102 usb_log_error("Failed to read sense data.\n"); 103 return EIO; 104 } 105 106 /* Dump sense data to log */ 107 usbmast_dump_sense(&sense_buf); 108 109 /* Get sense key */ 110 sense_key = sense_buf.flags_key & 0x0f; 111 112 if (sense_key == SCSI_SK_UNIT_ATTENTION) { 113 printf("Got unit attention. Re-trying command.\n"); 114 } 115 116 } while (sense_key == SCSI_SK_UNIT_ATTENTION); 117 118 /* Command status is not good, nevertheless transport succeeded. */ 119 return EOK; 120 } 121 62 122 /** Perform SCSI Inquiry command on USB mass storage device. 63 123 * 64 * @param dev USB device.65 * @param inquiry_result Where to store parsed inquiry result .66 * @return Error code .67 */ 68 int usbmast_inquiry(usb _device_t *dev, usbmast_inquiry_data_t *inq_res)124 * @param mfun Mass storage function 125 * @param inquiry_result Where to store parsed inquiry result 126 * @return Error code 127 */ 128 int usbmast_inquiry(usbmast_fun_t *mfun, usbmast_inquiry_data_t *inq_res) 69 129 { 70 130 scsi_std_inquiry_data_t inq_data; 71 s ize_t response_len;131 scsi_cmd_t cmd; 72 132 scsi_cdb_inquiry_t cdb; 73 133 int rc; … … 77 137 cdb.alloc_len = host2uint16_t_be(sizeof(inq_data)); 78 138 79 rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb, 80 sizeof(cdb), &inq_data, sizeof(inq_data), &response_len); 139 memset(&cmd, 0, sizeof(cmd)); 140 cmd.cdb = &cdb; 141 cmd.cdb_size = sizeof(cdb); 142 cmd.data_in = &inq_data; 143 cmd.data_in_size = sizeof(inq_data); 144 145 rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd); 81 146 82 147 if (rc != EOK) { 83 usb_log_error("Inquiry failed, device %s: %s.\n", 84 dev->ddf_dev->name, str_error(rc)); 85 return rc; 86 } 87 88 if (response_len < SCSI_STD_INQUIRY_DATA_MIN_SIZE) { 148 usb_log_error("Inquiry transport failed, device %s: %s.\n", 149 mfun->mdev->ddf_dev->name, str_error(rc)); 150 return rc; 151 } 152 153 if (cmd.status != CMDS_GOOD) { 154 usb_log_error("Inquiry command failed, device %s.\n", 155 mfun->mdev->ddf_dev->name); 156 return EIO; 157 } 158 159 if (cmd.rcvd_size < SCSI_STD_INQUIRY_DATA_MIN_SIZE) { 89 160 usb_log_error("SCSI Inquiry response too short (%zu).\n", 90 response_len);161 cmd.rcvd_size); 91 162 return EIO; 92 163 } … … 118 189 /** Perform SCSI Request Sense command on USB mass storage device. 119 190 * 120 * @param dev USB device191 * @param mfun Mass storage function 121 192 * @param buf Destination buffer 122 193 * @param size Size of @a buf … … 124 195 * @return Error code. 125 196 */ 126 int usbmast_request_sense(usb_device_t *dev, void *buf, size_t size) 127 { 197 int usbmast_request_sense(usbmast_fun_t *mfun, void *buf, size_t size) 198 { 199 scsi_cmd_t cmd; 128 200 scsi_cdb_request_sense_t cdb; 129 size_t data_len;130 201 int rc; 131 202 … … 134 205 cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE); 135 206 136 rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb, 137 sizeof(cdb), buf, size, &data_len); 138 139 if (rc != EOK) { 207 memset(&cmd, 0, sizeof(cmd)); 208 cmd.cdb = &cdb; 209 cmd.cdb_size = sizeof(cdb); 210 cmd.data_in = buf; 211 cmd.data_in_size = size; 212 213 rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd); 214 215 if (rc != EOK || cmd.status != CMDS_GOOD) { 140 216 usb_log_error("Request Sense failed, device %s: %s.\n", 141 dev->ddf_dev->name, str_error(rc));142 return rc; 143 } 144 145 if ( data_len< SCSI_SENSE_DATA_MIN_SIZE) {217 mfun->mdev->ddf_dev->name, str_error(rc)); 218 return rc; 219 } 220 221 if (cmd.rcvd_size < SCSI_SENSE_DATA_MIN_SIZE) { 146 222 /* The missing bytes should be considered to be zeroes. */ 147 memset((uint8_t *)buf + data_len, 0,148 SCSI_SENSE_DATA_MIN_SIZE - data_len);223 memset((uint8_t *)buf + cmd.rcvd_size, 0, 224 SCSI_SENSE_DATA_MIN_SIZE - cmd.rcvd_size); 149 225 } 150 226 … … 154 230 /** Perform SCSI Read Capacity command on USB mass storage device. 155 231 * 156 * @param dev USB device.157 * @param nblocks Output, number of blocks .158 * @param block_size Output, block size in bytes .232 * @param mfun Mass storage function 233 * @param nblocks Output, number of blocks 234 * @param block_size Output, block size in bytes 159 235 * 160 236 * @return Error code. 161 237 */ 162 int usbmast_read_capacity(usb _device_t *dev, uint32_t *nblocks,238 int usbmast_read_capacity(usbmast_fun_t *mfun, uint32_t *nblocks, 163 239 uint32_t *block_size) 164 240 { 241 scsi_cmd_t cmd; 165 242 scsi_cdb_read_capacity_10_t cdb; 166 243 scsi_read_capacity_10_data_t data; 167 size_t data_len;168 244 int rc; 169 245 … … 171 247 cdb.op_code = SCSI_CMD_READ_CAPACITY_10; 172 248 173 rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb, 174 sizeof(cdb), &data, sizeof(data), &data_len); 249 memset(&cmd, 0, sizeof(cmd)); 250 cmd.cdb = &cdb; 251 cmd.cdb_size = sizeof(cdb); 252 cmd.data_in = &data; 253 cmd.data_in_size = sizeof(data); 254 255 rc = usbmast_run_cmd(mfun, &cmd); 175 256 176 257 if (rc != EOK) { 177 usb_log_error("Read Capacity (10) failed, device %s: %s.\n", 178 dev->ddf_dev->name, str_error(rc)); 179 return rc; 180 } 181 182 if (data_len < sizeof(data)) { 258 usb_log_error("Read Capacity (10) transport failed, device %s: %s.\n", 259 mfun->mdev->ddf_dev->name, str_error(rc)); 260 return rc; 261 } 262 263 if (cmd.status != CMDS_GOOD) { 264 usb_log_error("Read Capacity (10) command failed, device %s.\n", 265 mfun->mdev->ddf_dev->name); 266 return EIO; 267 } 268 269 if (cmd.rcvd_size < sizeof(data)) { 183 270 usb_log_error("SCSI Read Capacity response too short (%zu).\n", 184 data_len);271 cmd.rcvd_size); 185 272 return EIO; 186 273 } … … 194 281 /** Perform SCSI Read command on USB mass storage device. 195 282 * 196 * @param dev USB device. 197 * @param ba Address of first block. 198 * @param nblocks Number of blocks to read. 199 * @param bsize Block size. 200 * 201 * @return Error code. 202 */ 203 int usbmast_read(usb_device_t *dev, uint64_t ba, size_t nblocks, size_t bsize, 204 void *buf) 205 { 206 scsi_cdb_read_12_t cdb; 207 size_t data_len; 208 int rc; 209 210 /* XXX Need softstate to store block size. */ 283 * @param mfun Mass storage function 284 * @param ba Address of first block 285 * @param nblocks Number of blocks to read 286 * 287 * @return Error code 288 */ 289 int usbmast_read(usbmast_fun_t *mfun, uint64_t ba, size_t nblocks, void *buf) 290 { 291 scsi_cmd_t cmd; 292 scsi_cdb_read_10_t cdb; 293 int rc; 211 294 212 295 if (ba > UINT32_MAX) 213 296 return ELIMIT; 214 297 215 if ( (uint64_t)nblocks * bsize > UINT32_MAX)298 if (nblocks > UINT16_MAX) 216 299 return ELIMIT; 217 300 218 301 memset(&cdb, 0, sizeof(cdb)); 219 cdb.op_code = SCSI_CMD_READ_1 2;302 cdb.op_code = SCSI_CMD_READ_10; 220 303 cdb.lba = host2uint32_t_be(ba); 221 cdb.xfer_len = host2uint32_t_be(nblocks); 222 223 rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb, 224 sizeof(cdb), buf, nblocks * bsize, &data_len); 304 cdb.xfer_len = host2uint16_t_be(nblocks); 305 306 memset(&cmd, 0, sizeof(cmd)); 307 cmd.cdb = &cdb; 308 cmd.cdb_size = sizeof(cdb); 309 cmd.data_in = buf; 310 cmd.data_in_size = nblocks * mfun->block_size; 311 312 rc = usbmast_run_cmd(mfun, &cmd); 225 313 226 314 if (rc != EOK) { 227 usb_log_error("Read (12) failed, device %s: %s.\n", 228 dev->ddf_dev->name, str_error(rc)); 229 return rc; 230 } 231 232 if (data_len < nblocks * bsize) { 315 usb_log_error("Read (10) transport failed, device %s: %s.\n", 316 mfun->mdev->ddf_dev->name, str_error(rc)); 317 return rc; 318 } 319 320 if (cmd.status != CMDS_GOOD) { 321 usb_log_error("Read (10) command failed, device %s.\n", 322 mfun->mdev->ddf_dev->name); 323 return EIO; 324 } 325 326 if (cmd.rcvd_size < nblocks * mfun->block_size) { 233 327 usb_log_error("SCSI Read response too short (%zu).\n", 234 data_len); 328 cmd.rcvd_size); 329 return EIO; 330 } 331 332 return EOK; 333 } 334 335 /** Perform SCSI Write command on USB mass storage device. 336 * 337 * @param mfun Mass storage function 338 * @param ba Address of first block 339 * @param nblocks Number of blocks to read 340 * @param data Data to write 341 * 342 * @return Error code 343 */ 344 int usbmast_write(usbmast_fun_t *mfun, uint64_t ba, size_t nblocks, 345 const void *data) 346 { 347 scsi_cmd_t cmd; 348 scsi_cdb_write_10_t cdb; 349 int rc; 350 351 if (ba > UINT32_MAX) 352 return ELIMIT; 353 354 if (nblocks > UINT16_MAX) 355 return ELIMIT; 356 357 memset(&cdb, 0, sizeof(cdb)); 358 cdb.op_code = SCSI_CMD_WRITE_10; 359 cdb.lba = host2uint32_t_be(ba); 360 cdb.xfer_len = host2uint16_t_be(nblocks); 361 362 memset(&cmd, 0, sizeof(cmd)); 363 cmd.cdb = &cdb; 364 cmd.cdb_size = sizeof(cdb); 365 cmd.data_out = data; 366 cmd.data_out_size = nblocks * mfun->block_size; 367 368 rc = usbmast_run_cmd(mfun, &cmd); 369 370 if (rc != EOK) { 371 usb_log_error("Write (10) transport failed, device %s: %s.\n", 372 mfun->mdev->ddf_dev->name, str_error(rc)); 373 return rc; 374 } 375 376 if (cmd.status != CMDS_GOOD) { 377 usb_log_error("Write (10) command failed, device %s.\n", 378 mfun->mdev->ddf_dev->name); 235 379 return EIO; 236 380 }
Note:
See TracChangeset
for help on using the changeset viewer.