Changeset 00c2de63 in mainline for uspace/drv/bus/usb/usbmast/scsi_ms.c
- Timestamp:
- 2011-07-29T14:50:22Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b6759f4
- Parents:
- 6c69d19 (diff), 7ae249d (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
r6c69d19 r00c2de63 61 61 } 62 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 63 122 /** Perform SCSI Inquiry command on USB mass storage device. 64 123 * … … 70 129 { 71 130 scsi_std_inquiry_data_t inq_data; 72 s ize_t response_len;131 scsi_cmd_t cmd; 73 132 scsi_cdb_inquiry_t cdb; 74 133 int rc; … … 78 137 cdb.alloc_len = host2uint16_t_be(sizeof(inq_data)); 79 138 80 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 81 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); 82 146 83 147 if (rc != EOK) { 84 usb_log_error("Inquiry failed, device %s: %s.\n", 85 mfun->mdev->ddf_dev->name, str_error(rc)); 86 return rc; 87 } 88 89 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) { 90 160 usb_log_error("SCSI Inquiry response too short (%zu).\n", 91 response_len);161 cmd.rcvd_size); 92 162 return EIO; 93 163 } … … 127 197 int usbmast_request_sense(usbmast_fun_t *mfun, void *buf, size_t size) 128 198 { 199 scsi_cmd_t cmd; 129 200 scsi_cdb_request_sense_t cdb; 130 size_t data_len;131 201 int rc; 132 202 … … 135 205 cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE); 136 206 137 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 138 sizeof(cdb), buf, size, &data_len); 139 140 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) { 141 216 usb_log_error("Request Sense failed, device %s: %s.\n", 142 217 mfun->mdev->ddf_dev->name, str_error(rc)); … … 144 219 } 145 220 146 if ( data_len< SCSI_SENSE_DATA_MIN_SIZE) {221 if (cmd.rcvd_size < SCSI_SENSE_DATA_MIN_SIZE) { 147 222 /* The missing bytes should be considered to be zeroes. */ 148 memset((uint8_t *)buf + data_len, 0,149 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); 150 225 } 151 226 … … 164 239 uint32_t *block_size) 165 240 { 241 scsi_cmd_t cmd; 166 242 scsi_cdb_read_capacity_10_t cdb; 167 243 scsi_read_capacity_10_data_t data; 168 size_t data_len;169 244 int rc; 170 245 … … 172 247 cdb.op_code = SCSI_CMD_READ_CAPACITY_10; 173 248 174 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 175 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); 176 256 177 257 if (rc != EOK) { 178 usb_log_error("Read Capacity (10) failed, device %s: %s.\n", 179 mfun->mdev->ddf_dev->name, str_error(rc)); 180 return rc; 181 } 182 183 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)) { 184 270 usb_log_error("SCSI Read Capacity response too short (%zu).\n", 185 data_len);271 cmd.rcvd_size); 186 272 return EIO; 187 273 } … … 203 289 int usbmast_read(usbmast_fun_t *mfun, uint64_t ba, size_t nblocks, void *buf) 204 290 { 205 scsi_cdb_read_12_t cdb; 206 size_t data_len; 207 int rc; 208 209 /* XXX Need softstate to store block size. */ 291 scsi_cmd_t cmd; 292 scsi_cdb_read_10_t cdb; 293 int rc; 210 294 211 295 if (ba > UINT32_MAX) 212 296 return ELIMIT; 213 297 214 if ( (uint64_t)nblocks * mfun->block_size > UINT32_MAX)298 if (nblocks > UINT16_MAX) 215 299 return ELIMIT; 216 300 217 301 memset(&cdb, 0, sizeof(cdb)); 218 cdb.op_code = SCSI_CMD_READ_1 2;302 cdb.op_code = SCSI_CMD_READ_10; 219 303 cdb.lba = host2uint32_t_be(ba); 220 cdb.xfer_len = host2uint32_t_be(nblocks); 221 222 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 223 sizeof(cdb), buf, nblocks * mfun->block_size, &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); 224 313 225 314 if (rc != EOK) { 226 usb_log_error("Read (12) failed, device %s: %s.\n", 227 mfun->mdev->ddf_dev->name, str_error(rc)); 228 return rc; 229 } 230 231 if (data_len < nblocks * mfun->block_size) { 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) { 232 327 usb_log_error("SCSI Read response too short (%zu).\n", 233 data_len);328 cmd.rcvd_size); 234 329 return EIO; 235 330 } … … 250 345 const void *data) 251 346 { 252 scsi_c db_write_12_t cdb;253 s ize_t sent_len;347 scsi_cmd_t cmd; 348 scsi_cdb_write_10_t cdb; 254 349 int rc; 255 350 … … 257 352 return ELIMIT; 258 353 259 if ( (uint64_t)nblocks * mfun->block_size > UINT32_MAX)354 if (nblocks > UINT16_MAX) 260 355 return ELIMIT; 261 356 262 357 memset(&cdb, 0, sizeof(cdb)); 263 cdb.op_code = SCSI_CMD_WRITE_1 2;358 cdb.op_code = SCSI_CMD_WRITE_10; 264 359 cdb.lba = host2uint32_t_be(ba); 265 cdb.xfer_len = host2uint32_t_be(nblocks); 266 267 rc = usb_massstor_data_out(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 268 sizeof(cdb), data, nblocks * mfun->block_size, &sent_len); 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); 269 369 270 370 if (rc != EOK) { 271 usb_log_error("Write (1 2)failed, device %s: %s.\n",272 mfun->mdev->ddf_dev->name, str_error(rc)); 273 return rc; 274 } 275 276 if ( sent_len < nblocks * mfun->block_size) {277 usb_log_error(" SCSI Write not all bytes transferred (%zu).\n",278 sent_len);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); 279 379 return EIO; 280 380 }
Note:
See TracChangeset
for help on using the changeset viewer.