Changeset 38c9505 in mainline for uspace/drv/bus/usb/usbmast/mast.c


Ignore:
Timestamp:
2011-07-06T21:38:42Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
026793d
Parents:
ff65e91
Message:

Write support in USB mass storage driver.

File:
1 edited

Legend:

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

    rff65e91 r38c9505  
    5151        } while (false)
    5252
    53 /** Request data from mass storage device.
    54  *
    55  * @param tag Command block wrapper tag (automatically compared with answer).
    56  * @param lun LUN index.
    57  * @param cmd SCSI command buffer (in SCSI endianness).
    58  * @param cmd_size Length of SCSI command @p cmd in bytes.
    59  * @param in_buffer Buffer where to store the answer (CSW is not returned).
    60  * @param in_buffer_size Size of the buffer (size of the request to the device).
    61  * @param received_size Number of actually received bytes.
    62  * @return Error code.
    63  */
    64 int usb_massstor_data_in(usb_device_t *dev,
    65     uint32_t tag, uint8_t lun, void *cmd, size_t cmd_size,
    66     void *in_buffer, size_t in_buffer_size, size_t *received_size)
     53/** Send command via bulk-only transport.
     54 *
     55 * @param tag           Command block wrapper tag (automatically compared
     56 *                      with answer)
     57 * @param lun           LUN
     58 * @param cmd           Command block
     59 * @param cmd_size      Command block size in bytes
     60 * @param ddir          Direction in which data will be transferred
     61 * @param dbuf          Data send/receive buffer
     62 * @param dbuf_size     Size of the data buffer
     63 * @param xferred_size  Number of bytes actually transferred
     64 *
     65 * @return              Error code
     66 */
     67static int usb_massstor_cmd(usb_device_t *dev, uint32_t tag, uint8_t lun,
     68    const void *cmd, size_t cmd_size, usb_direction_t ddir, void *dbuf,
     69    size_t dbuf_size, size_t *xferred_size)
    6770{
    6871        int rc;
     
    7376        /* Prepare CBW - command block wrapper */
    7477        usb_massstor_cbw_t cbw;
    75         usb_massstor_cbw_prepare(&cbw, tag, in_buffer_size,
    76             USB_DIRECTION_IN, lun, cmd_size, cmd);
    77 
    78         /* First, send the CBW. */
     78        usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, lun, cmd_size,
     79            cmd);
     80
     81        /* Send the CBW. */
    7982        rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw));
    8083        MASTLOG("CBW '%s' sent: %s.\n",
     
    8588        }
    8689
    87         /* Try to retrieve the data from the device. */
    88         act_size = 0;
    89         rc = usb_pipe_read(bulk_in_pipe, in_buffer, in_buffer_size, &act_size);
    90         MASTLOG("Received %zuB (%s): %s.\n", act_size,
    91             usb_debug_str_buffer((uint8_t *) in_buffer, act_size, 0),
    92             str_error(rc));
     90        if (ddir == USB_DIRECTION_IN) {
     91                /* Recieve data from the device. */
     92                rc = usb_pipe_read(bulk_in_pipe, dbuf, dbuf_size, &act_size);
     93                MASTLOG("Received %zu bytes (%s): %s.\n", act_size,
     94                    usb_debug_str_buffer((uint8_t *) dbuf, act_size, 0),
     95                    str_error(rc));
     96        } else {
     97                /* Send data to the device. */
     98                rc = usb_pipe_write(bulk_out_pipe, dbuf, dbuf_size);
     99                MASTLOG("Sent %zu bytes (%s): %s.\n", act_size,
     100                    usb_debug_str_buffer((uint8_t *) dbuf, act_size, 0),
     101                    str_error(rc));
     102        }
     103
    93104        if (rc != EOK) {
    94105                /*
     
    103114        size_t csw_size;
    104115        rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size);
    105         MASTLOG("CSW '%s' received (%zuB): %s.\n",
     116        MASTLOG("CSW '%s' received (%zu bytes): %s.\n",
    106117            usb_debug_str_buffer((uint8_t *) &csw, csw_size, 0), csw_size,
    107118            str_error(rc));
     
    132143
    133144        size_t residue = (size_t) uint32_usb2host(csw.dCSWDataResidue);
    134         if (residue > in_buffer_size) {
    135                 MASTLOG("residue > in_buffer_size\n");
     145        if (residue > dbuf_size) {
     146                MASTLOG("residue > dbuf_size\n");
    136147                return ERANGE;
    137148        }
    138149
    139150        /*
    140          * When the device has less data to send than requested, it can
    141          * either stall the pipe or send garbage and indicate that via
    142          * the residue field in CSW. That means in_buffer_size - residue
    143          * is the authoritative size of data received.
     151         * When the device has less data to send than requested (or cannot
     152         * receive moredata), it can either stall the pipe or send garbage
     153         * (ignore data) and indicate that via the residue field in CSW.
     154         * That means dbuf_size - residue is the authoritative size of data
     155         * received (sent).
    144156         */
    145157
    146         if (received_size != NULL) {
    147                 *received_size = in_buffer_size - residue;
    148         }
     158        if (xferred_size != NULL)
     159                *xferred_size = dbuf_size - residue;
    149160
    150161        return EOK;
     162}
     163
     164/** Perform data-in command.
     165 *
     166 * @param tag           Command block wrapper tag (automatically compared with
     167 *                      answer)
     168 * @param lun           LUN
     169 * @param cmd           CDB (Command Descriptor)
     170 * @param cmd_size      CDB length in bytes
     171 * @param dbuf          Data receive buffer
     172 * @param dbuf_size     Data receive buffer size in bytes
     173 * @param proc_size     Number of bytes actually processed by device
     174 *
     175 * @return Error code
     176 */
     177int usb_massstor_data_in(usb_device_t *dev, uint32_t tag, uint8_t lun,
     178    const void *cmd, size_t cmd_size, void *dbuf, size_t dbuf_size, size_t *proc_size)
     179{
     180        return usb_massstor_cmd(dev, tag, lun, cmd, cmd_size, USB_DIRECTION_IN,
     181            dbuf, dbuf_size, proc_size);
     182}
     183
     184/** Perform data-out command.
     185 *
     186 * @param tag           Command block wrapper tag (automatically compared with
     187 *                      answer)
     188 * @param lun           LUN
     189 * @param cmd           CDB (Command Descriptor)
     190 * @param cmd_size      CDB length in bytes
     191 * @param data          Command data
     192 * @param data_size     Size of @a data in bytes
     193 * @param proc_size     Number of bytes actually processed by device
     194 *
     195 * @return Error code
     196 */
     197int usb_massstor_data_out(usb_device_t *dev, uint32_t tag, uint8_t lun,
     198    const void *cmd, size_t cmd_size, const void *data, size_t data_size,
     199    size_t *proc_size)
     200{
     201        return usb_massstor_cmd(dev, tag, lun, cmd, cmd_size, USB_DIRECTION_OUT,
     202            (void *) data, data_size, proc_size);
    151203}
    152204
Note: See TracChangeset for help on using the changeset viewer.