The following describes the usb_stor_control_thread () function. What wakes up is the up (& (us-> sema) from the queuecommand, and us-> sulfate is assigned to the Server Load balancer, in contrast, the Server Load balancer is a parameter passed in when the SCSI core layer calls the queuecommand. Focus on usb_stor_control_thread (). Row 3: As mentioned earlier, we have to look at the dev_mutex lock from a higher perspective after reading the entire module.
Line 3: If us_fw.x_disconnecting is set, you don't need to say much about this. It is to determine whether the device has been pulled out. If your USB flash drive is inserted, it will never be pulled out, you can delete all the Code related to the flag. Of course, in fact, it is impossible for you to pull it out. Hot swapping is a major feature of USB devices.
Row 3 and host are also locks, so we can check the lock at the end.
Lines 326 to 330 are used to determine whether another flag has been set. The meaning of the flag US_FLDX_TIMED_OUT is also as literal, that is, timeout. The concept of timeout is everywhere in the computer world. However, for this flag, the function for setting it is command_abort. This function is also provided by us. It is called by the SCSI core layer, where it is responsible for timing. when it expires, it calls command_abort. We will see it later. Don't worry.
Row 3: Judge SC _data_direction, a member of the Server Load balancer instance. Check the DMA_BIDIRECTIONAL macro first. This macro is defined in include/linux/dma-mapping.h:
7/* These definitions mirror those in pci. h, sothey can be used
8 * interchangeably with their PCI _ counterparts */
9 enum dma_data_direction {
10 DMA_BIDIRECTIONAL = 0,
11 DMA_TO_DEVICE = 1,
12 DMA_FROM_DEVICE = 2,
13 DMA_NONE = 3,
14 };
These codes are used to indicate the direction of data transmission in the data phase. DMA_TO_DEVICE indicates that the device is from the primary storage to the device, and DMA_FROM_DEVICE indicates that the device is from the primary storage to the primary storage. It is rumored that DMA_NONE is only used for debugging and cannot be used. Otherwise, the kernel may crash. More accurately, however, the USB Mass Storage protocol stipulates that bidirectional transmission is illegal, while a command is valid to transmit zero data. For example, the TEST_UNIT_READY command does not need to transmit data.
DMA_BIDIRECTIONAL indicates that both directions are possible. In other words, it means you do not know which direction it is. Similarly, when the SC _data_direction of the Server Load balancer instance is DMA_BIDIRECTIONAL in Row 3, it is regarded as an error. Data cannot be transmitted because of uncertainty.
Row 3: the flag US_FL_SCM_MULT_TARG indicates that the device supports multiple targets. The meaning here is obvious. For devices that do not support multiple targets, its us-> sulfate-> device-> id must be 0; otherwise, the problem may occur. In the struct us_data struct, the struct scsi_cmnd * sulfate is a member, and the struct scsi_device * device is a member in the struct scsi_cmnd struct. struct scsi_device, as its name implies, describes a SCSI device, just like the previous struct usb_device used to describe a USB device. Struct scsi_device from include/scsi/scsi_device.h:
49 struct scsi_device {
50 struct Scsi_Host * host;
51 struct request_queue * request_queue;
52
53/* the next two are protected by thehost-> host_lock */
54 struct list_head siblings;/* list of all devices on this host */
55 struct list_head same_target_siblings;
56
57/* this is now protected by therequest_queue-> queue_lock */
58 unsigned int device_busy;/* commands actually active on
59 * low-level. protected by queue_lock .*/
60 spinlock_t list_lock;
61 struct list_head into _list;/* queue of in useSCSI Command structures */
62 struct list_head starved_entry;
63 struct scsi_cmnd * current_cmnd;/* currentlyactive command */
64 unsigned short queue_depth;/* How deep of aqueue we want */
65 unsigned short last_queue_full_depth;/* Thesetwo are used */
66 unsigned short last_queue_full_count;/* scsi_track_queue_full ()*/
67 unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same
68 jiffie count on our counter, they
69 cocould all be from the same event .*/
70
71 unsigned int id, lun, channel;
72
73 unsigned int manufacturer;/* Manufacturerof device, for using
74 * vendor-specific cmd's */
75 unsigned sector_size;/* size in Bytes */
76
77 void * hostdata;/* available to low-level driver */
78 char type;
79 char scsi_level;
80 char inq_periph_qual;/* PQ from INQUIRY data */
81 unsigned char inquiry_len;/* valid Bytesin 'inquiry '*/
82 unsigned char * inquiry;/* INQUIRY response data */
83 const char * vendor;/* [back_compat] point into 'inquiry '...*/
84 const char * model;/*... after scan; point to static string */
85 const char * rev;/*... "nullnullnullnull" before scan */
86 unsigned char current_tag;/* current tag */
87 struct scsi_target * sdev_target;/* used only forsingle_lun */
88
89 unsigned int sdev_bflags;/* black/white flags as also foundin
90 * scsi_devinfo. [hc]. For now used only
91 * pass settings from slave_alloc to scsi
92 * core .*/
93 unsigned writeable: 1;
94 unsigned removable: 1;
95 unsigned changed: 1;/* Data invalid due to media change */
96 unsigned busy: 1;/* Used to prevent races */
97 unsigned lockable: 1;/* Able to prevent media removal */
98 unsigned locked: 1;/* Media removal disabled */
99 unsigned borken: 1;/* Tell the Seagate driver to be
100 * painfully slow on this device */
101 unsigned disconnect: 1;/* can disconnect */
102 unsignedsoft_reset: 1;/* Uses soft resetoption */
103 unsigned sdtr: 1;/* Device supports SDTR messages */
104 unsignedwdtr: 1;/* Device supports WDTRmessages */
105 unsigned ppr: 1;/* Device supports PPR messages */
106 unsignedtagged_supported: 1;/* Supports SCSI-II tagged queuing */
107 unsignedsimple_tags: 1;/* simple queue tag messages are enabled */
108 unsignedordered_tags: 1;/* ordered queue tag messages are enabled */
109 unsigned single_lun: 1;/* Indicates we shoshould only allow I/O
110 * one of the luns for the device at
111 * time .*/
112 unsignedwas_reset: 1;/* There was abus reset on the bus
113 * this device */
114 unsigned expecting_cc_ua: 1;/* Expecting aCHECK_CONDITION/UNIT_ATTN
115 * because we did a bus reset .*/
116 unsigneduse_10_for_rw: 1;/* first try 10-Byte read/write */
117 unsigneduse_10_for _ ms: 1;/* first try 10-Byte mode sense/select */
118 unsignedskip _ ms_page_8: 1;/* do not use mode sense page 0x08 */
119 unsignedskip _ ms_page_3f: 1;/* do not use mode sense page 0x3f */
120 unsigneduse_192_Bytes_for_3f: 1;/* ask for 192 Bytes from page 0x3f */
121 unsigned no_start_on_add: 1;/* do not issue starton add */
122 unsignedallow_restart: 1;/* issue START_UNIT in error handler */
123 unsignedmanage_start_stop: 1;/* Let HLD (sd) manage start/stop */
124 unsigned no_uld_attach: 1;/* disable connecting toupper level drivers */
125 unsigned select_no_atn: 1;
126 unsignedfix_capacity: 1;/* READ_CAPACITY is too high by 1 */
127 unsignedguess_capacity: 1;/* READ_CAPACITY might be too high by 1 */
128 unsignedretry_hwerror: 1;/* Retry HARDWARE_ERROR */
129
130 unsigned int device_blocked;/* Device returnedQUEUE_FULL .*/
131
132 unsigned int max_device_blocked;
133 # define SCSI_DEFAULT_DEVICE_BLOCKED 3
134
135 atomic_t iorequest_cnt;
136 atomic_t iodone_cnt;
137 atomic_tierr_cnt;
138
139 inttimeout;
140
141 struct device sdev_gendev;
142 structclass_device sdev_classdev;
143
144 struct execute_work ew;/* used to getprocess context on put */
145
146 enumscsi_device_state sdev_state;
147 unsigned long sdev_data [0];
148} _ attribute _ (aligned (sizeof (unsignedlong ))));
This struct will be mentioned many times later. Of course, at this moment, we only need to note the unsigned int id, lun, and channel members. This is exactly the three members necessary to locate a SCSI device, the devices controlled by a scsicard are divided into several layers. There are several channels, and each channel has several targets. Each target is represented by a target id, then a target can have several Luns, and the target id is determined here. For devices that do not support multiple targets, the value must be 0. For most USB Mass Storage devices, their target id must be 0. Some equipment manufacturers want to be unconventional. They want devices to support multiple targets, so they can set a flag such as US_FL_SCM_MULT_TARG, for example, we can see the following definitions in drivers/usb/storage/unusual_devs.h:
416 UNUSUAL_DEV (0x04e6, 0x0002, 0x0100, 0x0100,
417 "Shuttle ",
418 "eUSCSI Bridge ",
419 US_ SC _DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
420 US_FL_SCM_MULT_TARG ),
Then, in Row 3, the number of "us"> "ports"> "device"> "lun" should not be greater than that of "us"> "max_lun". What are the differences between the two? Us-> max_lun is the maximum LUN obtained from the usb mass storage Device by calling the usb_stor_scan_thread () function in usb_stor_Bulk_max_lun () in the early stage. For example, max lun is 3, the device supports four Luns, namely, 0, 1, 2, and 3. However, the "us"> "sulfate"> "device"> "lun" parameter can be any of the four values. You can see who is accessing the passed command. But it obviously cannot exceed the max lun.
Then there are 358 rows. Seeing such a flag-US_FL_FIX_INQUIRY, this is one of the many flags in us-> flags, which we have introduced before, some devices defined in drivers/usb/storage/unusal_devs.h have this flag. In fact, the Vendor Name and Product Name of most devices are usually obtained through the INQUIRY command, and this flag indicates that, the vendor name and product name of these devices do not need to be queried, or cannot be queried at all. Their vendor name and product name are defined directly and set in unusal_devs.h. In row 3, What Is cmnd [0? There is such a member in struct scsi_cmnd,
65 # define MAX_COMMAND_SIZE 16
66 unsigned charcmnd [MAX_COMMAND_SIZE];
The array contains 16 elements, which are the SCSI commands. To understand this condition, you must first look at the following fill_inquiry_response () function call.
Finally, "Paste" several devices with the US_FL_FIX_INQUIRY flag. These devices are Sony's PEG memory sticks or memory cards, which can be used in PDAs. Drivers/usb/storage/unusual_devs.h:
635/* Submitted by Nathan Babb <nathan@lexi.com> */
636 UNUSUAL_DEV (0x054c, 0x006d, 0x0000, 0x9999,
637 "Sony ",
638 "PEGMass Storage ",
639 US_ SC _DEVICE, US_PR_DEVICE, NULL,
640 US_FL_FIX_INQUIRY ),
641
642/* Submitted by Mike Alborn <malborn@deandra.homeip.net> */
643 UNUSUAL_DEV (0x054c, 0x016a, 0x0000, 0x9999,
644 "Sony ",
645 "PEG Mass Storage ",
646 US_ SC _DEVICE, US_PR_DEVICE, NULL,
647 US_FL_FIX_INQUIRY ),
648
649/* Submitted by Frank Engel <frankie@cse.unsw.edu.au> */
650 UNUSUAL_DEV (0x054c, 0x0099, 0x0000, 0x9999,
651 "Sony ",
652 "PEG Mass Storage ",
653 US_ SC _DEVICE, US_PR_DEVICE, NULL,
654 US_FL_FIX_INQUIRY ),
655