From the Protocol to the Protocol (above)
In structusb_driver, the prototype of. Probe and. Disconnect is as follows:
836 int (* probe) (struct usb_interface * INTF,
837 const struct usb_device_id * ID );
838
839 void (* disconnect) (struct usb_interface * INTF );
Let's take a look at the parameter structusb_device_id, Which is needless to say. As we have already introduced, where does struct usb_interface come from? Let's start with struct usb_device.
We know that each device corresponds to a struct device struct variable, but the device cannot be omnipotent and life is diverse. Just like we can use "people" to collectively refer to all humans, but we can get a little more detailed, there are also differences between men and women. The same is true for devices. As there are various devices, more words (data structures) Come out, such as for USB devices, developers have designed a struct called struct usb_device. It is defined in include/Linux/USB. h:
336 struct usb_device {
337 int devnum;/* address on usbbus */
338 char devpath [16];/* use in messages:/port /...*/
339 enumusb_device_state state;/* configured, not attached, etc */
340 Enum usb_device_speed speed;/* High/full/low (or error )*/
341
342 structusb_tt * tt;/* low/full speed Dev, highspeed hub */
343 int ttport;/* Device port onthat TT hub */
344
345 unsigned inttoggle [2];/* one bit foreach endpoint
346 * ([0] = In, [1] = out )*/
347
348 structusb_device * parent;/* ourhub, unless we're the root */
349 structusb_bus * bus;/* bus we're part */
350 structusb_host_endpoint ep0;
351
352 structdevice dev;/* generic device interface */
353
354 structusb_device_descriptor descriptor;/* descriptor */
355 struct usb_host_config * config;/* all of the configs */
356
357 structusb_host_config * actconfig;/* The Active configuration */
358 structusb_host_endpoint * ep_in [16];
359 structusb_host_endpoint * ep_out [16];
361 char ** rawdescriptors;/* Raw descriptors for eachconfig */
362
363 unsignedshort bus_ma;/* current available from thebus */
364 u8portnum;/* parent port number (origin 1 )*/
365 u8level;/* Number of USB hub ancestors */
366
367 unsigneddiscon_suincluded: 1;/* disconnected while suspended */
368 unsignedhave_langid: 1;/* Whether string_langid is valid */
369 intstring_langid;/* language ID for strings */
370
371/* staticstrings from the device */
372 char * product;/* iproduct string, if present */
373 char * manufacturer;/* imanufacturer string, if present */
374 char * serial;/* iserialnumber string, if present */
375
376 structlist_head filelist;
377 # ifdef config_usb_device_class
378 structdevice * usb_classdev;
379 # endif
380 # ifdef config_usb_devicefs
381 structdentry * usbfs_dentry;/* usbfs dentry entry for the device */
382 # endif
383 /*
384 * child devices-these can be eithernew Devices
385 * (if this is a hub device), ordifferent instances
386 * of this same device.
387 *
388 * each instance needs its own set ofdata structures.
389 */
390
391 intmaxchild;/* Number of ports if hub */
392 structusb_device * Children [usb_maxchildren];
393
394 intpm_usage_cnt;/* usage counter for autosuspend */
395 u32quirks;/* quirks of the whole device */
396
397 # ifdef config_pm
398 structdelayed_work autosuspend;/* for delayed autosuspends */
399 struct mutex pm_mutex;/* protectspm operations */
400
401 unsignedlong last_busy;/* time of last use */
402 intautosuspend_delay;/* injiffies */
403
404 unsignedauto_pm: 1;/* autosuspend/resume in progress */
405 unsigneddo_remote_wakeup: 1;/* remote wakeup shocould be enabled */
406 unsignedautosuspend_disabled: 1;/* autosuspend and autoresume */
407 unsignedautoresume_disabled: 1;/* disabled by the user */
408 # endif
409 };
410 # define to_usb_device (d) container_of (D, struct usb_device, Dev)
It looks like a complicated data structure, but we do not need to understand every member of her, but we can see that one of the members is struct device Dev, this is the struct device struct variable of each device.
In fact, the USB flash drive does not directly process this struct, because for a USB flash drive, it corresponds to such a struct usb_device variable, which is applied for and assigned a value by the USB core. But we need to remember this struct variable, because this variable will be passed as a parameter when we call the function provided by USB core in the future. Because it is very simple, to communicate with USB core, people must know who we are. For example, for a function to be called later, usb_buffer_alloc, it needs this parameter.
For the drive of the USB flash drive, the data structure that is more important than struct usb_device is struct usb_interface. At this step, we have to learn about the specifications of some USB devices, or specifically, the USB protocol. Because we should at least know what a USB interface is ).
From the Protocol to the Protocol)
Everything has its own rules. USB devices must follow the USB protocol. Whether it is software or hardware, you must always refer to the USB protocol at the beginning of the design. How to Design hardware? How to write software? No one can imagine it without looking at the USB protocol.
The USB Protocol specifies that each USB device has some basic elements called descriptors. There are four types of descriptors that are required by any USB device: device descriptor, configurationdescriptor, and interface descriptor ), endpoint descriptor ). Something in the descriptor is a device that is solidified by the manufacturer at the factory. This kind of things won't change either way. For example, if I have an Intel USB flash drive, the inherent information must be branded at Intel's factory, manufacturers have already branded everything about it with intel. So when I insert a USB flash drive and run the CAT/proc/SCSI command to check it, "vendor" definitely displays intel.
With regard to these descriptors, USB core will read and obtain the information in the bus scan. The device descriptor describes the entire device. Note that this device is different from the device driver we have been talking about. Because a USB device actually refers to a macro concept, it can be a multi-functional device. after the reform and opening up, there are more and more multi-functional devices, for example, a common multi-function all-in-one machine in a foreign company is a device integrating printers, photocopiers, scanners, and fax machines. Of course, this is not a USB device, but this is also the case for USB devices. For example, a radio DJ may use a keyboard with a speaker, they connect two USB interfaces to the USB hub, and the device descriptor describes the characteristics of the entire device.
What about the configuration descriptor? To be honest, it makes no sense to know about the USB flash drive. But as a responsible person, I have to say a few words for it at the moment. One device can have one or more configurations. Have you ever seen a specific USB device? Well, you can see it on a mobile phone. Each mobile phone has multiple configurations or "Settings", for example, Nokia 6300, my mobile phone. The mobile phone language can be set to English, traditional Chinese, or simplified Chinese. Once one of them is selected, all the information displayed on the mobile phone is in this language/font. There are also the simplest examples. There are also several operating modes, such as standard, silent, and meeting. Basically, if I set it to a "meeting", it means that only the vibration is not audible. If it is set to silent, there will be no dynamic and static content. So is the configuration of the USB device. Of course, different USB devices have different configurations, or what needs to be configured will be different. Okay, so much about configuration.
For drivers of USB devices, the following interfaces and endpoints are more important. First, let's talk about the interface. First, an interface corresponds to a USB device driver. That's right. Let's look at the example above. One USB device, two functions, one keyboard with one speaker and two interfaces, two drivers, one is the keyboard driver and the other is the audio stream driver. The brother of the "road" prefers to call these two integrated things a device. I use interfaces to distinguish the two. So with the data structure we mentioned earlier, struct usb_interface is defined in include/Linux/USB. h:
140 struct usb_interface {
141/* array of alternate settings forthis interface,
142 * stored in no special order */
143 struct usb_host_interface * altsetting;
144
145 struct usb_host_interface * cur_altsetting;/* The currently
146 * active alternate setting */
147 unsignednum_altsetting;/* Number of alternatesettings */
148
149 int minor;/* minor number this interface is
150 * bound */
151 enumusb_interface_condition condition;/* state of binding */
152 unsignedis_active: 1;/* The interfaceis not suincluded */
153 unsignedneeds_remote_wakeup: 1;/* driver requires remote wakeup */
154
155 structdevice dev;/* interface specific device info */
156 struct device * usb_dev;/* pointer to the usbclass's device, if any */
157 int pm_usage_cnt;/* usage counter for autosuspend */
158 };
159 # defineto_usb_interface (d) container_of (D, struct usb_interface, Dev)
160 # define interface_to_usbdev (INTF )\
161 container_of (INTF-> Dev. Parent, struct usb_device, Dev)
This struct runs through the entire USB flash drive, so although we don't need to know it in depth, we need to remember that the struct usb_interface mentioned in any of the following sections of the USB flash drive is the same variable, this variable was applied for during a USB core bus scan. We only need to use it directly. For example, the parameter INTF in the previously mentioned storage_probe (struct usb_interface * INTF, const struct usb_device_id * ID) and storage_disconnect (structusb_interface * INTF) functions.
Here, the macro interface_to_usbdev of the 130 line will also be used. As the name suggests, it is to convert it from structusb_interface to structusb_device. As we have said, some functions require parameters such as struct usb_device instead of usb_interface, so this type of conversion is often used, and the designers of this macro and USB core are ready for us. Apart from gratitude, what else can we say?
From the Protocol to the Protocol (below)
If you are an acute user, you will be very interested in reading the storage_probe function at this time, because the work of the entire USB flash drive starts from here.
We have learned about devices, configurations, and interfaces. The last one is the endpoint. The most basic form of USB communication is through the endpoint. An interface has one or more endpoints. As a storage device such as a USB flash disk, it has at least one control endpoint and two batch endpoints. What are these endpoints used? It's really hard to say a long story.
The USB Protocol specifies that the USB device has four communication modes: control transmission, interrupt transmission, batch transmission, and other time transmission. Among them, the time transmission is obviously used for audio and video devices, such devices expect a relatively stable data stream, such as your QQ video chat on the internet, we certainly hope that the image/sound rate transmitted per minute will be relatively stable. The USB-storage will certainly not use the same time transmission. Because we only need to copy a file, but what is the difference between the first second and the second transmission, as long as the transfer is complete in dozens of seconds.
In contrast, the synchronous transmission is the most troublesome among the four types of transmission, so the USB flash disk is not needed. However, I would like to say that there is no need to interrupt transmission, but it does not need to be used for USB flash drives. Although there is a transfer protocol called CBI in the USB Mass Storage protocol, CBI is control/bulk/interrupt, that is, control/batch/interruption, all three types of transmission will be used, but this transmission protocol is not applicable to USB flash disks, and the USB flash disk uses a transmission protocol called bulk-only. Devices using this Protocol have only two transmission modes: batch transmission and control transmission, which must be supported by any USB device, it is used to transmit some control information. For example, if I want to query some information about this interface, use control transmission. In batch transmission, it is the main task of a USB flash drive, which reads and writes data. In this case, batch transmission is required. The specific transmission will be discussed later.
Now that you know the transmission method, you can get to know the endpoint. There is a pipe in the same name as the endpoint, or a cultural person calls pipe. The endpoint is the sending or receiving point of the communication. To send data, you only need to send the data to the correct endpoint. The reason why a USB flash disk has two batch endpoints is that the endpoints also have a direction. One is bulk in and the other is bulk out. From the USB host to the device is called out, and from the device to the host is called in. In fact, the pipeline is just to allow us to find the endpoint, which is equivalent to the ZIP Code address we call everyday. For example, in a country, we must name each place for communication, name all roads, large and small. For example, if you want to start from a remote city and go to Beijing, your endpoint is Beijing, and you need to know your route to Beijing, the route from your county seat to Beijing is a pipe. Someone curiously asked, should there be two endpoints in the pipeline, one in Beijing, and the other in Beijing? The answer is that this pipeline is special. We only need to know that the destination of one end is Beijing, but it doesn't matter where the other end is, because you get Beijing wherever you are.
Strictly speaking, the other end of the pipe should be a USB host, and the sides in the USB protocol are also stipulated. the pipe in the Protocol represents a capability. What kind of capability? Moving data between the host and the terminal on the device sounds mysterious. In fact, all data transmission in USB is initiated by the host. Everything is centered on the host, and various devices are closely around the host. Therefore, many functions in the USB core are used to enable the USB host to correctly complete data transmission or transmission scheduling. In other words, you have to tell the host the pipe, it needs to know who the scheduled data is to or from. But someone has to ask again. For example, if you want to read a file from a USB flash drive, will it tell the USB host that an endpoint is useful? The file is not stored in an endpoint. Isn't it stored in a USB flash disk? This can only be known in the code below.