Changeset 7ae249d in mainline for uspace/drv/bus/usb/usbmast/scsi_ms.c


Ignore:
Timestamp:
2011-07-29T14:47:52Z (13 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
00c2de63, 1814ee4d, ffff746
Parents:
9350bfdd (diff), f5d51de (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.
Message:

Merge mainline.

File:
1 edited

Legend:

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

    r9350bfdd r7ae249d  
    6161}
    6262
     63static 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 */
     80static 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
    63122/** Perform SCSI Inquiry command on USB mass storage device.
    64123 *
     
    70129{
    71130        scsi_std_inquiry_data_t inq_data;
    72         size_t response_len;
     131        scsi_cmd_t cmd;
    73132        scsi_cdb_inquiry_t cdb;
    74133        int rc;
     
    78137        cdb.alloc_len = host2uint16_t_be(sizeof(inq_data));
    79138
    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);
    82146
    83147        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) {
    90160                usb_log_error("SCSI Inquiry response too short (%zu).\n",
    91                     response_len);
     161                    cmd.rcvd_size);
    92162                return EIO;
    93163        }
     
    127197int usbmast_request_sense(usbmast_fun_t *mfun, void *buf, size_t size)
    128198{
     199        scsi_cmd_t cmd;
    129200        scsi_cdb_request_sense_t cdb;
    130         size_t data_len;
    131201        int rc;
    132202
     
    135205        cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE);
    136206
    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) {
    141216                usb_log_error("Request Sense failed, device %s: %s.\n",
    142217                   mfun->mdev->ddf_dev->name, str_error(rc));
     
    144219        }
    145220
    146         if (data_len < SCSI_SENSE_DATA_MIN_SIZE) {
     221        if (cmd.rcvd_size < SCSI_SENSE_DATA_MIN_SIZE) {
    147222                /* 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);
    150225        }
    151226
     
    164239    uint32_t *block_size)
    165240{
     241        scsi_cmd_t cmd;
    166242        scsi_cdb_read_capacity_10_t cdb;
    167243        scsi_read_capacity_10_data_t data;
    168         size_t data_len;
    169244        int rc;
    170245
     
    172247        cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
    173248
    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);
    176256
    177257        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)) {
    184270                usb_log_error("SCSI Read Capacity response too short (%zu).\n",
    185                     data_len);
     271                    cmd.rcvd_size);
    186272                return EIO;
    187273        }
     
    203289int usbmast_read(usbmast_fun_t *mfun, uint64_t ba, size_t nblocks, void *buf)
    204290{
    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;
    210294
    211295        if (ba > UINT32_MAX)
    212296                return ELIMIT;
    213297
    214         if ((uint64_t)nblocks * mfun->block_size > UINT32_MAX)
     298        if (nblocks > UINT16_MAX)
    215299                return ELIMIT;
    216300
    217301        memset(&cdb, 0, sizeof(cdb));
    218         cdb.op_code = SCSI_CMD_READ_12;
     302        cdb.op_code = SCSI_CMD_READ_10;
    219303        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);
    224313
    225314        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) {
    232327                usb_log_error("SCSI Read response too short (%zu).\n",
    233                     data_len);
     328                    cmd.rcvd_size);
    234329                return EIO;
    235330        }
     
    250345    const void *data)
    251346{
    252         scsi_cdb_write_12_t cdb;
    253         size_t sent_len;
     347        scsi_cmd_t cmd;
     348        scsi_cdb_write_10_t cdb;
    254349        int rc;
    255350
     
    257352                return ELIMIT;
    258353
    259         if ((uint64_t)nblocks * mfun->block_size > UINT32_MAX)
     354        if (nblocks > UINT16_MAX)
    260355                return ELIMIT;
    261356
    262357        memset(&cdb, 0, sizeof(cdb));
    263         cdb.op_code = SCSI_CMD_WRITE_12;
     358        cdb.op_code = SCSI_CMD_WRITE_10;
    264359        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);
    269369
    270370        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);
     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);
    279379                return EIO;
    280380        }
Note: See TracChangeset for help on using the changeset viewer.