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
File:
1 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
Note: See TracChangeset for help on using the changeset viewer.