Changeset f7a55f9 in mainline
- Timestamp:
- 2011-07-05T10:43:21Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5e2aa83, bee37cf
- Parents:
- b5085a7
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbmast/main.c
rb5085a7 rf7a55f9 138 138 "block_size=%" PRIu32 "\n", nblocks, block_size); 139 139 140 usb_log_info("Doing test read of block 0.\n"); 141 static uint8_t bdata[512]; 142 143 rc = usbmast_read(dev, 0, 1, 512, &bdata); 144 if (rc != EOK) { 145 usb_log_warning("Failed to read block 0, device `%s': %s.\n", 146 dev->ddf_dev->name, str_error(rc)); 147 return EOK; 148 } 149 150 usb_log_info("Requesting sense data.\n"); 151 static scsi_sense_data_t sdata; 152 153 rc = usbmast_request_sense(dev, &sdata, sizeof(sdata)); 154 if (rc != EOK) { 155 usb_log_warning("Failed to get sense data, device `%s': %s.\n", 156 dev->ddf_dev->name, str_error(rc)); 157 return EOK; 158 } 159 140 160 return EOK; 141 161 } -
uspace/drv/bus/usb/usbmast/mast.c
rb5085a7 rf7a55f9 92 92 str_error(rc)); 93 93 if (rc != EOK) { 94 /* 95 * XXX If the pipe is stalled, we should clear it 96 * and read CSW. 97 */ 94 98 return rc; 95 99 } … … 103 107 str_error(rc)); 104 108 if (rc != EOK) { 105 return rc; 106 } 109 MASTLOG("rc != EOK\n"); 110 return rc; 111 } 112 107 113 if (csw_size != sizeof(csw)) { 114 MASTLOG("csw_size != sizeof(csw)\n"); 108 115 return ERANGE; 109 116 } 110 117 111 118 if (csw.dCSWTag != tag) { 119 MASTLOG("csw.dCSWTag != tag\n"); 112 120 return EBADCHECKSUM; 113 121 } … … 117 125 */ 118 126 if (csw.dCSWStatus != 0) { 127 MASTLOG("csw.dCSWStatus != 0\n"); 119 128 // FIXME: better error code 120 129 // FIXME: distinguish 0x01 and 0x02 … … 124 133 size_t residue = (size_t) uint32_usb2host(csw.dCSWDataResidue); 125 134 if (residue > in_buffer_size) { 135 MASTLOG("residue > in_buffer_size\n"); 126 136 return ERANGE; 127 137 } 128 if (act_size != in_buffer_size - residue) { 129 return ERANGE; 130 } 138 139 /* 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. 144 */ 145 131 146 if (received_size != NULL) { 132 147 *received_size = in_buffer_size - residue; -
uspace/drv/bus/usb/usbmast/scsi_ms.c
rb5085a7 rf7a55f9 38 38 #include <byteorder.h> 39 39 #include <inttypes.h> 40 #include <macros.h> 40 41 #include <usb/dev/driver.h> 41 42 #include <usb/debug.h> … … 115 116 } 116 117 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 */ 126 int 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 117 154 /** Perform SCSI Read Capacity command on USB mass storage device. 118 155 * … … 155 192 } 156 193 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 */ 203 int 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 157 241 /** 158 242 * @} -
uspace/drv/bus/usb/usbmast/scsi_ms.h
rb5085a7 rf7a55f9 60 60 61 61 extern int usbmast_inquiry(usb_device_t *, usbmast_inquiry_data_t *); 62 extern int usbmast_read_capacity(usb_device_t *dev, uint32_t *, uint32_t *); 62 extern int usbmast_request_sense(usb_device_t *, void *, size_t); 63 extern int usbmast_read_capacity(usb_device_t *, uint32_t *, uint32_t *); 64 extern int usbmast_read(usb_device_t *, uint64_t, size_t, size_t, void *); 63 65 extern const char *usbmast_scsi_dev_type_str(unsigned); 64 66 -
uspace/lib/scsi/include/scsi/spc.h
rb5085a7 rf7a55f9 42 42 /** SCSI command codes defined in SCSI-SPC */ 43 43 enum scsi_cmd_spc { 44 SCSI_CMD_INQUIRY = 0x12 44 SCSI_CMD_INQUIRY = 0x12, 45 SCSI_CMD_REQUEST_SENSE = 0x03 45 46 }; 46 47 47 48 /** SCSI Inquiry command */ 48 49 typedef struct { 49 /** Operation code ( 12h,SCSI_CMD_INQUIRY) */50 /** Operation code (SCSI_CMD_INQUIRY) */ 50 51 uint8_t op_code; 51 52 /** Reserved:7-2, obsolete:1, evpd:0 */ … … 92 93 93 94 /* End of required data */ 94 } scsi_std_inquiry_data_t;95 } __attribute__((packed)) scsi_std_inquiry_data_t; 95 96 96 97 /** Size of struct or union member. */ … … 138 139 }; 139 140 141 /** SCSI Request Sense command */ 142 typedef struct { 143 /** Operation code (SCSI_CMD_REQUEST_SENSE) */ 144 uint8_t op_code; 145 /** Reserved, Desc */ 146 uint8_t desc; 147 /* Reserved */ 148 uint16_t res_2; 149 /* Allocation Length */ 150 uint8_t alloc_len; 151 /* Control */ 152 uint8_t control; 153 } __attribute__((packed)) scsi_cdb_request_sense_t; 154 155 /** Minimum size of sense data. 156 * 157 * If the target returns less data, the missing bytes should be considered 158 * zero. 159 */ 160 #define SCSI_SENSE_DATA_MIN_SIZE 18 161 162 /** Maximum size of sense data */ 163 #define SCSI_SENSE_DATA_MAX_SIZE 252 164 165 /** Fixed-format sense data. 166 * 167 * Returned for Request Sense command with Desc bit cleared. 168 */ 169 typedef struct { 170 /** Valid, Response Code */ 171 uint8_t valid_rcode; 172 /** Peripheral qualifier, Peripheral device type */ 173 uint8_t obsolete_1; 174 /** Filemark, EOM, ILI, Reserved, Sense Key */ 175 uint8_t flags_key; 176 /** Information */ 177 uint32_t info; 178 /** Additional Sense Length */ 179 uint8_t additional_len; 180 /** Command-specific Information */ 181 uint8_t cmd_spec; 182 /** Additional Sense Code */ 183 uint8_t additional_code; 184 /** Additional Sense Code Qualifier */ 185 uint8_t additional_cqual; 186 /** Field-replaceable Unit Code */ 187 uint8_t fru_code; 188 /** SKSV, Sense-key specific */ 189 uint8_t key_spec[3]; 190 } __attribute__((packed)) scsi_sense_data_t; 191 192 /** Sense key */ 193 enum scsi_sense_key { 194 SCSI_SK_NO_SENSE = 0x0, 195 SCSI_SK_RECOVERED_ERROR = 0x1, 196 SCSI_SK_NOT_READY = 0x2, 197 SCSI_SK_MEDIUM_ERROR = 0x3, 198 SCSI_SK_HARDWARE_ERROR = 0x4, 199 SCSI_SK_ILLEGAL_REQUEST = 0x5, 200 SCSI_SK_UNIT_ATTENTION = 0x6, 201 SCSI_SK_DATA_PROTECT = 0x7, 202 SCSI_SK_BLANK_CHECK = 0x8, 203 SCSI_SK_VENDOR_SPECIFIC = 0x9, 204 SCSI_SK_COPY_ABORTED = 0xa, 205 SCSI_SK_ABORTED_COMMAND = 0xb, 206 SCSI_SK_VOLUME_OVERFLOW = 0xd, 207 SCSI_SK_MISCOMPARE = 0xe 208 }; 209 140 210 extern const char *scsi_dev_type_str[SCSI_DEV_LIMIT]; 141 211 extern const char *scsi_get_dev_type_str(unsigned);
Note:
See TracChangeset
for help on using the changeset viewer.