Ignore:
File:
1 edited

Legend:

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

    rde3432b r2aceec5  
    5858 * @param tag           Command block wrapper tag (automatically compared
    5959 *                      with answer)
    60  * @param cmd           SCSI command
     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
    6166 *
    6267 * @return              Error code
    6368 */
    64 int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, scsi_cmd_t *cmd)
     69static 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)
    6572{
    6673        int rc;
    67         int retval = EOK;
    6874        size_t act_size;
    6975        usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe;
    7076        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         }
    8677
    8778        /* Prepare CBW - command block wrapper */
    8879        usb_massstor_cbw_t cbw;
    8980        usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, mfun->lun,
    90             cmd->cdb_size, cmd->cdb);
     81            cmd_size, cmd);
    9182
    9283        /* Send the CBW. */
    93         MASTLOG("Sending CBW.\n");
    9484        rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw));
    9585        MASTLOG("CBW '%s' sent: %s.\n",
    9686            usb_debug_str_buffer((uint8_t *) &cbw, sizeof(cbw), 0),
    9787            str_error(rc));
    98         if (rc != EOK)
    99                 return EIO;
    100 
    101         MASTLOG("Transferring data.\n");
     88        if (rc != EOK) {
     89                return rc;
     90        }
     91
    10292        if (ddir == USB_DIRECTION_IN) {
    10393                /* Recieve data from the device. */
     
    114104        }
    115105
    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;
     106        if (rc != EOK) {
     107                /*
     108                 * XXX If the pipe is stalled, we should clear it
     109                 * and read CSW.
     110                 */
     111                return rc;
    127112        }
    128113
     
    130115        usb_massstor_csw_t csw;
    131116        size_t csw_size;
    132         MASTLOG("Reading CSW.\n");
    133117        rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size);
    134118        MASTLOG("CSW '%s' received (%zu bytes): %s.\n",
     
    137121        if (rc != EOK) {
    138122                MASTLOG("rc != EOK\n");
    139                 return EIO;
     123                return rc;
    140124        }
    141125
    142126        if (csw_size != sizeof(csw)) {
    143127                MASTLOG("csw_size != sizeof(csw)\n");
    144                 return EIO;
     128                return ERANGE;
    145129        }
    146130
    147131        if (csw.dCSWTag != tag) {
    148132                MASTLOG("csw.dCSWTag != tag\n");
    149                 return EIO;
     133                return EBADCHECKSUM;
    150134        }
    151135
     
    153137         * Determine the actual return value from the CSW.
    154138         */
    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;
     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;
    170144        }
    171145
     
    173147        if (residue > dbuf_size) {
    174148                MASTLOG("residue > dbuf_size\n");
    175                 return EIO;
     149                return ERANGE;
    176150        }
    177151
     
    184158         */
    185159
    186         if (ddir == USB_DIRECTION_IN)
    187                 cmd->rcvd_size = dbuf_size - residue;
    188 
    189         return retval;
     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 */
     179int 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 */
     199int 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);
    190204}
    191205
Note: See TracChangeset for help on using the changeset viewer.