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 1218 if (device->is_ufi) 1219 gUSBModule->cancel_queued_transfers(device->interrupt); 1220 usb_disk_free_device_and_luns(device); 1221 return result; 1222 } 1223 1224 mutex_unlock(&device->lock); 1225 recursive_lock_unlock(&device->io_lock); 1226 1227 TRACE("new device: 0x%p\n", device); 1228 *cookie = (void *)device; 1229 return B_OK; 1230 } 1231 1232 1233 static void 1234 usb_disk_device_removed(void *cookie) 1235 { 1236 TRACE("device_removed(0x%p)\n", cookie); 1237 disk_device *device = (disk_device *)cookie; 1238 mutex_lock(&device->lock); 1239 1240 for (uint8 i = 0; i < device->lun_count; i++) { 1241 // unpublish_device() can call close(). 1242 mutex_unlock(&device->lock); 1243 gDeviceManager->unpublish_device(device->node, device->luns[i]->name); 1244 mutex_lock(&device->lock); 1245 } 1246 1247 device->removed = true; 1248 gUSBModule->cancel_queued_transfers(device->bulk_in); 1249 gUSBModule->cancel_queued_transfers(device->bulk_out); 1250 if (device->is_ufi) 1251 gUSBModule->cancel_queued_transfers(device->interrupt); 1252 1253 // At this point, open_count should always be 0 anyway. 1254 if (device->open_count == 0) 1255 usb_disk_free_device_and_luns(device); 1256 else 1257 mutex_unlock(&device->lock); 1258 } 1259 1260 1261 static bool 1262 usb_disk_needs_bounce(device_lun *lun, io_request *request) 1263 { 1264 if (!request->Buffer()->IsVirtual()) 1265 return true; 1266 if ((request->Offset() % lun->block_size) != 0) 1267 return true; 1268 if ((request->Length() % lun->block_size) != 0) 1269 return true; 1270 if (request->Length() > (lun->block_size * MAX_IO_BLOCKS)) 1271 return true; 1272 return false; 1273 } 1274 1275 1276 static status_t 1277 usb_disk_block_read(device_lun *lun, uint64 blockPosition, size_t blockCount, 1278 struct transfer_data data, size_t *length) 1279 { 1280 uint8 commandBlock[16]; 1281 memset(commandBlock, 0, sizeof(commandBlock)); 1282 if (lun->device->is_ufi) { 1283 commandBlock[0] = SCSI_READ_12; 1284 commandBlock[1] = lun->logical_unit_number << 5; 1285 commandBlock[2] = blockPosition >> 24; 1286 commandBlock[3] = blockPosition >> 16; 1287 commandBlock[4] = blockPosition >> 8; 1288 commandBlock[5] = blockPosition; 1289 commandBlock[6] = blockCount >> 24; 1290 commandBlock[7] = blockCount >> 16; 1291 commandBlock[8] = blockCount >> 8; 1292 commandBlock[9] = blockCount; 1293 1294 status_t result = B_OK; 1295 for (int tries = 0; tries < 5; tries++) { 1296 result = usb_disk_operation(lun, commandBlock, 12, data, 1297 length, true); 1298 if (result == B_OK) 1299 break; 1300 else 1301 snooze(10000); 1302 } 1303 return result; 1304 } else if (blockPosition + blockCount < 0x100000000LL && blockCount <= 0x10000) { 1305 commandBlock[0] = SCSI_READ_10; 1306 commandBlock[1] = 0; 1307 commandBlock[2] = blockPosition >> 24; 1308 commandBlock[3] = blockPosition >> 16; 1309 commandBlock[4] = blockPosition >> 8; 1310 commandBlock[5] = blockPosition; 1311 commandBlock[7] = blockCount >> 8; 1312 commandBlock[8] = blockCount; 1313 status_t result = usb_disk_operation(lun, commandBlock, 10, 1314 data, length, true); 1315 return result; 1316 } else { 1317 commandBlock[0] = SCSI_READ_16; 1318 commandBlock[1] = 0; 1319 commandBlock[2] = blockPosition >> 56; 1320 commandBlock[3] = blockPosition >> 48; 1321 commandBlock[4] = blockPosition >> 40; 1322 commandBlock[5] = blockPosition >> 32; 1323 commandBlock[6] = blockPosition >> 24; 1324 commandBlock[7] = blockPosition >> 16; 1325 commandBlock[8] = blockPosition >> 8; 1326 commandBlock[9] = blockPosition; 1327 commandBlock[10] = blockCount >> 24; 1328 commandBlock[11] = blockCount >> 16; 1329 commandBlock[12] = blockCount >> 8; 1330 commandBlock[13] = blockCount; 1331 status_t result = usb_disk_operation(lun, commandBlock, 16, 1332 data, length, true); 1333 return result; 1334 } 1335 } 1336 1337 1338 static status_t 1339 usb_disk_block_write(device_lun *lun, uint64 blockPosition, size_t blockCount, 1340 struct transfer_data data, size_t *length) 1341 { 1342 uint8 commandBlock[16]; 1343 memset(commandBlock, 0, sizeof(commandBlock)); 1344 1345 if (lun->device->is_ufi) { 1346 commandBlock[0] = SCSI_WRITE_12; 1347 commandBlock[1] = lun->logical_unit_number << 5; 1348 commandBlock[2] = blockPosition >> 24; 1349 commandBlock[3] = blockPosition >> 16; 1350 commandBlock[4] = blockPosition >> 8; 1351 commandBlock[5] = blockPosition; 1352 commandBlock[6] = blockCount >> 24; 1353 commandBlock[7] = blockCount >> 16; 1354 commandBlock[8] = blockCount >> 8; 1355 commandBlock[9] = blockCount; 1356 1357 status_t result; 1358 result = usb_disk_operation(lun, commandBlock, 12, 1359 data, length, false); 1360 1361 int retry = 10; 1362 err_act action = err_act_ok; 1363 while (result == B_DEV_NO_MEDIA && retry > 0) { 1364 snooze(10000); 1365 result = usb_disk_request_sense(lun, &action); 1366 retry--; 1367 } 1368 1369 if (result == B_OK) 1370 lun->should_sync = true; 1371 return result; 1372 } else if (blockPosition + blockCount < 0x100000000LL && blockCount <= 0x10000) { 1373 commandBlock[0] = SCSI_WRITE_10; 1374 commandBlock[2] = blockPosition >> 24; 1375 commandBlock[3] = blockPosition >> 16; 1376 commandBlock[4] = blockPosition >> 8; 1377 commandBlock[5] = blockPosition; 1378 commandBlock[7] = blockCount >> 8; 1379 commandBlock[8] = blockCount; 1380 status_t result = usb_disk_operation(lun, commandBlock, 10, 1381 data, length, false); 1382 if (result == B_OK) 1383 lun->should_sync = true; 1384 return result; 1385 } else { 1386 commandBlock[0] = SCSI_WRITE_16; 1387 commandBlock[1] = 0; 1388 commandBlock[2] = blockPosition >> 56; 1389 commandBlock[3] = blockPosition >> 48; 1390 commandBlock[4] = blockPosition >> 40; 1391 commandBlock[5] = blockPosition >> 32; 1392 commandBlock[6] = blockPosition >> 24; 1393 commandBlock[7] = blockPosition >> 16; 1394 commandBlock[8] = blockPosition >> 8; 1395 commandBlock[9] = blockPosition; 1396 commandBlock[10] = blockCount >> 24; 1397 commandBlock[11] = blockCount >> 16; 1398 commandBlock[12] = blockCount >> 8; 1399 commandBlock[13] = blockCount; 1400 status_t result = usb_disk_operation(lun, commandBlock, 16, 1401 data, length, false); 1402 if (result == B_OK) 1403 lun->should_sync = true; 1404 return result; 1405 } 1406 } 1407 1408 1409 // 1410 //#pragma mark - Driver Hooks 1411 // 1412 1413 1414 static status_t 1415 usb_disk_init_device(void* _info, void** _cookie) 1416 { 1417 CALLED(); 1418 *_cookie = _info; 1419 return B_OK; 1420 } 1421 1422 1423 static void 1424 usb_disk_uninit_device(void* _cookie) 1425 { 1426 // Nothing to do. 1427 } 1428 1429 1430 static status_t 1431 usb_disk_open(void *deviceCookie, const char *path, int flags, void **_cookie) 1432 { 1433 TRACE("open(%s)\n", path); 1434 if (strncmp(path, DEVICE_NAME_BASE, strlen(DEVICE_NAME_BASE)) != 0) 1435 return B_NAME_NOT_FOUND; 1436 1437 int32 lastPart = 0; 1438 size_t nameLength = strlen(path); 1439 for (int32 i = nameLength - 1; i >= 0; i--) { 1440 if (path[i] == '/') { 1441 lastPart = i; 1442 break; 1443 } 1444 } 1445 1446 char rawName[nameLength + 4]; 1447 strncpy(rawName, path, lastPart + 1); 1448 rawName[lastPart + 1] = 0; 1449 strcat(rawName, "raw"); 1450 1451 disk_device *device = (disk_device *)deviceCookie; 1452 MutexLocker locker(device->lock); 1453 for (uint8 i = 0; i < device->lun_count; i++) { 1454 device_lun *lun = device->luns[i]; 1455 if (strncmp(rawName, lun->name, 32) == 0) { 1456 // found the matching device/lun 1457 if (device->removed) 1458 return B_ERROR; 1459 1460 device->open_count++; 1461 *_cookie = lun; 1462 return B_OK; 1463 } 1464 } 1465 1466 return B_NAME_NOT_FOUND; 1467 } 1468 1469 1470 static status_t 1471 usb_disk_close(void *cookie) 1472 { 1473 TRACE("close()\n"); 1474 device_lun *lun = (device_lun *)cookie; 1475 disk_device *device = lun->device; 1476 1477 RecursiveLocker ioLocker(device->io_lock); 1478 MutexLocker deviceLocker(device->lock); 1479 1480 if (!device->removed) 1481 usb_disk_synchronize(lun, false); 1482 1483 return B_OK; 1484 } 1485 1486 1487 static status_t 1488 usb_disk_free(void *cookie) 1489 { 1490 TRACE("free()\n"); 1491 1492 device_lun *lun = (device_lun *)cookie; 1493 disk_device *device = lun->device; 1494 mutex_lock(&device->lock); 1495 1496 device->open_count--; 1497 if (device->open_count == 0 && device->removed) { 1498 // we can simply free the device here as it has been removed from 1499 // the device list in the device removed notification hook 1500 usb_disk_free_device_and_luns(device); 1501 } else { 1502 mutex_unlock(&device->lock); 1503 } 1504 1505 return B_OK; 1506 } 1507 1508 1509 static inline void 1510 normalize_name(char *name, size_t nameLength) 1511 { 1512 bool wasSpace = false; 1513 size_t insertIndex = 0; 1514 for (size_t i = 0; i < nameLength; i++) { 1515 bool isSpace = name[i] == ' '; 1516 if (isSpace && wasSpace) 1517 continue; 1518 1519 name[insertIndex++] = name[i]; 1520 wasSpace = isSpace; 1521 } 1522 1523 if (insertIndex > 0 && name[insertIndex - 1] == ' ') 1524 insertIndex--; 1525 1526 name[insertIndex] = 0; 1527 } 1528 1529 1530 static status_t 1531 acquire_io_lock(disk_device *device, MutexLocker& locker, RecursiveLocker& ioLocker) 1532 { 1533 locker.Unlock(); 1534 ioLocker.SetTo(device->io_lock, false, true); 1535 locker.Lock(); 1536 1537 if (!locker.IsLocked() || !ioLocker.IsLocked()) 1538 return B_ERROR; 1539 1540 if (device->removed) 1541 return B_DEV_NOT_READY; 1542 1543 return B_OK; 1544 } 1545 1546 1547 static status_t 1548 handle_media_change(device_lun *lun, MutexLocker& locker) 1549 { 1550 RecursiveLocker ioLocker; 1551 status_t result = acquire_io_lock(lun->device, locker, ioLocker); 1552 if (result != B_OK) 1553 return result; 1554 1555 // It may have been handled while we were waiting for locks. 1556 if (lun->media_changed) { 1557 result = usb_disk_update_capacity(lun); 1558 if (result != B_OK) 1559 return result; 1560 } 1561 1562 return B_OK; 1563 } 1564 1565 1566 static status_t 1567 usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) 1568 { 1569 device_lun *lun = (device_lun *)cookie; 1570 disk_device *device = lun->device; 1571 MutexLocker locker(&device->lock); 1572 if (device->removed) 1573 return B_DEV_NOT_READY; 1574 RecursiveLocker ioLocker; 1575 1576 switch (op) { 1577 case B_GET_DEVICE_SIZE: 1578 { 1579 if (lun->media_changed) { 1580 status_t result = handle_media_change(lun, locker); 1581 if (result != B_OK) 1582 return result; 1583 } 1584 1585 size_t size = lun->block_size * lun->block_count; 1586 return user_memcpy(buffer, &size, sizeof(size)); 1587 } 1588 1589 case B_GET_MEDIA_STATUS: 1590 { 1591 status_t result = acquire_io_lock(lun->device, locker, ioLocker); 1592 if (result != B_OK) 1593 return result; 1594 1595 err_act action = err_act_ok; 1596 status_t ready; 1597 for (uint32 tries = 0; tries < 3; tries++) { 1598 ready = usb_disk_test_unit_ready(lun, &action); 1599 if (ready == B_OK || ready == B_DEV_NO_MEDIA 1600 || (action != err_act_retry 1601 && action != err_act_many_retries)) { 1602 if (IS_USER_ADDRESS(buffer)) { 1603 if (user_memcpy(buffer, &ready, sizeof(status_t)) != B_OK) 1604 return B_BAD_ADDRESS; 1605 } else if (is_called_via_syscall()) { 1606 return B_BAD_ADDRESS; 1607 } else 1608 *(status_t *)buffer = ready; 1609 break; 1610 } 1611 snooze(500000); 1612 } 1613 TRACE("B_GET_MEDIA_STATUS: 0x%08" B_PRIx32 "\n", ready); 1614 return B_OK; 1615 } 1616 1617 case B_GET_GEOMETRY: 1618 { 1619 if (buffer == NULL || length > sizeof(device_geometry)) 1620 return B_BAD_VALUE; 1621 if (lun->media_changed) { 1622 status_t result = handle_media_change(lun, locker); 1623 if (result != B_OK) 1624 return result; 1625 } 1626 1627 device_geometry geometry; 1628 devfs_compute_geometry_size(&geometry, lun->block_count, 1629 lun->block_size); 1630 geometry.bytes_per_physical_sector = lun->physical_block_size; 1631 1632 geometry.device_type = lun->device_type; 1633 geometry.removable = lun->removable; 1634 geometry.read_only = lun->write_protected; 1635 geometry.write_once = lun->device_type == B_WORM; 1636 TRACE("B_GET_GEOMETRY: %" B_PRId32 " sectors at %" B_PRId32 1637 " bytes per sector\n", geometry.cylinder_count, 1638 geometry.bytes_per_sector); 1639 return user_memcpy(buffer, &geometry, length); 1640 } 1641 1642 case B_FLUSH_DRIVE_CACHE: 1643 { 1644 TRACE("B_FLUSH_DRIVE_CACHE\n"); 1645 1646 status_t result = acquire_io_lock(lun->device, locker, ioLocker); 1647 if (result != B_OK) 1648 return result; 1649 1650 return usb_disk_synchronize(lun, true); 1651 } 1652 1653 case B_EJECT_DEVICE: 1654 { 1655 status_t result = acquire_io_lock(lun->device, locker, ioLocker); 1656 if (result != B_OK) 1657 return result; 1658 1659 uint8 commandBlock[12]; 1660 memset(commandBlock, 0, sizeof(commandBlock)); 1661 1662 commandBlock[0] = SCSI_START_STOP_UNIT_6; 1663 commandBlock[1] = lun->logical_unit_number << 5; 1664 commandBlock[4] = 2; 1665 1666 return usb_disk_operation(lun, commandBlock, 6, NULL, NULL, 1667 false); 1668 } 1669 1670 case B_LOAD_MEDIA: 1671 { 1672 status_t result = acquire_io_lock(lun->device, locker, ioLocker); 1673 if (result != B_OK) 1674 return result; 1675 1676 uint8 commandBlock[12]; 1677 memset(commandBlock, 0, sizeof(commandBlock)); 1678 1679 commandBlock[0] = SCSI_START_STOP_UNIT_6; 1680 commandBlock[1] = lun->logical_unit_number << 5; 1681 commandBlock[4] = 3; 1682 1683 return usb_disk_operation(lun, commandBlock, 6, NULL, NULL, 1684 false); 1685 } 1686 1687 case B_GET_ICON: 1688 // We don't support this legacy ioctl anymore, but the two other 1689 // icon ioctls below instead. 1690 break; 1691 1692 case B_GET_ICON_NAME: 1693 { 1694 const char *iconName = "devices/drive-removable-media-usb"; 1695 char vendor[sizeof(lun->vendor_name)+1]; 1696 char product[sizeof(lun->product_name)+1]; 1697 1698 if (device->is_ufi) { 1699 iconName = "devices/drive-floppy-usb"; 1700 } 1701 1702 switch (lun->device_type) { 1703 case B_CD: 1704 case B_OPTICAL: 1705 iconName = "devices/drive-optical"; 1706 break; 1707 case B_TAPE: // TODO 1708 default: 1709 snprintf(vendor, sizeof(vendor), "%.8s", 1710 lun->vendor_name); 1711 snprintf(product, sizeof(product), "%.16s", 1712 lun->product_name); 1713 for (int i = 0; kIconMatches[i].icon; i++) { 1714 if (kIconMatches[i].vendor != NULL 1715 && strstr(vendor, kIconMatches[i].vendor) == NULL) 1716 continue; 1717 if (kIconMatches[i].product != NULL 1718 && strstr(product, kIconMatches[i].product) == NULL) 1719 continue; 1720 iconName = kIconMatches[i].name; 1721 } 1722 break; 1723 } 1724 return user_strlcpy((char *)buffer, iconName, 1725 B_FILE_NAME_LENGTH); 1726 } 1727 1728 case B_GET_VECTOR_ICON: 1729 { 1730 device_icon *icon = &kKeyIconData; 1731 char vendor[sizeof(lun->vendor_name)+1]; 1732 char product[sizeof(lun->product_name)+1]; 1733 1734 if (length != sizeof(device_icon)) 1735 return B_BAD_VALUE; 1736 1737 if (device->is_ufi) { 1738 // UFI is specific for floppy drives 1739 icon = &kFloppyIconData; 1740 } else { 1741 switch (lun->device_type) { 1742 case B_CD: 1743 case B_OPTICAL: 1744 icon = &kCDIconData; 1745 break; 1746 case B_TAPE: // TODO 1747 default: 1748 snprintf(vendor, sizeof(vendor), "%.8s", 1749 lun->vendor_name); 1750 snprintf(product, sizeof(product), "%.16s", 1751 lun->product_name); 1752 for (int i = 0; kIconMatches[i].icon; i++) { 1753 if (kIconMatches[i].vendor != NULL 1754 && strstr(vendor, 1755 kIconMatches[i].vendor) == NULL) 1756 continue; 1757 if (kIconMatches[i].product != NULL 1758 && strstr(product, 1759 kIconMatches[i].product) == NULL) 1760 continue; 1761 icon = kIconMatches[i].icon; 1762 } 1763 break; 1764 } 1765 } 1766 1767 device_icon iconData; 1768 if (user_memcpy(&iconData, buffer, sizeof(device_icon)) != B_OK) 1769 return B_BAD_ADDRESS; 1770 1771 if (iconData.icon_size >= icon->icon_size) { 1772 if (user_memcpy(iconData.icon_data, icon->icon_data, 1773 (size_t)icon->icon_size) != B_OK) 1774 return B_BAD_ADDRESS; 1775 } 1776 1777 iconData.icon_size = icon->icon_size; 1778 return user_memcpy(buffer, &iconData, sizeof(device_icon)); 1779 } 1780 1781 case B_GET_DEVICE_NAME: 1782 { 1783 size_t nameLength = sizeof(lun->vendor_name) 1784 + sizeof(lun->product_name) + sizeof(lun->product_revision) + 3; 1785 1786 char name[nameLength]; 1787 snprintf(name, nameLength, "%.8s %.16s %.4s", lun->vendor_name, 1788 lun->product_name, lun->product_revision); 1789 1790 normalize_name(name, nameLength); 1791 1792 status_t result = user_strlcpy((char *)buffer, name, length); 1793 if (result > 0) 1794 result = B_OK; 1795 1796 TRACE_ALWAYS("got device name \"%s\": %s\n", name, 1797 strerror(result)); 1798 return result; 1799 } 1800 } 1801 1802 TRACE_ALWAYS("unhandled ioctl %" B_PRId32 "\n", op); 1803 return B_DEV_INVALID_IOCTL; 1804 } 1805 1806 1807 static status_t 1808 usb_disk_bounced_io(device_lun *lun, io_request *request) 1809 { 1810 DMAResource* dmaResource = get_dma_resource(lun->device, lun->block_size); 1811 if (dmaResource == NULL) 1812 return B_NO_INIT; 1813 1814 if (!request->Buffer()->IsPhysical()) { 1815 status_t status = request->Buffer()->LockMemory(request->TeamID(), request->IsWrite()); 1816 if (status != B_OK) { 1817 TRACE_ALWAYS("failed to lock memory: %s\n", strerror(status)); 1818 return status; 1819 } 1820 // SetStatusAndNotify() takes care of unlocking memory if necessary. 1821 } 1822 1823 status_t status = B_OK; 1824 while (request->RemainingBytes() > 0) { 1825 IOOperation operation; 1826 status = dmaResource->TranslateNext(request, &operation, 0); 1827 if (status != B_OK) 1828 break; 1829 1830 do { 1831 TRACE("%p: IOO offset: %" B_PRIdOFF ", length: %" B_PRIuGENADDR 1832 ", write: %s\n", request, operation.Offset(), 1833 operation.Length(), operation.IsWrite() ? "yes" : "no"); 1834 1835 struct transfer_data data; 1836 data.physical = true; 1837 data.phys_vecs = (physical_entry*)operation.Vecs(); 1838 data.vec_count = operation.VecCount(); 1839 1840 size_t length = operation.Length(); 1841 const uint64 blockPosition = operation.Offset() / lun->block_size; 1842 const size_t blockCount = length / lun->block_size; 1843 if (operation.IsWrite()) { 1844 status = usb_disk_block_write(lun, 1845 blockPosition, blockCount, data, &length); 1846 } else { 1847 status = usb_disk_block_read(lun, 1848 blockPosition, blockCount, data, &length); 1849 } 1850 1851 operation.SetStatus(status, length); 1852 } while (status == B_OK && !operation.Finish()); 1853 1854 if (status == B_OK && operation.Status() != B_OK) { 1855 TRACE_ALWAYS("I/O succeeded but IOOperation failed!\n"); 1856 status = operation.Status(); 1857 } 1858 1859 request->OperationFinished(&operation); 1860 dmaResource->RecycleBuffer(operation.Buffer()); 1861 1862 TRACE("%p: status %s, remaining bytes %" B_PRIuGENADDR "\n", request, 1863 strerror(status), request->RemainingBytes()); 1864 if (status != B_OK) 1865 break; 1866 } 1867 1868 return status; 1869 } 1870 1871 1872 static status_t 1873 usb_disk_direct_io(device_lun *lun, io_request *request) 1874 { 1875 generic_io_vec* genericVecs = request->Buffer()->Vecs(); 1876 const uint32 count = request->Buffer()->VecCount(); 1877 BStackOrHeapArray<iovec, 16> vecs(count); 1878 for (uint32 i = 0; i < count; i++) { 1879 vecs[i].iov_base = (void*)genericVecs[i].base; 1880 vecs[i].iov_len = genericVecs[i].length; 1881 } 1882 struct transfer_data data; 1883 data.vecs = vecs; 1884 data.vec_count = count; 1885 1886 size_t length = request->Length(); 1887 const uint64 blockPosition = request->Offset() / lun->block_size; 1888 const size_t blockCount = length / lun->block_size; 1889 1890 status_t status; 1891 if (request->IsWrite()) { 1892 status = usb_disk_block_write(lun, 1893 blockPosition, blockCount, data, &length); 1894 } else { 1895 status = usb_disk_block_read(lun, 1896 blockPosition, blockCount, data, &length); 1897 } 1898 1899 request->SetTransferredBytes(length != request->Length(), length); 1900 return status; 1901 } 1902 1903 1904 static status_t 1905 usb_disk_io(void *cookie, io_request *request) 1906 { 1907 TRACE("io(%p)\n", request); 1908 1909 device_lun *lun = (device_lun *)cookie; 1910 disk_device *device = lun->device; 1911 1912 RecursiveLocker ioLocker(device->io_lock); 1913 MutexLocker deviceLocker(device->lock); 1914 1915 if (device->removed) 1916 return B_DEV_NOT_READY; 1917 1918 status_t status; 1919 if (!usb_disk_needs_bounce(lun, request)) { 1920 status = usb_disk_direct_io(lun, request); 1921 } else { 1922 status = usb_disk_bounced_io(lun, request); 1923 } 1924 1925 deviceLocker.Unlock(); 1926 ioLocker.Unlock(); 1927 1928 if (request->Status() > 0) 1929 request->SetStatusAndNotify(status); 1930 else 1931 request->NotifyFinished(); 1932 return status; 1933 } 1934 1935 1936 // #pragma mark - driver module API 1937 1938 1939 static float 1940 usb_disk_supports_device(device_node *parent) 1941 { 1942 CALLED(); 1943 const char *bus; 1944 1945 // make sure parent is really the usb bus manager 1946 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false)) 1947 return -1; 1948 if (strcmp(bus, "usb") != 0) 1949 return 0.0; 1950 1951 usb_device device; 1952 if (gDeviceManager->get_attr_uint32(parent, USB_DEVICE_ID_ITEM, &device, true) != B_OK) 1953 return -1; 1954 1955 const usb_configuration_info *configuration = gUSBModule->get_configuration(device); 1956 if (configuration == NULL) 1957 return -1; 1958 1959 static usb_support_descriptor supportedDevices[] = { 1960 { USB_MASS_STORAGE_DEVICE_CLASS, 0x06 /* SCSI */, 0x50 /* bulk */, 0, 0 }, 1961 { USB_MASS_STORAGE_DEVICE_CLASS, 0x02 /* ATAPI */, 0x50 /* bulk */, 0, 0 }, 1962 { USB_MASS_STORAGE_DEVICE_CLASS, 0x05 /* ATAPI */, 0x50 /* bulk */, 0, 0 }, 1963 { USB_MASS_STORAGE_DEVICE_CLASS, 0x04 /* UFI */, 0x00, 0, 0 } 1964 }; 1965 1966 for (size_t i = 0; i < configuration->interface_count; i++) { 1967 usb_interface_info *interface = configuration->interface[i].active; 1968 if (interface == NULL) 1969 continue; 1970 1971 for (size_t i = 0; i < B_COUNT_OF(supportedDevices); i++) { 1972 if (interface->descr->interface_class != supportedDevices[i].dev_class) 1973 continue; 1974 if (interface->descr->interface_subclass != supportedDevices[i].dev_subclass) 1975 continue; 1976 if (interface->descr->interface_protocol != supportedDevices[i].dev_protocol) 1977 continue; 1978 1979 TRACE("USB disk device found!\n"); 1980 return 0.6; 1981 } 1982 } 1983 1984 return 0.0; 1985 } 1986 1987 1988 static status_t 1989 usb_disk_register_device(device_node *node) 1990 { 1991 CALLED(); 1992 1993 device_attr attrs[] = { 1994 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {.string = "USB Disk"} }, 1995 { NULL } 1996 }; 1997 1998 return gDeviceManager->register_node(node, USB_DISK_DRIVER_MODULE_NAME, 1999 attrs, NULL, NULL); 2000 } 2001 2002 2003 static status_t 2004 usb_disk_init_driver(device_node *node, void **cookie) 2005 { 2006 CALLED(); 2007 2008 usb_device usb_device; 2009 if (gDeviceManager->get_attr_uint32(node, USB_DEVICE_ID_ITEM, &usb_device, true) != B_OK) 2010 return B_BAD_VALUE; 2011 2012 return usb_disk_attach(node, usb_device, cookie); 2013 } 2014 2015 2016 static void 2017 usb_disk_uninit_driver(void *_cookie) 2018 { 2019 CALLED(); 2020 // Nothing to do. 2021 } 2022 2023 2024 static status_t 2025 usb_disk_register_child_devices(void* _cookie) 2026 { 2027 CALLED(); 2028 disk_device *device = (disk_device *)_cookie; 2029 2030 device->number = gDeviceManager->create_id(USB_DISK_DEVICE_ID_GENERATOR); 2031 if (device->number < 0) 2032 return device->number; 2033 2034 status_t status = B_OK; 2035 for (uint8 i = 0; i < device->lun_count; i++) { 2036 sprintf(device->luns[i]->name, DEVICE_NAME, device->number, i); 2037 status = gDeviceManager->publish_device(device->node, device->luns[i]->name, 2038 USB_DISK_DEVICE_MODULE_NAME); 2039 } 2040 2041 return status; 2042 } 2043 2044 2045 // #pragma mark - 2046 2047 2048 module_dependency module_dependencies[] = { 2049 { B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&gDeviceManager }, 2050 { B_USB_MODULE_NAME, (module_info**)&gUSBModule}, 2051 { NULL } 2052 }; 2053 2054 struct device_module_info sUsbDiskDevice = { 2055 { 2056 USB_DISK_DEVICE_MODULE_NAME, 2057 0, 2058 NULL 2059 }, 2060 2061 usb_disk_init_device, 2062 usb_disk_uninit_device, 2063 usb_disk_device_removed, 2064 2065 usb_disk_open, 2066 usb_disk_close, 2067 usb_disk_free, 2068 NULL, // read 2069 NULL, // write 2070 usb_disk_io, 2071 usb_disk_ioctl, 2072 2073 NULL, // select 2074 NULL, // deselect 2075 }; 2076 2077 struct driver_module_info sUsbDiskDriver = { 2078 { 2079 USB_DISK_DRIVER_MODULE_NAME, 2080 0, 2081 NULL 2082 }, 2083 2084 usb_disk_supports_device, 2085 usb_disk_register_device, 2086 usb_disk_init_driver, 2087 usb_disk_uninit_driver, 2088 usb_disk_register_child_devices, 2089 NULL, // rescan 2090 NULL, // removed 2091 }; 2092 2093 module_info* modules[] = { 2094 (module_info*)&sUsbDiskDriver, 2095 (module_info*)&sUsbDiskDevice, 2096 NULL 2097 }; 2098