Changeset 45cae6b in mainline


Ignore:
Timestamp:
2011-07-24T16:05:37Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
582fe388
Parents:
4022513
Message:

Work on USB mass storage:

  • handle pipe stalls when transferring data
  • distinguish between transport failure and failed command (i.e. check condition)
  • when a command fails, read sense data and log sense key, ASC, ASCQ
Location:
uspace
Files:
5 edited

Legend:

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

    r4022513 r45cae6b  
    6464 * @param dbuf_size     Size of the data buffer
    6565 * @param xferred_size  Number of bytes actually transferred
     66 * @param cmd_status    Command status
    6667 *
    6768 * @return              Error code
     
    6970static int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, const void *cmd,
    7071    size_t cmd_size, usb_direction_t ddir, void *dbuf, size_t dbuf_size,
    71     size_t *xferred_size)
     72    size_t *xferred_size, cmd_status_t *cmd_status)
    7273{
    7374        int rc;
     75        int retval = EOK;
    7476        size_t act_size;
    7577        usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe;
     
    8284
    8385        /* Send the CBW. */
     86        MASTLOG("Sending CBW.\n");
    8487        rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw));
    8588        MASTLOG("CBW '%s' sent: %s.\n",
    8689            usb_debug_str_buffer((uint8_t *) &cbw, sizeof(cbw), 0),
    8790            str_error(rc));
    88         if (rc != EOK) {
    89                 return rc;
    90         }
    91 
     91        if (rc != EOK)
     92                return EIO;
     93
     94        MASTLOG("Transferring data.\n");
    9295        if (ddir == USB_DIRECTION_IN) {
    9396                /* Recieve data from the device. */
     
    104107        }
    105108
    106         if (rc != EOK) {
    107                 /*
    108                  * XXX If the pipe is stalled, we should clear it
    109                  * and read CSW.
    110                  */
    111                 return rc;
     109        if (rc == ESTALL) {
     110                /* Clear stall condition and continue below to read CSW. */
     111                if (ddir == USB_DIRECTION_IN) {
     112                        usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe,
     113                            mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe);
     114                } else {
     115                        usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe,
     116                            mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe);
     117                }
     118        } else if (rc != EOK) {
     119                return EIO;
    112120        }
    113121
     
    115123        usb_massstor_csw_t csw;
    116124        size_t csw_size;
     125        MASTLOG("Reading CSW.\n");
    117126        rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size);
    118127        MASTLOG("CSW '%s' received (%zu bytes): %s.\n",
     
    121130        if (rc != EOK) {
    122131                MASTLOG("rc != EOK\n");
    123                 return rc;
     132                return EIO;
    124133        }
    125134
    126135        if (csw_size != sizeof(csw)) {
    127136                MASTLOG("csw_size != sizeof(csw)\n");
    128                 return ERANGE;
     137                return EIO;
    129138        }
    130139
    131140        if (csw.dCSWTag != tag) {
    132141                MASTLOG("csw.dCSWTag != tag\n");
    133                 return EBADCHECKSUM;
     142                return EIO;
    134143        }
    135144
     
    137146         * Determine the actual return value from the CSW.
    138147         */
    139         if (csw.dCSWStatus != 0) {
    140                 MASTLOG("csw.dCSWStatus != 0\n");
    141                 // FIXME: better error code
    142                 // FIXME: distinguish 0x01 and 0x02
    143                 return EXDEV;
     148        switch (csw.dCSWStatus) {
     149        case cbs_passed:
     150                *cmd_status = CMDS_GOOD;
     151                break;
     152        case cbs_failed:
     153                MASTLOG("Command failed\n");
     154                *cmd_status = CMDS_FAILED;
     155                break;
     156        case cbs_phase_error:
     157                MASTLOG("Phase error\n");
     158                retval = EIO;
     159                break;
     160        default:
     161                retval = EIO;
     162                break;
    144163        }
    145164
     
    147166        if (residue > dbuf_size) {
    148167                MASTLOG("residue > dbuf_size\n");
    149                 return ERANGE;
     168                return EIO;
    150169        }
    151170
     
    161180                *xferred_size = dbuf_size - residue;
    162181
    163         return EOK;
     182        return retval;
    164183}
    165184
     
    174193 * @param dbuf_size     Data receive buffer size in bytes
    175194 * @param proc_size     Number of bytes actually processed by device
     195 * @param cmd_status    Command status
    176196 *
    177197 * @return Error code
    178198 */
    179199int usb_massstor_data_in(usbmast_fun_t *mfun, uint32_t tag, const void *cmd,
    180     size_t cmd_size, void *dbuf, size_t dbuf_size, size_t *proc_size)
     200    size_t cmd_size, void *dbuf, size_t dbuf_size, size_t *proc_size,
     201    cmd_status_t *cmd_status)
    181202{
    182203        return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_IN,
    183             dbuf, dbuf_size, proc_size);
     204            dbuf, dbuf_size, proc_size, cmd_status);
    184205}
    185206
     
    194215 * @param data_size     Size of @a data in bytes
    195216 * @param proc_size     Number of bytes actually processed by device
     217 * @param cmd_status    Command status
    196218 *
    197219 * @return Error code
    198220 */
    199221int usb_massstor_data_out(usbmast_fun_t *mfun, uint32_t tag, const void *cmd,
    200     size_t cmd_size, const void *data, size_t data_size, size_t *proc_size)
     222    size_t cmd_size, const void *data, size_t data_size, size_t *proc_size,
     223    cmd_status_t *cmd_status)
    201224{
    202225        return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_OUT,
    203             (void *) data, data_size, proc_size);
     226            (void *) data, data_size, proc_size, cmd_status);
    204227}
    205228
  • uspace/drv/bus/usb/usbmast/bo_trans.h

    r4022513 r45cae6b  
    4747#define BULK_OUT_EP 1
    4848
     49typedef enum cmd_status {
     50        CMDS_GOOD,
     51        CMDS_FAILED
     52} cmd_status_t;
     53
    4954extern int usb_massstor_data_in(usbmast_fun_t *, uint32_t, const void *,
    50     size_t, void *, size_t, size_t *);
     55    size_t, void *, size_t, size_t *, cmd_status_t *);
    5156extern int usb_massstor_data_out(usbmast_fun_t *, uint32_t, const void *,
    52     size_t, const void *, size_t, size_t *);
     57    size_t, const void *, size_t, size_t *, cmd_status_t *);
    5358extern int usb_massstor_reset(usbmast_dev_t *);
    5459extern void usb_massstor_reset_recovery(usbmast_dev_t *);
  • uspace/drv/bus/usb/usbmast/cmdw.h

    r4022513 r45cae6b  
    5757} __attribute__((packed)) usb_massstor_csw_t;
    5858
     59enum cmd_block_status {
     60        cbs_passed      = 0x00,
     61        cbs_failed      = 0x01,
     62        cbs_phase_error = 0x02
     63};
     64
    5965extern void usb_massstor_cbw_prepare(usb_massstor_cbw_t *, uint32_t, uint32_t,
    6066    usb_direction_t, uint8_t, uint8_t, const uint8_t *);
  • uspace/drv/bus/usb/usbmast/scsi_ms.c

    r4022513 r45cae6b  
    6161}
    6262
     63static void usbmast_dump_sense(usbmast_fun_t *mfun)
     64{
     65        scsi_sense_data_t sense_buf;
     66        int rc;
     67
     68        rc = usbmast_request_sense(mfun, &sense_buf, sizeof(sense_buf));
     69        if (rc == EOK) {
     70                printf("Got sense data (sense_key=0x%x, asc=0x%02x, "
     71                    "ascq=0x%02x.\n", sense_buf.flags_key & 0x0f,
     72                    sense_buf.additional_code,
     73                    sense_buf.additional_cqual);
     74        } else {
     75                printf("Failed to read sense data.\n");
     76        }
     77}
     78
    6379/** Perform SCSI Inquiry command on USB mass storage device.
    6480 *
     
    7288        size_t response_len;
    7389        scsi_cdb_inquiry_t cdb;
     90        cmd_status_t status;
    7491        int rc;
    7592
     
    7996
    8097        rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    81             sizeof(cdb), &inq_data, sizeof(inq_data), &response_len);
     98            sizeof(cdb), &inq_data, sizeof(inq_data), &response_len, &status);
    8299
    83100        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;
     101                usb_log_error("Inquiry transport failed, device %s: %s.\n",
     102                   mfun->mdev->ddf_dev->name, str_error(rc));
     103                return rc;
     104        }
     105
     106        if (status != CMDS_GOOD) {
     107                usb_log_error("Inquiry command failed, device %s.\n",
     108                   mfun->mdev->ddf_dev->name);
     109                usbmast_dump_sense(mfun);
     110                return EIO;
    87111        }
    88112
     
    129153        scsi_cdb_request_sense_t cdb;
    130154        size_t data_len;
     155        cmd_status_t status;
    131156        int rc;
    132157
     
    136161
    137162        rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    138             sizeof(cdb), buf, size, &data_len);
    139 
    140         if (rc != EOK) {
     163            sizeof(cdb), buf, size, &data_len, &status);
     164
     165        if (rc != EOK || status != CMDS_GOOD) {
    141166                usb_log_error("Request Sense failed, device %s: %s.\n",
    142167                   mfun->mdev->ddf_dev->name, str_error(rc));
     
    167192        scsi_read_capacity_10_data_t data;
    168193        size_t data_len;
     194        cmd_status_t status;
    169195        int rc;
    170196
     
    173199
    174200        rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    175             sizeof(cdb), &data, sizeof(data), &data_len);
     201            sizeof(cdb), &data, sizeof(data), &data_len, &status);
    176202
    177203        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;
     204                usb_log_error("Read Capacity (10) transport failed, device %s: %s.\n",
     205                   mfun->mdev->ddf_dev->name, str_error(rc));
     206                return rc;
     207        }
     208
     209        if (status != CMDS_GOOD) {
     210                usb_log_error("Read Capacity (10) command failed, device %s.\n",
     211                   mfun->mdev->ddf_dev->name);
     212                usbmast_dump_sense(mfun);
     213                return EIO;
    181214        }
    182215
     
    205238        scsi_cdb_read_12_t cdb;
    206239        size_t data_len;
     240        cmd_status_t status;
    207241        int rc;
    208242
     
    221255
    222256        rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    223             sizeof(cdb), buf, nblocks * mfun->block_size, &data_len);
     257            sizeof(cdb), buf, nblocks * mfun->block_size, &data_len, &status);
    224258
    225259        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;
     260                usb_log_error("Read (12) transport failed, device %s: %s.\n",
     261                   mfun->mdev->ddf_dev->name, str_error(rc));
     262                return rc;
     263        }
     264
     265        if (status != CMDS_GOOD) {
     266                usb_log_error("Read (12) command failed, device %s.\n",
     267                   mfun->mdev->ddf_dev->name);
     268                usbmast_dump_sense(mfun);
     269                return EIO;
    229270        }
    230271
     
    252293        scsi_cdb_write_12_t cdb;
    253294        size_t sent_len;
     295        cmd_status_t status;
    254296        int rc;
    255297
     
    266308
    267309        rc = usb_massstor_data_out(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    268             sizeof(cdb), data, nblocks * mfun->block_size, &sent_len);
     310            sizeof(cdb), data, nblocks * mfun->block_size, &sent_len, &status);
    269311
    270312        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;
     313                usb_log_error("Write (12) transport failed, device %s: %s.\n",
     314                   mfun->mdev->ddf_dev->name, str_error(rc));
     315                return rc;
     316        }
     317
     318        if (status != CMDS_GOOD) {
     319                usb_log_error("Write (12) command failed, device %s.\n",
     320                   mfun->mdev->ddf_dev->name);
     321                usbmast_dump_sense(mfun);
     322                return EIO;
    274323        }
    275324
  • uspace/lib/scsi/include/scsi/spc.h

    r4022513 r45cae6b  
    179179        uint8_t additional_len;
    180180        /** Command-specific Information */
    181         uint8_t cmd_spec;
     181        uint32_t cmd_spec;
    182182        /** Additional Sense Code */
    183183        uint8_t additional_code;
Note: See TracChangeset for help on using the changeset viewer.