// SPDX-License-Identifier: GPL-2.0+ /* * Driver for USB Mass Storage compliant devices * * Current development and maintenance by: * (c) 1999-2003 Matthew Dharm ([email protected]) * * Developed with the assistance of: * (c) 2000 David L. Brown, Jr. ([email protected]) * (c) 2003-2009 Alan Stern ([email protected]) * * Initial work by: * (c) 1999 Michael Gee ([email protected]) * * usb_device_id support by Adam J. Richter ([email protected]): * (c) 2000 Yggdrasil Computing, Inc. * * This driver is based on the 'USB Mass Storage Class' document. This * describes in detail the protocol used to communicate with such * devices. Clearly, the designers had SCSI and ATAPI commands in * mind when they created this document. The commands are all very * similar to commands in the SCSI-II and ATAPI specifications. * * It is important to note that in a number of cases this class * exhibits class-specific exemptions from the USB specification. * Notably the usage of NAK, STALL and ACK differs from the norm, in * that they are used to communicate wait, failed and OK on commands. * * Also, for certain devices, the interrupt endpoint is used to convey * status of a command. */ #ifdef CONFIG_USB_STORAGE_DEBUG #define DEBUG #endif #include <linux/sched.h> #include <linux/errno.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/kthread.h> #include <linux/mutex.h> #include <linux/utsname.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_device.h> #include "usb.h" #include <linux/usb/hcd.h> #include "scsiglue.h" #include "transport.h" #include "protocol.h" #include "debug.h" #include "initializers.h" #include "sierra_ms.h" #include "option_ms.h" #if IS_ENABLED(CONFIG_USB_UAS) #include "uas-detect.h" #endif #define DRV_NAME … /* Some informational data */ MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; static unsigned int delay_use = …; /** * parse_delay_str - parse an unsigned decimal integer delay * @str: String to parse. * @ndecimals: Number of decimal to scale up. * @suffix: Suffix string to parse. * @val: Where to store the parsed value. * * Parse an unsigned decimal value in @str, optionally end with @suffix. * Stores the parsed value in @val just as it is if @str ends with @suffix. * Otherwise store the value scale up by 10^(@ndecimal). * * Returns 0 on success, a negative error code otherwise. */ static int parse_delay_str(const char *str, int ndecimals, const char *suffix, unsigned int *val) { … } /** * format_delay_ms - format an integer value into a delay string * @val: The integer value to format, scaled by 10^(@ndecimals). * @ndecimals: Number of decimal to scale down. * @suffix: Suffix string to format. * @str: Where to store the formatted string. * @size: The size of buffer for @str. * * Format an integer value in @val scale down by 10^(@ndecimals) without @suffix * if @val is divisible by 10^(@ndecimals). * Otherwise format a value in @val just as it is with @suffix * * Returns the number of characters written into @str. */ static int format_delay_ms(unsigned int val, int ndecimals, const char *suffix, char *str, int size) { … } static int delay_use_set(const char *s, const struct kernel_param *kp) { … } static int delay_use_get(char *s, const struct kernel_param *kp) { … } static const struct kernel_param_ops delay_use_ops = …; module_param_cb(…); MODULE_PARM_DESC(…) …; static char quirks[128]; module_param_string(…); MODULE_PARM_DESC(…) …; /* * The entries in this table correspond, line for line, * with the entries in usb_storage_usb_ids[], defined in usual-tables.c. */ /* *The vendor name should be kept at eight characters or less, and * the product name should be kept at 16 characters or less. If a device * has the US_FL_FIX_INQUIRY flag, then the vendor and product names * normally generated by a device through the INQUIRY response will be * taken from this list, and this is the reason for the above size * restriction. However, if the flag is not present, then you * are free to use as many characters as you like. */ #define UNUSUAL_DEV … #define COMPLIANT_DEV … #define USUAL_DEV … static const struct us_unusual_dev us_unusual_dev_list[] = …; static const struct us_unusual_dev for_dynamic_ids = …; #undef UNUSUAL_DEV #undef COMPLIANT_DEV #undef USUAL_DEV #ifdef CONFIG_LOCKDEP static struct lock_class_key us_interface_key[USB_MAXINTERFACES]; static void us_set_lock_class(struct mutex *mutex, struct usb_interface *intf) { … } #else static void us_set_lock_class(struct mutex *mutex, struct usb_interface *intf) { } #endif #ifdef CONFIG_PM /* Minimal support for suspend and resume */ int usb_stor_suspend(struct usb_interface *iface, pm_message_t message) { … } EXPORT_SYMBOL_GPL(…); int usb_stor_resume(struct usb_interface *iface) { … } EXPORT_SYMBOL_GPL(…); int usb_stor_reset_resume(struct usb_interface *iface) { … } EXPORT_SYMBOL_GPL(…); #endif /* CONFIG_PM */ /* * The next two routines get called just before and just after * a USB port reset, whether from this driver or a different one. */ int usb_stor_pre_reset(struct usb_interface *iface) { … } EXPORT_SYMBOL_GPL(…); int usb_stor_post_reset(struct usb_interface *iface) { … } EXPORT_SYMBOL_GPL(…); /* * fill_inquiry_response takes an unsigned char array (which must * be at least 36 characters) and populates the vendor name, * product name, and revision fields. Then the array is copied * into the SCSI command's response buffer (oddly enough * called request_buffer). data_len contains the length of the * data array, which again must be at least 36. */ void fill_inquiry_response(struct us_data *us, unsigned char *data, unsigned int data_len) { … } EXPORT_SYMBOL_GPL(…); static int usb_stor_control_thread(void * __us) { … } /*********************************************************************** * Device probing and disconnecting ***********************************************************************/ /* Associate our private data with the USB device */ static int associate_dev(struct us_data *us, struct usb_interface *intf) { … } /* Works only for digits and letters, but small and fast */ #define TOLOWER(x) … /* Adjust device flags based on the "quirks=" module parameter */ void usb_stor_adjust_quirks(struct usb_device *udev, u64 *fflags) { … } EXPORT_SYMBOL_GPL(…); /* Get the unusual_devs entries and the string descriptors */ static int get_device_info(struct us_data *us, const struct usb_device_id *id, const struct us_unusual_dev *unusual_dev) { … } /* Get the transport settings */ static void get_transport(struct us_data *us) { … } /* Get the protocol settings */ static void get_protocol(struct us_data *us) { … } /* Get the pipe settings */ static int get_pipes(struct us_data *us) { … } /* Initialize all the dynamic resources we need */ static int usb_stor_acquire_resources(struct us_data *us) { … } /* Release all our dynamic resources */ static void usb_stor_release_resources(struct us_data *us) { … } /* Dissociate from the USB device */ static void dissociate_dev(struct us_data *us) { … } /* * First stage of disconnect processing: stop SCSI scanning, * remove the host, and stop accepting new commands */ static void quiesce_and_remove_host(struct us_data *us) { … } /* Second stage of disconnect processing: deallocate all resources */ static void release_everything(struct us_data *us) { … } /* Delayed-work routine to carry out SCSI-device scanning */ static void usb_stor_scan_dwork(struct work_struct *work) { … } static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf) { … } /* First part of general USB mass-storage probing */ int usb_stor_probe1(struct us_data **pus, struct usb_interface *intf, const struct usb_device_id *id, const struct us_unusual_dev *unusual_dev, const struct scsi_host_template *sht) { … } EXPORT_SYMBOL_GPL(…); /* Second part of general USB mass-storage probing */ int usb_stor_probe2(struct us_data *us) { … } EXPORT_SYMBOL_GPL(…); /* Handle a USB mass-storage disconnect */ void usb_stor_disconnect(struct usb_interface *intf) { … } EXPORT_SYMBOL_GPL(…); static struct scsi_host_template usb_stor_host_template; /* The main probe routine for standard devices */ static int storage_probe(struct usb_interface *intf, const struct usb_device_id *id) { … } static struct usb_driver usb_storage_driver = …; module_usb_stor_driver(usb_storage_driver, usb_stor_host_template, DRV_NAME);