Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset de3432b in mainline


Ignore:
Timestamp:
2011-07-24T18:09:09Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
1bfae13, 358dc13, eff10e03
Parents:
582fe388
Message:

Allow simpler passing around / processing of SCSI commands by creating
scsi_cmd_t structure which holds input and output arguments of a SCSI
command and is loosely modeled after the SAM-4 Execute Command procedure
call.

Location:
uspace/drv/bus/usb/usbmast
Files:
3 edited

Legend:

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

    r582fe388 rde3432b  
    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
    66  * @param cmd_status    Command status
     60 * @param cmd           SCSI command
    6761 *
    6862 * @return              Error code
    6963 */
    70 static int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, const void *cmd,
    71     size_t cmd_size, usb_direction_t ddir, void *dbuf, size_t dbuf_size,
    72     size_t *xferred_size, cmd_status_t *cmd_status)
     64int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, scsi_cmd_t *cmd)
    7365{
    7466        int rc;
     
    7769        usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe;
    7870        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        }
    7986
    8087        /* Prepare CBW - command block wrapper */
    8188        usb_massstor_cbw_t cbw;
    8289        usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, mfun->lun,
    83             cmd_size, cmd);
     90            cmd->cdb_size, cmd->cdb);
    8491
    8592        /* Send the CBW. */
     
    148155        switch (csw.dCSWStatus) {
    149156        case cbs_passed:
    150                 *cmd_status = CMDS_GOOD;
     157                cmd->status = CMDS_GOOD;
    151158                break;
    152159        case cbs_failed:
    153160                MASTLOG("Command failed\n");
    154                 *cmd_status = CMDS_FAILED;
     161                cmd->status = CMDS_FAILED;
    155162                break;
    156163        case cbs_phase_error:
     
    177184         */
    178185
    179         if (xferred_size != NULL)
    180                 *xferred_size = dbuf_size - residue;
     186        if (ddir == USB_DIRECTION_IN)
     187                cmd->rcvd_size = dbuf_size - residue;
    181188
    182189        return retval;
    183 }
    184 
    185 /** Perform data-in command.
    186  *
    187  * @param mfun          Mass storage function
    188  * @param tag           Command block wrapper tag (automatically compared with
    189  *                      answer)
    190  * @param cmd           CDB (Command Descriptor)
    191  * @param cmd_size      CDB length in bytes
    192  * @param dbuf          Data receive buffer
    193  * @param dbuf_size     Data receive buffer size in bytes
    194  * @param proc_size     Number of bytes actually processed by device
    195  * @param cmd_status    Command status
    196  *
    197  * @return Error code
    198  */
    199 int usb_massstor_data_in(usbmast_fun_t *mfun, uint32_t tag, const void *cmd,
    200     size_t cmd_size, void *dbuf, size_t dbuf_size, size_t *proc_size,
    201     cmd_status_t *cmd_status)
    202 {
    203         return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_IN,
    204             dbuf, dbuf_size, proc_size, cmd_status);
    205 }
    206 
    207 /** Perform data-out command.
    208  *
    209  * @param mfun          Mass storage function
    210  * @param tag           Command block wrapper tag (automatically compared with
    211  *                      answer)
    212  * @param cmd           CDB (Command Descriptor)
    213  * @param cmd_size      CDB length in bytes
    214  * @param data          Command data
    215  * @param data_size     Size of @a data in bytes
    216  * @param proc_size     Number of bytes actually processed by device
    217  * @param cmd_status    Command status
    218  *
    219  * @return Error code
    220  */
    221 int usb_massstor_data_out(usbmast_fun_t *mfun, uint32_t tag, const void *cmd,
    222     size_t cmd_size, const void *data, size_t data_size, size_t *proc_size,
    223     cmd_status_t *cmd_status)
    224 {
    225         return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_OUT,
    226             (void *) data, data_size, proc_size, cmd_status);
    227190}
    228191
  • uspace/drv/bus/usb/usbmast/bo_trans.h

    r582fe388 rde3432b  
    5252} cmd_status_t;
    5353
    54 extern int usb_massstor_data_in(usbmast_fun_t *, uint32_t, const void *,
    55     size_t, void *, size_t, size_t *, cmd_status_t *);
    56 extern int usb_massstor_data_out(usbmast_fun_t *, uint32_t, const void *,
    57     size_t, const void *, size_t, size_t *, cmd_status_t *);
     54/** SCSI command.
     55 *
     56 * Contains (a subset of) the input and output arguments of SCSI
     57 * Execute Command procedure call (see SAM-4 chapter 5.1)
     58 */
     59typedef struct {
     60        /*
     61         * Related to IN fields
     62         */
     63
     64        /** Command Descriptor Block */
     65        void *cdb;
     66        /** CDB size in bytes */
     67        size_t cdb_size;
     68
     69        /** Outgoing data */
     70        const void *data_out;
     71        /** Size of outgoing data in bytes */
     72        size_t data_out_size;
     73
     74        /*
     75         * Related to OUT fields
     76         */
     77
     78        /** Buffer for incoming data */
     79        void *data_in;
     80        /** Size of input buffer in bytes */
     81        size_t data_in_size;
     82
     83        /** Number of bytes actually received */
     84        size_t rcvd_size;
     85
     86        /** Status */
     87        cmd_status_t status;
     88} scsi_cmd_t;
     89
     90extern int usb_massstor_cmd(usbmast_fun_t *, uint32_t, scsi_cmd_t *);
    5891extern int usb_massstor_reset(usbmast_dev_t *);
    5992extern void usb_massstor_reset_recovery(usbmast_dev_t *);
  • uspace/drv/bus/usb/usbmast/scsi_ms.c

    r582fe388 rde3432b  
    8989{
    9090        scsi_std_inquiry_data_t inq_data;
    91         size_t response_len;
     91        scsi_cmd_t cmd;
    9292        scsi_cdb_inquiry_t cdb;
    93         cmd_status_t status;
    9493        int rc;
    9594
     
    9897        cdb.alloc_len = host2uint16_t_be(sizeof(inq_data));
    9998
    100         rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    101             sizeof(cdb), &inq_data, sizeof(inq_data), &response_len, &status);
     99        memset(&cmd, 0, sizeof(cmd));
     100        cmd.cdb = &cdb;
     101        cmd.cdb_size = sizeof(cdb);
     102        cmd.data_in = &inq_data;
     103        cmd.data_in_size = sizeof(inq_data);
     104
     105        rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd);
    102106
    103107        if (rc != EOK) {
     
    107111        }
    108112
    109         if (status != CMDS_GOOD) {
     113        if (cmd.status != CMDS_GOOD) {
    110114                usb_log_error("Inquiry command failed, device %s.\n",
    111115                   mfun->mdev->ddf_dev->name);
     
    114118        }
    115119
    116         if (response_len < SCSI_STD_INQUIRY_DATA_MIN_SIZE) {
     120        if (cmd.rcvd_size < SCSI_STD_INQUIRY_DATA_MIN_SIZE) {
    117121                usb_log_error("SCSI Inquiry response too short (%zu).\n",
    118                     response_len);
     122                    cmd.rcvd_size);
    119123                return EIO;
    120124        }
     
    154158int usbmast_request_sense(usbmast_fun_t *mfun, void *buf, size_t size)
    155159{
     160        scsi_cmd_t cmd;
    156161        scsi_cdb_request_sense_t cdb;
    157         size_t data_len;
    158         cmd_status_t status;
    159162        int rc;
    160163
     
    163166        cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE);
    164167
    165         rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    166             sizeof(cdb), buf, size, &data_len, &status);
    167 
    168         if (rc != EOK || status != CMDS_GOOD) {
     168        memset(&cmd, 0, sizeof(cmd));
     169        cmd.cdb = &cdb;
     170        cmd.cdb_size = sizeof(cdb);
     171        cmd.data_in = buf;
     172        cmd.data_in_size = size;
     173
     174        rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd);
     175
     176        if (rc != EOK || cmd.status != CMDS_GOOD) {
    169177                usb_log_error("Request Sense failed, device %s: %s.\n",
    170178                   mfun->mdev->ddf_dev->name, str_error(rc));
     
    172180        }
    173181
    174         if (data_len < SCSI_SENSE_DATA_MIN_SIZE) {
     182        if (cmd.rcvd_size < SCSI_SENSE_DATA_MIN_SIZE) {
    175183                /* The missing bytes should be considered to be zeroes. */
    176                 memset((uint8_t *)buf + data_len, 0,
    177                     SCSI_SENSE_DATA_MIN_SIZE - data_len);
     184                memset((uint8_t *)buf + cmd.rcvd_size, 0,
     185                    SCSI_SENSE_DATA_MIN_SIZE - cmd.rcvd_size);
    178186        }
    179187
     
    192200    uint32_t *block_size)
    193201{
     202        scsi_cmd_t cmd;
    194203        scsi_cdb_read_capacity_10_t cdb;
    195204        scsi_read_capacity_10_data_t data;
    196         size_t data_len;
    197         cmd_status_t status;
    198205        int rc;
    199206
     
    201208        cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
    202209
    203         rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    204             sizeof(cdb), &data, sizeof(data), &data_len, &status);
     210        memset(&cmd, 0, sizeof(cmd));
     211        cmd.cdb = &cdb;
     212        cmd.cdb_size = sizeof(cdb);
     213        cmd.data_in = &data;
     214        cmd.data_in_size = sizeof(data);
     215
     216        rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd);
    205217
    206218        if (rc != EOK) {
     
    210222        }
    211223
    212         if (status != CMDS_GOOD) {
     224        if (cmd.status != CMDS_GOOD) {
    213225                usb_log_error("Read Capacity (10) command failed, device %s.\n",
    214226                   mfun->mdev->ddf_dev->name);
     
    217229        }
    218230
    219         if (data_len < sizeof(data)) {
     231        if (cmd.rcvd_size < sizeof(data)) {
    220232                usb_log_error("SCSI Read Capacity response too short (%zu).\n",
    221                     data_len);
     233                    cmd.rcvd_size);
    222234                return EIO;
    223235        }
     
    239251int usbmast_read(usbmast_fun_t *mfun, uint64_t ba, size_t nblocks, void *buf)
    240252{
     253        scsi_cmd_t cmd;
    241254        scsi_cdb_read_12_t cdb;
    242         size_t data_len;
    243         cmd_status_t status;
    244         int rc;
    245 
    246         /* XXX Need softstate to store block size. */
     255        int rc;
    247256
    248257        if (ba > UINT32_MAX)
     
    257266        cdb.xfer_len = host2uint32_t_be(nblocks);
    258267
    259         rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    260             sizeof(cdb), buf, nblocks * mfun->block_size, &data_len, &status);
     268        memset(&cmd, 0, sizeof(cmd));
     269        cmd.cdb = &cdb;
     270        cmd.cdb_size = sizeof(cdb);
     271        cmd.data_in = buf;
     272        cmd.data_in_size = nblocks * mfun->block_size;
     273
     274        rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd);
    261275
    262276        if (rc != EOK) {
     
    266280        }
    267281
    268         if (status != CMDS_GOOD) {
     282        if (cmd.status != CMDS_GOOD) {
    269283                usb_log_error("Read (12) command failed, device %s.\n",
    270284                   mfun->mdev->ddf_dev->name);
     
    273287        }
    274288
    275         if (data_len < nblocks * mfun->block_size) {
     289        if (cmd.rcvd_size < nblocks * mfun->block_size) {
    276290                usb_log_error("SCSI Read response too short (%zu).\n",
    277                     data_len);
     291                    cmd.rcvd_size);
    278292                return EIO;
    279293        }
     
    294308    const void *data)
    295309{
     310        scsi_cmd_t cmd;
    296311        scsi_cdb_write_12_t cdb;
    297         size_t sent_len;
    298         cmd_status_t status;
    299312        int rc;
    300313
     
    310323        cdb.xfer_len = host2uint32_t_be(nblocks);
    311324
    312         rc = usb_massstor_data_out(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    313             sizeof(cdb), data, nblocks * mfun->block_size, &sent_len, &status);
     325        memset(&cmd, 0, sizeof(cmd));
     326        cmd.cdb = &cdb;
     327        cmd.cdb_size = sizeof(cdb);
     328        cmd.data_out = data;
     329        cmd.data_out_size = nblocks * mfun->block_size;
     330
     331        rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd);
    314332
    315333        if (rc != EOK) {
     
    319337        }
    320338
    321         if (status != CMDS_GOOD) {
     339        if (cmd.status != CMDS_GOOD) {
    322340                usb_log_error("Write (12) command failed, device %s.\n",
    323341                   mfun->mdev->ddf_dev->name);
     
    326344        }
    327345
    328         if (sent_len < nblocks * mfun->block_size) {
    329                 usb_log_error("SCSI Write not all bytes transferred (%zu).\n",
    330                     sent_len);
    331                 return EIO;
    332         }
    333 
    334346        return EOK;
    335347}
Note: See TracChangeset for help on using the changeset viewer.