1 /* 2 * Copyright 2008-2023, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 * Augustin Cavalier <waddlesplash> 8 */ 9 10 11 #include "usb_disk.h" 12 13 #include <ByteOrder.h> 14 #include <StackOrHeapArray.h> 15 #include <Drivers.h> 16 #include <bus/USB.h> 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #include <kernel.h> 23 #include <fs/devfs.h> 24 #include <syscall_restart.h> 25 #include <util/AutoLock.h> 26 27 #include "IORequest.h" 28 29 #include "scsi_sense.h" 30 #include "usb_disk_scsi.h" 31 #include "icons.h" 32 33 34 #define MAX_IO_BLOCKS (128) 35 36 #define USB_DISK_DEVICE_MODULE_NAME "drivers/disk/usb_disk/device_v1" 37 #define USB_DISK_DRIVER_MODULE_NAME "drivers/disk/usb_disk/driver_v1" 38 #define USB_DISK_DEVICE_ID_GENERATOR "usb_disk/device_id" 39 40 #define DRIVER_NAME "usb_disk" 41 #define DEVICE_NAME_BASE "disk/usb/" 42 #define DEVICE_NAME DEVICE_NAME_BASE "%" B_PRIu32 "/%d/raw" 43 44 45 //#define TRACE_USB_DISK 46 #ifdef TRACE_USB_DISK 47 #define TRACE(x...) dprintf(DRIVER_NAME ": " x) 48 #define TRACE_ALWAYS(x...) dprintf(DRIVER_NAME ": " x) 49 #define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 50 #else 51 #define TRACE(x...) /* nothing */ 52 #define CALLED() 53 #define TRACE_ALWAYS(x...) dprintf(DRIVER_NAME ": " x) 54 #endif 55 56 57 device_manager_info *gDeviceManager; 58 static usb_module_info *gUSBModule = NULL; 59 60 struct { 61 const char *vendor; 62 const char *product; 63 device_icon *icon; 64 const char *name; 65 } kIconMatches[] = { 66 // matches for Hama USB 2.0 Card Reader 35 in 1 67 // vendor: "Transcend Information, Inc." 68 // product: "63-in-1 Multi-Card Reader/Writer" ver. 0100 69 // which report things like "Generic " "USB CF Reader " 70 // { NULL, " CF Reader", &kCFIconData, "devices/drive-removable-media-flash" }, 71 { NULL, " SD Reader", &kSDIconData, "devices/drive-removable-media-flash" }, 72 { NULL, " MS Reader", &kMSIconData, "devices/drive-removable-media-flash" }, 73 // { NULL, " SM Reader", &kSMIconData, "devices/drive-removable-media-flash" }, 74 // match for my Kazam mobile phone 75 // stupid thing says "MEDIATEK" " FLASH DISK " even for internal memory 76 { "MEDIATEK", NULL, &kMobileIconData, 77 "devices/drive-removable-media-flash" }, 78 { NULL, NULL, NULL, NULL } 79 }; 80 81 82 // 83 //#pragma mark - Forward Declarations 84 // 85 86 87 static void usb_disk_callback(void *cookie, status_t status, void *data, 88 size_t actualLength); 89 90 uint8 usb_disk_get_max_lun(disk_device *device); 91 void usb_disk_reset_recovery(disk_device *device); 92 status_t usb_disk_receive_csw(disk_device *device, 93 usb_massbulk_command_status_wrapper *status); 94 95 status_t usb_disk_send_diagnostic(device_lun *lun); 96 status_t usb_disk_request_sense(device_lun *lun, err_act *action); 97 status_t usb_disk_mode_sense(device_lun *lun); 98 status_t usb_disk_test_unit_ready(device_lun *lun, err_act *action = NULL); 99 status_t usb_disk_inquiry(device_lun *lun); 100 status_t usb_disk_reset_capacity(device_lun *lun); 101 status_t usb_disk_update_capacity(device_lun *lun); 102 status_t usb_disk_synchronize(device_lun *lun, bool force); 103 104 105 // #pragma mark - disk_device helper functions 106 107 108 disk_device_s::disk_device_s() 109 : 110 notify(-1), 111 interruptLock(-1) 112 { 113 recursive_lock_init(&io_lock, "usb_disk i/o lock"); 114 mutex_init(&lock, "usb_disk device lock"); 115 } 116 117 118 disk_device_s::~disk_device_s() 119 { 120 recursive_lock_destroy(&io_lock); 121 mutex_destroy(&lock); 122 123 if (notify >= 0) 124 delete_sem(notify); 125 if (interruptLock >= 0) 126 delete_sem(interruptLock); 127 } 128 129 130 static DMAResource* 131 get_dma_resource(disk_device *device, uint32 blockSize) 132 { 133 for (int32 i = 0; i < device->dma_resources.Count(); i++) { 134 DMAResource* r = device->dma_resources[i]; 135 if (r->BlockSize() == blockSize) 136 return r; 137 } 138 return NULL; 139 } 140 141 142 void 143 usb_disk_free_device_and_luns(disk_device *device) 144 { 145 ASSERT_LOCKED_MUTEX(&device->lock); 146 147 for (int32 i = 0; i < device->dma_resources.Count(); i++) 148 delete device->dma_resources[i]; 149 for (uint8 i = 0; i < device->lun_count; i++) 150 free(device->luns[i]); 151 free(device->luns); 152 delete device; 153 } 154 155 156 // 157 //#pragma mark - Bulk-only Mass Storage Functions 158 // 159 160 161 static status_t 162 usb_disk_mass_storage_reset(disk_device *device) 163 { 164 return gUSBModule->send_request(device->device, USB_REQTYPE_INTERFACE_OUT 165 | USB_REQTYPE_CLASS, USB_MASSBULK_REQUEST_MASS_STORAGE_RESET, 0x0000, 166 device->interface, 0, NULL, NULL); 167 } 168 169 170 uint8 171 usb_disk_get_max_lun(disk_device *device) 172 { 173 ASSERT_LOCKED_RECURSIVE(&device->io_lock); 174 175 uint8 result = 0; 176 size_t actualLength = 0; 177 178 // devices that do not support multiple LUNs may stall this request 179 if (gUSBModule->send_request(device->device, USB_REQTYPE_INTERFACE_IN 180 | USB_REQTYPE_CLASS, USB_MASSBULK_REQUEST_GET_MAX_LUN, 0x0000, 181 device->interface, 1, &result, &actualLength) != B_OK 182 || actualLength != 1) { 183 return 0; 184 } 185 186 if (result > MAX_LOGICAL_UNIT_NUMBER) { 187 // invalid max lun 188 return 0; 189 } 190 191 return result; 192 } 193 194 195 static void 196 usb_disk_clear_halt(usb_pipe pipe) 197 { 198 gUSBModule->cancel_queued_transfers(pipe); 199 gUSBModule->clear_feature(pipe, USB_FEATURE_ENDPOINT_HALT); 200 } 201 202 203 void 204 usb_disk_reset_recovery(disk_device *device, err_act *_action) 205 { 206 TRACE("reset recovery\n"); 207 ASSERT_LOCKED_RECURSIVE(&device->io_lock); 208 209 usb_disk_mass_storage_reset(device); 210 usb_disk_clear_halt(device->bulk_in); 211 usb_disk_clear_halt(device->bulk_out); 212 if (device->is_ufi) 213 usb_disk_clear_halt(device->interrupt); 214 215 if (_action != NULL) 216 *_action = err_act_retry; 217 } 218 219 220 struct transfer_data { 221 union { 222 physical_entry* phys_vecs; 223 iovec* vecs; 224 }; 225 uint32 vec_count = 0; 226 bool physical = false; 227 }; 228 229 230 static status_t 231 usb_disk_transfer_data(disk_device *device, bool directionIn, const transfer_data& data) 232 { 233 status_t result; 234 if (data.physical) { 235 result = gUSBModule->queue_bulk_v_physical( 236 directionIn ? device->bulk_in : device->bulk_out, 237 data.phys_vecs, data.vec_count, usb_disk_callback, device); 238 } else { 239 result = gUSBModule->queue_bulk_v( 240 directionIn ? device->bulk_in : device->bulk_out, 241 data.vecs, data.vec_count, usb_disk_callback, device); 242 } 243 if (result != B_OK) { 244 TRACE_ALWAYS("failed to queue data transfer: %s\n", strerror(result)); 245 return result; 246 } 247 248 mutex_unlock(&device->lock); 249 do { 250 result = acquire_sem_etc(device->notify, 1, B_RELATIVE_TIMEOUT, 251 10 * 1000 * 1000); 252 if (result == B_TIMED_OUT) { 253 // Cancel the transfer and collect the sem that should now be 254 // released through the callback on cancel. Handling of device 255 // reset is done in usb_disk_operation() when it detects that 256 // the transfer failed. 257 gUSBModule->cancel_queued_transfers(directionIn ? device->bulk_in 258 : device->bulk_out); 259 acquire_sem_etc(device->notify, 1, B_RELATIVE_TIMEOUT, 0); 260 } 261 } while (result == B_INTERRUPTED); 262 mutex_lock(&device->lock); 263 264 if (result != B_OK) { 265 TRACE_ALWAYS("acquire_sem failed while waiting for data transfer: %s\n", 266 strerror(result)); 267 return result; 268 } 269 270 return B_OK; 271 } 272 273 274 static status_t 275 usb_disk_transfer_data(disk_device *device, bool directionIn, 276 void* buffer, size_t dataLength) 277 { 278 iovec vec; 279 vec.iov_base = buffer; 280 vec.iov_len = dataLength; 281 282 struct transfer_data data; 283 data.vecs = &vec; 284 data.vec_count = 1; 285 286 return usb_disk_transfer_data(device, directionIn, data); 287 } 288 289 290 static void 291 callback_interrupt(void* cookie, int32 status, void* data, size_t length) 292 { 293 disk_device* device = (disk_device*)cookie; 294 // We release the lock even if the interrupt is invalid. This way there 295 // is at least a chance for the driver to terminate properly. 296 release_sem(device->interruptLock); 297 298 if (length != 2) { 299 TRACE_ALWAYS("interrupt of length %" B_PRIuSIZE "! (expected 2)\n", 300 length); 301 // In this case we do not reschedule the interrupt. This means the 302 // driver will be locked. The interrupt should perhaps be scheduled 303 // when starting a transfer instead. But getting there means something 304 // is really broken, so... 305 return; 306 } 307 308 // Reschedule the interrupt for next time 309 gUSBModule->queue_interrupt(device->interrupt, device->interruptBuffer, 2, 310 callback_interrupt, cookie); 311 } 312 313 314 static status_t 315 receive_csw_interrupt(disk_device *device, 316 interrupt_status_wrapper *status) 317 { 318 TRACE("Waiting for result...\n"); 319 320 gUSBModule->queue_interrupt(device->interrupt, 321 device->interruptBuffer, 2, callback_interrupt, device); 322 323 acquire_sem(device->interruptLock); 324 325 status->status = device->interruptBuffer[0]; 326 status->misc = device->interruptBuffer[1]; 327 328 return B_OK; 329 } 330 331 332 static status_t 333 receive_csw_bulk(disk_device *device, 334 usb_massbulk_command_status_wrapper *status) 335 { 336 status_t result = usb_disk_transfer_data(device, true, status, 337 sizeof(usb_massbulk_command_status_wrapper)); 338 if (result != B_OK) 339 return result; 340 341 if (device->status != B_OK 342 || device->actual_length 343 != sizeof(usb_massbulk_command_status_wrapper)) { 344 // receiving the command status wrapper failed 345 return B_ERROR; 346 } 347 348 return B_OK; 349 } 350 351 352 status_t 353 usb_disk_operation_interrupt(device_lun *lun, uint8* operation, 354 const transfer_data& data, size_t *dataLength, 355 bool directionIn, err_act *_action) 356 { 357 TRACE("operation: lun: %u; op: 0x%x; data: %p; dlen: %p (%lu); in: %c\n", 358 lun->logical_unit_number, operation[0], data.vecs, dataLength, 359 dataLength ? *dataLength : 0, directionIn ? 'y' : 'n'); 360 ASSERT_LOCKED_RECURSIVE(&lun->device->io_lock); 361 362 disk_device* device = lun->device; 363 364 // Step 1 : send the SCSI operation as a class specific request 365 size_t actualLength = 12; 366 status_t result = gUSBModule->send_request(device->device, 367 USB_REQTYPE_CLASS | USB_REQTYPE_INTERFACE_OUT, 0 /*request*/, 368 0/*value*/, device->interface/*index*/, 12, operation, &actualLength); 369 370 if (result != B_OK || actualLength != 12) { 371 TRACE("Command stage: wrote %ld bytes (error: %s)\n", 372 actualLength, strerror(result)); 373 374 // There was an error, we have to do a request sense to reset the device 375 if (operation[0] != SCSI_REQUEST_SENSE_6) { 376 usb_disk_request_sense(lun, _action); 377 } 378 return result; 379 } 380 381 // Step 2 : data phase : send or receive data 382 size_t transferedData = 0; 383 if (data.vec_count != 0) { 384 // we have data to transfer in a data stage 385 result = usb_disk_transfer_data(device, directionIn, data); 386 if (result != B_OK) { 387 TRACE("Error %s in data phase\n", strerror(result)); 388 return result; 389 } 390 391 transferedData = device->actual_length; 392 if (device->status != B_OK || transferedData != *dataLength) { 393 // sending or receiving of the data failed 394 if (device->status == B_DEV_STALLED) { 395 TRACE("stall while transfering data\n"); 396 usb_disk_clear_halt(directionIn ? device->bulk_in : device->bulk_out); 397 } else { 398 TRACE_ALWAYS("sending or receiving of the data failed\n"); 399 usb_disk_reset_recovery(device, _action); 400 return B_IO_ERROR; 401 } 402 } 403 } 404 405 // step 3 : wait for the device to send the interrupt ACK 406 if (operation[0] != SCSI_REQUEST_SENSE_6) { 407 interrupt_status_wrapper status; 408 result = receive_csw_interrupt(device, &status); 409 if (result != B_OK) { 410 // in case of a stall or error clear the stall and try again 411 TRACE("Error receiving interrupt: %s. Retrying...\n", 412 strerror(result)); 413 usb_disk_clear_halt(device->bulk_in); 414 result = receive_csw_interrupt(device, &status); 415 } 416 417 if (result != B_OK) { 418 TRACE_ALWAYS("receiving the command status interrupt failed\n"); 419 usb_disk_reset_recovery(device, _action); 420 return result; 421 } 422 423 // wait for the device to finish the operation. 424 result = usb_disk_request_sense(lun, _action); 425 } 426 return result; 427 } 428 429 430 status_t 431 usb_disk_operation_bulk(device_lun *lun, uint8 *operation, size_t operationLength, 432 const transfer_data& data, size_t *dataLength, 433 bool directionIn, err_act *_action) 434 { 435 TRACE("operation: lun: %u; op: %u; data: %p; dlen: %p (%lu); in: %c\n", 436 lun->logical_unit_number, operation[0], 437 data.vecs, dataLength, dataLength ? *dataLength : 0, 438 directionIn ? 'y' : 'n'); 439 ASSERT_LOCKED_RECURSIVE(&lun->device->io_lock); 440 441 disk_device *device = lun->device; 442 usb_massbulk_command_block_wrapper command; 443 command.signature = USB_MASSBULK_CBW_SIGNATURE; 444 command.tag = device->current_tag++; 445 command.data_transfer_length = (dataLength != NULL ? *dataLength : 0); 446 command.flags = (directionIn ? USB_MASSBULK_CBW_DATA_INPUT 447 : USB_MASSBULK_CBW_DATA_OUTPUT); 448 command.lun = lun->logical_unit_number; 449 command.command_block_length 450 = device->is_atapi ? ATAPI_COMMAND_LENGTH : operationLength; 451 memset(command.command_block, 0, sizeof(command.command_block)); 452 memcpy(command.command_block, operation, operationLength); 453 454 status_t result = usb_disk_transfer_data(device, false, &command, 455 sizeof(usb_massbulk_command_block_wrapper)); 456 if (result != B_OK) 457 return result; 458 459 if (device->status != B_OK || 460 device->actual_length != sizeof(usb_massbulk_command_block_wrapper)) { 461 // sending the command block wrapper failed 462 TRACE_ALWAYS("sending the command block wrapper failed: %s\n", 463 strerror(device->status)); 464 usb_disk_reset_recovery(device, _action); 465 return B_IO_ERROR; 466 } 467 468 size_t transferedData = 0; 469 if (data.vec_count != 0) { 470 // we have data to transfer in a data stage 471 result = usb_disk_transfer_data(device, directionIn, data); 472 if (result != B_OK) 473 return result; 474 475 transferedData = device->actual_length; 476 if (device->status != B_OK || transferedData != *dataLength) { 477 // sending or receiving of the data failed 478 if (device->status == B_DEV_STALLED) { 479 TRACE("stall while transfering data\n"); 480 usb_disk_clear_halt(directionIn ? device->bulk_in : device->bulk_out); 481 } else { 482 TRACE_ALWAYS("sending or receiving of the data failed: %s\n", 483 strerror(device->status)); 484 usb_disk_reset_recovery(device, _action); 485 return B_IO_ERROR; 486 } 487 } 488 } 489 490 usb_massbulk_command_status_wrapper status; 491 result = receive_csw_bulk(device, &status); 492 if (result != B_OK) { 493 // in case of a stall or error clear the stall and try again 494 usb_disk_clear_halt(device->bulk_in); 495 result = receive_csw_bulk(device, &status); 496 } 497 498 if (result != B_OK) { 499 TRACE_ALWAYS("receiving the command status wrapper failed: %s\n", 500 strerror(result)); 501 usb_disk_reset_recovery(device, _action); 502 return result; 503 } 504 505 if (status.signature != USB_MASSBULK_CSW_SIGNATURE 506 || status.tag != command.tag) { 507 // the command status wrapper is not valid 508 TRACE_ALWAYS("command status wrapper is not valid: %#" B_PRIx32 "\n", 509 status.signature); 510 usb_disk_reset_recovery(device, _action); 511 return B_ERROR; 512 } 513 514 switch (status.status) { 515 case USB_MASSBULK_CSW_STATUS_COMMAND_PASSED: 516 case USB_MASSBULK_CSW_STATUS_COMMAND_FAILED: 517 { 518 // The residue from "status.data_residue" is not maintained 519 // correctly by some devices, so calculate it instead. 520 uint32 residue = command.data_transfer_length - transferedData; 521 522 if (dataLength != NULL) { 523 *dataLength -= residue; 524 if (transferedData < *dataLength) { 525 TRACE_ALWAYS("less data transfered than indicated: %" 526 B_PRIuSIZE " vs. %" B_PRIuSIZE "\n", transferedData, 527 *dataLength); 528 *dataLength = transferedData; 529 } 530 } 531 532 if (status.status == USB_MASSBULK_CSW_STATUS_COMMAND_PASSED) { 533 // the operation is complete and has succeeded 534 return B_OK; 535 } else { 536 if (operation[0] == SCSI_REQUEST_SENSE_6) 537 return B_ERROR; 538 539 // the operation is complete but has failed at the SCSI level 540 if (operation[0] != SCSI_TEST_UNIT_READY_6) { 541 TRACE_ALWAYS("operation %#" B_PRIx8 542 " failed at the SCSI level\n", operation[0]); 543 } 544 545 result = usb_disk_request_sense(lun, _action); 546 return result == B_OK ? B_ERROR : result; 547 } 548 } 549 550 case USB_MASSBULK_CSW_STATUS_PHASE_ERROR: 551 { 552 // a protocol or device error occured 553 TRACE_ALWAYS("phase error in operation %#" B_PRIx8 "\n", 554 operation[0]); 555 usb_disk_reset_recovery(device, _action); 556 return B_ERROR; 557 } 558 559 default: 560 { 561 // command status wrapper is not meaningful 562 TRACE_ALWAYS("command status wrapper has invalid status\n"); 563 usb_disk_reset_recovery(device, _action); 564 return B_ERROR; 565 } 566 } 567 } 568 569 570 static status_t 571 usb_disk_operation(device_lun *lun, uint8* operation, size_t opLength, 572 const transfer_data& data, size_t *dataLength, 573 bool directionIn, err_act *_action = NULL) 574 { 575 if (lun->device->is_ufi) { 576 return usb_disk_operation_interrupt(lun, operation, 577 data, dataLength, directionIn, _action); 578 } else { 579 return usb_disk_operation_bulk(lun, operation, opLength, 580 data, dataLength, directionIn, _action); 581 } 582 } 583 584 585 static status_t 586 usb_disk_operation(device_lun *lun, uint8* operation, size_t opLength, 587 void *buffer, size_t *dataLength, 588 bool directionIn, err_act *_action = NULL) 589 { 590 iovec vec; 591 vec.iov_base = buffer; 592 593 struct transfer_data data; 594 data.vecs = &vec; 595 596 if (dataLength != NULL && *dataLength != 0) { 597 vec.iov_len = *dataLength; 598 data.vec_count = 1; 599 } else { 600 vec.iov_len = 0; 601 data.vec_count = 0; 602 } 603 604 return usb_disk_operation(lun, operation, opLength, 605 data, dataLength, directionIn, _action); 606 } 607 608 609 // 610 //#pragma mark - Helper/Convenience Functions 611 // 612 613 614 status_t 615 usb_disk_send_diagnostic(device_lun *lun) 616 { 617 uint8 commandBlock[12]; 618 memset(commandBlock, 0, sizeof(commandBlock)); 619 620 commandBlock[0] = SCSI_SEND_DIAGNOSTIC; 621 commandBlock[1] = (lun->logical_unit_number << 5) | 4; 622 623 status_t result = usb_disk_operation(lun, commandBlock, 6, NULL, NULL, false); 624 625 int retry = 100; 626 err_act action = err_act_ok; 627 while (result == B_DEV_NO_MEDIA && retry > 0) { 628 snooze(10000); 629 result = usb_disk_request_sense(lun, &action); 630 retry--; 631 } 632 633 if (result != B_OK) 634 TRACE("Send Diagnostic failed: %s\n", strerror(result)); 635 return result; 636 } 637 638 639 status_t 640 usb_disk_request_sense(device_lun *lun, err_act *_action) 641 { 642 size_t dataLength = sizeof(scsi_request_sense_6_parameter); 643 uint8 commandBlock[12]; 644 memset(commandBlock, 0, sizeof(commandBlock)); 645 646 commandBlock[0] = SCSI_REQUEST_SENSE_6; 647 commandBlock[1] = lun->logical_unit_number << 5; 648 commandBlock[2] = 0; // page code 649 commandBlock[4] = dataLength; 650 651 scsi_request_sense_6_parameter parameter; 652 status_t result = B_ERROR; 653 for (uint32 tries = 0; tries < 3; tries++) { 654 result = usb_disk_operation(lun, commandBlock, 6, ¶meter, 655 &dataLength, true); 656 if (result != B_TIMED_OUT) 657 break; 658 snooze(100000); 659 } 660 if (result != B_OK) { 661 TRACE_ALWAYS("getting request sense data failed: %s\n", 662 strerror(result)); 663 return result; 664 } 665 666 const char *label = NULL; 667 err_act action = err_act_fail; 668 status_t status = B_ERROR; 669 scsi_get_sense_asc_info((parameter.additional_sense_code << 8) 670 | parameter.additional_sense_code_qualifier, &label, &action, 671 &status); 672 673 if (parameter.sense_key > SCSI_SENSE_KEY_NOT_READY 674 && parameter.sense_key != SCSI_SENSE_KEY_UNIT_ATTENTION) { 675 TRACE_ALWAYS("request_sense: key: 0x%02x; asc: 0x%02x; ascq: " 676 "0x%02x; %s\n", parameter.sense_key, 677 parameter.additional_sense_code, 678 parameter.additional_sense_code_qualifier, 679 label ? label : "(unknown)"); 680 } 681 682 if ((parameter.additional_sense_code == 0 683 && parameter.additional_sense_code_qualifier == 0) 684 || label == NULL) { 685 scsi_get_sense_key_info(parameter.sense_key, &label, &action, &status); 686 } 687 688 if (status == B_DEV_MEDIA_CHANGED) { 689 lun->media_changed = true; 690 lun->media_present = true; 691 } else if (parameter.sense_key == SCSI_SENSE_KEY_UNIT_ATTENTION 692 && status != B_DEV_NO_MEDIA) { 693 lun->media_present = true; 694 } else if (status == B_DEV_NOT_READY) { 695 lun->media_present = false; 696 usb_disk_reset_capacity(lun); 697 } 698 699 if (_action != NULL) 700 *_action = action; 701 702 return status; 703 } 704 705 706 status_t 707 usb_disk_mode_sense(device_lun *lun) 708 { 709 size_t dataLength = sizeof(scsi_mode_sense_6_parameter); 710 711 uint8 commandBlock[12]; 712 memset(commandBlock, 0, sizeof(commandBlock)); 713 714 commandBlock[0] = SCSI_MODE_SENSE_6; 715 commandBlock[1] = SCSI_MODE_PAGE_DEVICE_CONFIGURATION; 716 commandBlock[2] = 0; // Current values 717 commandBlock[3] = dataLength >> 8; 718 commandBlock[4] = dataLength; 719 720 scsi_mode_sense_6_parameter parameter; 721 status_t result = usb_disk_operation(lun, commandBlock, 6, 722 ¶meter, &dataLength, true); 723 if (result != B_OK) { 724 TRACE_ALWAYS("getting mode sense data failed: %s\n", strerror(result)); 725 return result; 726 } 727 728 lun->write_protected 729 = (parameter.device_specific & SCSI_DEVICE_SPECIFIC_WRITE_PROTECT) 730 != 0; 731 TRACE_ALWAYS("write protected: %s\n", lun->write_protected ? "yes" : "no"); 732 return B_OK; 733 } 734 735 736 status_t 737 usb_disk_test_unit_ready(device_lun *lun, err_act *_action) 738 { 739 // if unsupported we assume the unit is fixed and therefore always ok 740 if (lun->device->is_ufi || !lun->device->tur_supported) 741 return B_OK; 742 743 status_t result = B_OK; 744 uint8 commandBlock[12]; 745 memset(commandBlock, 0, sizeof(commandBlock)); 746 747 if (lun->device->is_atapi) { 748 commandBlock[0] = SCSI_START_STOP_UNIT_6; 749 commandBlock[1] = lun->logical_unit_number << 5; 750 commandBlock[2] = 0; 751 commandBlock[3] = 0; 752 commandBlock[4] = 1; 753 754 result = usb_disk_operation(lun, commandBlock, 6, NULL, NULL, false, 755 _action); 756 } else { 757 commandBlock[0] = SCSI_TEST_UNIT_READY_6; 758 commandBlock[1] = lun->logical_unit_number << 5; 759 commandBlock[2] = 0; 760 commandBlock[3] = 0; 761 commandBlock[4] = 0; 762 result = usb_disk_operation(lun, commandBlock, 6, NULL, NULL, true, 763 _action); 764 } 765 766 if (result == B_DEV_INVALID_IOCTL) { 767 lun->device->tur_supported = false; 768 return B_OK; 769 } 770 771 return result; 772 } 773 774 775 status_t 776 usb_disk_inquiry(device_lun *lun) 777 { 778 size_t dataLength = sizeof(scsi_inquiry_6_parameter); 779 780 uint8 commandBlock[12]; 781 memset(commandBlock, 0, sizeof(commandBlock)); 782 783 commandBlock[0] = SCSI_INQUIRY_6; 784 commandBlock[1] = lun->logical_unit_number << 5; 785 commandBlock[2] = 0; // page code 786 commandBlock[4] = dataLength; 787 788 scsi_inquiry_6_parameter parameter; 789 status_t result = B_ERROR; 790 err_act action = err_act_ok; 791 for (uint32 tries = 0; tries < 3; tries++) { 792 result = usb_disk_operation(lun, commandBlock, 6, ¶meter, 793 &dataLength, true, &action); 794 if (result == B_OK || (action != err_act_retry 795 && action != err_act_many_retries)) { 796 break; 797 } 798 } 799 if (result != B_OK) { 800 TRACE_ALWAYS("getting inquiry data failed: %s\n", strerror(result)); 801 lun->device_type = B_DISK; 802 lun->removable = true; 803 return result; 804 } 805 806 TRACE("peripherial_device_type 0x%02x\n", 807 parameter.peripherial_device_type); 808 TRACE("peripherial_qualifier 0x%02x\n", 809 parameter.peripherial_qualifier); 810 TRACE("removable_medium %s\n", 811 parameter.removable_medium ? "yes" : "no"); 812 TRACE("version 0x%02x\n", parameter.version); 813 TRACE("response_data_format 0x%02x\n", parameter.response_data_format); 814 TRACE_ALWAYS("vendor_identification \"%.8s\"\n", 815 parameter.vendor_identification); 816 TRACE_ALWAYS("product_identification \"%.16s\"\n", 817 parameter.product_identification); 818 TRACE_ALWAYS("product_revision_level \"%.4s\"\n", 819 parameter.product_revision_level); 820 821 memcpy(lun->vendor_name, parameter.vendor_identification, 822 MIN(sizeof(lun->vendor_name), sizeof(parameter.vendor_identification))); 823 memcpy(lun->product_name, parameter.product_identification, 824 MIN(sizeof(lun->product_name), 825 sizeof(parameter.product_identification))); 826 memcpy(lun->product_revision, parameter.product_revision_level, 827 MIN(sizeof(lun->product_revision), 828 sizeof(parameter.product_revision_level))); 829 830 lun->device_type = parameter.peripherial_device_type; /* 1:1 mapping */ 831 lun->removable = (parameter.removable_medium == 1); 832 return B_OK; 833 } 834 835 836 status_t 837 usb_disk_reset_capacity(device_lun *lun) 838 { 839 lun->block_size = 512; 840 lun->block_count = 0; 841 return B_OK; 842 } 843 844 845 static status_t 846 usb_disk_update_capacity_16(device_lun *lun) 847 { 848 size_t dataLength = sizeof(scsi_read_capacity_16_parameter); 849 scsi_read_capacity_16_parameter parameter; 850 status_t result = B_ERROR; 851 err_act action = err_act_ok; 852 853 uint8 commandBlock[16]; 854 memset(commandBlock, 0, sizeof(commandBlock)); 855 856 commandBlock[0] = SCSI_SERVICE_ACTION_IN; 857 commandBlock[1] = SCSI_SAI_READ_CAPACITY_16; 858 commandBlock[10] = dataLength >> 24; 859 commandBlock[11] = dataLength >> 16; 860 commandBlock[12] = dataLength >> 8; 861 commandBlock[13] = dataLength; 862 863 // Retry reading the capacity up to three times. The first try might only 864 // yield a unit attention telling us that the device or media status 865 // changed, which is more or less expected if it is the first operation 866 // on the device or the device only clears the unit atention for capacity 867 // reads. 868 for (int32 i = 0; i < 5; i++) { 869 result = usb_disk_operation(lun, commandBlock, 16, ¶meter, 870 &dataLength, true, &action); 871 872 if (result == B_OK || (action != err_act_retry 873 && action != err_act_many_retries)) { 874 break; 875 } 876 } 877 878 if (result != B_OK) { 879 TRACE_ALWAYS("failed to update capacity: %s\n", strerror(result)); 880 lun->media_present = false; 881 lun->media_changed = false; 882 usb_disk_reset_capacity(lun); 883 return result; 884 } 885 886 lun->media_present = true; 887 lun->media_changed = false; 888 lun->block_size = B_BENDIAN_TO_HOST_INT32(parameter.logical_block_length); 889 lun->physical_block_size = lun->block_size; 890 lun->block_count = 891 B_BENDIAN_TO_HOST_INT64(parameter.last_logical_block_address) + 1; 892 return B_OK; 893 } 894 895 896 status_t 897 usb_disk_update_capacity(device_lun *lun) 898 { 899 size_t dataLength = sizeof(scsi_read_capacity_10_parameter); 900 scsi_read_capacity_10_parameter parameter; 901 status_t result = B_ERROR; 902 err_act action = err_act_ok; 903 904 uint8 commandBlock[12]; 905 memset(commandBlock, 0, sizeof(commandBlock)); 906 907 commandBlock[0] = SCSI_READ_CAPACITY_10; 908 commandBlock[1] = lun->logical_unit_number << 5; 909 910 // Retry reading the capacity up to three times. The first try might only 911 // yield a unit attention telling us that the device or media status 912 // changed, which is more or less expected if it is the first operation 913 // on the device or the device only clears the unit atention for capacity 914 // reads. 915 for (int32 i = 0; i < 5; i++) { 916 result = usb_disk_operation(lun, commandBlock, 10, ¶meter, 917 &dataLength, true, &action); 918 919 if (result == B_OK || (action != err_act_retry 920 && action != err_act_many_retries)) { 921 break; 922 } 923 924 // In some cases, it's best to wait a little for the device to settle 925 // before retrying. 926 if (lun->device->is_ufi && (result == B_DEV_NO_MEDIA 927 || result == B_TIMED_OUT || result == B_DEV_STALLED)) 928 snooze(10000); 929 } 930 931 if (result != B_OK) { 932 TRACE_ALWAYS("failed to update capacity: %s\n", strerror(result)); 933 lun->media_present = false; 934 lun->media_changed = false; 935 usb_disk_reset_capacity(lun); 936 return result; 937 } 938 939 lun->media_present = true; 940 lun->media_changed = false; 941 lun->block_size = B_BENDIAN_TO_HOST_INT32(parameter.logical_block_length); 942 lun->physical_block_size = lun->block_size; 943 lun->block_count = 944 B_BENDIAN_TO_HOST_INT32(parameter.last_logical_block_address) + 1; 945 if (lun->block_count == 0) { 946 // try SCSI_READ_CAPACITY_16 947 result = usb_disk_update_capacity_16(lun); 948 if (result != B_OK) 949 return result; 950 } 951 952 // ensure we have a DMAResource for this block_size 953 if (get_dma_resource(lun->device, lun->block_size) == NULL) { 954 dma_restrictions restrictions = {}; 955 restrictions.max_transfer_size = (lun->block_size * MAX_IO_BLOCKS); 956 957 DMAResource* dmaResource = new DMAResource; 958 result = dmaResource->Init(restrictions, lun->block_size, 1, 1); 959 if (result != B_OK) 960 return result; 961 962 lun->device->dma_resources.Add(dmaResource); 963 } 964 965 return B_OK; 966 } 967 968 969 status_t 970 usb_disk_synchronize(device_lun *lun, bool force) 971 { 972 if (lun->device->is_ufi) { 973 // UFI use interrupt because it runs all commands immediately, and 974 // tells us when its done. There is no cache involved in that case, 975 // so nothing to synchronize. 976 return B_UNSUPPORTED; 977 } 978 979 if (lun->device->sync_support == 0) { 980 // this device reported an illegal request when syncing or repeatedly 981 // returned an other error, it apparently does not support syncing... 982 return B_UNSUPPORTED; 983 } 984 985 if (!lun->should_sync && !force) 986 return B_OK; 987 988 uint8 commandBlock[12]; 989 memset(commandBlock, 0, sizeof(commandBlock)); 990 991 commandBlock[0] = SCSI_SYNCHRONIZE_CACHE_10; 992 commandBlock[1] = lun->logical_unit_number << 5; 993 994 status_t result = usb_disk_operation(lun, commandBlock, 10, 995 NULL, NULL, false); 996 997 if (result == B_OK) { 998 lun->device->sync_support = SYNC_SUPPORT_RELOAD; 999 lun->should_sync = false; 1000 return B_OK; 1001 } 1002 1003 if (result == B_DEV_INVALID_IOCTL) 1004 lun->device->sync_support = 0; 1005 else 1006 lun->device->sync_support--; 1007 1008 return result; 1009 } 1010 1011 1012 // 1013 //#pragma mark - Device Attach/Detach Notifications and Callback 1014 // 1015 1016 1017 static void 1018 usb_disk_callback(void *cookie, status_t status, void *data, 1019 size_t actualLength) 1020 { 1021 //TRACE("callback()\n"); 1022 disk_device *device = (disk_device *)cookie; 1023 device->status = status; 1024 device->actual_length = actualLength; 1025 release_sem(device->notify); 1026 } 1027 1028 1029 static status_t 1030 usb_disk_attach(device_node *node, usb_device newDevice, void **cookie) 1031 { 1032 TRACE("device_added(0x%08" B_PRIx32 ")\n", newDevice); 1033 disk_device *device = new(std::nothrow) disk_device; 1034 recursive_lock_lock(&device->io_lock); 1035 mutex_lock(&device->lock); 1036 1037 device->node = node; 1038 device->device = newDevice; 1039 device->removed = false; 1040 device->open_count = 0; 1041 device->interface = 0xff; 1042 device->current_tag = 0; 1043 device->sync_support = SYNC_SUPPORT_RELOAD; 1044 device->tur_supported = true; 1045 device->is_atapi = false; 1046 device->is_ufi = false; 1047 device->luns = NULL; 1048 1049 // scan through the interfaces to find our bulk-only data interface 1050 const usb_configuration_info *configuration 1051 = gUSBModule->get_configuration(newDevice); 1052 if (configuration == NULL) { 1053 delete device; 1054 return B_ERROR; 1055 } 1056 1057 for (size_t i = 0; i < configuration->interface_count; i++) { 1058 usb_interface_info *interface = configuration->interface[i].active; 1059 if (interface == NULL) 1060 continue; 1061 1062 if (interface->descr->interface_class == USB_MASS_STORAGE_DEVICE_CLASS 1063 && (((interface->descr->interface_subclass == 0x06 /* SCSI */ 1064 || interface->descr->interface_subclass == 0x02 /* ATAPI */ 1065 || interface->descr->interface_subclass == 0x05 /* ATAPI */) 1066 && interface->descr->interface_protocol == 0x50 /* bulk-only */) 1067 || (interface->descr->interface_subclass == 0x04 /* UFI */ 1068 && interface->descr->interface_protocol == 0x00))) { 1069 1070 bool hasIn = false; 1071 bool hasOut = false; 1072 bool hasInt = false; 1073 for (size_t j = 0; j < interface->endpoint_count; j++) { 1074 usb_endpoint_info *endpoint = &interface->endpoint[j]; 1075 if (endpoint == NULL) 1076 continue; 1077 1078 if (!hasIn && (endpoint->descr->endpoint_address 1079 & USB_ENDPOINT_ADDR_DIR_IN) != 0 1080 && endpoint->descr->attributes == USB_ENDPOINT_ATTR_BULK) { 1081 device->bulk_in = endpoint->handle; 1082 hasIn = true; 1083 } else if (!hasOut && (endpoint->descr->endpoint_address 1084 & USB_ENDPOINT_ADDR_DIR_IN) == 0 1085 && endpoint->descr->attributes == USB_ENDPOINT_ATTR_BULK) { 1086 device->bulk_out = endpoint->handle; 1087 hasOut = true; 1088 } else if (!hasInt && (endpoint->descr->endpoint_address 1089 & USB_ENDPOINT_ADDR_DIR_IN) 1090 && endpoint->descr->attributes 1091 == USB_ENDPOINT_ATTR_INTERRUPT) { 1092 device->interrupt = endpoint->handle; 1093 hasInt = true; 1094 } 1095 1096 if (hasIn && hasOut && hasInt) 1097 break; 1098 } 1099 1100 if (!(hasIn && hasOut)) { 1101 // Missing one of the required endpoints, try next interface 1102 continue; 1103 } 1104 1105 device->interface = interface->descr->interface_number; 1106 device->is_atapi = interface->descr->interface_subclass != 0x06 1107 && interface->descr->interface_subclass != 0x04; 1108 device->is_ufi = interface->descr->interface_subclass == 0x04; 1109 1110 if (device->is_ufi && !hasInt) { 1111 // UFI without interrupt endpoint is not possible. 1112 continue; 1113 } 1114 break; 1115 } 1116 } 1117 1118 if (device->interface == 0xff) { 1119 TRACE_ALWAYS("no valid bulk-only or CBI interface found\n"); 1120 delete device; 1121 return B_ERROR; 1122 } 1123 1124 device->notify = create_sem(0, "usb_disk callback notify"); 1125 if (device->notify < B_OK) { 1126 status_t result = device->notify; 1127 delete device; 1128 return result; 1129 } 1130 1131 if (device->is_ufi) { 1132 device->interruptLock = create_sem(0, "usb_disk interrupt lock"); 1133 if (device->interruptLock < B_OK) { 1134 status_t result = device->interruptLock; 1135 delete device; 1136 return result; 1137 } 1138 } 1139 1140 device->lun_count = usb_disk_get_max_lun(device) + 1; 1141 device->luns = (device_lun **)malloc(device->lun_count 1142 * sizeof(device_lun *)); 1143 for (uint8 i = 0; i < device->lun_count; i++) 1144 device->luns[i] = NULL; 1145 1146 status_t result = B_OK; 1147 1148 TRACE_ALWAYS("device reports a lun count of %d\n", device->lun_count); 1149 for (uint8 i = 0; i < device->lun_count; i++) { 1150 // create the individual luns present on this device 1151 device_lun *lun = (device_lun *)malloc(sizeof(device_lun)); 1152 if (lun == NULL) { 1153 result = B_NO_MEMORY; 1154 break; 1155 } 1156 1157 device->luns[i] = lun; 1158 lun->device = device; 1159 lun->logical_unit_number = i; 1160 lun->should_sync = false; 1161 lun->media_present = true; 1162 lun->media_changed = true; 1163 1164 memset(lun->vendor_name, 0, sizeof(lun->vendor_name)); 1165 memset(lun->product_name, 0, sizeof(lun->product_name)); 1166 memset(lun->product_revision, 0, sizeof(lun->product_revision)); 1167 1168 usb_disk_reset_capacity(lun); 1169 1170 // initialize this lun 1171 result = usb_disk_inquiry(lun); 1172 1173 if (device->is_ufi) { 1174 // Reset the device 1175 // If we don't do it all the other commands except inquiry and send 1176 // diagnostics will be stalled. 1177 result = usb_disk_send_diagnostic(lun); 1178 } 1179 1180 err_act action = err_act_ok; 1181 for (uint32 tries = 0; tries < 8; tries++) { 1182 TRACE("usb lun %" B_PRIu8 " inquiry attempt %" B_PRIu32 " begin\n", 1183 i, tries); 1184 status_t ready = usb_disk_test_unit_ready(lun, &action); 1185 if (ready == B_OK || ready == B_DEV_NO_MEDIA 1186 || ready == B_DEV_MEDIA_CHANGED) { 1187 if (lun->device_type == B_CD) 1188 lun->write_protected = true; 1189 // TODO: check for write protection; disabled since some 1190 // devices lock up when getting the mode sense 1191 else if (/*usb_disk_mode_sense(lun) != B_OK*/true) 1192 lun->write_protected = false; 1193 1194 TRACE("usb lun %" B_PRIu8 " ready. write protected = %c%s\n", i, 1195 lun->write_protected ? 'y' : 'n', 1196 ready == B_DEV_NO_MEDIA ? " (no media inserted)" : ""); 1197 1198 break; 1199 } 1200 TRACE("usb lun %" B_PRIu8 " inquiry attempt %" B_PRIu32 " failed\n", 1201 i, tries); 1202 if (action != err_act_retry && action != err_act_many_retries) 1203 break; 1204 bigtime_t snoozeTime = 1000000 * tries; 1205 TRACE("snoozing %" B_PRIu64 " microseconds for usb lun\n", 1206 snoozeTime); 1207 snooze(snoozeTime); 1208 } 1209 1210 if (result != B_OK) 1211 break; 1212 } 1213 1214 if (result != B_OK) { 1215 TRACE_ALWAYS("failed to initialize logical units: %s\n", 1216 strerror(result)); 1217 usb_disk_free_device_and_luns(device); 1218 return result; 1219 } 1220 1221 mutex_unlock(&device->lock); 1222 recursive_lock_unlock(&device->io_lock); 1223 1224 TRACE("new device: 0x%p\n", device); 1225 *cookie = (void *)device; 1226 return B_OK; 1227 } 1228 1229 1230 static void 1231 usb_disk_device_removed(void *cookie) 1232 { 1233 TRACE("device_removed(0x%p)\n", cookie); 1234 disk_device *device = (disk_device *)cookie; 1235 mutex_lock(&device->lock); 1236 1237 for (uint8 i = 0; i < device->lun_count; i++) { 1238 // unpublish_device() can call close(). 1239 mutex_unlock(&device->lock); 1240 gDeviceManager->unpublish_device(device->node, device->luns[i]->name); 1241 mutex_lock(&device->lock); 1242 } 1243 1244 device->removed = true; 1245 gUSBModule->cancel_queued_transfers(device->bulk_in); 1246 gUSBModule->cancel_queued_transfers(device->bulk_out); 1247 1248 // At this point, open_count should always be 0 anyway. 1249 if (device->open_count == 0) 1250 usb_disk_free_device_and_luns(device); 1251 else 1252 mutex_unlock(&device->lock); 1253 } 1254 1255 1256 static bool 1257 usb_disk_needs_bounce(device_lun *lun, io_request *request) 1258 { 1259 if (!request->Buffer()->IsVirtual()) 1260 return true; 1261 if ((request->Offset() % lun->block_size) != 0) 1262 return true; 1263 if ((request->Length() % lun->block_size) != 0) 1264 return true; 1265 if (request->Length() > (lun->block_size * MAX_IO_BLOCKS)) 1266 return true; 1267 return false; 1268 } 1269 1270 1271 static status_t 1272 usb_disk_block_read(device_lun *lun, uint64 blockPosition, size_t blockCount, 1273 struct transfer_data data, size_t *length) 1274 { 1275 uint8 commandBlock[16]; 1276 memset(commandBlock, 0, sizeof(commandBlock)); 1277 if (lun->device->is_ufi) { 1278 commandBlock[0] = SCSI_READ_12; 1279 commandBlock[1] = lun->logical_unit_number << 5; 1280 commandBlock[2] = blockPosition >> 24; 1281 commandBlock[3] = blockPosition >> 16; 1282 commandBlock[4] = blockPosition >> 8; 1283 commandBlock[5] = blockPosition; 1284 commandBlock[6] = blockCount >> 24; 1285 commandBlock[7] = blockCount >> 16; 1286 commandBlock[8] = blockCount >> 8; 1287 commandBlock[9] = blockCount; 1288 1289 status_t result = B_OK; 1290 for (int tries = 0; tries < 5; tries++) { 1291 result = usb_disk_operation(lun, commandBlock, 12, data, 1292 length, true); 1293 if (result == B_OK) 1294 break; 1295 else 1296 snooze(10000); 1297 } 1298 return result; 1299 } else if (blockPosition + blockCount < 0x100000000LL && blockCount <= 0x10000) { 1300 commandBlock[0] = SCSI_READ_10; 1301 commandBlock[1] = 0; 1302 commandBlock[2] = blockPosition >> 24; 1303 commandBlock[3] = blockPosition >> 16; 1304 commandBlock[4] = blockPosition >> 8; 1305 commandBlock[5] = blockPosition; 1306 commandBlock[7] = blockCount >> 8; 1307 commandBlock[8] = blockCount; 1308 status_t result = usb_disk_operation(lun, commandBlock, 10, 1309 data, length, true); 1310 return result; 1311 } else { 1312 commandBlock[0] = SCSI_READ_16; 1313 commandBlock[1] = 0; 1314 commandBlock[2] = blockPosition >> 56; 1315 commandBlock[3] = blockPosition >> 48; 1316 commandBlock[4] = blockPosition >> 40; 1317 commandBlock[5] = blockPosition >> 32; 1318 commandBlock[6] = blockPosition >> 24; 1319 commandBlock[7] = blockPosition >> 16; 1320 commandBlock[8] = blockPosition >> 8; 1321 commandBlock[9] = blockPosition; 1322 commandBlock[10] = blockCount >> 24; 1323 commandBlock[11] = blockCount >> 16; 1324 commandBlock[12] = blockCount >> 8; 1325 commandBlock[13] = blockCount; 1326 status_t result = usb_disk_operation(lun, commandBlock, 16, 1327 data, length, true); 1328 return result; 1329 } 1330 } 1331 1332 1333 static status_t 1334 usb_disk_block_write(device_lun *lun, uint64 blockPosition, size_t blockCount, 1335 struct transfer_data data, size_t *length) 1336 { 1337 uint8 commandBlock[16]; 1338 memset(commandBlock, 0, sizeof(commandBlock)); 1339 1340 if (lun->device->is_ufi) { 1341 commandBlock[0] = SCSI_WRITE_12; 1342 commandBlock[1] = lun->logical_unit_number << 5; 1343 commandBlock[2] = blockPosition >> 24; 1344 commandBlock[3] = blockPosition >> 16; 1345 commandBlock[4] = blockPosition >> 8; 1346 commandBlock[5] = blockPosition; 1347 commandBlock[6] = blockCount >> 24; 1348 commandBlock[7] = blockCount >> 16; 1349 commandBlock[8] = blockCount >> 8; 1350 commandBlock[9] = blockCount; 1351 1352 status_t result; 1353 result = usb_disk_operation(lun, commandBlock, 12, 1354 data, length, false); 1355 1356 int retry = 10; 1357 err_act action = err_act_ok; 1358 while (result == B_DEV_NO_MEDIA && retry > 0) { 1359 snooze(10000); 1360 result = usb_disk_request_sense(lun, &action); 1361 retry--; 1362 } 1363 1364 if (result == B_OK) 1365 lun->should_sync = true; 1366 return result; 1367 } else if (blockPosition + blockCount < 0x100000000LL && blockCount <= 0x10000) { 1368 commandBlock[0] = SCSI_WRITE_10; 1369 commandBlock[2] = blockPosition >> 24; 1370 commandBlock[3] = blockPosition >> 16; 1371 commandBlock[4] = blockPosition >> 8; 1372 commandBlock[5] = blockPosition; 1373 commandBlock[7] = blockCount >> 8; 1374 commandBlock[8] = blockCount; 1375 status_t result = usb_disk_operation(lun, commandBlock, 10, 1376 data, length, false); 1377 if (result == B_OK) 1378 lun->should_sync = true; 1379 return result; 1380 } else { 1381 commandBlock[0] = SCSI_WRITE_16; 1382 commandBlock[1] = 0; 1383 commandBlock[2] = blockPosition >> 56; 1384 commandBlock[3] = blockPosition >> 48; 1385 commandBlock[4] = blockPosition >> 40; 1386 commandBlock[5] = blockPosition >> 32; 1387 commandBlock[6] = blockPosition >> 24; 1388 commandBlock[7] = blockPosition >> 16; 1389 commandBlock[8] = blockPosition >> 8; 1390 commandBlock[9] = blockPosition; 1391 commandBlock[10] = blockCount >> 24; 1392 commandBlock[11] = blockCount >> 16; 1393 commandBlock[12] = blockCount >> 8; 1394 commandBlock[13] = blockCount; 1395 status_t result = usb_disk_operation(lun, commandBlock, 16, 1396 data, length, false); 1397 if (result == B_OK) 1398 lun->should_sync = true; 1399 return result; 1400 } 1401 } 1402 1403 1404 // 1405 //#pragma mark - Driver Hooks 1406 // 1407 1408 1409 static status_t 1410 usb_disk_init_device(void* _info, void** _cookie) 1411 { 1412 CALLED(); 1413 *_cookie = _info; 1414 return B_OK; 1415 } 1416 1417 1418 static void 1419 usb_disk_uninit_device(void* _cookie) 1420 { 1421 // Nothing to do. 1422 } 1423 1424 1425 static status_t 1426 usb_disk_open(void *deviceCookie, const char *path, int flags, void **_cookie) 1427 { 1428 TRACE("open(%s)\n", path); 1429 if (strncmp(path, DEVICE_NAME_BASE, strlen(DEVICE_NAME_BASE)) != 0) 1430 return B_NAME_NOT_FOUND; 1431 1432 int32 lastPart = 0; 1433 size_t nameLength = strlen(path); 1434 for (int32 i = nameLength - 1; i >= 0; i--) { 1435 if (path[i] == '/') { 1436 lastPart = i; 1437 break; 1438 } 1439 } 1440 1441 char rawName[nameLength + 4]; 1442 strncpy(rawName, path, lastPart + 1); 1443 rawName[lastPart + 1] = 0; 1444 strcat(rawName, "raw"); 1445 1446 disk_device *device = (disk_device *)deviceCookie; 1447 MutexLocker locker(device->lock); 1448 for (uint8 i = 0; i < device->lun_count; i++) { 1449 device_lun *lun = device->luns[i]; 1450 if (strncmp(rawName, lun->name, 32) == 0) { 1451 // found the matching device/lun 1452 if (device->removed) 1453 return B_ERROR; 1454 1455 device->open_count++; 1456 *_cookie = lun; 1457 return B_OK; 1458 } 1459 } 1460 1461 return B_NAME_NOT_FOUND; 1462 } 1463 1464 1465 static status_t 1466 usb_disk_close(void *cookie) 1467 { 1468 TRACE("close()\n"); 1469 device_lun *lun = (device_lun *)cookie; 1470 disk_device *device = lun->device; 1471 1472 RecursiveLocker ioLocker(device->io_lock); 1473 MutexLocker deviceLocker(device->lock); 1474 1475 if (!device->removed) 1476 usb_disk_synchronize(lun, false); 1477 1478 return B_OK; 1479 } 1480 1481 1482 static status_t 1483 usb_disk_free(void *cookie) 1484 { 1485 TRACE("free()\n"); 1486 1487 device_lun *lun = (device_lun *)cookie; 1488 disk_device *device = lun->device; 1489 mutex_lock(&device->lock); 1490 1491 device->open_count--; 1492 if (device->open_count == 0 && device->removed) { 1493 // we can simply free the device here as it has been removed from 1494 // the device list in the device removed notification hook 1495 usb_disk_free_device_and_luns(device); 1496 } else { 1497 mutex_unlock(&device->lock); 1498 } 1499 1500 return B_OK; 1501 } 1502 1503 1504 static inline void 1505 normalize_name(char *name, size_t nameLength) 1506 { 1507 bool wasSpace = false; 1508 size_t insertIndex = 0; 1509 for (size_t i = 0; i < nameLength; i++) { 1510 bool isSpace = name[i] == ' '; 1511 if (isSpace && wasSpace) 1512 continue; 1513 1514 name[insertIndex++] = name[i]; 1515 wasSpace = isSpace; 1516 } 1517 1518 if (insertIndex > 0 && name[insertIndex - 1] == ' ') 1519 insertIndex--; 1520 1521 name[insertIndex] = 0; 1522 } 1523 1524 1525 static status_t 1526 acquire_io_lock(disk_device *device, MutexLocker& locker, RecursiveLocker& ioLocker) 1527 { 1528 locker.Unlock(); 1529 ioLocker.SetTo(device->io_lock, false, true); 1530 locker.Lock(); 1531 1532 if (!locker.IsLocked() || !ioLocker.IsLocked()) 1533 return B_ERROR; 1534 1535 if (device->removed) 1536 return B_DEV_NOT_READY; 1537 1538 return B_OK; 1539 } 1540 1541 1542 static status_t 1543 handle_media_change(device_lun *lun, MutexLocker& locker) 1544 { 1545 RecursiveLocker ioLocker; 1546 status_t result = acquire_io_lock(lun->device, locker, ioLocker); 1547 if (result != B_OK) 1548 return result; 1549 1550 // It may have been handled while we were waiting for locks. 1551 if (lun->media_changed) { 1552 result = usb_disk_update_capacity(lun); 1553 if (result != B_OK) 1554 return result; 1555 } 1556 1557 return B_OK; 1558 } 1559 1560 1561 static status_t 1562 usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) 1563 { 1564 device_lun *lun = (device_lun *)cookie; 1565 disk_device *device = lun->device; 1566 MutexLocker locker(&device->lock); 1567 if (device->removed) 1568 return B_DEV_NOT_READY; 1569 RecursiveLocker ioLocker; 1570 1571 switch (op) { 1572 case B_GET_DEVICE_SIZE: 1573 { 1574 if (lun->media_changed) { 1575 status_t result = handle_media_change(lun, locker); 1576 if (result != B_OK) 1577 return result; 1578 } 1579 1580 size_t size = lun->block_size * lun->block_count; 1581 return user_memcpy(buffer, &size, sizeof(size)); 1582 } 1583 1584 case B_GET_MEDIA_STATUS: 1585 { 1586 status_t result = acquire_io_lock(lun->device, locker, ioLocker); 1587 if (result != B_OK) 1588 return result; 1589 1590 err_act action = err_act_ok; 1591 status_t ready; 1592 for (uint32 tries = 0; tries < 3; tries++) { 1593 ready = usb_disk_test_unit_ready(lun, &action); 1594 if (ready == B_OK || ready == B_DEV_NO_MEDIA 1595 || (action != err_act_retry 1596 && action != err_act_many_retries)) { 1597 if (IS_USER_ADDRESS(buffer)) { 1598 if (user_memcpy(buffer, &ready, sizeof(status_t)) != B_OK) 1599 return B_BAD_ADDRESS; 1600 } else if (is_called_via_syscall()) { 1601 return B_BAD_ADDRESS; 1602 } else 1603 *(status_t *)buffer = ready; 1604 break; 1605 } 1606 snooze(500000); 1607 } 1608 TRACE("B_GET_MEDIA_STATUS: 0x%08" B_PRIx32 "\n", ready); 1609 return B_OK; 1610 } 1611 1612 case B_GET_GEOMETRY: 1613 { 1614 if (buffer == NULL || length > sizeof(device_geometry)) 1615 return B_BAD_VALUE; 1616 if (lun->media_changed) { 1617 status_t result = handle_media_change(lun, locker); 1618 if (result != B_OK) 1619 return result; 1620 } 1621 1622 device_geometry geometry; 1623 devfs_compute_geometry_size(&geometry, lun->block_count, 1624 lun->block_size); 1625 geometry.bytes_per_physical_sector = lun->physical_block_size; 1626 1627 geometry.device_type = lun->device_type; 1628 geometry.removable = lun->removable; 1629 geometry.read_only = lun->write_protected; 1630 geometry.write_once = lun->device_type == B_WORM; 1631 TRACE("B_GET_GEOMETRY: %" B_PRId32 " sectors at %" B_PRId32 1632 " bytes per sector\n", geometry.cylinder_count, 1633 geometry.bytes_per_sector); 1634 return user_memcpy(buffer, &geometry, length); 1635 } 1636 1637 case B_FLUSH_DRIVE_CACHE: 1638 { 1639 TRACE("B_FLUSH_DRIVE_CACHE\n"); 1640 1641 status_t result = acquire_io_lock(lun->device, locker, ioLocker); 1642 if (result != B_OK) 1643 return result; 1644 1645 return usb_disk_synchronize(lun, true); 1646 } 1647 1648 case B_EJECT_DEVICE: 1649 { 1650 status_t result = acquire_io_lock(lun->device, locker, ioLocker); 1651 if (result != B_OK) 1652 return result; 1653 1654 uint8 commandBlock[12]; 1655 memset(commandBlock, 0, sizeof(commandBlock)); 1656 1657 commandBlock[0] = SCSI_START_STOP_UNIT_6; 1658 commandBlock[1] = lun->logical_unit_number << 5; 1659 commandBlock[4] = 2; 1660 1661 return usb_disk_operation(lun, commandBlock, 6, NULL, NULL, 1662 false); 1663 } 1664 1665 case B_LOAD_MEDIA: 1666 { 1667 status_t result = acquire_io_lock(lun->device, locker, ioLocker); 1668 if (result != B_OK) 1669 return result; 1670 1671 uint8 commandBlock[12]; 1672 memset(commandBlock, 0, sizeof(commandBlock)); 1673 1674 commandBlock[0] = SCSI_START_STOP_UNIT_6; 1675 commandBlock[1] = lun->logical_unit_number << 5; 1676 commandBlock[4] = 3; 1677 1678 return usb_disk_operation(lun, commandBlock, 6, NULL, NULL, 1679 false); 1680 } 1681 1682 case B_GET_ICON: 1683 // We don't support this legacy ioctl anymore, but the two other 1684 // icon ioctls below instead. 1685 break; 1686 1687 case B_GET_ICON_NAME: 1688 { 1689 const char *iconName = "devices/drive-removable-media-usb"; 1690 char vendor[sizeof(lun->vendor_name)+1]; 1691 char product[sizeof(lun->product_name)+1]; 1692 1693 if (device->is_ufi) { 1694 iconName = "devices/drive-floppy-usb"; 1695 } 1696 1697 switch (lun->device_type) { 1698 case B_CD: 1699 case B_OPTICAL: 1700 iconName = "devices/drive-optical"; 1701 break; 1702 case B_TAPE: // TODO 1703 default: 1704 snprintf(vendor, sizeof(vendor), "%.8s", 1705 lun->vendor_name); 1706 snprintf(product, sizeof(product), "%.16s", 1707 lun->product_name); 1708 for (int i = 0; kIconMatches[i].icon; i++) { 1709 if (kIconMatches[i].vendor != NULL 1710 && strstr(vendor, kIconMatches[i].vendor) == NULL) 1711 continue; 1712 if (kIconMatches[i].product != NULL 1713 && strstr(product, kIconMatches[i].product) == NULL) 1714 continue; 1715 iconName = kIconMatches[i].name; 1716 } 1717 break; 1718 } 1719 return user_strlcpy((char *)buffer, iconName, 1720 B_FILE_NAME_LENGTH); 1721 } 1722 1723 case B_GET_VECTOR_ICON: 1724 { 1725 device_icon *icon = &kKeyIconData; 1726 char vendor[sizeof(lun->vendor_name)+1]; 1727 char product[sizeof(lun->product_name)+1]; 1728 1729 if (length != sizeof(device_icon)) 1730 return B_BAD_VALUE; 1731 1732 if (device->is_ufi) { 1733 // UFI is specific for floppy drives 1734 icon = &kFloppyIconData; 1735 } else { 1736 switch (lun->device_type) { 1737 case B_CD: 1738 case B_OPTICAL: 1739 icon = &kCDIconData; 1740 break; 1741 case B_TAPE: // TODO 1742 default: 1743 snprintf(vendor, sizeof(vendor), "%.8s", 1744 lun->vendor_name); 1745 snprintf(product, sizeof(product), "%.16s", 1746 lun->product_name); 1747 for (int i = 0; kIconMatches[i].icon; i++) { 1748 if (kIconMatches[i].vendor != NULL 1749 && strstr(vendor, 1750 kIconMatches[i].vendor) == NULL) 1751 continue; 1752 if (kIconMatches[i].product != NULL 1753 && strstr(product, 1754 kIconMatches[i].product) == NULL) 1755 continue; 1756 icon = kIconMatches[i].icon; 1757 } 1758 break; 1759 } 1760 } 1761 1762 device_icon iconData; 1763 if (user_memcpy(&iconData, buffer, sizeof(device_icon)) != B_OK) 1764 return B_BAD_ADDRESS; 1765 1766 if (iconData.icon_size >= icon->icon_size) { 1767 if (user_memcpy(iconData.icon_data, icon->icon_data, 1768 (size_t)icon->icon_size) != B_OK) 1769 return B_BAD_ADDRESS; 1770 } 1771 1772 iconData.icon_size = icon->icon_size; 1773 return user_memcpy(buffer, &iconData, sizeof(device_icon)); 1774 } 1775 1776 case B_GET_DEVICE_NAME: 1777 { 1778 size_t nameLength = sizeof(lun->vendor_name) 1779 + sizeof(lun->product_name) + sizeof(lun->product_revision) + 3; 1780 1781 char name[nameLength]; 1782 snprintf(name, nameLength, "%.8s %.16s %.4s", lun->vendor_name, 1783 lun->product_name, lun->product_revision); 1784 1785 normalize_name(name, nameLength); 1786 1787 status_t result = user_strlcpy((char *)buffer, name, length); 1788 if (result > 0) 1789 result = B_OK; 1790 1791 TRACE_ALWAYS("got device name \"%s\": %s\n", name, 1792 strerror(result)); 1793 return result; 1794 } 1795 } 1796 1797 TRACE_ALWAYS("unhandled ioctl %" B_PRId32 "\n", op); 1798 return B_DEV_INVALID_IOCTL; 1799 } 1800 1801 1802 static status_t 1803 usb_disk_bounced_io(device_lun *lun, io_request *request) 1804 { 1805 DMAResource* dmaResource = get_dma_resource(lun->device, lun->block_size); 1806 if (dmaResource == NULL) 1807 return B_NO_INIT; 1808 1809 if (!request->Buffer()->IsPhysical()) { 1810 status_t status = request->Buffer()->LockMemory(request->TeamID(), request->IsWrite()); 1811 if (status != B_OK) { 1812 TRACE_ALWAYS("failed to lock memory: %s\n", strerror(status)); 1813 return status; 1814 } 1815 // SetStatusAndNotify() takes care of unlocking memory if necessary. 1816 } 1817 1818 status_t status = B_OK; 1819 while (request->RemainingBytes() > 0) { 1820 IOOperation operation; 1821 status = dmaResource->TranslateNext(request, &operation, 0); 1822 if (status != B_OK) 1823 break; 1824 1825 do { 1826 TRACE("%p: IOO offset: %" B_PRIdOFF ", length: %" B_PRIuGENADDR 1827 ", write: %s\n", request, operation.Offset(), 1828 operation.Length(), operation.IsWrite() ? "yes" : "no"); 1829 1830 struct transfer_data data; 1831 data.physical = true; 1832 data.phys_vecs = (physical_entry*)operation.Vecs(); 1833 data.vec_count = operation.VecCount(); 1834 1835 size_t length = operation.Length(); 1836 const uint64 blockPosition = operation.Offset() / lun->block_size; 1837 const size_t blockCount = length / lun->block_size; 1838 if (operation.IsWrite()) { 1839 status = usb_disk_block_write(lun, 1840 blockPosition, blockCount, data, &length); 1841 } else { 1842 status = usb_disk_block_read(lun, 1843 blockPosition, blockCount, data, &length); 1844 } 1845 1846 operation.SetStatus(status, length); 1847 } while (status == B_OK && !operation.Finish()); 1848 1849 if (status == B_OK && operation.Status() != B_OK) { 1850 TRACE_ALWAYS("I/O succeeded but IOOperation failed!\n"); 1851 status = operation.Status(); 1852 } 1853 1854 request->OperationFinished(&operation); 1855 dmaResource->RecycleBuffer(operation.Buffer()); 1856 1857 TRACE("%p: status %s, remaining bytes %" B_PRIuGENADDR "\n", request, 1858 strerror(status), request->RemainingBytes()); 1859 if (status != B_OK) 1860 break; 1861 } 1862 1863 return status; 1864 } 1865 1866 1867 static status_t 1868 usb_disk_direct_io(device_lun *lun, io_request *request) 1869 { 1870 generic_io_vec* genericVecs = request->Buffer()->Vecs(); 1871 const uint32 count = request->Buffer()->VecCount(); 1872 BStackOrHeapArray<iovec, 16> vecs(count); 1873 for (uint32 i = 0; i < count; i++) { 1874 vecs[i].iov_base = (void*)genericVecs[i].base; 1875 vecs[i].iov_len = genericVecs[i].length; 1876 } 1877 struct transfer_data data; 1878 data.vecs = vecs; 1879 data.vec_count = count; 1880 1881 size_t length = request->Length(); 1882 const uint64 blockPosition = request->Offset() / lun->block_size; 1883 const size_t blockCount = length / lun->block_size; 1884 1885 status_t status; 1886 if (request->IsWrite()) { 1887 status = usb_disk_block_write(lun, 1888 blockPosition, blockCount, data, &length); 1889 } else { 1890 status = usb_disk_block_read(lun, 1891 blockPosition, blockCount, data, &length); 1892 } 1893 1894 request->SetTransferredBytes(length != request->Length(), length); 1895 return status; 1896 } 1897 1898 1899 static status_t 1900 usb_disk_io(void *cookie, io_request *request) 1901 { 1902 TRACE("io(%p)\n", request); 1903 1904 device_lun *lun = (device_lun *)cookie; 1905 disk_device *device = lun->device; 1906 1907 RecursiveLocker ioLocker(device->io_lock); 1908 MutexLocker deviceLocker(device->lock); 1909 1910 if (device->removed) 1911 return B_DEV_NOT_READY; 1912 1913 status_t status; 1914 if (!usb_disk_needs_bounce(lun, request)) { 1915 status = usb_disk_direct_io(lun, request); 1916 } else { 1917 status = usb_disk_bounced_io(lun, request); 1918 } 1919 1920 deviceLocker.Unlock(); 1921 ioLocker.Unlock(); 1922 1923 if (request->Status() > 0) 1924 request->SetStatusAndNotify(status); 1925 else 1926 request->NotifyFinished(); 1927 return status; 1928 } 1929 1930 1931 // #pragma mark - driver module API 1932 1933 1934 static float 1935 usb_disk_supports_device(device_node *parent) 1936 { 1937 CALLED(); 1938 const char *bus; 1939 1940 // make sure parent is really the usb bus manager 1941 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) 1942 return -1; 1943 if (strcmp(bus, "usb") != 0) 1944 return 0.0; 1945 1946 usb_device device; 1947 if (gDeviceManager->get_attr_uint32(parent, USB_DEVICE_ID_ITEM, &device, true) != B_OK) 1948 return -1; 1949 1950 const usb_configuration_info *configuration = gUSBModule->get_configuration(device); 1951 if (configuration == NULL) 1952 return -1; 1953 1954 static usb_support_descriptor supportedDevices[] = { 1955 { USB_MASS_STORAGE_DEVICE_CLASS, 0x06 /* SCSI */, 0x50 /* bulk */, 0, 0 }, 1956 { USB_MASS_STORAGE_DEVICE_CLASS, 0x02 /* ATAPI */, 0x50 /* bulk */, 0, 0 }, 1957 { USB_MASS_STORAGE_DEVICE_CLASS, 0x05 /* ATAPI */, 0x50 /* bulk */, 0, 0 }, 1958 { USB_MASS_STORAGE_DEVICE_CLASS, 0x04 /* UFI */, 0x00, 0, 0 } 1959 }; 1960 1961 for (size_t i = 0; i < configuration->interface_count; i++) { 1962 usb_interface_info *interface = configuration->interface[i].active; 1963 if (interface == NULL) 1964 continue; 1965 1966 for (size_t i = 0; i < B_COUNT_OF(supportedDevices); i++) { 1967 if (interface->descr->interface_class != supportedDevices[i].dev_class) 1968 continue; 1969 if (interface->descr->interface_subclass != supportedDevices[i].dev_subclass) 1970 continue; 1971 if (interface->descr->interface_protocol != supportedDevices[i].dev_protocol) 1972 continue; 1973 1974 TRACE("USB disk device found!\n"); 1975 return 0.6; 1976 } 1977 } 1978 1979 return 0.0; 1980 } 1981 1982 1983 static status_t 1984 usb_disk_register_device(device_node *node) 1985 { 1986 CALLED(); 1987 1988 device_attr attrs[] = { 1989 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {.string = "USB Disk"} }, 1990 { NULL } 1991 }; 1992 1993 return gDeviceManager->register_node(node, USB_DISK_DRIVER_MODULE_NAME, 1994 attrs, NULL, NULL); 1995 } 1996 1997 1998 static status_t 1999 usb_disk_init_driver(device_node *node, void **cookie) 2000 { 2001 CALLED(); 2002 2003 usb_device usb_device; 2004 if (gDeviceManager->get_attr_uint32(node, USB_DEVICE_ID_ITEM, &usb_device, true) != B_OK) 2005 return B_BAD_VALUE; 2006 2007 return usb_disk_attach(node, usb_device, cookie); 2008 } 2009 2010 2011 static void 2012 usb_disk_uninit_driver(void *_cookie) 2013 { 2014 CALLED(); 2015 // Nothing to do. 2016 } 2017 2018 2019 static status_t 2020 usb_disk_register_child_devices(void* _cookie) 2021 { 2022 CALLED(); 2023 disk_device *device = (disk_device *)_cookie; 2024 2025 device->number = gDeviceManager->create_id(USB_DISK_DEVICE_ID_GENERATOR); 2026 if (device->number < 0) 2027 return device->number; 2028 2029 status_t status = B_OK; 2030 for (uint8 i = 0; i < device->lun_count; i++) { 2031 sprintf(device->luns[i]->name, DEVICE_NAME, device->number, i); 2032 status = gDeviceManager->publish_device(device->node, device->luns[i]->name, 2033 USB_DISK_DEVICE_MODULE_NAME); 2034 } 2035 2036 return status; 2037 } 2038 2039 2040 // #pragma mark - 2041 2042 2043 module_dependency module_dependencies[] = { 2044 { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager }, 2045 { B_USB_MODULE_NAME, (module_info**)&gUSBModule}, 2046 { NULL } 2047 }; 2048 2049 struct device_module_info sUsbDiskDevice = { 2050 { 2051 USB_DISK_DEVICE_MODULE_NAME, 2052 0, 2053 NULL 2054 }, 2055 2056 usb_disk_init_device, 2057 usb_disk_uninit_device, 2058 usb_disk_device_removed, 2059 2060 usb_disk_open, 2061 usb_disk_close, 2062 usb_disk_free, 2063 NULL, // read 2064 NULL, // write 2065 usb_disk_io, 2066 usb_disk_ioctl, 2067 2068 NULL, // select 2069 NULL, // deselect 2070 }; 2071 2072 struct driver_module_info sUsbDiskDriver = { 2073 { 2074 USB_DISK_DRIVER_MODULE_NAME, 2075 0, 2076 NULL 2077 }, 2078 2079 usb_disk_supports_device, 2080 usb_disk_register_device, 2081 usb_disk_init_driver, 2082 usb_disk_uninit_driver, 2083 usb_disk_register_child_devices, 2084 NULL, // rescan 2085 NULL, // removed 2086 }; 2087 2088 module_info* modules[] = { 2089 (module_info*)&sUsbDiskDriver, 2090 (module_info*)&sUsbDiskDevice, 2091 NULL 2092 }; 2093