diff options
Diffstat (limited to 'drivers/usb/storage/usb.c')
| -rw-r--r-- | drivers/usb/storage/usb.c | 344 |
1 files changed, 114 insertions, 230 deletions
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 4becf495ca2d..8060b85fe1a3 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Developed with the assistance of: | 6 | * Developed with the assistance of: |
| 7 | * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org) | 7 | * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org) |
| 8 | * (c) 2003 Alan Stern (stern@rowland.harvard.edu) | 8 | * (c) 2003-2009 Alan Stern (stern@rowland.harvard.edu) |
| 9 | * | 9 | * |
| 10 | * Initial work by: | 10 | * Initial work by: |
| 11 | * (c) 1999 Michael Gee (michael@linuxspecific.com) | 11 | * (c) 1999 Michael Gee (michael@linuxspecific.com) |
| @@ -66,39 +66,6 @@ | |||
| 66 | #include "debug.h" | 66 | #include "debug.h" |
| 67 | #include "initializers.h" | 67 | #include "initializers.h" |
| 68 | 68 | ||
| 69 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
| 70 | #include "shuttle_usbat.h" | ||
| 71 | #endif | ||
| 72 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
| 73 | #include "sddr09.h" | ||
| 74 | #endif | ||
| 75 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
| 76 | #include "sddr55.h" | ||
| 77 | #endif | ||
| 78 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
| 79 | #include "freecom.h" | ||
| 80 | #endif | ||
| 81 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
| 82 | #include "isd200.h" | ||
| 83 | #endif | ||
| 84 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
| 85 | #include "datafab.h" | ||
| 86 | #endif | ||
| 87 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
| 88 | #include "jumpshot.h" | ||
| 89 | #endif | ||
| 90 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | ||
| 91 | #include "onetouch.h" | ||
| 92 | #endif | ||
| 93 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 94 | #include "alauda.h" | ||
| 95 | #endif | ||
| 96 | #ifdef CONFIG_USB_STORAGE_KARMA | ||
| 97 | #include "karma.h" | ||
| 98 | #endif | ||
| 99 | #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB | ||
| 100 | #include "cypress_atacb.h" | ||
| 101 | #endif | ||
| 102 | #include "sierra_ms.h" | 69 | #include "sierra_ms.h" |
| 103 | #include "option_ms.h" | 70 | #include "option_ms.h" |
| 104 | 71 | ||
| @@ -118,36 +85,8 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks"); | |||
| 118 | 85 | ||
| 119 | /* | 86 | /* |
| 120 | * The entries in this table correspond, line for line, | 87 | * The entries in this table correspond, line for line, |
| 121 | * with the entries of us_unusual_dev_list[]. | 88 | * with the entries in usb_storage_usb_ids[], defined in usual-tables.c. |
| 122 | */ | 89 | */ |
| 123 | #ifndef CONFIG_USB_LIBUSUAL | ||
| 124 | |||
| 125 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 126 | vendorName, productName,useProtocol, useTransport, \ | ||
| 127 | initFunction, flags) \ | ||
| 128 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ | ||
| 129 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 130 | |||
| 131 | #define COMPLIANT_DEV UNUSUAL_DEV | ||
| 132 | |||
| 133 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
| 134 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
| 135 | .driver_info = (USB_US_TYPE_STOR<<24) } | ||
| 136 | |||
| 137 | static struct usb_device_id storage_usb_ids [] = { | ||
| 138 | |||
| 139 | # include "unusual_devs.h" | ||
| 140 | #undef UNUSUAL_DEV | ||
| 141 | #undef COMPLIANT_DEV | ||
| 142 | #undef USUAL_DEV | ||
| 143 | /* Terminating entry */ | ||
| 144 | { } | ||
| 145 | }; | ||
| 146 | |||
| 147 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); | ||
| 148 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
| 149 | |||
| 150 | /* This is the list of devices we recognize, along with their flag data */ | ||
| 151 | 90 | ||
| 152 | /* The vendor name should be kept at eight characters or less, and | 91 | /* The vendor name should be kept at eight characters or less, and |
| 153 | * the product name should be kept at 16 characters or less. If a device | 92 | * the product name should be kept at 16 characters or less. If a device |
| @@ -179,18 +118,17 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
| 179 | 118 | ||
| 180 | static struct us_unusual_dev us_unusual_dev_list[] = { | 119 | static struct us_unusual_dev us_unusual_dev_list[] = { |
| 181 | # include "unusual_devs.h" | 120 | # include "unusual_devs.h" |
| 182 | # undef UNUSUAL_DEV | 121 | { } /* Terminating entry */ |
| 183 | # undef COMPLIANT_DEV | ||
| 184 | # undef USUAL_DEV | ||
| 185 | |||
| 186 | /* Terminating entry */ | ||
| 187 | { NULL } | ||
| 188 | }; | 122 | }; |
| 189 | 123 | ||
| 124 | #undef UNUSUAL_DEV | ||
| 125 | #undef COMPLIANT_DEV | ||
| 126 | #undef USUAL_DEV | ||
| 127 | |||
| 190 | 128 | ||
| 191 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ | 129 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ |
| 192 | 130 | ||
| 193 | static int storage_suspend(struct usb_interface *iface, pm_message_t message) | 131 | int usb_stor_suspend(struct usb_interface *iface, pm_message_t message) |
| 194 | { | 132 | { |
| 195 | struct us_data *us = usb_get_intfdata(iface); | 133 | struct us_data *us = usb_get_intfdata(iface); |
| 196 | 134 | ||
| @@ -207,8 +145,9 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) | |||
| 207 | mutex_unlock(&us->dev_mutex); | 145 | mutex_unlock(&us->dev_mutex); |
| 208 | return 0; | 146 | return 0; |
| 209 | } | 147 | } |
| 148 | EXPORT_SYMBOL_GPL(usb_stor_suspend); | ||
| 210 | 149 | ||
| 211 | static int storage_resume(struct usb_interface *iface) | 150 | int usb_stor_resume(struct usb_interface *iface) |
| 212 | { | 151 | { |
| 213 | struct us_data *us = usb_get_intfdata(iface); | 152 | struct us_data *us = usb_get_intfdata(iface); |
| 214 | 153 | ||
| @@ -221,8 +160,9 @@ static int storage_resume(struct usb_interface *iface) | |||
| 221 | mutex_unlock(&us->dev_mutex); | 160 | mutex_unlock(&us->dev_mutex); |
| 222 | return 0; | 161 | return 0; |
| 223 | } | 162 | } |
| 163 | EXPORT_SYMBOL_GPL(usb_stor_resume); | ||
| 224 | 164 | ||
| 225 | static int storage_reset_resume(struct usb_interface *iface) | 165 | int usb_stor_reset_resume(struct usb_interface *iface) |
| 226 | { | 166 | { |
| 227 | struct us_data *us = usb_get_intfdata(iface); | 167 | struct us_data *us = usb_get_intfdata(iface); |
| 228 | 168 | ||
| @@ -235,6 +175,7 @@ static int storage_reset_resume(struct usb_interface *iface) | |||
| 235 | * the device */ | 175 | * the device */ |
| 236 | return 0; | 176 | return 0; |
| 237 | } | 177 | } |
| 178 | EXPORT_SYMBOL_GPL(usb_stor_reset_resume); | ||
| 238 | 179 | ||
| 239 | #endif /* CONFIG_PM */ | 180 | #endif /* CONFIG_PM */ |
| 240 | 181 | ||
| @@ -243,7 +184,7 @@ static int storage_reset_resume(struct usb_interface *iface) | |||
| 243 | * a USB port reset, whether from this driver or a different one. | 184 | * a USB port reset, whether from this driver or a different one. |
| 244 | */ | 185 | */ |
| 245 | 186 | ||
| 246 | static int storage_pre_reset(struct usb_interface *iface) | 187 | int usb_stor_pre_reset(struct usb_interface *iface) |
| 247 | { | 188 | { |
| 248 | struct us_data *us = usb_get_intfdata(iface); | 189 | struct us_data *us = usb_get_intfdata(iface); |
| 249 | 190 | ||
| @@ -253,8 +194,9 @@ static int storage_pre_reset(struct usb_interface *iface) | |||
| 253 | mutex_lock(&us->dev_mutex); | 194 | mutex_lock(&us->dev_mutex); |
| 254 | return 0; | 195 | return 0; |
| 255 | } | 196 | } |
| 197 | EXPORT_SYMBOL_GPL(usb_stor_pre_reset); | ||
| 256 | 198 | ||
| 257 | static int storage_post_reset(struct usb_interface *iface) | 199 | int usb_stor_post_reset(struct usb_interface *iface) |
| 258 | { | 200 | { |
| 259 | struct us_data *us = usb_get_intfdata(iface); | 201 | struct us_data *us = usb_get_intfdata(iface); |
| 260 | 202 | ||
| @@ -269,6 +211,7 @@ static int storage_post_reset(struct usb_interface *iface) | |||
| 269 | mutex_unlock(&us->dev_mutex); | 211 | mutex_unlock(&us->dev_mutex); |
| 270 | return 0; | 212 | return 0; |
| 271 | } | 213 | } |
| 214 | EXPORT_SYMBOL_GPL(usb_stor_post_reset); | ||
| 272 | 215 | ||
| 273 | /* | 216 | /* |
| 274 | * fill_inquiry_response takes an unsigned char array (which must | 217 | * fill_inquiry_response takes an unsigned char array (which must |
| @@ -311,6 +254,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data, | |||
| 311 | 254 | ||
| 312 | usb_stor_set_xfer_buf(data, data_len, us->srb); | 255 | usb_stor_set_xfer_buf(data, data_len, us->srb); |
| 313 | } | 256 | } |
| 257 | EXPORT_SYMBOL_GPL(fill_inquiry_response); | ||
| 314 | 258 | ||
| 315 | static int usb_stor_control_thread(void * __us) | 259 | static int usb_stor_control_thread(void * __us) |
| 316 | { | 260 | { |
| @@ -551,20 +495,13 @@ static void adjust_quirks(struct us_data *us) | |||
| 551 | vid, pid, f); | 495 | vid, pid, f); |
| 552 | } | 496 | } |
| 553 | 497 | ||
| 554 | /* Find an unusual_dev descriptor (always succeeds in the current code) */ | ||
| 555 | static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | ||
| 556 | { | ||
| 557 | const int id_index = id - storage_usb_ids; | ||
| 558 | return &us_unusual_dev_list[id_index]; | ||
| 559 | } | ||
| 560 | |||
| 561 | /* Get the unusual_devs entries and the string descriptors */ | 498 | /* Get the unusual_devs entries and the string descriptors */ |
| 562 | static int get_device_info(struct us_data *us, const struct usb_device_id *id) | 499 | static int get_device_info(struct us_data *us, const struct usb_device_id *id, |
| 500 | struct us_unusual_dev *unusual_dev) | ||
| 563 | { | 501 | { |
| 564 | struct usb_device *dev = us->pusb_dev; | 502 | struct usb_device *dev = us->pusb_dev; |
| 565 | struct usb_interface_descriptor *idesc = | 503 | struct usb_interface_descriptor *idesc = |
| 566 | &us->pusb_intf->cur_altsetting->desc; | 504 | &us->pusb_intf->cur_altsetting->desc; |
| 567 | struct us_unusual_dev *unusual_dev = find_unusual(id); | ||
| 568 | 505 | ||
| 569 | /* Store the entries */ | 506 | /* Store the entries */ |
| 570 | us->unusual_dev = unusual_dev; | 507 | us->unusual_dev = unusual_dev; |
| @@ -629,7 +566,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) | |||
| 629 | } | 566 | } |
| 630 | 567 | ||
| 631 | /* Get the transport settings */ | 568 | /* Get the transport settings */ |
| 632 | static int get_transport(struct us_data *us) | 569 | static void get_transport(struct us_data *us) |
| 633 | { | 570 | { |
| 634 | switch (us->protocol) { | 571 | switch (us->protocol) { |
| 635 | case US_PR_CB: | 572 | case US_PR_CB: |
| @@ -651,100 +588,11 @@ static int get_transport(struct us_data *us) | |||
| 651 | us->transport = usb_stor_Bulk_transport; | 588 | us->transport = usb_stor_Bulk_transport; |
| 652 | us->transport_reset = usb_stor_Bulk_reset; | 589 | us->transport_reset = usb_stor_Bulk_reset; |
| 653 | break; | 590 | break; |
| 654 | |||
| 655 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
| 656 | case US_PR_USBAT: | ||
| 657 | us->transport_name = "Shuttle USBAT"; | ||
| 658 | us->transport = usbat_transport; | ||
| 659 | us->transport_reset = usb_stor_CB_reset; | ||
| 660 | us->max_lun = 1; | ||
| 661 | break; | ||
| 662 | #endif | ||
| 663 | |||
| 664 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
| 665 | case US_PR_EUSB_SDDR09: | ||
| 666 | us->transport_name = "EUSB/SDDR09"; | ||
| 667 | us->transport = sddr09_transport; | ||
| 668 | us->transport_reset = usb_stor_CB_reset; | ||
| 669 | us->max_lun = 0; | ||
| 670 | break; | ||
| 671 | #endif | ||
| 672 | |||
| 673 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
| 674 | case US_PR_SDDR55: | ||
| 675 | us->transport_name = "SDDR55"; | ||
| 676 | us->transport = sddr55_transport; | ||
| 677 | us->transport_reset = sddr55_reset; | ||
| 678 | us->max_lun = 0; | ||
| 679 | break; | ||
| 680 | #endif | ||
| 681 | |||
| 682 | #ifdef CONFIG_USB_STORAGE_DPCM | ||
| 683 | case US_PR_DPCM_USB: | ||
| 684 | us->transport_name = "Control/Bulk-EUSB/SDDR09"; | ||
| 685 | us->transport = dpcm_transport; | ||
| 686 | us->transport_reset = usb_stor_CB_reset; | ||
| 687 | us->max_lun = 1; | ||
| 688 | break; | ||
| 689 | #endif | ||
| 690 | |||
| 691 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
| 692 | case US_PR_FREECOM: | ||
| 693 | us->transport_name = "Freecom"; | ||
| 694 | us->transport = freecom_transport; | ||
| 695 | us->transport_reset = usb_stor_freecom_reset; | ||
| 696 | us->max_lun = 0; | ||
| 697 | break; | ||
| 698 | #endif | ||
| 699 | |||
| 700 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
| 701 | case US_PR_DATAFAB: | ||
| 702 | us->transport_name = "Datafab Bulk-Only"; | ||
| 703 | us->transport = datafab_transport; | ||
| 704 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 705 | us->max_lun = 1; | ||
| 706 | break; | ||
| 707 | #endif | ||
| 708 | |||
| 709 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
| 710 | case US_PR_JUMPSHOT: | ||
| 711 | us->transport_name = "Lexar Jumpshot Control/Bulk"; | ||
| 712 | us->transport = jumpshot_transport; | ||
| 713 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 714 | us->max_lun = 1; | ||
| 715 | break; | ||
| 716 | #endif | ||
| 717 | |||
| 718 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 719 | case US_PR_ALAUDA: | ||
| 720 | us->transport_name = "Alauda Control/Bulk"; | ||
| 721 | us->transport = alauda_transport; | ||
| 722 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 723 | us->max_lun = 1; | ||
| 724 | break; | ||
| 725 | #endif | ||
| 726 | |||
| 727 | #ifdef CONFIG_USB_STORAGE_KARMA | ||
| 728 | case US_PR_KARMA: | ||
| 729 | us->transport_name = "Rio Karma/Bulk"; | ||
| 730 | us->transport = rio_karma_transport; | ||
| 731 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 732 | break; | ||
| 733 | #endif | ||
| 734 | |||
| 735 | default: | ||
| 736 | return -EIO; | ||
| 737 | } | 591 | } |
| 738 | US_DEBUGP("Transport: %s\n", us->transport_name); | ||
| 739 | |||
| 740 | /* fix for single-lun devices */ | ||
| 741 | if (us->fflags & US_FL_SINGLE_LUN) | ||
| 742 | us->max_lun = 0; | ||
| 743 | return 0; | ||
| 744 | } | 592 | } |
| 745 | 593 | ||
| 746 | /* Get the protocol settings */ | 594 | /* Get the protocol settings */ |
| 747 | static int get_protocol(struct us_data *us) | 595 | static void get_protocol(struct us_data *us) |
| 748 | { | 596 | { |
| 749 | switch (us->subclass) { | 597 | switch (us->subclass) { |
| 750 | case US_SC_RBC: | 598 | case US_SC_RBC: |
| @@ -779,26 +627,7 @@ static int get_protocol(struct us_data *us) | |||
| 779 | us->protocol_name = "Uniform Floppy Interface (UFI)"; | 627 | us->protocol_name = "Uniform Floppy Interface (UFI)"; |
| 780 | us->proto_handler = usb_stor_ufi_command; | 628 | us->proto_handler = usb_stor_ufi_command; |
| 781 | break; | 629 | break; |
| 782 | |||
| 783 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
| 784 | case US_SC_ISD200: | ||
| 785 | us->protocol_name = "ISD200 ATA/ATAPI"; | ||
| 786 | us->proto_handler = isd200_ata_command; | ||
| 787 | break; | ||
| 788 | #endif | ||
| 789 | |||
| 790 | #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB | ||
| 791 | case US_SC_CYP_ATACB: | ||
| 792 | us->protocol_name = "Transparent SCSI with Cypress ATACB"; | ||
| 793 | us->proto_handler = cypress_atacb_passthrough; | ||
| 794 | break; | ||
| 795 | #endif | ||
| 796 | |||
| 797 | default: | ||
| 798 | return -EIO; | ||
| 799 | } | 630 | } |
| 800 | US_DEBUGP("Protocol: %s\n", us->protocol_name); | ||
| 801 | return 0; | ||
| 802 | } | 631 | } |
| 803 | 632 | ||
| 804 | /* Get the pipe settings */ | 633 | /* Get the pipe settings */ |
| @@ -846,12 +675,12 @@ static int get_pipes(struct us_data *us) | |||
| 846 | us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0); | 675 | us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0); |
| 847 | us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0); | 676 | us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0); |
| 848 | us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, | 677 | us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, |
| 849 | ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 678 | usb_endpoint_num(ep_out)); |
| 850 | us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, | 679 | us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, |
| 851 | ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 680 | usb_endpoint_num(ep_in)); |
| 852 | if (ep_int) { | 681 | if (ep_int) { |
| 853 | us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, | 682 | us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, |
| 854 | ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 683 | usb_endpoint_num(ep_int)); |
| 855 | us->ep_bInterval = ep_int->bInterval; | 684 | us->ep_bInterval = ep_int->bInterval; |
| 856 | } | 685 | } |
| 857 | return 0; | 686 | return 0; |
| @@ -1012,17 +841,15 @@ static int usb_stor_scan_thread(void * __us) | |||
| 1012 | } | 841 | } |
| 1013 | 842 | ||
| 1014 | 843 | ||
| 1015 | /* Probe to see if we can drive a newly-connected USB device */ | 844 | /* First part of general USB mass-storage probing */ |
| 1016 | static int storage_probe(struct usb_interface *intf, | 845 | int usb_stor_probe1(struct us_data **pus, |
| 1017 | const struct usb_device_id *id) | 846 | struct usb_interface *intf, |
| 847 | const struct usb_device_id *id, | ||
| 848 | struct us_unusual_dev *unusual_dev) | ||
| 1018 | { | 849 | { |
| 1019 | struct Scsi_Host *host; | 850 | struct Scsi_Host *host; |
| 1020 | struct us_data *us; | 851 | struct us_data *us; |
| 1021 | int result; | 852 | int result; |
| 1022 | struct task_struct *th; | ||
| 1023 | |||
| 1024 | if (usb_usual_check_type(id, USB_US_TYPE_STOR)) | ||
| 1025 | return -ENXIO; | ||
| 1026 | 853 | ||
| 1027 | US_DEBUGP("USB Mass Storage device detected\n"); | 854 | US_DEBUGP("USB Mass Storage device detected\n"); |
| 1028 | 855 | ||
| @@ -1041,7 +868,7 @@ static int storage_probe(struct usb_interface *intf, | |||
| 1041 | * Allow 16-byte CDBs and thus > 2TB | 868 | * Allow 16-byte CDBs and thus > 2TB |
| 1042 | */ | 869 | */ |
| 1043 | host->max_cmd_len = 16; | 870 | host->max_cmd_len = 16; |
| 1044 | us = host_to_us(host); | 871 | *pus = us = host_to_us(host); |
| 1045 | memset(us, 0, sizeof(struct us_data)); | 872 | memset(us, 0, sizeof(struct us_data)); |
| 1046 | mutex_init(&(us->dev_mutex)); | 873 | mutex_init(&(us->dev_mutex)); |
| 1047 | init_completion(&us->cmnd_ready); | 874 | init_completion(&us->cmnd_ready); |
| @@ -1054,24 +881,46 @@ static int storage_probe(struct usb_interface *intf, | |||
| 1054 | if (result) | 881 | if (result) |
| 1055 | goto BadDevice; | 882 | goto BadDevice; |
| 1056 | 883 | ||
| 1057 | /* | 884 | /* Get the unusual_devs entries and the descriptors */ |
| 1058 | * Get the unusual_devs entries and the descriptors | 885 | result = get_device_info(us, id, unusual_dev); |
| 1059 | * | ||
| 1060 | * id_index is calculated in the declaration to be the index number | ||
| 1061 | * of the match from the usb_device_id table, so we can find the | ||
| 1062 | * corresponding entry in the private table. | ||
| 1063 | */ | ||
| 1064 | result = get_device_info(us, id); | ||
| 1065 | if (result) | 886 | if (result) |
| 1066 | goto BadDevice; | 887 | goto BadDevice; |
| 1067 | 888 | ||
| 1068 | /* Get the transport, protocol, and pipe settings */ | 889 | /* Get standard transport and protocol settings */ |
| 1069 | result = get_transport(us); | 890 | get_transport(us); |
| 1070 | if (result) | 891 | get_protocol(us); |
| 1071 | goto BadDevice; | 892 | |
| 1072 | result = get_protocol(us); | 893 | /* Give the caller a chance to fill in specialized transport |
| 1073 | if (result) | 894 | * or protocol settings. |
| 895 | */ | ||
| 896 | return 0; | ||
| 897 | |||
| 898 | BadDevice: | ||
| 899 | US_DEBUGP("storage_probe() failed\n"); | ||
| 900 | release_everything(us); | ||
| 901 | return result; | ||
| 902 | } | ||
| 903 | EXPORT_SYMBOL_GPL(usb_stor_probe1); | ||
| 904 | |||
| 905 | /* Second part of general USB mass-storage probing */ | ||
| 906 | int usb_stor_probe2(struct us_data *us) | ||
| 907 | { | ||
| 908 | struct task_struct *th; | ||
| 909 | int result; | ||
| 910 | |||
| 911 | /* Make sure the transport and protocol have both been set */ | ||
| 912 | if (!us->transport || !us->proto_handler) { | ||
| 913 | result = -ENXIO; | ||
| 1074 | goto BadDevice; | 914 | goto BadDevice; |
| 915 | } | ||
| 916 | US_DEBUGP("Transport: %s\n", us->transport_name); | ||
| 917 | US_DEBUGP("Protocol: %s\n", us->protocol_name); | ||
| 918 | |||
| 919 | /* fix for single-lun devices */ | ||
| 920 | if (us->fflags & US_FL_SINGLE_LUN) | ||
| 921 | us->max_lun = 0; | ||
| 922 | |||
| 923 | /* Find the endpoints and calculate pipe values */ | ||
| 1075 | result = get_pipes(us); | 924 | result = get_pipes(us); |
| 1076 | if (result) | 925 | if (result) |
| 1077 | goto BadDevice; | 926 | goto BadDevice; |
| @@ -1080,7 +929,7 @@ static int storage_probe(struct usb_interface *intf, | |||
| 1080 | result = usb_stor_acquire_resources(us); | 929 | result = usb_stor_acquire_resources(us); |
| 1081 | if (result) | 930 | if (result) |
| 1082 | goto BadDevice; | 931 | goto BadDevice; |
| 1083 | result = scsi_add_host(host, &intf->dev); | 932 | result = scsi_add_host(us_to_host(us), &us->pusb_intf->dev); |
| 1084 | if (result) { | 933 | if (result) { |
| 1085 | printk(KERN_WARNING USB_STORAGE | 934 | printk(KERN_WARNING USB_STORAGE |
| 1086 | "Unable to add the scsi host\n"); | 935 | "Unable to add the scsi host\n"); |
| @@ -1108,9 +957,10 @@ BadDevice: | |||
| 1108 | release_everything(us); | 957 | release_everything(us); |
| 1109 | return result; | 958 | return result; |
| 1110 | } | 959 | } |
| 960 | EXPORT_SYMBOL_GPL(usb_stor_probe2); | ||
| 1111 | 961 | ||
| 1112 | /* Handle a disconnect event from the USB core */ | 962 | /* Handle a USB mass-storage disconnect */ |
| 1113 | static void storage_disconnect(struct usb_interface *intf) | 963 | void usb_stor_disconnect(struct usb_interface *intf) |
| 1114 | { | 964 | { |
| 1115 | struct us_data *us = usb_get_intfdata(intf); | 965 | struct us_data *us = usb_get_intfdata(intf); |
| 1116 | 966 | ||
| @@ -1118,6 +968,42 @@ static void storage_disconnect(struct usb_interface *intf) | |||
| 1118 | quiesce_and_remove_host(us); | 968 | quiesce_and_remove_host(us); |
| 1119 | release_everything(us); | 969 | release_everything(us); |
| 1120 | } | 970 | } |
| 971 | EXPORT_SYMBOL_GPL(usb_stor_disconnect); | ||
| 972 | |||
| 973 | /* The main probe routine for standard devices */ | ||
| 974 | static int storage_probe(struct usb_interface *intf, | ||
| 975 | const struct usb_device_id *id) | ||
| 976 | { | ||
| 977 | struct us_data *us; | ||
| 978 | int result; | ||
| 979 | |||
| 980 | /* | ||
| 981 | * If libusual is configured, let it decide whether a standard | ||
| 982 | * device should be handled by usb-storage or by ub. | ||
| 983 | * If the device isn't standard (is handled by a subdriver | ||
| 984 | * module) then don't accept it. | ||
| 985 | */ | ||
| 986 | if (usb_usual_check_type(id, USB_US_TYPE_STOR) || | ||
| 987 | usb_usual_ignore_device(intf)) | ||
| 988 | return -ENXIO; | ||
| 989 | |||
| 990 | /* | ||
| 991 | * Call the general probe procedures. | ||
| 992 | * | ||
| 993 | * The unusual_dev_list array is parallel to the usb_storage_usb_ids | ||
| 994 | * table, so we use the index of the id entry to find the | ||
| 995 | * corresponding unusual_devs entry. | ||
| 996 | */ | ||
| 997 | result = usb_stor_probe1(&us, intf, id, | ||
| 998 | (id - usb_storage_usb_ids) + us_unusual_dev_list); | ||
| 999 | if (result) | ||
| 1000 | return result; | ||
| 1001 | |||
| 1002 | /* No special transport or protocol settings in the main module */ | ||
| 1003 | |||
| 1004 | result = usb_stor_probe2(us); | ||
| 1005 | return result; | ||
| 1006 | } | ||
| 1121 | 1007 | ||
| 1122 | /*********************************************************************** | 1008 | /*********************************************************************** |
| 1123 | * Initialization and registration | 1009 | * Initialization and registration |
| @@ -1126,15 +1012,13 @@ static void storage_disconnect(struct usb_interface *intf) | |||
| 1126 | static struct usb_driver usb_storage_driver = { | 1012 | static struct usb_driver usb_storage_driver = { |
| 1127 | .name = "usb-storage", | 1013 | .name = "usb-storage", |
| 1128 | .probe = storage_probe, | 1014 | .probe = storage_probe, |
| 1129 | .disconnect = storage_disconnect, | 1015 | .disconnect = usb_stor_disconnect, |
| 1130 | #ifdef CONFIG_PM | 1016 | .suspend = usb_stor_suspend, |
| 1131 | .suspend = storage_suspend, | 1017 | .resume = usb_stor_resume, |
| 1132 | .resume = storage_resume, | 1018 | .reset_resume = usb_stor_reset_resume, |
| 1133 | .reset_resume = storage_reset_resume, | 1019 | .pre_reset = usb_stor_pre_reset, |
| 1134 | #endif | 1020 | .post_reset = usb_stor_post_reset, |
| 1135 | .pre_reset = storage_pre_reset, | 1021 | .id_table = usb_storage_usb_ids, |
| 1136 | .post_reset = storage_post_reset, | ||
| 1137 | .id_table = storage_usb_ids, | ||
| 1138 | .soft_unbind = 1, | 1022 | .soft_unbind = 1, |
| 1139 | }; | 1023 | }; |
| 1140 | 1024 | ||
