Changeset f7a55f9 in mainline for uspace/drv/bus/usb/usbmast/scsi_ms.c


Ignore:
Timestamp:
2011-07-05T10:43:21Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5e2aa83, bee37cf
Parents:
b5085a7
Message:

Implement Read and Request Sense commands for USB mass storage. In bulk-only
transport fix case when less data is returned by padding + residue. Add note
for case when less data is returned by stalling the pipe.

File:
1 edited

Legend:

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

    rb5085a7 rf7a55f9  
    3838#include <byteorder.h>
    3939#include <inttypes.h>
     40#include <macros.h>
    4041#include <usb/dev/driver.h>
    4142#include <usb/debug.h>
     
    115116}
    116117
     118/** Perform SCSI Request Sense command on USB mass storage device.
     119 *
     120 * @param dev           USB device
     121 * @param buf           Destination buffer
     122 * @param size          Size of @a buf
     123 *
     124 * @return              Error code.
     125 */
     126int usbmast_request_sense(usb_device_t *dev, void *buf, size_t size)
     127{
     128        scsi_cdb_request_sense_t cdb;
     129        size_t data_len;
     130        int rc;
     131
     132        memset(&cdb, 0, sizeof(cdb));
     133        cdb.op_code = SCSI_CMD_REQUEST_SENSE;
     134        cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE);
     135
     136        rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
     137            sizeof(cdb), buf, size, &data_len);
     138
     139        if (rc != EOK) {
     140                usb_log_error("Request Sense failed, device %s: %s.\n",
     141                   dev->ddf_dev->name, str_error(rc));
     142                return rc;
     143        }
     144
     145        if (data_len < SCSI_SENSE_DATA_MIN_SIZE) {
     146                /* The missing bytes should be considered to be zeroes. */
     147                memset((uint8_t *)buf + data_len, 0,
     148                    SCSI_SENSE_DATA_MIN_SIZE - data_len);
     149        }
     150
     151        return EOK;
     152}
     153
    117154/** Perform SCSI Read Capacity command on USB mass storage device.
    118155 *
     
    155192}
    156193
     194/** Perform SCSI Read command on USB mass storage device.
     195 *
     196 * @param dev           USB device.
     197 * @param ba            Address of first block.
     198 * @param nblocks       Number of blocks to read.
     199 * @param bsize         Block size.
     200 *
     201 * @return              Error code.
     202 */
     203int usbmast_read(usb_device_t *dev, uint64_t ba, size_t nblocks, size_t bsize,
     204    void *buf)
     205{
     206        scsi_cdb_read_12_t cdb;
     207        size_t data_len;
     208        int rc;
     209
     210        /* XXX Need softstate to store block size. */
     211
     212        if (ba > UINT32_MAX)
     213                return ELIMIT;
     214
     215        if ((uint64_t)nblocks * bsize > UINT32_MAX)
     216                return ELIMIT;
     217
     218        memset(&cdb, 0, sizeof(cdb));
     219        cdb.op_code = SCSI_CMD_READ_12;
     220        cdb.lba = host2uint32_t_be(ba);
     221        cdb.xfer_len = host2uint32_t_be(nblocks);
     222
     223        rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
     224            sizeof(cdb), buf, nblocks * bsize, &data_len);
     225
     226        if (rc != EOK) {
     227                usb_log_error("Read (12) failed, device %s: %s.\n",
     228                   dev->ddf_dev->name, str_error(rc));
     229                return rc;
     230        }
     231
     232        if (data_len < nblocks * bsize) {
     233                usb_log_error("SCSI Read response too short (%zu).\n",
     234                    data_len);
     235                return EIO;
     236        }
     237
     238        return EOK;
     239}
     240
    157241/**
    158242 * @}
Note: See TracChangeset for help on using the changeset viewer.