Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbmast/scsi_ms.c

    r132a6073 r2aceec5  
    6161}
    6262
    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 
    12263/** Perform SCSI Inquiry command on USB mass storage device.
    12364 *
     
    12970{
    13071        scsi_std_inquiry_data_t inq_data;
    131         scsi_cmd_t cmd;
     72        size_t response_len;
    13273        scsi_cdb_inquiry_t cdb;
    13374        int rc;
     
    13778        cdb.alloc_len = host2uint16_t_be(sizeof(inq_data));
    13879
    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);
     80        rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
     81            sizeof(cdb), &inq_data, sizeof(inq_data), &response_len);
    14682
    14783        if (rc != EOK) {
    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) {
     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) {
    16090                usb_log_error("SCSI Inquiry response too short (%zu).\n",
    161                     cmd.rcvd_size);
     91                    response_len);
    16292                return EIO;
    16393        }
     
    197127int usbmast_request_sense(usbmast_fun_t *mfun, void *buf, size_t size)
    198128{
    199         scsi_cmd_t cmd;
    200129        scsi_cdb_request_sense_t cdb;
     130        size_t data_len;
    201131        int rc;
    202132
     
    205135        cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE);
    206136
    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) {
     137        rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
     138            sizeof(cdb), buf, size, &data_len);
     139
     140        if (rc != EOK) {
    216141                usb_log_error("Request Sense failed, device %s: %s.\n",
    217142                   mfun->mdev->ddf_dev->name, str_error(rc));
     
    219144        }
    220145
    221         if (cmd.rcvd_size < SCSI_SENSE_DATA_MIN_SIZE) {
     146        if (data_len < SCSI_SENSE_DATA_MIN_SIZE) {
    222147                /* The missing bytes should be considered to be zeroes. */
    223                 memset((uint8_t *)buf + cmd.rcvd_size, 0,
    224                     SCSI_SENSE_DATA_MIN_SIZE - cmd.rcvd_size);
     148                memset((uint8_t *)buf + data_len, 0,
     149                    SCSI_SENSE_DATA_MIN_SIZE - data_len);
    225150        }
    226151
     
    239164    uint32_t *block_size)
    240165{
    241         scsi_cmd_t cmd;
    242166        scsi_cdb_read_capacity_10_t cdb;
    243167        scsi_read_capacity_10_data_t data;
     168        size_t data_len;
    244169        int rc;
    245170
     
    247172        cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
    248173
    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);
    256 
    257         if (rc != EOK) {
    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)) {
     174        rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
     175            sizeof(cdb), &data, sizeof(data), &data_len);
     176
     177        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)) {
    270184                usb_log_error("SCSI Read Capacity response too short (%zu).\n",
    271                     cmd.rcvd_size);
     185                    data_len);
    272186                return EIO;
    273187        }
     
    289203int usbmast_read(usbmast_fun_t *mfun, uint64_t ba, size_t nblocks, void *buf)
    290204{
    291         scsi_cmd_t cmd;
    292         scsi_cdb_read_10_t cdb;
    293         int rc;
     205        scsi_cdb_read_12_t cdb;
     206        size_t data_len;
     207        int rc;
     208
     209        /* XXX Need softstate to store block size. */
    294210
    295211        if (ba > UINT32_MAX)
    296212                return ELIMIT;
    297213
    298         if (nblocks > UINT16_MAX)
    299                 return ELIMIT;
    300 
    301         memset(&cdb, 0, sizeof(cdb));
    302         cdb.op_code = SCSI_CMD_READ_10;
     214        if ((uint64_t)nblocks * mfun->block_size > UINT32_MAX)
     215                return ELIMIT;
     216
     217        memset(&cdb, 0, sizeof(cdb));
     218        cdb.op_code = SCSI_CMD_READ_12;
    303219        cdb.lba = host2uint32_t_be(ba);
    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);
    313 
    314         if (rc != EOK) {
    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) {
     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);
     224
     225        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) {
    327232                usb_log_error("SCSI Read response too short (%zu).\n",
    328                     cmd.rcvd_size);
     233                    data_len);
    329234                return EIO;
    330235        }
     
    345250    const void *data)
    346251{
    347         scsi_cmd_t cmd;
    348         scsi_cdb_write_10_t cdb;
     252        scsi_cdb_write_12_t cdb;
     253        size_t sent_len;
    349254        int rc;
    350255
     
    352257                return ELIMIT;
    353258
    354         if (nblocks > UINT16_MAX)
    355                 return ELIMIT;
    356 
    357         memset(&cdb, 0, sizeof(cdb));
    358         cdb.op_code = SCSI_CMD_WRITE_10;
     259        if ((uint64_t)nblocks * mfun->block_size > UINT32_MAX)
     260                return ELIMIT;
     261
     262        memset(&cdb, 0, sizeof(cdb));
     263        cdb.op_code = SCSI_CMD_WRITE_12;
    359264        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);
     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);
     269
     270        if (rc != EOK) {
     271                usb_log_error("Write (12) 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);
    379279                return EIO;
    380280        }
Note: See TracChangeset for help on using the changeset viewer.