1 #include <sys/cdefs.h> 2 __FBSDID("$FreeBSD: releng/12.2/sys/dev/usb/storage/umass.c 327173 2017-12-25 04:48:39Z kan $"); 3 4 /*- 5 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 6 * 7 * Copyright (c) 1999 MAEKAWA Masahide <bishop@rr.iij4u.or.jp>, 8 * Nick Hibma <n_hibma@FreeBSD.org> 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $FreeBSD: releng/12.2/sys/dev/usb/storage/umass.c 327173 2017-12-25 04:48:39Z kan $ 33 * $NetBSD: umass.c,v 1.28 2000/04/02 23:46:53 augustss Exp $ 34 */ 35 36 /* Also already merged from NetBSD: 37 * $NetBSD: umass.c,v 1.67 2001/11/25 19:05:22 augustss Exp $ 38 * $NetBSD: umass.c,v 1.90 2002/11/04 19:17:33 pooka Exp $ 39 * $NetBSD: umass.c,v 1.108 2003/11/07 17:03:25 wiz Exp $ 40 * $NetBSD: umass.c,v 1.109 2003/12/04 13:57:31 keihan Exp $ 41 */ 42 43 /* 44 * Universal Serial Bus Mass Storage Class specs: 45 * http://www.usb.org/developers/devclass_docs/usb_msc_overview_1.2.pdf 46 * http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf 47 * http://www.usb.org/developers/devclass_docs/usb_msc_cbi_1.1.pdf 48 * http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf 49 */ 50 51 /* 52 * Ported to NetBSD by Lennart Augustsson <augustss@NetBSD.org>. 53 * Parts of the code written by Jason R. Thorpe <thorpej@shagadelic.org>. 54 */ 55 56 /* 57 * The driver handles 3 Wire Protocols 58 * - Command/Bulk/Interrupt (CBI) 59 * - Command/Bulk/Interrupt with Command Completion Interrupt (CBI with CCI) 60 * - Mass Storage Bulk-Only (BBB) 61 * (BBB refers Bulk/Bulk/Bulk for Command/Data/Status phases) 62 * 63 * Over these wire protocols it handles the following command protocols 64 * - SCSI 65 * - UFI (floppy command set) 66 * - 8070i (ATAPI) 67 * 68 * UFI and 8070i (ATAPI) are transformed versions of the SCSI command set. The 69 * sc->sc_transform method is used to convert the commands into the appropriate 70 * format (if at all necessary). For example, UFI requires all commands to be 71 * 12 bytes in length amongst other things. 72 * 73 * The source code below is marked and can be split into a number of pieces 74 * (in this order): 75 * 76 * - probe/attach/detach 77 * - generic transfer routines 78 * - BBB 79 * - CBI 80 * - CBI_I (in addition to functions from CBI) 81 * - CAM (Common Access Method) 82 * - SCSI 83 * - UFI 84 * - 8070i (ATAPI) 85 * 86 * The protocols are implemented using a state machine, for the transfers as 87 * well as for the resets. The state machine is contained in umass_t_*_callback. 88 * The state machine is started through either umass_command_start() or 89 * umass_reset(). 90 * 91 * The reason for doing this is a) CAM performs a lot better this way and b) it 92 * avoids using tsleep from interrupt context (for example after a failed 93 * transfer). 94 */ 95 96 /* 97 * The SCSI related part of this driver has been derived from the 98 * dev/ppbus/vpo.c driver, by Nicolas Souchu (nsouch@FreeBSD.org). 99 * 100 * The CAM layer uses so called actions which are messages sent to the host 101 * adapter for completion. The actions come in through umass_cam_action. The 102 * appropriate block of routines is called depending on the transport protocol 103 * in use. When the transfer has finished, these routines call 104 * umass_cam_cb again to complete the CAM command. 105 */ 106 107 #include <driver.h> 108 #include <disk.h> 109 110 #include "implementation/global_implementation.h" 111 #include "scsi_all.h" 112 #include "scsi.h" 113 #if USB_HAVE_DEVICE_TOPOLOGY 114 #include "implementation/usb_btree.h" 115 #endif 116 #include "user_copy.h" 117 118 #ifdef LOSCFG_USB_DEBUG 119 #define DIF(m, x) \ 120 do { \ 121 if (umass_debug & (m)) { x ; } \ 122 } while (0) 123 124 #define DPRINTF_UMASS(sc, m, fmt, ...) \ 125 do { \ 126 if (umass_debug & (m)) { \ 127 PRINTK("%s:%s: " fmt, \ 128 (sc) ? (const char *)(sc)->sc_name : \ 129 (const char *)"umassX", \ 130 __FUNCTION__ ,## __VA_ARGS__); \ 131 } \ 132 } while (0) 133 134 #define UDMASS_GEN 0x00010000 /* general */ 135 #define UDMASS_SCSI 0x00020000 /* scsi */ 136 #define UDMASS_UFI 0x00040000 /* ufi command set */ 137 #define UDMASS_ATAPI 0x00080000 /* 8070i command set */ 138 #define UDMASS_CMD (UDMASS_SCSI|UDMASS_UFI|UDMASS_ATAPI) 139 #define UDMASS_USB 0x00100000 /* USB general */ 140 #define UDMASS_BBB 0x00200000 /* Bulk-Only transfers */ 141 #define UDMASS_CBI 0x00400000 /* CBI transfers */ 142 #define UDMASS_WIRE (UDMASS_BBB|UDMASS_CBI) 143 #define UDMASS_ALL 0xffff0000 /* all of the above */ 144 static int umass_debug = 0; /* UDMASS_ALL; */ 145 static int umass_throttle; 146 147 void 148 umass_debug_func(int level) 149 { 150 switch(level) { 151 case 0: 152 umass_debug = 0; 153 PRINTK("Close the umass debug\n"); 154 break; 155 case UDMASS_GEN: 156 case UDMASS_SCSI: 157 case UDMASS_UFI: 158 case UDMASS_ATAPI: 159 case UDMASS_CMD: 160 case UDMASS_USB: 161 case UDMASS_BBB: 162 case UDMASS_CBI: 163 case UDMASS_WIRE: 164 case UDMASS_ALL: 165 umass_debug = level; 166 PRINTK("The level of umass debug is %x\n", level); 167 break; 168 default: 169 PRINT_ERR("The level of umass debug is invalid, please refer to umass.c\n"); 170 break; 171 } 172 } 173 DEBUG_MODULE(umass, umass_debug_func); 174 #else 175 #define DIF(...) do { } while (0) 176 #define DPRINTF_UMASS(...) do { } while (0) 177 #endif 178 179 #define UMASS_BULK_SIZE (1 << 17) 180 #define UMASS_CBI_DIAGNOSTIC_CMDLEN 12 /* bytes */ 181 #define UMASS_MAX_CMDLEN MAX(12, CBWCDBLENGTH) /* bytes */ 182 183 /* USB transfer definitions */ 184 185 #define UMASS_T_BBB_RESET1 0 /* Bulk-Only */ 186 #define UMASS_T_BBB_RESET2 1 187 #define UMASS_T_BBB_RESET3 2 188 #define UMASS_T_BBB_COMMAND 3 189 #define UMASS_T_BBB_DATA_READ 4 190 #define UMASS_T_BBB_DATA_RD_CS 5 191 #define UMASS_T_BBB_DATA_WRITE 6 192 #define UMASS_T_BBB_DATA_WR_CS 7 193 #define UMASS_T_BBB_STATUS 8 194 #define UMASS_T_BBB_MAX 9 195 196 #define UMASS_T_CBI_RESET1 0 /* CBI */ 197 #define UMASS_T_CBI_RESET2 1 198 #define UMASS_T_CBI_RESET3 2 199 #define UMASS_T_CBI_COMMAND 3 200 #define UMASS_T_CBI_DATA_READ 4 201 #define UMASS_T_CBI_DATA_RD_CS 5 202 #define UMASS_T_CBI_DATA_WRITE 6 203 #define UMASS_T_CBI_DATA_WR_CS 7 204 #define UMASS_T_CBI_STATUS 8 205 #define UMASS_T_CBI_RESET4 9 206 #define UMASS_T_CBI_MAX 10 207 208 #define UMASS_T_MAX MAX(UMASS_T_CBI_MAX, UMASS_T_BBB_MAX) 209 210 /* Generic definitions */ 211 212 /* Direction for transfer */ 213 #define DIR_NONE 0 214 #define DIR_IN 1 215 #define DIR_OUT 2 216 217 /* device name */ 218 #define DEVNAME "umass" 219 #define DEVNAME_SIM "umass-sim" 220 221 /* Approximate maximum transfer speeds (assumes 33% overhead). */ 222 #define UMASS_FULL_TRANSFER_SPEED 1000 223 #define UMASS_HIGH_TRANSFER_SPEED 40000 224 #define UMASS_SUPER_TRANSFER_SPEED 400000 225 #define UMASS_FLOPPY_TRANSFER_SPEED 20 226 227 #define UMASS_TIMEOUT 20000 /* ms */ 228 229 /* CAM specific definitions */ 230 #define UMASS_SCSIID_MAX 1 /* maximum number of drives expected */ 231 #define UMASS_SCSIID_HOST UMASS_SCSIID_MAX 232 233 /* Bulk-Only features */ 234 #define UR_BBB_RESET 0xff /* Bulk-Only reset */ 235 #define UR_BBB_GET_MAX_LUN 0xfe /* Get maximum lun */ 236 237 #define UMASS_ATTACH_PRENAME "/dev/sd" 238 #define MASS_NAME 10 239 #define MAX_DEVICE 5 240 241 /* 242 * SCSI I/O Request CCB used for the XPT_SCSI_IO and XPT_CONT_TARGET_IO 243 * function codes. 244 */ 245 struct ccb_scsiio { 246 uint8_t *data_ptr; /* Ptr to the data buf/SG list */ 247 uint32_t dxfer_len; /* Data transfer length */ 248 uint32_t resid; /* Transfer residual length: 2's comp */ 249 int32_t status; 250 251 struct scsi_sense_data sense_data; 252 uint8_t sense_len; /* Number of bytes to autosense */ 253 }; 254 255 union ccb { 256 struct ccb_scsiio csio; 257 }; 258 259 260 /* Command Block Wrapper */ 261 typedef struct { 262 uDWord dCBWSignature; 263 #define CBWSIGNATURE 0x43425355 264 uDWord dCBWTag; 265 uDWord dCBWDataTransferLength; 266 uByte bCBWFlags; 267 #define CBWFLAGS_OUT 0x00 268 #define CBWFLAGS_IN 0x80 269 uByte bCBWLUN; 270 uByte bCDBLength; 271 #define CBWCDBLENGTH 16 272 uByte CBWCDB[CBWCDBLENGTH]; 273 } __packed umass_bbb_cbw_t; 274 275 #define UMASS_BBB_CBW_SIZE 31 276 277 /* Command Status Wrapper */ 278 typedef struct { 279 uDWord dCSWSignature; 280 #define CSWSIGNATURE 0x53425355 281 #define CSWSIGNATURE_IMAGINATION_DBX1 0x43425355 282 #define CSWSIGNATURE_OLYMPUS_C1 0x55425355 283 uDWord dCSWTag; 284 uDWord dCSWDataResidue; 285 uByte bCSWStatus; 286 #define CSWSTATUS_GOOD 0x0 287 #define CSWSTATUS_FAILED 0x1 288 #define CSWSTATUS_PHASE 0x2 289 } __packed umass_bbb_csw_t; 290 291 #define UMASS_BBB_CSW_SIZE 13 292 293 /* CBI features */ 294 295 #define UR_CBI_ADSC 0x00 296 297 typedef union { 298 struct { 299 uint8_t type; 300 #define IDB_TYPE_CCI 0x00 301 uint8_t value; 302 #define IDB_VALUE_PASS 0x00 303 #define IDB_VALUE_FAIL 0x01 304 #define IDB_VALUE_PHASE 0x02 305 #define IDB_VALUE_PERSISTENT 0x03 306 #define IDB_VALUE_STATUS_MASK 0x03 307 } __packed common; 308 309 struct { 310 uint8_t asc; 311 uint8_t ascq; 312 } __packed ufi; 313 } __packed umass_cbi_sbl_t; 314 315 struct umass_info { 316 uint32_t sectorsize; 317 uint64_t sectornum; 318 }; 319 320 struct umass_softc; /* see below */ 321 322 typedef void (umass_callback_t)(struct umass_softc *sc, union ccb *ccb, 323 uint32_t residue, uint8_t status); 324 325 #define STATUS_CMD_OK 0 /* everything ok */ 326 #define STATUS_CMD_UNKNOWN 1 /* will have to fetch sense */ 327 #define STATUS_CMD_FAILED 2 /* transfer was ok, command failed */ 328 #define STATUS_WIRE_FAILED 3 /* couldn't even get command across */ 329 330 typedef uint8_t (umass_transform_t)(struct umass_softc *sc, uint8_t *cmd_ptr, 331 uint8_t cmd_len); 332 333 /* Wire and command protocol */ 334 #define UMASS_PROTO_BBB 0x0001 /* USB wire protocol */ 335 #define UMASS_PROTO_CBI 0x0002 336 #define UMASS_PROTO_CBI_I 0x0004 337 #define UMASS_PROTO_WIRE 0x00ff /* USB wire protocol mask */ 338 #define UMASS_PROTO_SCSI 0x0100 /* command protocol */ 339 #define UMASS_PROTO_ATAPI 0x0200 340 #define UMASS_PROTO_UFI 0x0400 341 #define UMASS_PROTO_RBC 0x0800 342 #define UMASS_PROTO_COMMAND 0xff00 /* command protocol mask */ 343 344 /* Device specific quirks */ 345 #define NO_QUIRKS 0x0000 346 /* 347 * The drive does not support Test Unit Ready. Convert to Start Unit 348 */ 349 #define NO_TEST_UNIT_READY 0x0001 350 /* 351 * The drive does not reset the Unit Attention state after REQUEST 352 * SENSE has been sent. The INQUIRY command does not reset the UA 353 * either, and so CAM runs in circles trying to retrieve the initial 354 * INQUIRY data. 355 */ 356 #define RS_NO_CLEAR_UA 0x0002 357 /* The drive does not support START STOP. */ 358 #define NO_START_STOP 0x0004 359 /* Don't ask for full inquiry data (255b). */ 360 #define FORCE_SHORT_INQUIRY 0x0008 361 /* Needs to be initialised the Shuttle way */ 362 #define SHUTTLE_INIT 0x0010 363 /* Drive needs to be switched to alternate iface 1 */ 364 #define ALT_IFACE_1 0x0020 365 /* Drive does not do 1Mb/s, but just floppy speeds (20kb/s) */ 366 #define FLOPPY_SPEED 0x0040 367 /* The device can't count and gets the residue of transfers wrong */ 368 #define IGNORE_RESIDUE 0x0080 369 /* No GetMaxLun call */ 370 #define NO_GETMAXLUN 0x0100 371 /* The device uses a weird CSWSIGNATURE. */ 372 #define WRONG_CSWSIG 0x0200 373 /* Device cannot handle INQUIRY so fake a generic response */ 374 #define NO_INQUIRY 0x0400 375 /* Device cannot handle INQUIRY EVPD, return CHECK CONDITION */ 376 #define NO_INQUIRY_EVPD 0x0800 377 /* Pad all RBC requests to 12 bytes. */ 378 #define RBC_PAD_TO_12 0x1000 379 /* 380 * Device reports number of sectors from READ_CAPACITY, not max 381 * sector number. 382 */ 383 #define READ_CAPACITY_OFFBY1 0x2000 384 /* 385 * Device cannot handle a SCSI synchronize cache command. Normally 386 * this quirk would be handled in the cam layer, but for IDE bridges 387 * we need to associate the quirk with the bridge and not the 388 * underlying disk device. This is handled by faking a success 389 * result. 390 */ 391 #define NO_SYNCHRONIZE_CACHE 0x4000 392 /* Device does not support 'PREVENT/ALLOW MEDIUM REMOVAL'. */ 393 #define NO_PREVENT_ALLOW 0x8000 394 395 #if USB_HAVE_DEVICE_TOPOLOGY 396 extern usbd_bt_tree hub_tree; 397 #endif 398 399 struct umass_softc { 400 union ccb *data_ccb; 401 struct scsi_sense cam_scsi_sense; 402 struct scsi_test_unit_ready cam_scsi_test_unit_ready; 403 struct mtx sc_mtx; 404 EVENT_CB_S sc_event; 405 struct { 406 uint8_t *data_ptr; 407 union ccb *ccb; 408 umass_callback_t *callback; 409 410 uint32_t data_len; /* bytes */ 411 uint32_t data_rem; /* bytes */ 412 uint32_t data_timeout; /* ms */ 413 uint32_t actlen; /* bytes */ 414 415 uint8_t cmd_data[UMASS_MAX_CMDLEN]; 416 uint8_t cmd_len; /* bytes */ 417 uint8_t dir; 418 uint8_t lun; 419 } sc_transfer; 420 421 struct umass_info info; 422 423 /* Bulk specific variables for transfers in progress */ 424 umass_bbb_cbw_t cbw; /* command block wrapper */ 425 umass_bbb_csw_t csw; /* command status wrapper */ 426 427 /* CBI specific variables for transfers in progress */ 428 umass_cbi_sbl_t sbl; /* status block */ 429 430 device_t sc_dev; 431 struct usb_device *sc_udev; 432 struct usb_xfer *sc_xfer[UMASS_T_MAX]; 433 434 /* 435 * The command transform function is used to convert the SCSI 436 * commands into their derivatives, like UFI, ATAPI, and friends. 437 */ 438 umass_transform_t *sc_transform; 439 440 uint32_t sc_unit; 441 uint32_t sc_quirks; /* they got it almost right */ 442 uint32_t sc_proto; /* wire and cmd protocol */ 443 444 uint8_t sc_name[16]; 445 uint8_t sc_iface_no; /* interface number */ 446 uint8_t sc_maxlun; /* maximum LUN number, inclusive */ 447 uint8_t sc_last_xfer_index; 448 uint8_t sc_status_try; 449 BOOL sc_detach_status; 450 BOOL sc_super_disk; /* TRUE: Disk is bigger than 2T; FALSE: Disk is less than 2T */ 451 struct mtx sc_umass_mtx; /* The mtx is used to prevent data read and write competition */ 452 }; 453 454 struct umass_probe_proto { 455 uint32_t quirks; 456 uint32_t proto; 457 458 int error; 459 }; 460 461 #if USB_SUPPORT_SD_HOT_PLUG 462 struct umass_dev_info { 463 struct umass_softc *sc; 464 unsigned int dev_unit; 465 int used; /* 0: not use; 1: in use */ 466 int attached; /* 0: not attach; 1: in attach */ 467 struct mtx dev_mtx; /* The mtx is used to prevent U disk insertion or extraction competition */ 468 }; 469 470 static struct umass_dev_info g_umass_dev_array[MAX_DEVICE] = {0}; 471 static void umass_task_check(int flag); 472 static void umass_dev_delete(struct umass_softc *sc, unsigned int dev_unit); 473 int umass_dev_is_attached(unsigned int dev_unit); 474 static void umass_dev_attach_flag_set(int dev_unit); 475 pthread_t umass_taskid; 476 #define umass_dev_mtx_init(id, type) (void)mtx_init(&g_umass_dev_array[id].dev_mtx, NULL, NULL, type) 477 #define umass_dev_mtx_destroy(id) (void)mtx_destroy(&g_umass_dev_array[id].dev_mtx) 478 #define umass_dev_lock(id) (void)mtx_lock(&g_umass_dev_array[id].dev_mtx) 479 #define umass_dev_unlock(id) (void)mtx_unlock(&g_umass_dev_array[id].dev_mtx) 480 #else 481 #define umass_dev_lock(id) (void)mtx_lock(NULL) 482 #define umass_dev_unlock(id) (void)mtx_unlock(NULL) 483 #endif 484 485 struct umass_softc *p_umsf = NULL; 486 /* prototypes */ 487 488 static device_probe_t umass_probe; 489 static device_attach_t umass_attach; 490 static device_detach_t umass_detach; 491 492 static usb_callback_t umass_tr_error; 493 static usb_callback_t umass_t_bbb_reset1_callback; 494 static usb_callback_t umass_t_bbb_reset2_callback; 495 static usb_callback_t umass_t_bbb_reset3_callback; 496 static usb_callback_t umass_t_bbb_command_callback; 497 static usb_callback_t umass_t_bbb_data_read_callback; 498 static usb_callback_t umass_t_bbb_data_rd_cs_callback; 499 static usb_callback_t umass_t_bbb_data_write_callback; 500 static usb_callback_t umass_t_bbb_data_wr_cs_callback; 501 static usb_callback_t umass_t_bbb_status_callback; 502 static usb_callback_t umass_t_cbi_reset1_callback; 503 static usb_callback_t umass_t_cbi_reset2_callback; 504 static usb_callback_t umass_t_cbi_reset3_callback; 505 static usb_callback_t umass_t_cbi_reset4_callback; 506 static usb_callback_t umass_t_cbi_command_callback; 507 static usb_callback_t umass_t_cbi_data_read_callback; 508 static usb_callback_t umass_t_cbi_data_rd_cs_callback; 509 static usb_callback_t umass_t_cbi_data_write_callback; 510 static usb_callback_t umass_t_cbi_data_wr_cs_callback; 511 static usb_callback_t umass_t_cbi_status_callback; 512 513 static void umass_cancel_ccb(struct umass_softc *); 514 static void umass_init_shuttle(struct umass_softc *); 515 static void umass_t_bbb_data_clear_stall_callback(struct usb_xfer *, 516 uint8_t, uint8_t, usb_error_t); 517 static int umass_command_start(struct umass_softc *, uint8_t, void *, 518 uint32_t, uint32_t, umass_callback_t *, union ccb *); 519 static uint8_t umass_bbb_get_max_lun(struct umass_softc *); 520 static void umass_cbi_start_status(struct umass_softc *); 521 static void umass_t_cbi_data_clear_stall_callback(struct usb_xfer *, 522 uint8_t, uint8_t, usb_error_t); 523 static void umass_cam_cb(struct umass_softc *, union ccb *, uint32_t, uint8_t); 524 static uint8_t umass_scsi_transform(struct umass_softc *, uint8_t *, uint8_t); 525 static uint8_t umass_rbc_transform(struct umass_softc *, uint8_t *, uint8_t); 526 static uint8_t umass_ufi_transform(struct umass_softc *, uint8_t *, uint8_t); 527 static uint8_t umass_atapi_transform(struct umass_softc *, uint8_t *, 528 uint8_t); 529 static uint8_t umass_no_transform(struct umass_softc *, uint8_t *, uint8_t); 530 531 #ifdef LOSCFG_USB_DEBUG 532 static void umass_bbb_dump_cbw(struct umass_softc *, umass_bbb_cbw_t *); 533 static void umass_bbb_dump_csw(struct umass_softc *, umass_bbb_csw_t *); 534 static void umass_cbi_dump_cmd(struct umass_softc *, void *, uint8_t); 535 #endif 536 537 static void devunit_to_devname(unsigned int dev_unit, char *devname); 538 static int32_t umass_attach_dev(struct umass_softc *sc, unsigned int dev_unit); 539 static void umass_detach_dev_sub(struct umass_softc *sc, int dev_unit, int flag); 540 541 static struct usb_config umass_bbb_config[UMASS_T_BBB_MAX] = { 542 543 [UMASS_T_BBB_RESET1] = { 544 .type = UE_CONTROL, 545 .endpoint = 0x00, /* Control pipe */ 546 .direction = UE_DIR_ANY, 547 .bufsize = sizeof(struct usb_device_request), 548 .callback = &umass_t_bbb_reset1_callback, 549 .timeout = 5000, /* 5 seconds */ 550 .interval = 500, /* 500 milliseconds */ 551 }, 552 553 [UMASS_T_BBB_RESET2] = { 554 .type = UE_CONTROL, 555 .endpoint = 0x00, /* Control pipe */ 556 .direction = UE_DIR_ANY, 557 .bufsize = sizeof(struct usb_device_request), 558 .callback = &umass_t_bbb_reset2_callback, 559 .timeout = 5000, /* 5 seconds */ 560 .interval = 50, /* 50 milliseconds */ 561 }, 562 563 [UMASS_T_BBB_RESET3] = { 564 .type = UE_CONTROL, 565 .endpoint = 0x00, /* Control pipe */ 566 .direction = UE_DIR_ANY, 567 .bufsize = sizeof(struct usb_device_request), 568 .callback = &umass_t_bbb_reset3_callback, 569 .timeout = 5000, /* 5 seconds */ 570 .interval = 50, /* 50 milliseconds */ 571 }, 572 573 [UMASS_T_BBB_COMMAND] = { 574 .type = UE_BULK, 575 .endpoint = UE_ADDR_ANY, 576 .direction = UE_DIR_OUT, 577 .bufsize = sizeof(umass_bbb_cbw_t), 578 .callback = &umass_t_bbb_command_callback, 579 .timeout = 5000, /* 5 seconds */ 580 }, 581 582 [UMASS_T_BBB_DATA_READ] = { 583 .type = UE_BULK, 584 .endpoint = UE_ADDR_ANY, 585 .direction = UE_DIR_IN, 586 .bufsize = UMASS_BULK_SIZE, 587 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,}, 588 .callback = &umass_t_bbb_data_read_callback, 589 .timeout = 0, /* overwritten later */ 590 }, 591 592 [UMASS_T_BBB_DATA_RD_CS] = { 593 .type = UE_CONTROL, 594 .endpoint = 0x00, /* Control pipe */ 595 .direction = UE_DIR_ANY, 596 .bufsize = sizeof(struct usb_device_request), 597 .callback = &umass_t_bbb_data_rd_cs_callback, 598 .timeout = 5000, /* 5 seconds */ 599 }, 600 601 [UMASS_T_BBB_DATA_WRITE] = { 602 .type = UE_BULK, 603 .endpoint = UE_ADDR_ANY, 604 .direction = UE_DIR_OUT, 605 .bufsize = UMASS_BULK_SIZE, 606 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,}, 607 .callback = &umass_t_bbb_data_write_callback, 608 .timeout = 0, /* overwritten later */ 609 }, 610 611 [UMASS_T_BBB_DATA_WR_CS] = { 612 .type = UE_CONTROL, 613 .endpoint = 0x00, /* Control pipe */ 614 .direction = UE_DIR_ANY, 615 .bufsize = sizeof(struct usb_device_request), 616 .callback = &umass_t_bbb_data_wr_cs_callback, 617 .timeout = 5000, /* 5 seconds */ 618 }, 619 620 [UMASS_T_BBB_STATUS] = { 621 .type = UE_BULK, 622 .endpoint = UE_ADDR_ANY, 623 .direction = UE_DIR_IN, 624 .bufsize = sizeof(umass_bbb_csw_t), 625 .flags = {.short_xfer_ok = 1,}, 626 .callback = &umass_t_bbb_status_callback, 627 .timeout = 5000, /* ms */ 628 }, 629 }; 630 631 static struct usb_config umass_cbi_config[UMASS_T_CBI_MAX] = { 632 633 [UMASS_T_CBI_RESET1] = { 634 .type = UE_CONTROL, 635 .endpoint = 0x00, /* Control pipe */ 636 .direction = UE_DIR_ANY, 637 .bufsize = (sizeof(struct usb_device_request) + 638 UMASS_CBI_DIAGNOSTIC_CMDLEN), 639 .callback = &umass_t_cbi_reset1_callback, 640 .timeout = 5000, /* 5 seconds */ 641 .interval = 500, /* 500 milliseconds */ 642 }, 643 644 [UMASS_T_CBI_RESET2] = { 645 .type = UE_CONTROL, 646 .endpoint = 0x00, /* Control pipe */ 647 .direction = UE_DIR_ANY, 648 .bufsize = sizeof(struct usb_device_request), 649 .callback = &umass_t_cbi_reset2_callback, 650 .timeout = 5000, /* 5 seconds */ 651 .interval = 50, /* 50 milliseconds */ 652 }, 653 654 [UMASS_T_CBI_RESET3] = { 655 .type = UE_CONTROL, 656 .endpoint = 0x00, /* Control pipe */ 657 .direction = UE_DIR_ANY, 658 .bufsize = sizeof(struct usb_device_request), 659 .callback = &umass_t_cbi_reset3_callback, 660 .timeout = 5000, /* 5 seconds */ 661 .interval = 50, /* 50 milliseconds */ 662 }, 663 664 [UMASS_T_CBI_COMMAND] = { 665 .type = UE_CONTROL, 666 .endpoint = 0x00, /* Control pipe */ 667 .direction = UE_DIR_ANY, 668 .bufsize = (sizeof(struct usb_device_request) + 669 UMASS_MAX_CMDLEN), 670 .callback = &umass_t_cbi_command_callback, 671 .timeout = 5000, /* 5 seconds */ 672 }, 673 674 [UMASS_T_CBI_DATA_READ] = { 675 .type = UE_BULK, 676 .endpoint = UE_ADDR_ANY, 677 .direction = UE_DIR_IN, 678 .bufsize = UMASS_BULK_SIZE, 679 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,}, 680 .callback = &umass_t_cbi_data_read_callback, 681 .timeout = 0, /* overwritten later */ 682 }, 683 684 [UMASS_T_CBI_DATA_RD_CS] = { 685 .type = UE_CONTROL, 686 .endpoint = 0x00, /* Control pipe */ 687 .direction = UE_DIR_ANY, 688 .bufsize = sizeof(struct usb_device_request), 689 .callback = &umass_t_cbi_data_rd_cs_callback, 690 .timeout = 5000, /* 5 seconds */ 691 }, 692 693 [UMASS_T_CBI_DATA_WRITE] = { 694 .type = UE_BULK, 695 .endpoint = UE_ADDR_ANY, 696 .direction = UE_DIR_OUT, 697 .bufsize = UMASS_BULK_SIZE, 698 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer=1,}, 699 .callback = &umass_t_cbi_data_write_callback, 700 .timeout = 0, /* overwritten later */ 701 }, 702 703 [UMASS_T_CBI_DATA_WR_CS] = { 704 .type = UE_CONTROL, 705 .endpoint = 0x00, /* Control pipe */ 706 .direction = UE_DIR_ANY, 707 .bufsize = sizeof(struct usb_device_request), 708 .callback = &umass_t_cbi_data_wr_cs_callback, 709 .timeout = 5000, /* 5 seconds */ 710 }, 711 712 [UMASS_T_CBI_STATUS] = { 713 .type = UE_INTERRUPT, 714 .endpoint = UE_ADDR_ANY, 715 .direction = UE_DIR_IN, 716 .flags = {.short_xfer_ok = 1,.no_pipe_ok = 1,}, 717 .bufsize = sizeof(umass_cbi_sbl_t), 718 .callback = &umass_t_cbi_status_callback, 719 .timeout = 5000, /* ms */ 720 }, 721 722 [UMASS_T_CBI_RESET4] = { 723 .type = UE_CONTROL, 724 .endpoint = 0x00, /* Control pipe */ 725 .direction = UE_DIR_ANY, 726 .bufsize = sizeof(struct usb_device_request), 727 .callback = &umass_t_cbi_reset4_callback, 728 .timeout = 5000, /* ms */ 729 }, 730 }; 731 732 #define UFI_COMMAND_LENGTH 12 /* UFI commands are always 12 bytes */ 733 #define ATAPI_COMMAND_LENGTH 12 /* ATAPI commands are always 12 bytes */ 734 735 static devclass_t umass_devclass; 736 737 static device_method_t umass_methods[] = { 738 /* Device interface */ 739 DEVMETHOD(device_probe, umass_probe), 740 DEVMETHOD(device_attach, umass_attach), 741 DEVMETHOD(device_detach, umass_detach), 742 743 DEVMETHOD_END 744 }; 745 746 static driver_t umass_driver = { 747 .name = "umass", 748 .methods = umass_methods, 749 .size = sizeof(struct umass_softc), 750 }; 751 752 #if USB_HAVE_DEVICE_TOPOLOGY 753 UINT64 dev_quantity = 0; 754 #endif 755 756 DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, NULL, 0); 757 758 static uint16_t 759 umass_get_proto(struct usb_interface *iface) 760 { 761 struct usb_interface_descriptor *id; 762 uint16_t retval; 763 764 retval = 0; 765 766 /* Check for a standards compliant device */ 767 id = usbd_get_interface_descriptor(iface); 768 if ((id == NULL) || 769 (id->bInterfaceClass != UICLASS_MASS)) { 770 goto done; 771 } 772 switch (id->bInterfaceSubClass) { 773 case UISUBCLASS_SCSI: 774 retval |= UMASS_PROTO_SCSI; 775 break; 776 case UISUBCLASS_UFI: 777 retval |= UMASS_PROTO_UFI; 778 break; 779 case UISUBCLASS_RBC: 780 retval |= UMASS_PROTO_RBC; 781 break; 782 case UISUBCLASS_SFF8020I: 783 case UISUBCLASS_SFF8070I: 784 retval |= UMASS_PROTO_ATAPI; 785 break; 786 default: 787 goto done; 788 } 789 790 switch (id->bInterfaceProtocol) { 791 case UIPROTO_MASS_CBI: 792 retval |= UMASS_PROTO_CBI; 793 break; 794 case UIPROTO_MASS_CBI_I: 795 retval |= UMASS_PROTO_CBI_I; 796 break; 797 case UIPROTO_MASS_BBB_OLD: 798 case UIPROTO_MASS_BBB: 799 retval |= UMASS_PROTO_BBB; 800 break; 801 default: 802 goto done; 803 } 804 done: 805 return (retval); 806 } 807 808 /* 809 * Match the device we are seeing with the devices supported. 810 */ 811 static struct umass_probe_proto 812 umass_probe_proto(device_t dev, struct usb_attach_arg *uaa) 813 { 814 struct umass_probe_proto ret; 815 uint32_t quirks = NO_QUIRKS; 816 uint32_t proto = umass_get_proto(uaa->iface); 817 818 (void)memset_s(&ret, sizeof(ret), 0, sizeof(ret)); 819 ret.error = BUS_PROBE_GENERIC; 820 821 /* Search for protocol enforcement */ 822 823 if (usb_test_quirk(uaa, UQ_MSC_FORCE_WIRE_BBB)) { 824 proto &= ~UMASS_PROTO_WIRE; 825 proto |= UMASS_PROTO_BBB; 826 } else if (usb_test_quirk(uaa, UQ_MSC_FORCE_WIRE_CBI)) { 827 proto &= ~UMASS_PROTO_WIRE; 828 proto |= UMASS_PROTO_CBI; 829 } else if (usb_test_quirk(uaa, UQ_MSC_FORCE_WIRE_CBI_I)) { 830 proto &= ~UMASS_PROTO_WIRE; 831 proto |= UMASS_PROTO_CBI_I; 832 } 833 834 if (usb_test_quirk(uaa, UQ_MSC_FORCE_PROTO_SCSI)) { 835 proto &= ~UMASS_PROTO_COMMAND; 836 proto |= UMASS_PROTO_SCSI; 837 } else if (usb_test_quirk(uaa, UQ_MSC_FORCE_PROTO_ATAPI)) { 838 proto &= ~UMASS_PROTO_COMMAND; 839 proto |= UMASS_PROTO_ATAPI; 840 } else if (usb_test_quirk(uaa, UQ_MSC_FORCE_PROTO_UFI)) { 841 proto &= ~UMASS_PROTO_COMMAND; 842 proto |= UMASS_PROTO_UFI; 843 } else if (usb_test_quirk(uaa, UQ_MSC_FORCE_PROTO_RBC)) { 844 proto &= ~UMASS_PROTO_COMMAND; 845 proto |= UMASS_PROTO_RBC; 846 } 847 848 /* Check if the protocol is invalid */ 849 850 if ((proto & UMASS_PROTO_COMMAND) == 0) { 851 ret.error = ENXIO; 852 goto done; 853 } 854 855 if ((proto & UMASS_PROTO_WIRE) == 0) { 856 ret.error = ENXIO; 857 goto done; 858 } 859 860 /* Search for quirks */ 861 862 if (usb_test_quirk(uaa, UQ_MSC_NO_TEST_UNIT_READY)) 863 quirks |= NO_TEST_UNIT_READY; 864 if (usb_test_quirk(uaa, UQ_MSC_NO_RS_CLEAR_UA)) 865 quirks |= RS_NO_CLEAR_UA; 866 if (usb_test_quirk(uaa, UQ_MSC_NO_START_STOP)) 867 quirks |= NO_START_STOP; 868 if (usb_test_quirk(uaa, UQ_MSC_NO_GETMAXLUN)) 869 quirks |= NO_GETMAXLUN; 870 if (usb_test_quirk(uaa, UQ_MSC_NO_INQUIRY)) 871 quirks |= NO_INQUIRY; 872 if (usb_test_quirk(uaa, UQ_MSC_NO_INQUIRY_EVPD)) 873 quirks |= NO_INQUIRY_EVPD; 874 if (usb_test_quirk(uaa, UQ_MSC_NO_PREVENT_ALLOW)) 875 quirks |= NO_PREVENT_ALLOW; 876 if (usb_test_quirk(uaa, UQ_MSC_NO_SYNC_CACHE)) 877 quirks |= NO_SYNCHRONIZE_CACHE; 878 if (usb_test_quirk(uaa, UQ_MSC_SHUTTLE_INIT)) 879 quirks |= SHUTTLE_INIT; 880 if (usb_test_quirk(uaa, UQ_MSC_ALT_IFACE_1)) 881 quirks |= ALT_IFACE_1; 882 if (usb_test_quirk(uaa, UQ_MSC_FLOPPY_SPEED)) 883 quirks |= FLOPPY_SPEED; 884 if (usb_test_quirk(uaa, UQ_MSC_IGNORE_RESIDUE)) 885 quirks |= IGNORE_RESIDUE; 886 if (usb_test_quirk(uaa, UQ_MSC_WRONG_CSWSIG)) 887 quirks |= WRONG_CSWSIG; 888 if (usb_test_quirk(uaa, UQ_MSC_RBC_PAD_TO_12)) 889 quirks |= RBC_PAD_TO_12; 890 if (usb_test_quirk(uaa, UQ_MSC_READ_CAP_OFFBY1)) 891 quirks |= READ_CAPACITY_OFFBY1; 892 if (usb_test_quirk(uaa, UQ_MSC_FORCE_SHORT_INQ)) 893 quirks |= FORCE_SHORT_INQUIRY; 894 895 done: 896 ret.quirks = quirks; 897 ret.proto = proto; 898 return (ret); 899 } 900 901 static int 902 umass_probe(device_t dev) 903 { 904 struct usb_attach_arg *uaa = 905 (struct usb_attach_arg *)device_get_ivars(dev); 906 struct umass_probe_proto temp; 907 908 if (uaa->usb_mode != USB_MODE_HOST) { 909 return (ENXIO); 910 } 911 temp = umass_probe_proto(dev, uaa); 912 913 return (temp.error); 914 } 915 916 static int 917 umass_attach(device_t dev) 918 { 919 struct umass_softc *sc = 920 (struct umass_softc *)device_get_softc(dev); 921 struct usb_attach_arg *uaa = 922 (struct usb_attach_arg *)device_get_ivars(dev); 923 struct umass_probe_proto temp = umass_probe_proto(dev, uaa); 924 struct usb_interface_descriptor *id; 925 usb_error_t err; 926 927 /* 928 * NOTE: the softc struct is cleared in device_set_driver. 929 * We can safely call umass_detach without specifically 930 * initializing the struct. 931 */ 932 933 sc->sc_dev = dev; 934 sc->sc_udev = uaa->device; 935 sc->sc_proto = temp.proto; 936 sc->sc_quirks = temp.quirks; 937 sc->sc_unit = device_get_unit(dev); 938 sc->data_ccb = NULL; 939 sc->sc_detach_status = FALSE; 940 sc->sc_super_disk = FALSE; 941 942 #if USB_HAVE_DEVICE_TOPOLOGY 943 dev_quantity |= 1ull << (unsigned int)device_get_unit(dev); 944 #endif 945 946 (void)snprintf_s((char *)sc->sc_name, sizeof(sc->sc_name), sizeof(sc->sc_name) - 1, 947 "%s", device_get_nameunit(dev)); 948 949 device_set_usb_desc(dev); 950 951 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), 952 NULL, MTX_DEF | MTX_RECURSE); 953 mtx_init(&sc->sc_umass_mtx, device_get_nameunit(dev), 954 NULL, MTX_DEF | MTX_RECURSE); 955 956 (void)LOS_EventInit(&sc->sc_event); 957 958 /* get interface index */ 959 960 id = usbd_get_interface_descriptor(uaa->iface); 961 if (id == NULL) { 962 device_printf(dev, "failed to get " 963 "interface number\n"); 964 goto detach; 965 } 966 sc->sc_iface_no = id->bInterfaceNumber; 967 968 device_printf(dev, " "); 969 970 switch (sc->sc_proto & UMASS_PROTO_COMMAND) { 971 case UMASS_PROTO_SCSI: 972 PRINTK("SCSI"); 973 break; 974 case UMASS_PROTO_ATAPI: 975 PRINTK("8070i (ATAPI)"); 976 break; 977 case UMASS_PROTO_UFI: 978 PRINTK("UFI"); 979 break; 980 case UMASS_PROTO_RBC: 981 PRINTK("RBC"); 982 break; 983 default: 984 PRINTK("(unknown 0x%02x)", 985 sc->sc_proto & UMASS_PROTO_COMMAND); 986 break; 987 } 988 989 PRINTK(" over "); 990 991 switch (sc->sc_proto & UMASS_PROTO_WIRE) { 992 case UMASS_PROTO_BBB: 993 PRINTK("Bulk-Only"); 994 break; 995 case UMASS_PROTO_CBI: /* uses Comand/Bulk pipes */ 996 PRINTK("CBI"); 997 break; 998 case UMASS_PROTO_CBI_I: /* uses Comand/Bulk/Interrupt pipes */ 999 PRINTK("CBI with CCI"); 1000 break; 1001 default: 1002 PRINTK("(unknown 0x%02x)", 1003 sc->sc_proto & UMASS_PROTO_WIRE); 1004 } 1005 1006 PRINTK("; quirks = 0x%04x\n", sc->sc_quirks); 1007 1008 if (sc->sc_quirks & ALT_IFACE_1) { 1009 err = usbd_set_alt_interface_index 1010 (uaa->device, uaa->info.bIfaceIndex, 1); 1011 1012 if (err) { 1013 DPRINTF_UMASS(sc, UDMASS_USB, "could not switch to " 1014 "Alt Interface 1\n"); 1015 goto detach; 1016 } 1017 } 1018 /* allocate all required USB transfers */ 1019 1020 if (sc->sc_proto & UMASS_PROTO_BBB) { 1021 1022 err = usbd_transfer_setup(uaa->device, 1023 &uaa->info.bIfaceIndex, sc->sc_xfer, umass_bbb_config, 1024 UMASS_T_BBB_MAX, sc, &sc->sc_mtx); 1025 1026 /* skip reset first time */ 1027 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND; 1028 1029 } else if (sc->sc_proto & (UMASS_PROTO_CBI | UMASS_PROTO_CBI_I)) { 1030 1031 err = usbd_transfer_setup(uaa->device, 1032 &uaa->info.bIfaceIndex, sc->sc_xfer, umass_cbi_config, 1033 UMASS_T_CBI_MAX, sc, &sc->sc_mtx); 1034 1035 /* skip reset first time */ 1036 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; 1037 1038 } else { 1039 err = USB_ERR_INVAL; 1040 } 1041 1042 if (err) { 1043 device_printf(dev, "could not setup required " 1044 "transfers, %s\n", usbd_errstr(err)); 1045 goto detach; 1046 } 1047 #ifdef LOSCFG_USB_DEBUG 1048 if (umass_throttle > 0) { 1049 uint8_t x; 1050 int iv; 1051 1052 iv = umass_throttle; 1053 1054 if (iv < 1) 1055 iv = 1; 1056 else if (iv > 8000) 1057 iv = 8000; 1058 1059 for (x = 0; x != UMASS_T_MAX; x++) { 1060 if (sc->sc_xfer[x] != NULL) 1061 usbd_xfer_set_interval(sc->sc_xfer[x], iv); 1062 } 1063 } 1064 #endif 1065 sc->sc_transform = 1066 (sc->sc_proto & UMASS_PROTO_SCSI) ? &umass_scsi_transform : 1067 (sc->sc_proto & UMASS_PROTO_UFI) ? &umass_ufi_transform : 1068 (sc->sc_proto & UMASS_PROTO_ATAPI) ? &umass_atapi_transform : 1069 (sc->sc_proto & UMASS_PROTO_RBC) ? &umass_rbc_transform : 1070 &umass_no_transform; 1071 1072 /* from here onwards the device can be used. */ 1073 1074 if (sc->sc_quirks & SHUTTLE_INIT) { 1075 umass_init_shuttle(sc); 1076 } 1077 /* get the maximum LUN supported by the device */ 1078 1079 if (((sc->sc_proto & UMASS_PROTO_WIRE) == UMASS_PROTO_BBB) && 1080 !(sc->sc_quirks & NO_GETMAXLUN)) 1081 sc->sc_maxlun = umass_bbb_get_max_lun(sc); 1082 else 1083 sc->sc_maxlun = 0; 1084 1085 /* Prepare the SCSI command block */ 1086 sc->cam_scsi_sense.opcode = REQUEST_SENSE; 1087 sc->cam_scsi_test_unit_ready.opcode = TEST_UNIT_READY; 1088 1089 #define SOFT_CACHE_SIZE 0x40 1090 sc->data_ccb = (union ccb *)malloc(sizeof(union ccb)); 1091 if (sc->data_ccb == NULL) 1092 goto detach; 1093 sc->data_ccb->csio.data_ptr = (uint8_t *)memalign(USB_CACHE_ALIGN_SIZE, SKB_DATA_ALIGN(SOFT_CACHE_SIZE)); 1094 if (sc->data_ccb->csio.data_ptr == NULL) 1095 goto detach; 1096 sc->data_ccb->csio.dxfer_len = SOFT_CACHE_SIZE; 1097 1098 DPRINTF_UMASS(sc, UDMASS_GEN, "Attach finished\n"); 1099 1100 /* register the device*/ 1101 if (umass_attach_dev(sc, device_get_unit(dev))) { 1102 goto detach; 1103 } 1104 1105 p_umsf = sc; 1106 return (0); /* success */ 1107 1108 detach: 1109 (void)umass_detach(dev); 1110 return (ENXIO); /* failure */ 1111 } 1112 1113 static int 1114 umass_detach(device_t dev) 1115 { 1116 struct umass_softc *sc = (struct umass_softc *)device_get_softc(dev); 1117 unsigned int dev_unit = device_get_unit(dev); 1118 1119 DPRINTF_UMASS(sc, UDMASS_USB, "\n"); 1120 1121 sc->sc_detach_status = TRUE; 1122 1123 /* teardown our statemachine */ 1124 usbd_transfer_unsetup(sc->sc_xfer, UMASS_T_MAX); 1125 1126 mtx_lock(&sc->sc_mtx); 1127 1128 /* cancel any leftover CCB's */ 1129 umass_cancel_ccb(sc); 1130 1131 mtx_lock(&sc->sc_umass_mtx); 1132 if (sc->data_ccb != NULL) { 1133 if (sc->data_ccb->csio.data_ptr != NULL) { 1134 free((void*)sc->data_ccb->csio.data_ptr); 1135 sc->data_ccb->csio.data_ptr = NULL; 1136 } 1137 free(sc->data_ccb); 1138 sc->data_ccb = NULL; 1139 } 1140 mtx_unlock(&sc->sc_umass_mtx); 1141 1142 umass_detach_dev_sub(sc, dev_unit, 0); 1143 #if USB_SUPPORT_SD_HOT_PLUG 1144 umass_task_check(1); 1145 #endif 1146 1147 mtx_unlock(&sc->sc_mtx); 1148 sc->sc_detach_status = FALSE; 1149 mtx_destroy(&sc->sc_mtx); 1150 mtx_destroy(&sc->sc_umass_mtx); 1151 1152 p_umsf = NULL; 1153 return (0); /* success */ 1154 } 1155 1156 static void 1157 umass_init_shuttle(struct umass_softc *sc) 1158 { 1159 struct usb_device_request req; 1160 usb_error_t err; 1161 uint8_t status[2] = {0, 0}; 1162 1163 /* 1164 * The Linux driver does this, but no one can tell us what the 1165 * command does. 1166 */ 1167 req.bmRequestType = UT_READ_VENDOR_DEVICE; 1168 req.bRequest = 1; /* XXX unknown command */ 1169 USETW(req.wValue, 0); 1170 req.wIndex[0] = sc->sc_iface_no; 1171 req.wIndex[1] = 0; 1172 USETW(req.wLength, sizeof(status)); 1173 err = usbd_do_request(sc->sc_udev, NULL, &req, &status); 1174 if (err) 1175 DPRINTF_UMASS(sc, UDMASS_GEN, "request failed in %s %d, err=%d\n", 1176 __FUNCTION__, __LINE__, err); 1177 1178 DPRINTF_UMASS(sc, UDMASS_GEN, "Shuttle init returned 0x%02x%02x\n", 1179 status[0], status[1]); 1180 } 1181 1182 /* 1183 * Generic functions to handle transfers 1184 */ 1185 1186 static void 1187 umass_transfer_start(struct umass_softc *sc, uint8_t xfer_index) 1188 { 1189 DPRINTF_UMASS(sc, UDMASS_GEN, "transfer index = " 1190 "%d\n", xfer_index); 1191 1192 if (sc->sc_xfer[xfer_index]) { 1193 sc->sc_last_xfer_index = xfer_index; 1194 usbd_transfer_start(sc->sc_xfer[xfer_index]); 1195 } else { 1196 umass_cancel_ccb(sc); 1197 } 1198 } 1199 1200 static void 1201 umass_cancel_ccb(struct umass_softc *sc) 1202 { 1203 union ccb *umass_ccb; 1204 1205 mtx_assert(&sc->sc_mtx, MA_OWNED); 1206 1207 umass_ccb = sc->sc_transfer.ccb; 1208 sc->sc_transfer.ccb = NULL; 1209 sc->sc_last_xfer_index = 0; 1210 1211 if (umass_ccb != NULL) { 1212 (sc->sc_transfer.callback) 1213 (sc, umass_ccb, (sc->sc_transfer.data_len - 1214 sc->sc_transfer.actlen), STATUS_WIRE_FAILED); 1215 } 1216 } 1217 1218 static void 1219 umass_tr_error(struct usb_xfer *xfer, usb_error_t error) 1220 { 1221 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1222 1223 if (error != USB_ERR_CANCELLED) { 1224 1225 DPRINTF_UMASS(sc, UDMASS_GEN, "transfer error, %s -> " 1226 "reset\n", usbd_errstr(error)); 1227 } 1228 umass_cancel_ccb(sc); 1229 } 1230 1231 /* 1232 *return 0: find the corresponding LUN; 1233 * 1: find the SBC Direct-access; 1234 * -1: did not find the LUN. 1235 */ 1236 static int 1237 umass_scsi_inquiry_data(struct umass_softc *sc, void *data, int len) 1238 { 1239 struct scsiresp_inquiry_s *cur_i; 1240 uint8_t pdt; 1241 uint8_t rmb; 1242 int is_dir; 1243 char *name; 1244 1245 if (len != SCSIRESP_INQUIRY_SIZEOF) 1246 return (-1); 1247 1248 is_dir = 0; 1249 cur_i = (struct scsiresp_inquiry_s *)data; 1250 1251 pdt = SCSI_GET_INQUIRY_PDT(cur_i->qualtype); 1252 rmb = SCSI_GET_INQUIRY_RMB(cur_i->flags1); 1253 switch (pdt) { 1254 case T_DIRECT: 1255 name = "SBC Direct-access"; 1256 is_dir = 1; 1257 break; 1258 case T_CDROM: 1259 name = "CD-ROM"; 1260 break; 1261 case T_OPTICAL: 1262 name = "Optical memory"; 1263 break; 1264 case T_RBC: 1265 name = "RBC Direct-access"; 1266 break; 1267 default: 1268 name = "PDT out of scope"; 1269 break; 1270 } 1271 DPRINTF_UMASS(sc, UDMASS_BBB, "SCSI: LUN-%d %s %s\n", sc->sc_transfer.lun, name, 1272 (rmb ? "Removable" : "Not Removable")); 1273 1274 (void)name; 1275 (void)rmb; /* this is for clearing warning */ 1276 return (is_dir); 1277 } 1278 1279 /* 1280 * BBB protocol specific functions 1281 */ 1282 1283 static void 1284 umass_t_bbb_reset1_callback(struct usb_xfer *xfer, usb_error_t error) 1285 { 1286 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1287 struct usb_device_request req; 1288 struct usb_page_cache *pc; 1289 1290 switch (USB_GET_STATE(xfer)) { 1291 case USB_ST_TRANSFERRED: 1292 umass_transfer_start(sc, UMASS_T_BBB_RESET2); 1293 return; 1294 1295 case USB_ST_SETUP: 1296 /* 1297 * Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class) 1298 * 1299 * For Reset Recovery the host shall issue in the following order: 1300 * a) a Bulk-Only Mass Storage Reset 1301 * b) a Clear Feature HALT to the Bulk-In endpoint 1302 * c) a Clear Feature HALT to the Bulk-Out endpoint 1303 * 1304 * This is done in 3 steps, using 3 transfers: 1305 * UMASS_T_BBB_RESET1 1306 * UMASS_T_BBB_RESET2 1307 * UMASS_T_BBB_RESET3 1308 */ 1309 1310 DPRINTF_UMASS(sc, UDMASS_BBB, "BBB reset!\n"); 1311 1312 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 1313 req.bRequest = UR_BBB_RESET; /* bulk only reset */ 1314 USETW(req.wValue, 0); 1315 req.wIndex[0] = sc->sc_iface_no; 1316 req.wIndex[1] = 0; 1317 USETW(req.wLength, 0); 1318 1319 pc = usbd_xfer_get_frame(xfer, 0); 1320 usbd_copy_in(pc, 0, &req, sizeof(req)); 1321 1322 usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); 1323 usbd_xfer_set_frames(xfer, 1); 1324 usbd_transfer_submit(xfer); 1325 return; 1326 1327 default: /* Error */ 1328 umass_tr_error(xfer, error); 1329 return; 1330 } 1331 } 1332 1333 static void 1334 umass_t_bbb_reset2_callback(struct usb_xfer *xfer, usb_error_t error) 1335 { 1336 umass_t_bbb_data_clear_stall_callback(xfer, UMASS_T_BBB_RESET3, 1337 UMASS_T_BBB_DATA_READ, error); 1338 } 1339 1340 static void 1341 umass_t_bbb_reset3_callback(struct usb_xfer *xfer, usb_error_t error) 1342 { 1343 umass_t_bbb_data_clear_stall_callback(xfer, UMASS_T_BBB_COMMAND, 1344 UMASS_T_BBB_DATA_WRITE, error); 1345 } 1346 1347 static void 1348 umass_t_bbb_data_clear_stall_callback(struct usb_xfer *xfer, 1349 uint8_t next_xfer, uint8_t stall_xfer, usb_error_t error) 1350 { 1351 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1352 1353 switch (USB_GET_STATE(xfer)) { 1354 case USB_ST_TRANSFERRED: 1355 tr_transferred: 1356 umass_transfer_start(sc, next_xfer); 1357 return; 1358 1359 case USB_ST_SETUP: 1360 if (usbd_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) { 1361 goto tr_transferred; 1362 } 1363 return; 1364 1365 default: /* Error */ 1366 umass_tr_error(xfer, error); 1367 return; 1368 } 1369 } 1370 1371 static void 1372 umass_t_bbb_command_callback(struct usb_xfer *xfer, usb_error_t error) 1373 { 1374 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1375 struct usb_page_cache *pc; 1376 uint32_t tag; 1377 int ret; 1378 1379 switch (USB_GET_STATE(xfer)) { 1380 case USB_ST_TRANSFERRED: 1381 umass_transfer_start 1382 (sc, ((sc->sc_transfer.dir == DIR_IN) ? UMASS_T_BBB_DATA_READ : 1383 (sc->sc_transfer.dir == DIR_OUT) ? UMASS_T_BBB_DATA_WRITE : 1384 UMASS_T_BBB_STATUS)); 1385 return; 1386 1387 case USB_ST_SETUP: 1388 1389 sc->sc_status_try = 0; 1390 1391 /* 1392 * the initial value is not important, 1393 * as long as the values are unique: 1394 */ 1395 tag = UGETDW(sc->cbw.dCBWTag) + 1; 1396 1397 USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE); 1398 USETDW(sc->cbw.dCBWTag, tag); 1399 1400 /* 1401 * dCBWDataTransferLength: 1402 * This field indicates the number of bytes of data that the host 1403 * intends to transfer on the IN or OUT Bulk endpoint(as indicated by 1404 * the Direction bit) during the execution of this command. If this 1405 * field is set to 0, the device will expect that no data will be 1406 * transferred IN or OUT during this command, regardless of the value 1407 * of the Direction bit defined in dCBWFlags. 1408 */ 1409 USETDW(sc->cbw.dCBWDataTransferLength, sc->sc_transfer.data_len); 1410 1411 /* 1412 * dCBWFlags: 1413 * The bits of the Flags field are defined as follows: 1414 * Bits 0-6 reserved 1415 * Bit 7 Direction - this bit shall be ignored if the 1416 * dCBWDataTransferLength field is zero. 1417 * 0 = data Out from host to device 1418 * 1 = data In from device to host 1419 */ 1420 sc->cbw.bCBWFlags = ((sc->sc_transfer.dir == DIR_IN) ? 1421 CBWFLAGS_IN : CBWFLAGS_OUT); 1422 sc->cbw.bCBWLUN = sc->sc_transfer.lun; 1423 1424 if (sc->sc_transfer.cmd_len > sizeof(sc->cbw.CBWCDB)) { 1425 sc->sc_transfer.cmd_len = sizeof(sc->cbw.CBWCDB); 1426 DPRINTF_UMASS(sc, UDMASS_BBB, "Truncating long command!\n"); 1427 } 1428 sc->cbw.bCDBLength = sc->sc_transfer.cmd_len; 1429 1430 /* copy SCSI command data */ 1431 ret = memcpy_s(sc->cbw.CBWCDB, CBWCDBLENGTH, 1432 sc->sc_transfer.cmd_data, sc->sc_transfer.cmd_len); 1433 if (ret != EOK) { 1434 DPRINTF_UMASS(sc, UDMASS_BBB, "memcpy_s fail, %d\n", ret); 1435 return; 1436 } 1437 1438 /* clear remaining command area */ 1439 (void)memset_s(sc->cbw.CBWCDB + sc->sc_transfer.cmd_len, 1440 sizeof(sc->cbw.CBWCDB) - sc->sc_transfer.cmd_len, 0, 1441 sizeof(sc->cbw.CBWCDB) - sc->sc_transfer.cmd_len); 1442 1443 DIF(UDMASS_BBB, umass_bbb_dump_cbw(sc, &sc->cbw)); 1444 1445 pc = usbd_xfer_get_frame(xfer, 0); 1446 usbd_copy_in(pc, 0, &sc->cbw, sizeof(sc->cbw)); 1447 usbd_xfer_set_frame_len(xfer, 0, sizeof(sc->cbw)); 1448 1449 usbd_transfer_submit(xfer); 1450 1451 return; 1452 1453 default: /* Error */ 1454 umass_tr_error(xfer, error); 1455 return; 1456 } 1457 } 1458 1459 static void 1460 umass_t_bbb_data_callback(struct usb_xfer *xfer, usb_error_t error, 1461 uint8_t xfer_index) 1462 { 1463 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1464 uint32_t max_bulk = usbd_xfer_max_len(xfer); 1465 int actlen, sumlen; 1466 1467 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 1468 1469 switch (USB_GET_STATE(xfer)) { 1470 case USB_ST_TRANSFERRED: 1471 sc->sc_transfer.data_rem -= actlen; 1472 sc->sc_transfer.data_ptr += actlen; 1473 sc->sc_transfer.actlen += actlen; 1474 1475 if (actlen < sumlen) { 1476 /* short transfer */ 1477 sc->sc_transfer.data_rem = 0; 1478 } 1479 case USB_ST_SETUP: 1480 DPRINTF_UMASS(sc, UDMASS_BBB, "max_bulk=%u, data_rem=%u\n", 1481 max_bulk, sc->sc_transfer.data_rem); 1482 1483 if (sc->sc_transfer.data_rem == 0) { 1484 umass_transfer_start(sc, UMASS_T_BBB_STATUS); 1485 return; 1486 } 1487 if (max_bulk > sc->sc_transfer.data_rem) { 1488 max_bulk = sc->sc_transfer.data_rem; 1489 } 1490 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout); 1491 1492 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, 1493 max_bulk); 1494 1495 usbd_transfer_submit(xfer); 1496 return; 1497 1498 default: /* Error */ 1499 if (error == USB_ERR_CANCELLED) { 1500 umass_tr_error(xfer, error); 1501 } else { 1502 umass_transfer_start(sc, xfer_index); 1503 } 1504 return; 1505 } 1506 } 1507 1508 static void 1509 umass_t_bbb_data_read_callback(struct usb_xfer *xfer, usb_error_t error) 1510 { 1511 umass_t_bbb_data_callback(xfer, error, UMASS_T_BBB_DATA_RD_CS); 1512 } 1513 1514 static void 1515 umass_t_bbb_data_rd_cs_callback(struct usb_xfer *xfer, usb_error_t error) 1516 { 1517 umass_t_bbb_data_clear_stall_callback(xfer, UMASS_T_BBB_STATUS, 1518 UMASS_T_BBB_DATA_READ, error); 1519 } 1520 1521 static void 1522 umass_t_bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error) 1523 { 1524 umass_t_bbb_data_callback(xfer, error, UMASS_T_BBB_DATA_WR_CS); 1525 } 1526 1527 static void 1528 umass_t_bbb_data_wr_cs_callback(struct usb_xfer *xfer, usb_error_t error) 1529 { 1530 umass_t_bbb_data_clear_stall_callback(xfer, UMASS_T_BBB_STATUS, 1531 UMASS_T_BBB_DATA_WRITE, error); 1532 } 1533 1534 static void 1535 umass_t_bbb_status_callback(struct usb_xfer *xfer, usb_error_t error) 1536 { 1537 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1538 union ccb *umass_ccb = sc->sc_transfer.ccb; 1539 struct usb_page_cache *pc; 1540 uint32_t residue; 1541 int actlen; 1542 1543 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 1544 1545 switch (USB_GET_STATE(xfer)) { 1546 case USB_ST_TRANSFERRED: 1547 1548 /* 1549 * Do a full reset if there is something wrong with the CSW: 1550 */ 1551 sc->sc_status_try = 1; 1552 1553 /* Zero missing parts of the CSW: */ 1554 1555 if (actlen < (int)sizeof(sc->csw)) { 1556 (void)memset_s(&sc->csw, sizeof(sc->csw), 0, sizeof(sc->csw)); 1557 } 1558 1559 pc = usbd_xfer_get_frame(xfer, 0); 1560 1561 usbd_copy_out(pc, 0, &sc->csw, actlen); 1562 1563 DIF(UDMASS_BBB, umass_bbb_dump_csw(sc, &sc->csw)); 1564 1565 residue = UGETDW(sc->csw.dCSWDataResidue); 1566 1567 if ((!residue) || (sc->sc_quirks & IGNORE_RESIDUE)) { 1568 residue = (sc->sc_transfer.data_len - 1569 sc->sc_transfer.actlen); 1570 } 1571 if (residue > sc->sc_transfer.data_len) { 1572 DPRINTF_UMASS(sc, UDMASS_BBB, "truncating residue from %d " 1573 "to %d bytes\n", residue, sc->sc_transfer.data_len); 1574 residue = sc->sc_transfer.data_len; 1575 } 1576 /* translate weird command-status signatures: */ 1577 if (sc->sc_quirks & WRONG_CSWSIG) { 1578 1579 uint32_t temp = UGETDW(sc->csw.dCSWSignature); 1580 1581 if ((temp == CSWSIGNATURE_OLYMPUS_C1) || 1582 (temp == CSWSIGNATURE_IMAGINATION_DBX1)) { 1583 USETDW(sc->csw.dCSWSignature, CSWSIGNATURE); 1584 } 1585 } 1586 /* check CSW and handle eventual error */ 1587 if (UGETDW(sc->csw.dCSWSignature) != CSWSIGNATURE) { 1588 DPRINTF_UMASS(sc, UDMASS_BBB, "bad CSW signature 0x%08x != 0x%08x\n", 1589 UGETDW(sc->csw.dCSWSignature), CSWSIGNATURE); 1590 /* 1591 * Invalid CSW: Wrong signature or wrong tag might 1592 * indicate that we lost synchronization. Reset the 1593 * device. 1594 */ 1595 goto tr_error; 1596 } else if (UGETDW(sc->csw.dCSWTag) != UGETDW(sc->cbw.dCBWTag)) { 1597 DPRINTF_UMASS(sc, UDMASS_BBB, "Invalid CSW: tag 0x%08x should be " 1598 "0x%08x\n", UGETDW(sc->csw.dCSWTag), 1599 UGETDW(sc->cbw.dCBWTag)); 1600 goto tr_error; 1601 } else if (sc->csw.bCSWStatus > CSWSTATUS_PHASE) { 1602 DPRINTF_UMASS(sc, UDMASS_BBB, "Invalid CSW: status %d > %d\n", 1603 sc->csw.bCSWStatus, CSWSTATUS_PHASE); 1604 goto tr_error; 1605 } else if (sc->csw.bCSWStatus == CSWSTATUS_PHASE) { 1606 DPRINTF_UMASS(sc, UDMASS_BBB, "Phase error, residue = " 1607 "%d\n", residue); 1608 goto tr_error; 1609 } else if (sc->sc_transfer.actlen > sc->sc_transfer.data_len) { 1610 DPRINTF_UMASS(sc, UDMASS_BBB, "Buffer overrun %d > %d\n", 1611 sc->sc_transfer.actlen, sc->sc_transfer.data_len); 1612 goto tr_error; 1613 } else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) { 1614 DPRINTF_UMASS(sc, UDMASS_BBB, "Command failed, residue = " 1615 "%d\n", residue); 1616 1617 sc->sc_transfer.ccb = NULL; 1618 1619 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND; 1620 1621 (sc->sc_transfer.callback) 1622 (sc, umass_ccb, residue, STATUS_CMD_FAILED); 1623 } else { 1624 sc->sc_transfer.ccb = NULL; 1625 1626 sc->sc_last_xfer_index = UMASS_T_BBB_COMMAND; 1627 1628 (sc->sc_transfer.callback) 1629 (sc, umass_ccb, residue, STATUS_CMD_OK); 1630 } 1631 return; 1632 1633 case USB_ST_SETUP: 1634 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 1635 usbd_transfer_submit(xfer); 1636 return; 1637 1638 default: 1639 tr_error: 1640 DPRINTF_UMASS(sc, UDMASS_BBB, "Failed to read CSW: %s, try %d\n", 1641 usbd_errstr(error), sc->sc_status_try); 1642 1643 if ((error == USB_ERR_CANCELLED) || 1644 (sc->sc_status_try)) { 1645 umass_tr_error(xfer, error); 1646 } else { 1647 sc->sc_status_try = 1; 1648 umass_transfer_start(sc, UMASS_T_BBB_DATA_RD_CS); 1649 } 1650 return; 1651 } 1652 } 1653 1654 static int 1655 umass_command_start(struct umass_softc *sc, uint8_t dir, 1656 void *data_ptr, uint32_t data_len, 1657 uint32_t data_timeout, umass_callback_t *callback, 1658 union ccb *umass_ccb) 1659 { 1660 if (sc->sc_detach_status) 1661 { 1662 PRINT_WARN("[%s][%d] usb is detaching\n",__FUNCTION__,__LINE__); 1663 return (-1); 1664 } 1665 1666 /* 1667 * NOTE: assumes that "sc->sc_transfer.cmd_data" and 1668 * "sc->sc_transfer.cmd_len" has been properly 1669 * initialized. 1670 */ 1671 1672 sc->sc_transfer.dir = data_len ? dir : DIR_NONE; 1673 sc->sc_transfer.data_ptr = (uint8_t *)data_ptr; 1674 sc->sc_transfer.data_len = data_len; 1675 sc->sc_transfer.data_rem = data_len; 1676 sc->sc_transfer.data_timeout = (data_timeout + UMASS_TIMEOUT); 1677 1678 sc->sc_transfer.actlen = 0; 1679 sc->sc_transfer.callback = callback; 1680 sc->sc_transfer.ccb = umass_ccb; 1681 1682 if (sc->sc_xfer[sc->sc_last_xfer_index]) { 1683 usbd_transfer_start(sc->sc_xfer[sc->sc_last_xfer_index]); 1684 } else { 1685 umass_cancel_ccb(sc); 1686 } 1687 1688 (void)LOS_EventRead(&sc->sc_event, 0xFF, 1689 LOS_WAITMODE_OR | LOS_WAITMODE_CLR, 10 * LOSCFG_BASE_CORE_TICK_PER_SECOND); /* 10 seconds. */ 1690 1691 return (0); 1692 } 1693 1694 static uint8_t 1695 umass_bbb_get_max_lun(struct umass_softc *sc) 1696 { 1697 struct usb_device_request req; 1698 usb_error_t err; 1699 uint8_t buf = 0; 1700 1701 /* The Get Max Lun command is a class-specific request. */ 1702 req.bmRequestType = UT_READ_CLASS_INTERFACE; 1703 req.bRequest = UR_BBB_GET_MAX_LUN; 1704 USETW(req.wValue, 0); 1705 req.wIndex[0] = sc->sc_iface_no; 1706 req.wIndex[1] = 0; 1707 USETW(req.wLength, 1); 1708 1709 err = usbd_do_request(sc->sc_udev, NULL, &req, &buf); 1710 if (err) { 1711 buf = 0; 1712 1713 /* Device doesn't support Get Max Lun request. */ 1714 PRINTK("%s: Get Max Lun not supported (%s)\n", 1715 sc->sc_name, usbd_errstr(err)); 1716 } 1717 return (buf); 1718 } 1719 1720 /* 1721 * Command/Bulk/Interrupt (CBI) specific functions 1722 */ 1723 1724 static void 1725 umass_cbi_start_status(struct umass_softc *sc) 1726 { 1727 if (sc->sc_xfer[UMASS_T_CBI_STATUS]) { 1728 umass_transfer_start(sc, UMASS_T_CBI_STATUS); 1729 } else { 1730 union ccb *umass_ccb = sc->sc_transfer.ccb; 1731 1732 sc->sc_transfer.ccb = NULL; 1733 1734 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; 1735 1736 (sc->sc_transfer.callback) 1737 (sc, umass_ccb, (sc->sc_transfer.data_len - 1738 sc->sc_transfer.actlen), STATUS_CMD_UNKNOWN); 1739 } 1740 } 1741 1742 static void 1743 umass_t_cbi_reset1_callback(struct usb_xfer *xfer, usb_error_t error) 1744 { 1745 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1746 struct usb_device_request req; 1747 struct usb_page_cache *pc; 1748 uint8_t buf[UMASS_CBI_DIAGNOSTIC_CMDLEN]; 1749 1750 uint8_t i; 1751 1752 switch (USB_GET_STATE(xfer)) { 1753 case USB_ST_TRANSFERRED: 1754 umass_transfer_start(sc, UMASS_T_CBI_RESET2); 1755 break; 1756 1757 case USB_ST_SETUP: 1758 /* 1759 * Command Block Reset Protocol 1760 * 1761 * First send a reset request to the device. Then clear 1762 * any possibly stalled bulk endpoints. 1763 * 1764 * This is done in 3 steps, using 3 transfers: 1765 * UMASS_T_CBI_RESET1 1766 * UMASS_T_CBI_RESET2 1767 * UMASS_T_CBI_RESET3 1768 * UMASS_T_CBI_RESET4 (only if there is an interrupt endpoint) 1769 */ 1770 1771 DPRINTF_UMASS(sc, UDMASS_CBI, "CBI reset!\n"); 1772 1773 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 1774 req.bRequest = UR_CBI_ADSC; 1775 USETW(req.wValue, 0); 1776 req.wIndex[0] = sc->sc_iface_no; 1777 req.wIndex[1] = 0; 1778 USETW(req.wLength, UMASS_CBI_DIAGNOSTIC_CMDLEN); 1779 1780 /* 1781 * The 0x1d code is the SEND DIAGNOSTIC command. To 1782 * distinguish between the two, the last 10 bytes of the CBL 1783 * is filled with 0xff (section 2.2 of the CBI 1784 * specification) 1785 */ 1786 buf[0] = 0x1d; /* Command Block Reset */ 1787 buf[1] = 0x04; 1788 1789 for (i = 2; i < UMASS_CBI_DIAGNOSTIC_CMDLEN; i++) { 1790 buf[i] = 0xff; 1791 } 1792 1793 pc = usbd_xfer_get_frame(xfer, 0); 1794 usbd_copy_in(pc, 0, &req, sizeof(req)); 1795 pc = usbd_xfer_get_frame(xfer, 1); 1796 usbd_copy_in(pc, 0, buf, sizeof(buf)); 1797 1798 usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); 1799 usbd_xfer_set_frame_len(xfer, 1, sizeof(buf)); 1800 usbd_xfer_set_frames(xfer, 2); 1801 usbd_transfer_submit(xfer); 1802 break; 1803 1804 default: /* Error */ 1805 if (error == USB_ERR_CANCELLED) 1806 umass_tr_error(xfer, error); 1807 else 1808 umass_transfer_start(sc, UMASS_T_CBI_RESET2); 1809 break; 1810 } 1811 } 1812 1813 static void 1814 umass_t_cbi_reset2_callback(struct usb_xfer *xfer, usb_error_t error) 1815 { 1816 umass_t_cbi_data_clear_stall_callback(xfer, UMASS_T_CBI_RESET3, 1817 UMASS_T_CBI_DATA_READ, error); 1818 } 1819 1820 static void 1821 umass_t_cbi_reset3_callback(struct usb_xfer *xfer, usb_error_t error) 1822 { 1823 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1824 1825 umass_t_cbi_data_clear_stall_callback 1826 (xfer, (sc->sc_xfer[UMASS_T_CBI_RESET4] && 1827 sc->sc_xfer[UMASS_T_CBI_STATUS]) ? 1828 UMASS_T_CBI_RESET4 : UMASS_T_CBI_COMMAND, 1829 UMASS_T_CBI_DATA_WRITE, error); 1830 } 1831 1832 static void 1833 umass_t_cbi_reset4_callback(struct usb_xfer *xfer, usb_error_t error) 1834 { 1835 umass_t_cbi_data_clear_stall_callback(xfer, UMASS_T_CBI_COMMAND, 1836 UMASS_T_CBI_STATUS, error); 1837 } 1838 1839 static void 1840 umass_t_cbi_data_clear_stall_callback(struct usb_xfer *xfer, 1841 uint8_t next_xfer, uint8_t stall_xfer, usb_error_t error) 1842 { 1843 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1844 1845 switch (USB_GET_STATE(xfer)) { 1846 case USB_ST_TRANSFERRED: 1847 tr_transferred: 1848 if (next_xfer == UMASS_T_CBI_STATUS) { 1849 umass_cbi_start_status(sc); 1850 } else { 1851 umass_transfer_start(sc, next_xfer); 1852 } 1853 break; 1854 1855 case USB_ST_SETUP: 1856 if (usbd_clear_stall_callback(xfer, sc->sc_xfer[stall_xfer])) { 1857 goto tr_transferred; /* should not happen */ 1858 } 1859 break; 1860 1861 default: /* Error */ 1862 umass_tr_error(xfer, error); 1863 break; 1864 } 1865 } 1866 1867 static void 1868 umass_t_cbi_command_callback(struct usb_xfer *xfer, usb_error_t error) 1869 { 1870 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1871 union ccb *umass_ccb = sc->sc_transfer.ccb; 1872 struct usb_device_request req; 1873 struct usb_page_cache *pc; 1874 1875 switch (USB_GET_STATE(xfer)) { 1876 case USB_ST_TRANSFERRED: 1877 1878 if (sc->sc_transfer.dir == DIR_NONE) { 1879 umass_cbi_start_status(sc); 1880 } else { 1881 umass_transfer_start 1882 (sc, (sc->sc_transfer.dir == DIR_IN) ? 1883 UMASS_T_CBI_DATA_READ : UMASS_T_CBI_DATA_WRITE); 1884 } 1885 break; 1886 1887 case USB_ST_SETUP: 1888 1889 if (umass_ccb) { 1890 1891 /* 1892 * do a CBI transfer with cmd_len bytes from 1893 * cmd_data, possibly a data phase of data_len 1894 * bytes from/to the device and finally a status 1895 * read phase. 1896 */ 1897 1898 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 1899 req.bRequest = UR_CBI_ADSC; 1900 USETW(req.wValue, 0); 1901 req.wIndex[0] = sc->sc_iface_no; 1902 req.wIndex[1] = 0; 1903 req.wLength[0] = sc->sc_transfer.cmd_len; 1904 req.wLength[1] = 0; 1905 1906 pc = usbd_xfer_get_frame(xfer, 0); 1907 usbd_copy_in(pc, 0, &req, sizeof(req)); 1908 pc = usbd_xfer_get_frame(xfer, 1); 1909 usbd_copy_in(pc, 0, sc->sc_transfer.cmd_data, 1910 sc->sc_transfer.cmd_len); 1911 1912 usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); 1913 usbd_xfer_set_frame_len(xfer, 1, sc->sc_transfer.cmd_len); 1914 usbd_xfer_set_frames(xfer, 1915 sc->sc_transfer.cmd_len ? 2 : 1); 1916 1917 DIF(UDMASS_CBI, 1918 umass_cbi_dump_cmd(sc, 1919 sc->sc_transfer.cmd_data, 1920 sc->sc_transfer.cmd_len)); 1921 1922 usbd_transfer_submit(xfer); 1923 } 1924 break; 1925 1926 default: /* Error */ 1927 /* 1928 * STALL on the control pipe can be result of the command error. 1929 * Attempt to clear this STALL same as for bulk pipe also 1930 * results in command completion interrupt, but ASC/ASCQ there 1931 * look like not always valid, so don't bother about it. 1932 */ 1933 if ((error == USB_ERR_STALLED) || 1934 (sc->sc_transfer.callback == &umass_cam_cb)) { 1935 sc->sc_transfer.ccb = NULL; 1936 (sc->sc_transfer.callback) 1937 (sc, umass_ccb, sc->sc_transfer.data_len, 1938 STATUS_CMD_UNKNOWN); 1939 } else { 1940 umass_tr_error(xfer, error); 1941 /* skip reset */ 1942 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; 1943 } 1944 break; 1945 } 1946 } 1947 1948 static void 1949 umass_t_cbi_data_read_callback(struct usb_xfer *xfer, usb_error_t error) 1950 { 1951 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 1952 uint32_t max_bulk = usbd_xfer_max_len(xfer); 1953 int actlen, sumlen; 1954 1955 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 1956 1957 switch (USB_GET_STATE(xfer)) { 1958 case USB_ST_TRANSFERRED: 1959 sc->sc_transfer.data_rem -= actlen; 1960 sc->sc_transfer.data_ptr += actlen; 1961 sc->sc_transfer.actlen += actlen; 1962 1963 if (actlen < sumlen) { 1964 /* short transfer */ 1965 sc->sc_transfer.data_rem = 0; 1966 } 1967 case USB_ST_SETUP: 1968 DPRINTF_UMASS(sc, UDMASS_CBI, "max_bulk=%d, data_rem=%d\n", 1969 max_bulk, sc->sc_transfer.data_rem); 1970 1971 if (sc->sc_transfer.data_rem == 0) { 1972 umass_cbi_start_status(sc); 1973 break; 1974 } 1975 if (max_bulk > sc->sc_transfer.data_rem) { 1976 max_bulk = sc->sc_transfer.data_rem; 1977 } 1978 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout); 1979 1980 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, 1981 max_bulk); 1982 1983 usbd_transfer_submit(xfer); 1984 break; 1985 1986 default: /* Error */ 1987 if ((error == USB_ERR_CANCELLED) || 1988 (sc->sc_transfer.callback != &umass_cam_cb)) { 1989 umass_tr_error(xfer, error); 1990 } else { 1991 umass_transfer_start(sc, UMASS_T_CBI_DATA_RD_CS); 1992 } 1993 break; 1994 } 1995 } 1996 1997 static void 1998 umass_t_cbi_data_rd_cs_callback(struct usb_xfer *xfer, usb_error_t error) 1999 { 2000 umass_t_cbi_data_clear_stall_callback(xfer, UMASS_T_CBI_STATUS, 2001 UMASS_T_CBI_DATA_READ, error); 2002 } 2003 2004 static void 2005 umass_t_cbi_data_write_callback(struct usb_xfer *xfer, usb_error_t error) 2006 { 2007 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 2008 uint32_t max_bulk = usbd_xfer_max_len(xfer); 2009 int actlen, sumlen; 2010 2011 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 2012 2013 switch (USB_GET_STATE(xfer)) { 2014 case USB_ST_TRANSFERRED: 2015 sc->sc_transfer.data_rem -= actlen; 2016 sc->sc_transfer.data_ptr += actlen; 2017 sc->sc_transfer.actlen += actlen; 2018 2019 if (actlen < sumlen) { 2020 /* short transfer */ 2021 sc->sc_transfer.data_rem = 0; 2022 } 2023 case USB_ST_SETUP: 2024 DPRINTF_UMASS(sc, UDMASS_CBI, "max_bulk=%d, data_rem=%d\n", 2025 max_bulk, sc->sc_transfer.data_rem); 2026 2027 if (sc->sc_transfer.data_rem == 0) { 2028 umass_cbi_start_status(sc); 2029 break; 2030 } 2031 if (max_bulk > sc->sc_transfer.data_rem) { 2032 max_bulk = sc->sc_transfer.data_rem; 2033 } 2034 usbd_xfer_set_timeout(xfer, sc->sc_transfer.data_timeout); 2035 2036 usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, 2037 max_bulk); 2038 2039 usbd_transfer_submit(xfer); 2040 break; 2041 2042 default: /* Error */ 2043 if ((error == USB_ERR_CANCELLED) || 2044 (sc->sc_transfer.callback != &umass_cam_cb)) { 2045 umass_tr_error(xfer, error); 2046 } else { 2047 umass_transfer_start(sc, UMASS_T_CBI_DATA_WR_CS); 2048 } 2049 break; 2050 } 2051 } 2052 2053 static void 2054 umass_t_cbi_data_wr_cs_callback(struct usb_xfer *xfer, usb_error_t error) 2055 { 2056 umass_t_cbi_data_clear_stall_callback(xfer, UMASS_T_CBI_STATUS, 2057 UMASS_T_CBI_DATA_WRITE, error); 2058 } 2059 2060 static void 2061 umass_t_cbi_status_callback(struct usb_xfer *xfer, usb_error_t error) 2062 { 2063 struct umass_softc *sc = (struct umass_softc *)usbd_xfer_softc(xfer); 2064 union ccb *umass_ccb = sc->sc_transfer.ccb; 2065 struct usb_page_cache *pc; 2066 uint32_t residue; 2067 uint8_t status; 2068 int actlen; 2069 2070 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 2071 2072 switch (USB_GET_STATE(xfer)) { 2073 case USB_ST_TRANSFERRED: 2074 2075 if (actlen < (int)sizeof(sc->sbl)) { 2076 goto tr_setup; 2077 } 2078 pc = usbd_xfer_get_frame(xfer, 0); 2079 usbd_copy_out(pc, 0, &sc->sbl, sizeof(sc->sbl)); 2080 2081 residue = (sc->sc_transfer.data_len - 2082 sc->sc_transfer.actlen); 2083 2084 /* dissect the information in the buffer */ 2085 2086 if (sc->sc_proto & UMASS_PROTO_UFI) { 2087 2088 /* 2089 * Section 3.4.3.1.3 specifies that the UFI command 2090 * protocol returns an ASC and ASCQ in the interrupt 2091 * data block. 2092 */ 2093 2094 DPRINTF_UMASS(sc, UDMASS_CBI, "UFI CCI, ASC = 0x%02x, " 2095 "ASCQ = 0x%02x\n", sc->sbl.ufi.asc, 2096 sc->sbl.ufi.ascq); 2097 2098 status = (((sc->sbl.ufi.asc == 0) && 2099 (sc->sbl.ufi.ascq == 0)) ? 2100 STATUS_CMD_OK : STATUS_CMD_FAILED); 2101 2102 sc->sc_transfer.ccb = NULL; 2103 2104 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; 2105 2106 (sc->sc_transfer.callback) 2107 (sc, umass_ccb, residue, status); 2108 2109 break; 2110 2111 } else { 2112 2113 /* Command Interrupt Data Block */ 2114 2115 DPRINTF_UMASS(sc, UDMASS_CBI, "type=0x%02x, value=0x%02x\n", 2116 sc->sbl.common.type, sc->sbl.common.value); 2117 2118 if (sc->sbl.common.type == IDB_TYPE_CCI) { 2119 2120 status = (sc->sbl.common.value & IDB_VALUE_STATUS_MASK); 2121 2122 status = ((status == IDB_VALUE_PASS) ? STATUS_CMD_OK : 2123 (status == IDB_VALUE_FAIL) ? STATUS_CMD_FAILED : 2124 (status == IDB_VALUE_PERSISTENT) ? STATUS_CMD_FAILED : 2125 STATUS_WIRE_FAILED); 2126 2127 sc->sc_transfer.ccb = NULL; 2128 2129 sc->sc_last_xfer_index = UMASS_T_CBI_COMMAND; 2130 2131 (sc->sc_transfer.callback) 2132 (sc, umass_ccb, residue, status); 2133 2134 break; 2135 } 2136 } 2137 2138 /* fallthrough */ 2139 2140 case USB_ST_SETUP: 2141 tr_setup: 2142 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 2143 usbd_transfer_submit(xfer); 2144 break; 2145 2146 default: /* Error */ 2147 DPRINTF_UMASS(sc, UDMASS_CBI, "Failed to read CSW: %s\n", 2148 usbd_errstr(error)); 2149 umass_tr_error(xfer, error); 2150 break; 2151 } 2152 } 2153 2154 /* umass_cam_cb 2155 * finalise a completed CAM command 2156 */ 2157 2158 static void 2159 umass_cam_cb(struct umass_softc *sc, union ccb *umass_ccb, uint32_t residue, 2160 uint8_t status) 2161 { 2162 umass_ccb->csio.resid = residue; 2163 umass_ccb->csio.status = status; 2164 2165 switch (status) { 2166 case STATUS_CMD_OK: 2167 (void)LOS_EventWrite(&sc->sc_event, 0x01); 2168 break; 2169 2170 case STATUS_CMD_UNKNOWN: 2171 case STATUS_CMD_FAILED: 2172 /* fetch sense data */ 2173 (void)LOS_EventWrite(&sc->sc_event, 0x02); 2174 break; 2175 2176 default: 2177 (void)LOS_EventWrite(&sc->sc_event, 0x04); 2178 break; 2179 } 2180 } 2181 2182 /* 2183 * SCSI specific functions 2184 */ 2185 2186 static uint8_t 2187 umass_scsi_transform(struct umass_softc *sc, uint8_t *cmd_ptr, 2188 uint8_t cmd_len) 2189 { 2190 int ret; 2191 2192 if ((cmd_len == 0) || 2193 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) { 2194 DPRINTF_UMASS(sc, UDMASS_SCSI, "Invalid command " 2195 "length: %d bytes\n", cmd_len); 2196 return (0); /* failure */ 2197 } 2198 sc->sc_transfer.cmd_len = cmd_len; 2199 2200 switch (cmd_ptr[0]) { 2201 case TEST_UNIT_READY: 2202 if (sc->sc_quirks & NO_TEST_UNIT_READY) { 2203 DPRINTF_UMASS(sc, UDMASS_SCSI, "Converted TEST_UNIT_READY " 2204 "to START_UNIT\n"); 2205 ret = memset_s(sc->sc_transfer.cmd_data, sizeof(sc->sc_transfer.cmd_data), 0, cmd_len); 2206 if (ret != EOK) { 2207 usb_err("memset_s failed!, ret:%d\n", ret); 2208 return (0); 2209 } 2210 sc->sc_transfer.cmd_data[0] = START_STOP_UNIT; 2211 sc->sc_transfer.cmd_data[4] = SSS_START; 2212 return (1); 2213 } 2214 break; 2215 2216 case INQUIRY: 2217 /* 2218 * some drives wedge when asked for full inquiry 2219 * information. 2220 */ 2221 if (sc->sc_quirks & FORCE_SHORT_INQUIRY) { 2222 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len); 2223 if (ret != EOK) { 2224 usb_err("memcpy_s failed!, ret:%d\n", ret); 2225 return (0); 2226 } 2227 sc->sc_transfer.cmd_data[4] = SHORT_INQUIRY_LENGTH; 2228 return (1); 2229 } 2230 break; 2231 } 2232 2233 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len); 2234 if (ret != EOK) { 2235 usb_err("memcpy_s failed!, ret:%d\n", ret); 2236 return (0); 2237 } 2238 2239 return (1); 2240 } 2241 2242 static uint8_t 2243 umass_rbc_transform(struct umass_softc *sc, uint8_t *cmd_ptr, uint8_t cmd_len) 2244 { 2245 int ret; 2246 2247 if ((cmd_len == 0) || 2248 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) { 2249 DPRINTF_UMASS(sc, UDMASS_SCSI, "Invalid command " 2250 "length: %d bytes\n", cmd_len); 2251 return (0); /* failure */ 2252 } 2253 switch (cmd_ptr[0]) { 2254 /* these commands are defined in RBC: */ 2255 case READ_10: 2256 case READ_CAPACITY: 2257 case START_STOP_UNIT: 2258 case SYNCHRONIZE_CACHE: 2259 case WRITE_10: 2260 case 0x2f: /* VERIFY_10 is absent from * scsi_all.h??? */ 2261 case INQUIRY: 2262 case MODE_SELECT_10: 2263 case MODE_SENSE_10: 2264 case TEST_UNIT_READY: 2265 case WRITE_BUFFER: 2266 /* 2267 * The following commands are not listed in my copy of the 2268 * RBC specs. CAM however seems to want those, and at least 2269 * the Sony DSC device appears to support those as well 2270 */ 2271 case REQUEST_SENSE: 2272 case PREVENT_ALLOW: 2273 2274 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len); 2275 if (ret != EOK) { 2276 usb_err("memcpy_s failed!, ret:%d\n", ret); 2277 return (0); 2278 } 2279 2280 if ((sc->sc_quirks & RBC_PAD_TO_12) && (cmd_len < 12)) { 2281 ret = memset_s(sc->sc_transfer.cmd_data + cmd_len, 2282 (size_t)(UMASS_MAX_CMDLEN - cmd_len), 0, (size_t)(12 - cmd_len)); 2283 if (ret != EOK){ 2284 usb_err("memset_s failed!, ret:%d\n", ret); 2285 return (0); 2286 } 2287 cmd_len = 12; 2288 } 2289 sc->sc_transfer.cmd_len = cmd_len; 2290 return (1); /* sucess */ 2291 2292 /* All other commands are not legal in RBC */ 2293 default: 2294 DPRINTF_UMASS(sc, UDMASS_SCSI, "Unsupported RBC " 2295 "command 0x%02x\n", cmd_ptr[0]); 2296 return (0); /* failure */ 2297 } 2298 } 2299 2300 static uint8_t 2301 umass_ufi_transform(struct umass_softc *sc, uint8_t *cmd_ptr, 2302 uint8_t cmd_len) 2303 { 2304 int ret; 2305 2306 if ((cmd_len == 0) || 2307 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) { 2308 DPRINTF_UMASS(sc, UDMASS_SCSI, "Invalid command " 2309 "length: %d bytes\n", cmd_len); 2310 return (0); /* failure */ 2311 } 2312 /* An UFI command is always 12 bytes in length */ 2313 sc->sc_transfer.cmd_len = UFI_COMMAND_LENGTH; 2314 2315 /* Zero the command data */ 2316 ret = memset_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, 0, UFI_COMMAND_LENGTH); 2317 if (ret != EOK) { 2318 usb_err("memset_s failed!, ret:%d\n", ret); 2319 return (0); 2320 } 2321 2322 switch (cmd_ptr[0]) { 2323 /* 2324 * Commands of which the format has been verified. They 2325 * should work. Copy the command into the (zeroed out) 2326 * destination buffer. 2327 */ 2328 case TEST_UNIT_READY: 2329 if (sc->sc_quirks & NO_TEST_UNIT_READY) { 2330 /* 2331 * Some devices do not support this command. Start 2332 * Stop Unit should give the same results 2333 */ 2334 DPRINTF_UMASS(sc, UDMASS_UFI, "Converted TEST_UNIT_READY " 2335 "to START_UNIT\n"); 2336 2337 sc->sc_transfer.cmd_data[0] = START_STOP_UNIT; 2338 sc->sc_transfer.cmd_data[4] = SSS_START; 2339 return (1); 2340 } 2341 break; 2342 2343 case REZERO_UNIT: 2344 case REQUEST_SENSE: 2345 case FORMAT_UNIT: 2346 case INQUIRY: 2347 case START_STOP_UNIT: 2348 case SEND_DIAGNOSTIC: 2349 case PREVENT_ALLOW: 2350 case READ_CAPACITY: 2351 case READ_10: 2352 case WRITE_10: 2353 case POSITION_TO_ELEMENT: /* SEEK_10 */ 2354 case WRITE_AND_VERIFY: 2355 case VERIFIED: 2356 case MODE_SELECT_10: 2357 case MODE_SENSE_10: 2358 case READ_12: 2359 case WRITE_12: 2360 case READ_FORMAT_CAPACITIES: 2361 break; 2362 2363 /* 2364 * SYNCHRONIZE_CACHE isn't supported by UFI, nor should it be 2365 * required for UFI devices, so it is appropriate to fake 2366 * success. 2367 */ 2368 case SYNCHRONIZE_CACHE: 2369 return (2); 2370 2371 default: 2372 DPRINTF_UMASS(sc, UDMASS_SCSI, "Unsupported UFI " 2373 "command 0x%02x\n", cmd_ptr[0]); 2374 return (0); /* failure */ 2375 } 2376 2377 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len); 2378 if (ret != EOK) { 2379 usb_err("memcpy_s failed!, ret:%d\n", ret); 2380 return (0); 2381 } 2382 2383 return (1); /* success */ 2384 } 2385 2386 /* 2387 * 8070i (ATAPI) specific functions 2388 */ 2389 static uint8_t 2390 umass_atapi_transform(struct umass_softc *sc, uint8_t *cmd_ptr, 2391 uint8_t cmd_len) 2392 { 2393 int ret; 2394 2395 if ((cmd_len == 0) || 2396 (cmd_len > sizeof(sc->sc_transfer.cmd_data))) { 2397 DPRINTF_UMASS(sc, UDMASS_SCSI, "Invalid command " 2398 "length: %d bytes\n", cmd_len); 2399 return (0); /* failure */ 2400 } 2401 /* An ATAPI command is always 12 bytes in length. */ 2402 sc->sc_transfer.cmd_len = ATAPI_COMMAND_LENGTH; 2403 2404 /* Zero the command data */ 2405 ret = memset_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, 0, ATAPI_COMMAND_LENGTH); 2406 if (ret != EOK) { 2407 usb_err("memset_s failed!, ret:%d\n", ret); 2408 return (0); 2409 } 2410 2411 switch (cmd_ptr[0]) { 2412 /* 2413 * Commands of which the format has been verified. They 2414 * should work. Copy the command into the destination 2415 * buffer. 2416 */ 2417 case INQUIRY: 2418 /* 2419 * some drives wedge when asked for full inquiry 2420 * information. 2421 */ 2422 if (sc->sc_quirks & FORCE_SHORT_INQUIRY) { 2423 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len); 2424 if (ret != EOK) { 2425 usb_err("memcpy_s failed!, ret:%d\n", ret); 2426 return (0); 2427 } 2428 sc->sc_transfer.cmd_data[4] = SHORT_INQUIRY_LENGTH; 2429 return (1); 2430 } 2431 break; 2432 2433 case TEST_UNIT_READY: 2434 if (sc->sc_quirks & NO_TEST_UNIT_READY) { 2435 DPRINTF_UMASS(sc, UDMASS_SCSI, "Converted TEST_UNIT_READY " 2436 "to START_UNIT\n"); 2437 sc->sc_transfer.cmd_data[0] = START_STOP_UNIT; 2438 sc->sc_transfer.cmd_data[4] = SSS_START; 2439 return (1); 2440 } 2441 break; 2442 2443 case REZERO_UNIT: 2444 case REQUEST_SENSE: 2445 case START_STOP_UNIT: 2446 case SEND_DIAGNOSTIC: 2447 case PREVENT_ALLOW: 2448 case READ_CAPACITY: 2449 case READ_10: 2450 case WRITE_10: 2451 case POSITION_TO_ELEMENT: /* SEEK_10 */ 2452 case SYNCHRONIZE_CACHE: 2453 case MODE_SELECT_10: 2454 case MODE_SENSE_10: 2455 case READ_BUFFER: 2456 case 0x42: /* READ_SUBCHANNEL */ 2457 case 0x43: /* READ_TOC */ 2458 case 0x44: /* READ_HEADER */ 2459 case 0x47: /* PLAY_MSF (Play Minute/Second/Frame) */ 2460 case 0x48: /* PLAY_TRACK */ 2461 case 0x49: /* PLAY_TRACK_REL */ 2462 case 0x4b: /* PAUSE */ 2463 case 0x51: /* READ_DISK_INFO */ 2464 case 0x52: /* READ_TRACK_INFO */ 2465 case 0x54: /* SEND_OPC */ 2466 case 0x59: /* READ_MASTER_CUE */ 2467 case 0x5b: /* CLOSE_TR_SESSION */ 2468 case 0x5c: /* READ_BUFFER_CAP */ 2469 case 0x5d: /* SEND_CUE_SHEET */ 2470 case 0xa1: /* BLANK */ 2471 case 0xa5: /* PLAY_12 */ 2472 case 0xa6: /* EXCHANGE_MEDIUM */ 2473 case 0xad: /* READ_DVD_STRUCTURE */ 2474 case 0xbb: /* SET_CD_SPEED */ 2475 case 0xe5: /* READ_TRACK_INFO_PHILIPS */ 2476 break; 2477 2478 case READ_12: 2479 case WRITE_12: 2480 default: 2481 DPRINTF_UMASS(sc, UDMASS_SCSI, "Unsupported ATAPI " 2482 "command 0x%02x - trying anyway\n", 2483 cmd_ptr[0]); 2484 break; 2485 } 2486 2487 ret = memcpy_s(sc->sc_transfer.cmd_data, UMASS_MAX_CMDLEN, cmd_ptr, cmd_len); 2488 if (ret != EOK) { 2489 usb_err("memcpy_s failed!, ret:%d\n", ret); 2490 return (0); 2491 } 2492 2493 return (1); /* success */ 2494 } 2495 2496 static uint8_t 2497 umass_no_transform(struct umass_softc *sc, uint8_t *cmd, 2498 uint8_t cmdlen) 2499 { 2500 return (0); /* failure */ 2501 } 2502 2503 #ifdef LOSCFG_USB_DEBUG 2504 static void 2505 umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw) 2506 { 2507 uint8_t *c = cbw->CBWCDB; 2508 2509 uint32_t dlen = UGETDW(cbw->dCBWDataTransferLength); 2510 uint32_t tag = UGETDW(cbw->dCBWTag); 2511 2512 uint8_t clen = cbw->bCDBLength; 2513 uint8_t flags = cbw->bCBWFlags; 2514 uint8_t lun = cbw->bCBWLUN; 2515 2516 DPRINTF_UMASS(sc, UDMASS_BBB, "CBW %d: cmd = %db " 2517 "(0x%02x%02x%02x%02x%02x%02x%s), " 2518 "data = %db, lun = %d, dir = %s\n", 2519 tag, clen, 2520 c[0], c[1], c[2], c[3], c[4], c[5], (clen > 6 ? "..." : ""), 2521 dlen, lun, (flags == CBWFLAGS_IN ? "in" : 2522 (flags == CBWFLAGS_OUT ? "out" : "<invalid>"))); 2523 } 2524 2525 static void 2526 umass_bbb_dump_csw(struct umass_softc *sc, umass_bbb_csw_t *csw) 2527 { 2528 uint32_t sig = UGETDW(csw->dCSWSignature); 2529 uint32_t tag = UGETDW(csw->dCSWTag); 2530 uint32_t res = UGETDW(csw->dCSWDataResidue); 2531 uint8_t status = csw->bCSWStatus; 2532 2533 DPRINTF_UMASS(sc, UDMASS_BBB, "CSW %d: sig = 0x%08x (%s), tag = 0x%08x, " 2534 "res = %d, status = 0x%02x (%s)\n", 2535 tag, sig, (sig == CSWSIGNATURE ? "valid" : "invalid"), 2536 tag, res, 2537 status, (status == CSWSTATUS_GOOD ? "good" : 2538 (status == CSWSTATUS_FAILED ? "failed" : 2539 (status == CSWSTATUS_PHASE ? "phase" : "<invalid>")))); 2540 } 2541 2542 static void 2543 umass_cbi_dump_cmd(struct umass_softc *sc, void *cmd, uint8_t cmdlen) 2544 { 2545 uint8_t *c = cmd; 2546 uint8_t dir = sc->sc_transfer.dir; 2547 2548 DPRINTF_UMASS(sc, UDMASS_BBB, "cmd = %db " 2549 "(0x%02x%02x%02x%02x%02x%02x%s), " 2550 "data = %db, dir = %s\n", 2551 cmdlen, 2552 c[0], c[1], c[2], c[3], c[4], c[5], (cmdlen > 6 ? "..." : ""), 2553 sc->sc_transfer.data_len, 2554 (dir == DIR_IN ? "in" : 2555 (dir == DIR_OUT ? "out" : 2556 (dir == DIR_NONE ? "no data phase" : "<invalid>")))); 2557 } 2558 2559 #endif 2560 2561 #define SCSI_INQ_LEN 0x24 2562 2563 static uint8_t scsi_test_unit_ready[] = { 2564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 2565 }; 2566 static uint8_t scsi_inquiry[] = { 2567 0x12, 0x00, 0x00, 0x00, SCSI_INQ_LEN, 0x00 2568 }; 2569 static uint8_t scsi_request_sense[] = { 2570 0x03, 0x00, 0x00, 0x00, 0x12, 0x00, 2571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 2572 }; 2573 static uint8_t scsi_read_capacity[] = { 2574 0x25, 0x00, 0x00, 0x00, 0x00, 2575 0x00, 0x00, 0x00, 0x00, 0x00 2576 }; 2577 2578 static uint8_t scsi_read_capacity_16[] = { 2579 0x9e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2580 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00 2581 }; 2582 2583 /* Description: Get a (possibly unaligned) 16-bit big endian value. */ 2584 static inline uint16_t 2585 usbhost_getbe16(const uint8_t *val) 2586 { 2587 return ((uint16_t)val[0] << 8 | (uint16_t)val[1]); 2588 } 2589 2590 /* Description: Put a (possibly unaligned) 16-bit little endian value. */ 2591 void 2592 usbhost_putle16(uint8_t *dest, uint16_t val) 2593 { 2594 dest[0] = val & 0xff; /* Little endian means LS byte first in byte stream */ 2595 dest[1] = val >> 8; 2596 } 2597 2598 /* Description: Put a (possibly unaligned) 16-bit big endian value. */ 2599 void 2600 usbhost_putbe16(uint8_t *dest, uint16_t val) 2601 { 2602 dest[0] = val >> 8; /* Big endian means MS byte first in byte stream */ 2603 dest[1] = val & 0xff; 2604 } 2605 2606 /* Description: Get a (possibly unaligned) 32-bit big endian value. */ 2607 uint32_t 2608 usbhost_getbe32(const uint8_t *val) 2609 { 2610 /* Big endian means MS halfword first in byte stream */ 2611 return ((uint32_t)usbhost_getbe16(val) << 16 | 2612 (uint32_t)usbhost_getbe16(&val[2])); 2613 } 2614 2615 /* Description: Get a (possibly unaligned) 64-bit big endian value. */ 2616 uint64_t 2617 usbhost_getbe64(const uint8_t *val) 2618 { 2619 /* Big endian means MS halfword first in byte stream */ 2620 return ((uint64_t)usbhost_getbe32(val) << 32 | 2621 (uint64_t)usbhost_getbe32(&val[4])); 2622 } 2623 2624 /* Description: Put a (possibly unaligned) 32-bit little endian value. */ 2625 void 2626 usbhost_putle32(uint8_t *dest, uint32_t val) 2627 { 2628 /* Little endian means LS halfword first in byte stream */ 2629 usbhost_putle16(dest, (uint16_t)(val & 0xffff)); 2630 usbhost_putle16(dest+2, (uint16_t)(val >> 16)); 2631 } 2632 2633 /* Put a (possibly unaligned) 32-bit big endian value. */ 2634 void 2635 usbhost_putbe32(uint8_t *dest, uint32_t val) 2636 { 2637 /* Big endian means MS halfword first in byte stream */ 2638 usbhost_putbe16(dest, (uint16_t)(val >> 16)); 2639 usbhost_putbe16(dest+2, (uint16_t)(val & 0xffff)); 2640 } 2641 2642 /* Put a (possibly unaligned) 64-bit big endian value. */ 2643 void 2644 usbhost_putbe64(uint8_t *dest, uint64_t val) 2645 { 2646 /* Big endian means MS halfword first in byte stream */ 2647 usbhost_putbe32(dest, (uint32_t)(val >> 32)); 2648 usbhost_putbe32(dest+4, (uint32_t)(val & 0xffffffff)); 2649 } 2650 2651 void 2652 usbhost_readcdb16(uint64_t startsector, uint16_t blocksize, 2653 unsigned int nsectors, struct scsicmd_read16_s *cdb) 2654 { 2655 struct scsicmd_read16_s *rd16 = (struct scsicmd_read16_s *)cdb; 2656 2657 /* Format the CDB */ 2658 rd16->opcode = SCSI_CMD_READ16; 2659 usbhost_putbe64(rd16->lba, startsector); 2660 usbhost_putbe32(rd16->xfrlen, nsectors); 2661 } 2662 2663 void 2664 usbhost_readcdb10(size_t startsector, uint16_t blocksize, 2665 unsigned int nsectors, struct scsicmd_read10_s *cdb) 2666 { 2667 struct scsicmd_read10_s *rd10 = (struct scsicmd_read10_s *)cdb; 2668 2669 /* Format the CDB */ 2670 rd10->opcode = SCSI_CMD_READ10; 2671 usbhost_putbe32(rd10->lba, startsector); 2672 usbhost_putbe16(rd10->xfrlen, nsectors); 2673 } 2674 2675 void 2676 usbhost_writecbw16(uint64_t startsector, uint16_t blocksize, 2677 unsigned int nsectors, struct scsicmd_write16_s *cdb) 2678 { 2679 struct scsicmd_write16_s *wr16 = (struct scsicmd_write16_s *)cdb; 2680 2681 wr16->opcode = SCSI_CMD_WRITE16; 2682 usbhost_putbe64(wr16->lba, startsector); 2683 usbhost_putbe32(wr16->xfrlen, nsectors); 2684 } 2685 2686 void 2687 usbhost_writecbw10(size_t startsector, uint16_t blocksize, 2688 unsigned int nsectors, struct scsicmd_write10_s *cdb) 2689 { 2690 struct scsicmd_write10_s *wr10 = (struct scsicmd_write10_s *)cdb; 2691 2692 wr10->opcode = SCSI_CMD_WRITE10; 2693 usbhost_putbe32(wr10->lba, startsector); 2694 usbhost_putbe16(wr10->xfrlen, nsectors); 2695 } 2696 2697 int 2698 umass_test_unit_ready(struct umass_softc *sc) 2699 { 2700 uint32_t status; 2701 int32_t res; 2702 2703 if((sc == NULL) || (sc->data_ccb == NULL)) { 2704 return (-1); 2705 } 2706 2707 (void)umass_scsi_transform(sc, scsi_test_unit_ready, SCSICMD_TESTUNITREADY8_SIZEOF); 2708 res = umass_command_start(sc, DIR_NONE, NULL, 0, 1000, umass_cam_cb, sc->data_ccb); 2709 if (STATUS_CMD_OK != res) { 2710 return (-1); 2711 } 2712 2713 status = sc->data_ccb->csio.status; 2714 if (status != STATUS_CMD_OK) { 2715 return (-1); 2716 } 2717 2718 return (0); 2719 } 2720 2721 int 2722 umass_read_capacity_16(struct umass_softc *sc) 2723 { 2724 struct scsiresp_readcapacity16_s resp; 2725 uint32_t res; 2726 int ret; 2727 2728 (void)umass_scsi_transform(sc, scsi_read_capacity_16, SCSICMD_READCAPACITY16_SIZEOF); 2729 res = (uint32_t)umass_command_start(sc, DIR_IN, sc->data_ccb->csio.data_ptr, 2730 (uint32_t)SCSIRESP_READCAPACITY16_SIZEOF, 2731 (uint32_t)1000, umass_cam_cb, sc->data_ccb); 2732 if (STATUS_CMD_OK != res) { 2733 return (-1); 2734 } 2735 2736 ret = memcpy_s((void *)&resp, sizeof(resp), sc->data_ccb->csio.data_ptr, 2737 SCSIRESP_READCAPACITY16_SIZEOF); 2738 if (ret != EOK) { 2739 usb_err("memcpy_s failed, %d\n", ret); 2740 return (-1); 2741 } 2742 2743 sc->info.sectornum= usbhost_getbe64(resp.lba) + 1; 2744 sc->info.sectorsize= usbhost_getbe32(resp.blklen); 2745 2746 return (0); 2747 } 2748 2749 int 2750 umass_read_capacity(struct umass_softc *sc) 2751 { 2752 struct scsiresp_readcapacity10_s resp; 2753 int32_t ret; 2754 2755 if ((sc == NULL) || (sc->data_ccb == NULL)) { 2756 return (-1); 2757 } 2758 2759 (void)umass_scsi_transform(sc, scsi_read_capacity, SCSICMD_READCAPACITY10_SIZEOF); 2760 ret = umass_command_start(sc, DIR_IN, sc->data_ccb->csio.data_ptr, 2761 SCSIRESP_READCAPACITY10_SIZEOF, 2762 1000, umass_cam_cb, sc->data_ccb); 2763 if (STATUS_CMD_OK != ret) { 2764 return (-1); 2765 } 2766 2767 ret = memcpy_s((void *)&resp, sizeof(resp), sc->data_ccb->csio.data_ptr, 2768 SCSIRESP_READCAPACITY10_SIZEOF); 2769 if (ret != EOK) { 2770 usb_err("memcpy_s failed, %d\n", ret); 2771 return (-1); 2772 } 2773 2774 /* The disk Capacity is bigger than 2T */ 2775 if (usbhost_getbe32(resp.lba) == 0xffffffff) { 2776 ret = umass_read_capacity_16(sc); 2777 if (ret != 0) { 2778 usb_err("Read Capacity failed, %d\n", ret); 2779 return (-1); 2780 } 2781 sc->sc_super_disk = TRUE; 2782 2783 return (0); 2784 } 2785 2786 sc->info.sectornum= usbhost_getbe32(resp.lba) + 1; 2787 sc->info.sectorsize= usbhost_getbe32(resp.blklen); 2788 sc->sc_super_disk = FALSE; 2789 2790 return (0); 2791 } 2792 2793 int 2794 umass_read10(struct umass_softc *sc, size_t startsector, uint16_t blocksize, 2795 unsigned int nsectors, unsigned char *buf) 2796 { 2797 struct scsicmd_read10_s cdb; 2798 uint8_t *data_buf = buf; 2799 uint32_t status; 2800 int32_t ret; 2801 uint32_t flag = 0; 2802 2803 if ((sc == NULL) || (sc->data_ccb == NULL)) { 2804 return (-1); 2805 } 2806 2807 if ((sc->info.sectornum < (startsector + nsectors)) || (sc->info.sectorsize < blocksize)) 2808 return (-1); 2809 2810 if (((uintptr_t)data_buf & (USB_CACHE_ALIGN_SIZE - 1)) != 0) 2811 { 2812 data_buf = (uint8_t *)memalign(USB_CACHE_ALIGN_SIZE, SKB_DATA_ALIGN(nsectors * blocksize)); 2813 if (data_buf == NULL) { 2814 PRINT_ERR("Malloc failed!->%s %d\n", __FUNCTION__, __LINE__); 2815 return (-1); 2816 } 2817 flag = 1; 2818 } 2819 2820 (void)memset_s(&cdb, sizeof(struct scsicmd_read10_s), 0, sizeof(struct scsicmd_read10_s)); 2821 usbhost_readcdb10(startsector, blocksize, nsectors, &cdb); 2822 (void)umass_scsi_transform(sc, (uint8_t *)&cdb, SCSICMD_READ10_SIZEOF); 2823 ret = umass_command_start(sc, DIR_IN, (void *)data_buf, blocksize * nsectors, 0, 2824 umass_cam_cb, sc->data_ccb); 2825 if (ret != STATUS_CMD_OK) { 2826 if (flag == 1) 2827 free(data_buf); 2828 return (-1); 2829 } 2830 2831 if (flag == 1) { 2832 if (!LOS_IsUserAddressRange((vaddr_t)buf, blocksize * nsectors - sc->data_ccb->csio.resid)) { 2833 ret = memcpy_s(buf, nsectors * blocksize, data_buf, blocksize * nsectors - sc->data_ccb->csio.resid); 2834 } else { 2835 ret = ((nsectors * blocksize >= blocksize * nsectors - sc->data_ccb->csio.resid) ? 2836 LOS_ArchCopyToUser(buf, data_buf, blocksize * nsectors - sc->data_ccb->csio.resid) : ERANGE_AND_RESET); 2837 } 2838 free(data_buf); 2839 if (ret != EOK) { 2840 return (-1); 2841 } 2842 } 2843 2844 status = sc->data_ccb->csio.status; 2845 if (status != STATUS_CMD_OK) { 2846 return (-1); 2847 } 2848 2849 return (0); 2850 } 2851 2852 int 2853 umass_read16(struct umass_softc *sc, uint64_t startsector, uint16_t blocksize, 2854 unsigned int nsectors, unsigned char *buf) 2855 { 2856 struct scsicmd_read16_s cdb; 2857 uint8_t *data_buf = buf; 2858 uint32_t status; 2859 uint32_t res; 2860 uint32_t flag = 0; 2861 int ret; 2862 2863 if ((sc == NULL) || (sc->data_ccb == NULL)) { 2864 return (-1); 2865 } 2866 2867 if ((sc->info.sectornum < (startsector + nsectors)) || (sc->info.sectorsize < blocksize)) 2868 return (-1); 2869 2870 if (((uintptr_t)data_buf & (USB_CACHE_ALIGN_SIZE - 1)) != 0) { 2871 data_buf = (uint8_t *)memalign(USB_CACHE_ALIGN_SIZE, SKB_DATA_ALIGN(nsectors * blocksize)); 2872 if (data_buf == NULL) { 2873 PRINT_ERR("Malloc failed!->%s %d\n", __FUNCTION__, __LINE__); 2874 return (-1); 2875 } 2876 flag = 1; 2877 } 2878 2879 (void)memset_s(&cdb, sizeof(struct scsicmd_read16_s), 0, sizeof(struct scsicmd_read16_s)); 2880 usbhost_readcdb16(startsector, blocksize, nsectors, &cdb); 2881 (void)umass_scsi_transform(sc, (uint8_t *)&cdb, SCSICMD_READ16_SIZEOF); 2882 res = umass_command_start(sc, DIR_IN, (void *)data_buf, blocksize * nsectors, 0, 2883 umass_cam_cb, sc->data_ccb); 2884 if (STATUS_CMD_OK != res) { 2885 if (flag == 1) 2886 free(data_buf); 2887 return (-1); 2888 } 2889 2890 if (flag == 1) { 2891 if (!LOS_IsUserAddressRange((vaddr_t)buf, blocksize * nsectors - sc->data_ccb->csio.resid)) { 2892 ret = memcpy_s(buf, nsectors * blocksize, data_buf, blocksize * nsectors - sc->data_ccb->csio.resid); 2893 } else { 2894 ret = ((nsectors * blocksize >= blocksize * nsectors - sc->data_ccb->csio.resid) ? 2895 LOS_ArchCopyToUser(buf, data_buf, blocksize * nsectors - sc->data_ccb->csio.resid) : ERANGE_AND_RESET); 2896 } 2897 free(data_buf); 2898 if (ret != EOK) { 2899 return (-1); 2900 } 2901 } 2902 2903 status = sc->data_ccb->csio.status; 2904 if (status != STATUS_CMD_OK) { 2905 return (-1); 2906 } 2907 2908 return (0); 2909 } 2910 2911 int 2912 umass_write10(struct umass_softc *sc, size_t startsector, uint16_t blocksize, 2913 unsigned int nsectors, const unsigned char *buf) 2914 { 2915 struct scsicmd_write10_s cdb; 2916 uint8_t *data_buf = (uint8_t *)buf; 2917 uint32_t status; 2918 int32_t ret; 2919 uint32_t flag = 0; 2920 2921 if((sc == NULL) || (sc->data_ccb == NULL)) { 2922 return (-1); 2923 } 2924 2925 if ((sc->info.sectornum < (startsector + nsectors)) || (sc->info.sectorsize < blocksize)) 2926 return (-1); 2927 2928 if (((uintptr_t)data_buf & (USB_CACHE_ALIGN_SIZE - 1)) != 0) { 2929 data_buf = (uint8_t *)memalign(USB_CACHE_ALIGN_SIZE, SKB_DATA_ALIGN(nsectors * blocksize)); 2930 if (data_buf == NULL) { 2931 PRINT_ERR("Malloc failed!->%s %d\n", __FUNCTION__, __LINE__); 2932 return (-1); 2933 } 2934 2935 if (!LOS_IsUserAddressRange((vaddr_t)buf, blocksize * nsectors)) { 2936 (void)memcpy_s(data_buf, blocksize * nsectors, buf, blocksize * nsectors); 2937 } else { 2938 ret = LOS_ArchCopyFromUser(data_buf, buf, blocksize * nsectors); 2939 if (ret != 0) { 2940 free(data_buf); 2941 PRINT_ERR("copy failed!->%s %d\n", __FUNCTION__, __LINE__); 2942 return (-1); 2943 } 2944 } 2945 flag = 1; 2946 } 2947 2948 (void)memset_s(&cdb, sizeof(struct scsicmd_write10_s), 0, sizeof(struct scsicmd_write10_s)); 2949 usbhost_writecbw10(startsector, blocksize, nsectors, &cdb); 2950 (void)umass_scsi_transform(sc, (uint8_t *)&cdb, SCSICMD_WRITE10_SIZEOF); 2951 ret = umass_command_start(sc, DIR_OUT, (void *)data_buf, blocksize * nsectors, 1000, 2952 umass_cam_cb, sc->data_ccb); 2953 2954 if (flag == 1) { 2955 free(data_buf); 2956 } 2957 2958 status = sc->data_ccb->csio.status; 2959 if ((ret != STATUS_CMD_OK) || (status != STATUS_CMD_OK)) { 2960 return (-1); 2961 } 2962 2963 return (0); 2964 } 2965 2966 int 2967 umass_write16(struct umass_softc *sc, uint64_t startsector, uint16_t blocksize, 2968 unsigned int nsectors, const unsigned char *buf) 2969 { 2970 struct scsicmd_write16_s cdb; 2971 uint8_t *data_buf = (uint8_t *)buf; 2972 uint32_t status; 2973 int32_t res; 2974 int32_t ret; 2975 uint32_t flag = 0; 2976 2977 if((sc == NULL) || (sc->data_ccb == NULL)) { 2978 return (-1); 2979 } 2980 2981 if ((sc->info.sectornum < (startsector + nsectors)) || (sc->info.sectorsize < blocksize)) { 2982 return (-1); 2983 } 2984 2985 if (((uintptr_t)data_buf & (USB_CACHE_ALIGN_SIZE - 1)) != 0) 2986 { 2987 data_buf = (uint8_t *)memalign(USB_CACHE_ALIGN_SIZE, SKB_DATA_ALIGN(nsectors * blocksize)); 2988 if (data_buf == NULL) { 2989 PRINT_ERR("Malloc failed!->%s %d\n", __FUNCTION__, __LINE__); 2990 return (-1); 2991 } 2992 2993 if (!LOS_IsUserAddressRange((vaddr_t)buf, blocksize * nsectors)) { 2994 (void)memcpy_s(data_buf, blocksize * nsectors, buf, blocksize * nsectors); 2995 } else { 2996 ret = LOS_ArchCopyFromUser(data_buf, buf, blocksize * nsectors); 2997 if (ret != 0) { 2998 free(data_buf); 2999 PRINT_ERR("copy failed!->%s %d\n", __FUNCTION__, __LINE__); 3000 return (-1); 3001 } 3002 } 3003 flag = 1; 3004 } 3005 3006 (void)memset_s(&cdb, sizeof(struct scsicmd_write16_s), 0, sizeof(struct scsicmd_write16_s)); 3007 usbhost_writecbw16(startsector, blocksize, nsectors, &cdb); 3008 (void)umass_scsi_transform(sc, (uint8_t *)&cdb, SCSICMD_WRITE16_SIZEOF); 3009 res = umass_command_start(sc, DIR_OUT, (void *)data_buf, blocksize * nsectors, 1000, 3010 umass_cam_cb, sc->data_ccb); 3011 3012 if (flag == 1) 3013 { 3014 free(data_buf); 3015 } 3016 3017 status = sc->data_ccb->csio.status; 3018 if ((res != STATUS_CMD_OK) || (status != STATUS_CMD_OK)) { 3019 return (-1); 3020 } 3021 3022 return (0); 3023 } 3024 3025 int 3026 umass_inquiry(struct umass_softc *sc) 3027 { 3028 uint32_t status; 3029 int32_t ret; 3030 3031 if ((sc == NULL) || (sc->data_ccb == NULL)) { 3032 goto error; 3033 } 3034 3035 (void)umass_scsi_transform(sc, scsi_inquiry, SCSICMD_INQUIRY_SIZEOF); 3036 ret = umass_command_start(sc, DIR_IN, sc->data_ccb->csio.data_ptr, SCSIRESP_INQUIRY_SIZEOF, 3037 1000, umass_cam_cb, sc->data_ccb); 3038 if (ret != STATUS_CMD_OK) { 3039 goto error; 3040 } 3041 3042 status = sc->data_ccb->csio.status; 3043 if (status != STATUS_CMD_OK) { 3044 PRINT_WARN("Failed to get the inquiry_status [status=%d].\n", status); 3045 goto error; 3046 } 3047 3048 ret = umass_scsi_inquiry_data(sc, sc->data_ccb->csio.data_ptr, SCSIRESP_INQUIRY_SIZEOF); 3049 if (ret == -1){ 3050 PRINT_WARN("Failed to get the scsi_inquiry data .\n"); 3051 goto error; 3052 }else if (ret == 1) { 3053 /* find Direct-access LUN */ 3054 return (0); 3055 } 3056 3057 error: 3058 return (-1); 3059 } 3060 3061 int 3062 umass_request_sense(struct umass_softc *sc) 3063 { 3064 uint32_t status; 3065 int32_t ret; 3066 if ((sc == NULL) || (sc->data_ccb == NULL)) { 3067 return (-1); 3068 } 3069 3070 (void)umass_scsi_transform(sc, scsi_request_sense, SCSICMD_REQUESTSENSE_SIZEOF); 3071 ret = umass_command_start(sc, DIR_IN, sc->data_ccb->csio.data_ptr, SCSIRESP_FIXEDSENSEDATA_SIZEOF, 3072 1000, umass_cam_cb, sc->data_ccb); 3073 if (ret != STATUS_CMD_OK) { 3074 return (-1); 3075 } 3076 3077 status = sc->data_ccb->csio.status; 3078 if (status != STATUS_CMD_OK) { 3079 return (-1); 3080 } 3081 3082 return (0); 3083 } 3084 3085 void * 3086 umass_bind(void) 3087 { 3088 return ((void*)p_umsf); 3089 } 3090 3091 void 3092 umass_status(void) 3093 { 3094 struct umass_softc *sc = p_umsf; 3095 UINT8 cmd; 3096 UINT8 lun; 3097 UINT8 max; 3098 UINT8 speed; 3099 UINT8 phase; 3100 UINT8 state; 3101 UINT16 vid; 3102 UINT16 pid; 3103 UINT32 tag, residuce; 3104 3105 if (sc == NULL) { 3106 return; 3107 } 3108 3109 cmd = sc->sc_transfer.cmd_data[0]; 3110 lun = sc->sc_transfer.lun; 3111 max = sc->sc_maxlun + 1; 3112 speed = sc->sc_udev->speed; 3113 phase = sc->sc_last_xfer_index; 3114 state = USB_GET_STATE(sc->sc_xfer[phase]); 3115 vid = UGETW(sc->sc_udev->ddesc.idVendor); 3116 pid = UGETW(sc->sc_udev->ddesc.idProduct); 3117 tag = UGETDW(sc->cbw.dCBWTag); 3118 residuce = UGETDW(sc->csw.dCSWDataResidue); 3119 3120 dprintf("VID:%04X/PID:%04X/SPD:%02d",vid,pid,speed); 3121 if (sc->sc_transfer.ccb) { 3122 dprintf("/ST:%02d ",state); 3123 if (state == USB_ST_SETUP) { 3124 dprintf("[SP]"); 3125 } else if (state == USB_ST_TRANSFERRED) { 3126 dprintf("[TD]"); 3127 } 3128 dprintf("/cPHASE:%02d ",phase); 3129 } else { 3130 dprintf("/nPHASE:%02d ",phase); 3131 } 3132 if (phase == UMASS_T_BBB_COMMAND) { 3133 dprintf("[CBW]"); 3134 } else if (phase == UMASS_T_BBB_DATA_READ) { 3135 dprintf("[DATA]"); 3136 } else if (phase == UMASS_T_BBB_DATA_WRITE) { 3137 dprintf("[DATA]"); 3138 } else if (phase == UMASS_T_BBB_STATUS) { 3139 dprintf("[CSW]"); 3140 } else if (phase == UMASS_T_BBB_DATA_RD_CS) { 3141 dprintf("[STAL]"); 3142 } else if (phase == UMASS_T_BBB_DATA_WR_CS) { 3143 dprintf("[STAL]"); 3144 } 3145 dprintf("\n"); 3146 3147 dprintf("CL:%d/ML:%d/TG:%08X/RDU:%d/CMD:%X ",lun,max,tag,residuce,cmd); 3148 if (cmd == SCSI_CMD_READ10) { 3149 dprintf("[RD]\n"); 3150 } else if (cmd == SCSI_CMD_WRITE10) { 3151 dprintf("[WR]\n"); 3152 } else if (cmd == SCSI_CMD_INQUIRY) { 3153 dprintf("[INQ]\n"); 3154 } else if (cmd == SCSI_CMD_TESTUNITREADY) { 3155 dprintf("[TUR]\n"); 3156 } else if (cmd == SCSI_CMD_REQUESTSENSE) { 3157 dprintf("[RS]\n"); 3158 } else if (cmd == SCSI_CMD_READCAPACITY10) { 3159 dprintf("[RC]\n"); 3160 } else { 3161 dprintf("\n"); 3162 } 3163 } 3164 3165 static int 3166 umass_open(struct Vnode *filep) 3167 { 3168 (void)filep; 3169 return (0); 3170 } 3171 3172 static int 3173 umass_close(struct Vnode *filep) 3174 { 3175 (void)filep; 3176 return (0); 3177 } 3178 3179 static ssize_t 3180 umass_read(struct Vnode *umass_inode, unsigned char *buffer, 3181 uint64_t start_sector, unsigned int nsectors) 3182 { 3183 int status; 3184 struct umass_softc *sc = (struct umass_softc *)((struct drv_data*)umass_inode->data)->priv; 3185 3186 mtx_lock(&sc->sc_umass_mtx); 3187 if (sc->sc_super_disk == TRUE) { 3188 status = umass_read16(sc, start_sector, (uint16_t)sc->info.sectorsize, nsectors, buffer); 3189 } else { 3190 status = umass_read10(sc, (size_t)start_sector, (uint16_t)sc->info.sectorsize, nsectors, buffer); 3191 } 3192 mtx_unlock(&sc->sc_umass_mtx); 3193 3194 if(status) 3195 return (-1); 3196 else 3197 return ((ssize_t)nsectors); 3198 } 3199 3200 static ssize_t 3201 umass_write(struct Vnode *umass_inode, const unsigned char *buffer, 3202 uint64_t start_sector, unsigned int nsectors) 3203 { 3204 int status; 3205 struct umass_softc *sc = (struct umass_softc *)((struct drv_data*)umass_inode->data)->priv; 3206 3207 mtx_lock(&sc->sc_umass_mtx); 3208 if (sc->sc_super_disk == TRUE) { 3209 status = umass_write16(sc, start_sector, (uint16_t)sc->info.sectorsize, nsectors, buffer); 3210 } else { 3211 status = umass_write10(sc, (size_t)start_sector, (uint16_t)sc->info.sectorsize, nsectors, buffer); 3212 } 3213 mtx_unlock(&sc->sc_umass_mtx); 3214 3215 if(status) 3216 return (-1); 3217 else 3218 return ((ssize_t)nsectors); 3219 } 3220 3221 static int 3222 umass_geometry(struct Vnode *umass_inode, struct geometry *ugeometry) 3223 { 3224 struct umass_softc *sc; 3225 3226 if ((ugeometry == NULL) || (umass_inode == NULL)) 3227 return (-1); 3228 3229 sc = (struct umass_softc *)(struct umass_softc *)((struct drv_data*)umass_inode->data)->priv; 3230 3231 if (sc == NULL) 3232 return (-1); 3233 3234 mtx_lock(&sc->sc_umass_mtx); 3235 ugeometry->geo_available = true; 3236 ugeometry->geo_mediachanged = false; 3237 ugeometry->geo_writeenabled = true; 3238 ugeometry->geo_nsectors = sc->info.sectornum; 3239 ugeometry->geo_sectorsize = sc->info.sectorsize; 3240 mtx_unlock(&sc->sc_umass_mtx); 3241 3242 return (0); 3243 } 3244 3245 static int 3246 umass_ioctl(struct Vnode *umass_inode, int cmd, unsigned long arg) 3247 { 3248 (void)umass_inode; 3249 (void)cmd; 3250 (void)arg; 3251 return (0); 3252 } 3253 3254 const struct block_operations g_dev_umass_ops = { 3255 .open = umass_open, 3256 .close = umass_close, 3257 .read = umass_read, 3258 .write = umass_write, 3259 .geometry = umass_geometry, 3260 .ioctl = umass_ioctl, 3261 .unlink = NULL 3262 }; 3263 3264 static int 3265 umass_dev_is_ready(struct umass_softc *sc) 3266 { 3267 int lun; 3268 int ret; 3269 uint8_t valid_lun; 3270 3271 mtx_lock(&sc->sc_umass_mtx); 3272 for (lun = 0; lun <= sc->sc_maxlun; lun++) { 3273 sc->sc_transfer.lun = lun; 3274 if (umass_inquiry(sc) < 0) 3275 continue; 3276 3277 valid_lun = lun; 3278 ret = umass_test_unit_ready(sc); 3279 if(ret == 0) { 3280 sc->sc_transfer.lun = valid_lun; 3281 ret = umass_read_capacity(sc); 3282 if (ret < 0) { 3283 mtx_unlock(&sc->sc_umass_mtx); 3284 PRINT_ERR("umass read capacity fail!\n"); 3285 return (0); 3286 } 3287 mtx_unlock(&sc->sc_umass_mtx); 3288 return (1); 3289 } 3290 3291 ret = umass_request_sense(sc); 3292 if(ret < 0) { 3293 PRINT_ERR("Request sense fail!\n"); 3294 mtx_unlock(&sc->sc_umass_mtx); 3295 return (0); 3296 } 3297 } 3298 mtx_unlock(&sc->sc_umass_mtx); 3299 return (0); 3300 } 3301 3302 static int 3303 umass_attach_dev_sub(struct umass_softc *sc, unsigned int dev_unit) 3304 { 3305 int ret; 3306 int disk_id; 3307 char devname[MASS_NAME]= {0}; 3308 #if USB_HAVE_DEVICE_TOPOLOGY 3309 device_t dev; 3310 struct usb_device *udev; 3311 usbd_bt_node *cur_node; 3312 struct node_info parent_info; 3313 struct node_info cur_info; 3314 #endif 3315 3316 umass_dev_lock(dev_unit); 3317 3318 #if USB_HAVE_DEVICE_TOPOLOGY 3319 dev = sc->sc_dev; 3320 udev = sc->sc_udev; 3321 dev_quantity |= 1ull << (unsigned int)device_get_unit(dev); 3322 #endif 3323 3324 #if USB_SUPPORT_SD_HOT_PLUG 3325 if (!umass_dev_is_attached(dev_unit)) 3326 #endif 3327 { 3328 devunit_to_devname(dev_unit, devname); 3329 disk_id = los_alloc_diskid_byname(devname); 3330 OsSetUsbStatus(disk_id); 3331 ret = los_disk_init(devname, &g_dev_umass_ops, (void *)sc, disk_id, NULL); 3332 if (ret) { 3333 PRINT_ERR("umass_attach_dev : los_disk_init fail!\n"); 3334 goto error; 3335 } 3336 } 3337 #if USB_SUPPORT_SD_HOT_PLUG 3338 umass_dev_attach_flag_set(dev_unit); 3339 #endif 3340 3341 #if USB_HAVE_DEVICE_TOPOLOGY 3342 cur_info.nameunit = device_get_nameunit(dev); 3343 cur_info.port_no = udev->port_no; 3344 cur_node = usbd_create_bt_node(&cur_info); 3345 if (cur_node == NULL) { 3346 goto error; 3347 } 3348 3349 parent_info.nameunit = device_get_nameunit(device_get_parent(dev)); 3350 parent_info.port_no = udev->port_no; 3351 3352 (void)usbd_insert_bt_node(cur_node, hub_tree, &parent_info); 3353 #endif 3354 3355 umass_dev_unlock(dev_unit); 3356 return (0); 3357 3358 error: 3359 umass_dev_unlock(dev_unit); 3360 return (-1); 3361 } 3362 3363 static void 3364 umass_detach_dev_sub(struct umass_softc *sc, int dev_unit, int flag) 3365 { 3366 int disk_id; 3367 char devname[MASS_NAME]= {0}; 3368 #if USB_HAVE_DEVICE_TOPOLOGY 3369 struct node_info cur_info; 3370 struct node_info parent_info; 3371 device_t dev = NULL; 3372 struct usb_device *udev = NULL; 3373 #endif 3374 3375 umass_dev_lock(dev_unit); 3376 3377 #if USB_HAVE_DEVICE_TOPOLOGY 3378 dev = sc->sc_dev; 3379 udev = sc->sc_udev; 3380 #if USB_SUPPORT_SD_HOT_PLUG 3381 if (umass_dev_is_attached(dev_unit)) 3382 #endif 3383 { 3384 parent_info.nameunit = device_get_nameunit(device_get_parent(dev)); 3385 parent_info.port_no = udev->port_no; 3386 3387 cur_info.nameunit = device_get_nameunit(dev); 3388 cur_info.port_no = udev->port_no; 3389 (void)usbd_remove_bt_node(hub_tree, &parent_info, &cur_info); 3390 } 3391 #endif 3392 3393 #if USB_SUPPORT_SD_HOT_PLUG 3394 if (umass_dev_is_attached(dev_unit)) 3395 #endif 3396 { 3397 devunit_to_devname(dev_unit, devname); 3398 disk_id = los_get_diskid_byname(devname); 3399 (void)los_disk_deinit(disk_id); 3400 (void)OsClearUsbStatus(disk_id); 3401 } 3402 3403 if (flag == 0) { /* 0: This interface is called from umass_detach, or is called elsewhere. */ 3404 #if USB_SUPPORT_SD_HOT_PLUG 3405 umass_dev_delete(sc, dev_unit); 3406 #endif 3407 } 3408 3409 #if USB_HAVE_DEVICE_TOPOLOGY 3410 dev_quantity &= ~(1ull << (unsigned int)device_get_unit(dev)); 3411 #endif 3412 3413 umass_dev_unlock(dev_unit); 3414 } 3415 3416 #if USB_SUPPORT_SD_HOT_PLUG 3417 void 3418 umass_dev_status_check(UINTPTR arg) 3419 { 3420 (void)arg; 3421 int ret; 3422 int i; 3423 struct umass_dev_info *dev = g_umass_dev_array; 3424 struct umass_softc *sc; 3425 3426 while(1) { 3427 for (i = 0; i < MAX_DEVICE; i++) { 3428 umass_dev_lock(i); 3429 if (dev[i].used == 1) { 3430 sc = dev[i].sc; 3431 ret = umass_dev_is_ready(sc); 3432 if (ret == 0) { 3433 if (dev[i].attached == 1) { 3434 umass_detach_dev_sub(sc, dev[i].dev_unit, 1); 3435 dev[i].attached = 0; 3436 } 3437 umass_dev_unlock(i); 3438 continue; 3439 } 3440 3441 if (dev[i].attached == 1) { 3442 umass_dev_unlock(i); 3443 continue; 3444 } 3445 3446 ret = umass_attach_dev_sub(sc, dev[i].dev_unit); 3447 if (ret< 0) { 3448 umass_dev_unlock(i); 3449 PRINT_ERR("umass attach device sub failed!\n"); 3450 continue; 3451 } 3452 } 3453 umass_dev_unlock(i); 3454 } 3455 (void)LOS_Msleep(1000); 3456 } 3457 } 3458 3459 int 3460 umass_dev_is_attached(unsigned int dev_unit) 3461 { 3462 if (dev_unit >= MAX_DEVICE) { 3463 PRINT_ERR("%s %d, The device unit is wrong!\n", __FUNCTION__, __LINE__); 3464 return (-1); 3465 } 3466 3467 return (g_umass_dev_array[dev_unit].attached); 3468 } 3469 3470 static void 3471 umass_dev_add(struct umass_softc *sc, int dev_unit) 3472 { 3473 int id = dev_unit; 3474 3475 if (g_umass_dev_array[id].used == 1) { 3476 PRINT_ERR("The id of umass device array is used!, id=%d\n", dev_unit); 3477 return; 3478 } 3479 3480 g_umass_dev_array[id].sc = sc; 3481 g_umass_dev_array[id].dev_unit = dev_unit; 3482 g_umass_dev_array[id].used = 1; 3483 umass_dev_mtx_init(id, MTX_DEF | MTX_RECURSE); 3484 } 3485 3486 static void 3487 umass_dev_delete(struct umass_softc *sc, unsigned int dev_unit) 3488 { 3489 unsigned int id = dev_unit; 3490 3491 if (g_umass_dev_array[id].used == 0) { 3492 PRINT_ERR("The id of umass device array is not used!\n"); 3493 return; 3494 } 3495 3496 if (g_umass_dev_array[id].dev_unit == dev_unit && 3497 g_umass_dev_array[id].sc == sc) { 3498 g_umass_dev_array[id].used = 0; 3499 g_umass_dev_array[id].sc = NULL; 3500 g_umass_dev_array[id].attached = 0; 3501 umass_dev_mtx_destroy(id); 3502 } else { 3503 PRINT_ERR("Can not find the umass device!\n"); 3504 } 3505 } 3506 3507 static void 3508 umass_dev_attach_flag_set(int dev_unit) 3509 { 3510 g_umass_dev_array[dev_unit].attached = 1; 3511 } 3512 3513 static void 3514 umass_task_check(int flag) 3515 { 3516 int i; 3517 int ret; 3518 3519 for (i = 0; i < MAX_DEVICE; i++) { 3520 if (g_umass_dev_array[i].used) 3521 break; 3522 } 3523 3524 if (i == MAX_DEVICE) { 3525 if (flag == 0) { /* create task */ 3526 ret = usb_os_task_creat(&umass_taskid, (TSK_ENTRY_FUNC)umass_dev_status_check, 3527 LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO, "umass_task", 0); 3528 if (ret) { 3529 PRINT_ERR("Create umass task fail!\n"); 3530 return; 3531 } 3532 } else if (flag == 1) { /* delete task */ 3533 ret = usb_os_task_delete(umass_taskid); 3534 if (ret) { 3535 PRINT_ERR("Delete umass task fail!\n"); 3536 return; 3537 } 3538 } else { 3539 PRINT_ERR("%s flag error!\n", __FUNCTION__); 3540 } 3541 } 3542 } 3543 #endif 3544 3545 static void 3546 devunit_to_devname(unsigned int dev_unit, char *devname) 3547 { 3548 char name_suf; 3549 int ret; 3550 3551 #if USB_HAVE_DEVICE_TOPOLOGY 3552 if (!(0x1 & (dev_quantity >> dev_unit))) 3553 #else 3554 if (dev_unit >= MAX_DEVICE) 3555 #endif 3556 { 3557 dprintf("sorry, we don't support so many devices\n"); 3558 return; 3559 } 3560 3561 name_suf = 'a' + dev_unit; 3562 ret = snprintf_s(devname, MASS_NAME, MASS_NAME - 1, "%s%c", UMASS_ATTACH_PRENAME, name_suf); 3563 if (ret < 0) { 3564 usb_err("snprintf_s failed!, ret:%d\n", ret); 3565 return; 3566 } 3567 } 3568 static int32_t 3569 umass_attach_dev(struct umass_softc *sc, unsigned int dev_unit) 3570 { 3571 int ret; 3572 3573 if (dev_unit >= MAX_DEVICE) { 3574 PRINT_ERR("sorry, we don't support so many devices\n"); 3575 return (-1); 3576 } 3577 #if USB_SUPPORT_SD_HOT_PLUG 3578 umass_task_check(0); 3579 umass_dev_add(sc, dev_unit); 3580 #endif 3581 3582 ret = umass_dev_is_ready(sc); 3583 if (ret) { 3584 ret = umass_attach_dev_sub(sc, dev_unit); 3585 if (ret < 0) { 3586 #if USB_SUPPORT_SD_HOT_PLUG 3587 umass_dev_delete(sc, dev_unit); 3588 #endif 3589 PRINT_ERR("umass attach device fail!\n"); 3590 return (-1); 3591 } 3592 } 3593 3594 return (0); 3595 } 3596 3597 #if USB_HAVE_DEVICE_TOPOLOGY 3598 int 3599 umass_medium_probe(uint8_t medium, char *devname) 3600 { 3601 struct usbd_bt_node *node; 3602 uint8_t dev_unit; 3603 3604 if ((devname == NULL) || strlen(devname) > 7) { /* /dev/sd* */ 3605 return (-1); 3606 } 3607 3608 if ((medium < 1) || (medium > usbd_get_hub_quantity())) { 3609 return (-1); 3610 } 3611 3612 node = usbd_per_order_probe(hub_tree, "umass", &medium); 3613 if (node != NULL) { 3614 dev_unit = usbd_atoi(node->info.nameunit + 5); /* 5 = umass */ 3615 devunit_to_devname(dev_unit, devname); 3616 } else { 3617 return (-1); 3618 } 3619 return (0); 3620 } 3621 #endif 3622 3623