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