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/bo_trans.c

    r9350bfdd r7ae249d  
    5858 * @param tag           Command block wrapper tag (automatically compared
    5959 *                      with answer)
    60  * @param cmd           Command block
    61  * @param cmd_size      Command block size in bytes
    62  * @param ddir          Direction in which data will be transferred
    63  * @param dbuf          Data send/receive buffer
    64  * @param dbuf_size     Size of the data buffer
    65  * @param xferred_size  Number of bytes actually transferred
     60 * @param cmd           SCSI command
    6661 *
    6762 * @return              Error code
    6863 */
    69 static int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, const void *cmd,
    70     size_t cmd_size, usb_direction_t ddir, void *dbuf, size_t dbuf_size,
    71     size_t *xferred_size)
     64int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, scsi_cmd_t *cmd)
    7265{
    7366        int rc;
     67        int retval = EOK;
    7468        size_t act_size;
    7569        usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe;
    7670        usb_pipe_t *bulk_out_pipe = mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe;
     71        usb_direction_t ddir;
     72        void *dbuf;
     73        size_t dbuf_size;
     74
     75        if (cmd->data_out != NULL && cmd->data_in == NULL) {
     76                ddir = USB_DIRECTION_OUT;
     77                dbuf = (void *)cmd->data_out;
     78                dbuf_size = cmd->data_out_size;
     79        } else if (cmd->data_out == NULL && cmd->data_in != NULL) {
     80                ddir = USB_DIRECTION_IN;
     81                dbuf = cmd->data_in;
     82                dbuf_size = cmd->data_in_size;
     83        } else {
     84                assert(false);
     85        }
    7786
    7887        /* Prepare CBW - command block wrapper */
    7988        usb_massstor_cbw_t cbw;
    8089        usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, mfun->lun,
    81             cmd_size, cmd);
     90            cmd->cdb_size, cmd->cdb);
    8291
    8392        /* Send the CBW. */
     93        MASTLOG("Sending CBW.\n");
    8494        rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw));
    8595        MASTLOG("CBW '%s' sent: %s.\n",
    8696            usb_debug_str_buffer((uint8_t *) &cbw, sizeof(cbw), 0),
    8797            str_error(rc));
    88         if (rc != EOK) {
    89                 return rc;
    90         }
    91 
     98        if (rc != EOK)
     99                return EIO;
     100
     101        MASTLOG("Transferring data.\n");
    92102        if (ddir == USB_DIRECTION_IN) {
    93103                /* Recieve data from the device. */
     
    104114        }
    105115
    106         if (rc != EOK) {
    107                 /*
    108                  * XXX If the pipe is stalled, we should clear it
    109                  * and read CSW.
    110                  */
    111                 return rc;
     116        if (rc == ESTALL) {
     117                /* Clear stall condition and continue below to read CSW. */
     118                if (ddir == USB_DIRECTION_IN) {
     119                        usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe,
     120                            mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe);
     121                } else {
     122                        usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe,
     123                            mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe);
     124                }
     125        } else if (rc != EOK) {
     126                return EIO;
    112127        }
    113128
     
    115130        usb_massstor_csw_t csw;
    116131        size_t csw_size;
     132        MASTLOG("Reading CSW.\n");
    117133        rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size);
    118134        MASTLOG("CSW '%s' received (%zu bytes): %s.\n",
     
    121137        if (rc != EOK) {
    122138                MASTLOG("rc != EOK\n");
    123                 return rc;
     139                return EIO;
    124140        }
    125141
    126142        if (csw_size != sizeof(csw)) {
    127143                MASTLOG("csw_size != sizeof(csw)\n");
    128                 return ERANGE;
     144                return EIO;
    129145        }
    130146
    131147        if (csw.dCSWTag != tag) {
    132148                MASTLOG("csw.dCSWTag != tag\n");
    133                 return EBADCHECKSUM;
     149                return EIO;
    134150        }
    135151
     
    137153         * Determine the actual return value from the CSW.
    138154         */
    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;
     155        switch (csw.dCSWStatus) {
     156        case cbs_passed:
     157                cmd->status = CMDS_GOOD;
     158                break;
     159        case cbs_failed:
     160                MASTLOG("Command failed\n");
     161                cmd->status = CMDS_FAILED;
     162                break;
     163        case cbs_phase_error:
     164                MASTLOG("Phase error\n");
     165                retval = EIO;
     166                break;
     167        default:
     168                retval = EIO;
     169                break;
    144170        }
    145171
     
    147173        if (residue > dbuf_size) {
    148174                MASTLOG("residue > dbuf_size\n");
    149                 return ERANGE;
     175                return EIO;
    150176        }
    151177
     
    158184         */
    159185
    160         if (xferred_size != NULL)
    161                 *xferred_size = dbuf_size - residue;
    162 
    163         return EOK;
    164 }
    165 
    166 /** Perform data-in command.
    167  *
    168  * @param mfun          Mass storage function
    169  * @param tag           Command block wrapper tag (automatically compared with
    170  *                      answer)
    171  * @param cmd           CDB (Command Descriptor)
    172  * @param cmd_size      CDB length in bytes
    173  * @param dbuf          Data receive buffer
    174  * @param dbuf_size     Data receive buffer size in bytes
    175  * @param proc_size     Number of bytes actually processed by device
    176  *
    177  * @return Error code
    178  */
    179 int 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)
    181 {
    182         return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_IN,
    183             dbuf, dbuf_size, proc_size);
    184 }
    185 
    186 /** Perform data-out command.
    187  *
    188  * @param mfun          Mass storage function
    189  * @param tag           Command block wrapper tag (automatically compared with
    190  *                      answer)
    191  * @param cmd           CDB (Command Descriptor)
    192  * @param cmd_size      CDB length in bytes
    193  * @param data          Command data
    194  * @param data_size     Size of @a data in bytes
    195  * @param proc_size     Number of bytes actually processed by device
    196  *
    197  * @return Error code
    198  */
    199 int 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)
    201 {
    202         return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_OUT,
    203             (void *) data, data_size, proc_size);
     186        if (ddir == USB_DIRECTION_IN)
     187                cmd->rcvd_size = dbuf_size - residue;
     188
     189        return retval;
    204190}
    205191
Note: See TracChangeset for help on using the changeset viewer.