I am USB in Linux. I am a USB flash drive (15). Will it be far away in spring? (1)

Source: Internet
Author: User
Tags 04x

In the code of the entire USB-storage module, the most soul part is in a function called usb_stor_control_thread (), which is naturally the climax of our entire story. Some special functions are called from the usb_stor_acquire_resources () function, which we will see soon. It only appears once in the whole play, that is, in storage_probe, where the row number is 1005.

However, before that, there were four functions in front of us, namely get_device_info, get_transport, get_protocol, and get_pipes. As I said before, to get two people together, first understand each other. These four functions let the driver know the device. We can also see this from the name. The driver needs to know the device name, so with get_device_info, the driver needs to know which type the device is. The code writer assigns the work to get_transport, get_protocol, and get_pipes.

In fact, the four functions, coupled with the previously mentioned associate_dev () function, are the most dull and boring part of the story. The first time I read this part of the code is confusing, why didn't I see any USB data communication? I have no idea how the USB Host communicates with the USB device. Is this USB? These functions can be said to pave the way for the future. safflower always has green leaves. Without this code, I am afraid the USB device will not work properly at the end. However, the good news is that these functions will only be met this time, and they have such an opportunity to show their faces throughout the story, like the youth of each of us, only once and cannot be turned back. So, let's enjoy this cool piece of code.

Get_device_info, which is defined in drivers/USB/storage/USB. C:

488/* Get the unusual_devs entries and the stringdescriptors */

489 static int get_device_info (struct us_data * us, const struct usb_device_id * ID)

490 {

491 struct usb_device * Dev = US-> pusb_dev;

492 structusb_interface_descriptor * idesc =

493 & US-> pusb_intf-> cur_altsetting-> DESC;

494 struct us_unusual_dev * unusual_dev = find_unusual (ID );

495

496/* store the entries */

497 US-> unusual_dev = unusual_dev;

498 US-> subclass = (unusual_dev-> useprotocol = us_ SC _device )?

499 idesc-> binterfacesubclass:

500 unusual_dev-> useprotocol;

501 US-> protocol = (unusual_dev-> usetransport = us_pr_device )?

502 idesc-> binterfaceprotocol:

503 unusual_dev-> usetransport;

504 US-> flags = usb_us_orig_flags (ID-> driver_info );

505

506 if (US-> flags & us_fl_ignore_device ){

507 printk (kern_info usb_storage "deviceignored \ n ");

508 return-enodev;

509}

510

511 /*

512 * this flag is onlyneeded when we're in high-speed, so let's

513 * disable it if we're in full-speed

514 */

515 if (Dev-> speed! = Usb_speed_high)

516 US-> flags & = ~ Us_fl_go_slow;

517

518/* log a message if a non-genericunusual_dev entry contains

519 * unnecessary subclass or Protocol override. This may stimulate

520 * reports from users that will help usremove unneeded entries

521 * from the unusual_devs.h table.

522 */

523 if (ID-> idvendor | ID-> idproduct ){

524 static const char * msgs [3] = {

525 "an unneeded subclass entry ",

526 "an unneeded protocol entry ",

527 "unneeded subclass and Protocol entries "};

528 struct usb_device_descriptor * ddesc = & Dev-> descriptor;

529 int MSG =-1;

530

531 if (unusual_dev-> useprotocol! = Us_ SC _device &&

532 US-> subclass = idesc-> binterfacesubclass)

533 MSG + = 1;

534 if (unusual_dev-> usetransport! = Us_pr_device &&

535 US-> protocol = idesc-> binterfaceprotocol)

536 MSG + = 2;

537 if (MSG> = 0 &&! (US-> flags & us_fl_need_override ))

538 printk (kern_notice usb_storage "this device"

539 "(% 04x, % 04x, % 04x S % 02x P % 02x )"

540 "has % s in unusual_devs.h (kernel"

541 "% s) \ n"

542 "Please send a copy of this message"

543 "<linux-usb-devel@lists.sourceforge.net> \ n ",

544 le16_to_cpu (ddesc-> idvendor ),

545 le16_to_cpu (ddesc-> idproduct ),

546 le16_to_cpu (ddesc-> bcddevice ),

547 idesc-> binterfacesubclass,

548 idesc-> binterfaceprotocol,

549 msgs [MSG],

550 utsname ()-> release );

551}

552

553 return0;

554}

Line 3: struct usb_interface_descriptor * idesc. You don't need to mention this. This struct has been introduced in the associate_dev function. The whole story is for an interface, an interface corresponds to an interface descriptor.

Row 3, struct us_unusual_dev, is the first occurrence of this struct, which is defined in drivers/USB/storage/USB. h:

61 struct us_unusual_dev {

62 constchar * vendorname;

63 const char * productname;

64 _ u8 useprotocol;

65 _ u8 usetransport;

66 int (* initfunction) (struct us_data *);

67 };

The find_unusual () function on the right of "=" is defined in drivers/USB/storage/USB. C:

482 static struct us_unusual_dev * find_unusual (const struct usb_device_id * ID)

483 {

484 const int id_index = ID-storage_usb_ids;

485 return & us_unusual_dev_list [id_index];

486}

Us_unusual_dev_list is an array defined in drivers/USB/storage/USB. C:

178 static struct us_unusual_devus_unusual_dev_list [] = {

179 # include "unusual_devs.h"

180 # UNDEF unuual_dev

181 # UNDEF usual_dev

182

183/* terminating entry */

184 {null}

185 };

There are a lot of strange things in Linux code, but I have never seen such an array as us_unusual_dev_list. To understand this array and the find_unusual () function, let's take a look at this storage_usb_ids. It is not someone else. It is the value of id_table, a member we assigned to usb_storage_driver. If you forget id_table, you can go back and view it. It is actually a table that tells drivers around the world what devices are supported. Storage_usb_ids also comes from drivers/USB/storage/USB. C:

138 static struct usb_device_id storage_usb_ids [] = {

139

140 # include "unusual_devs.h"

141 # UNDEF unuual_dev

142 # UNDEF usual_dev

143/* terminating entry */

144 {}

145 };

In this case, us_unusual_dev_list and storage_usb_ids are twins! The only difference is that the former has a null value. The most inexplicable here is that it contains a file. So let's first check what the unusual_devs.h file actually does? Let's take a look at the following lines in this file:

1476/* control/bulk transport for all subclassvalues */

1477 usual_dev (us_ SC _rb, us_pr_cb, usb_us_type_stor ),

1478 usual_dev (us_ SC _8020, us_pr_cb, usb_us_type_stor ),

1479 usual_dev (us_ SC _qic, us_pr_cb, usb_us_type_stor ),

1480 usual_dev (us_ SC _ufi, us_pr_cb, usb_us_type_stor ),

1481 usual_dev (us_ SC _8070, us_pr_cb, usb_us_type_stor ),

1482 usual_dev (us_ SC _scsi, us_pr_cb, usb_us_type_stor ),

1483

1484/* control/bulk/interrupt transport for allsubclass values */

1485 usual_dev (us_ SC _rb, us_pr_cbi, usb_us_type_stor ),

1486 usual_dev (us_ SC _8020, us_pr_cbi, usb_us_type_stor ),

1487 usual_dev (us_ SC _qic, us_pr_cbi, usb_us_type_stor ),

1488 usual_dev (us_ SC _ufi, us_pr_cbi, usb_us_type_stor ),

1489 usual_dev (us_ SC _8070, us_pr_cbi, usb_us_type_stor ),

1490 usual_dev (us_ SC _scsi, us_pr_cbi, usb_us_type_stor ),

1491

1492/* Bulk-only transport for all subclassvalues */

1493 usual_dev (us_ SC _rb, us_pr_bulk, usb_us_type_stor ),

1494 usual_dev (us_ SC _8020, us_pr_bulk, usb_us_type_stor ),

1495 usual_dev (us_ SC _qic, us_pr_bulk, usb_us_type_stor ),

1496 usual_dev (us_ SC _ufi, us_pr_bulk, usb_us_type_stor ),

1497 usual_dev (us_ SC _8070, us_pr_bulk, usb_us_type_stor ),

1498 usual_dev (us_ SC _scsi, us_pr_bulk, 0 ),

Usual_dev and unusual_dev are both defined in drivers/USB/storage/USB. C:

128 # define unusual_dev (id_vendor, id_product, bcddevicemin, bcddevicemax ,\

129 vendorname, productname, useprotocol, usetransport ,\

130 initfunction, flags )\

131 {usb_device_ver (id_vendor, id_product, bcddevicemin, bcddevicemax ),\

132. driver_info = (flags) | (usb_us_type_stor <24 )}

133

134 # define usual_dev (useproto, usetrans, usetype )\

135 {usb_interface_info (usb_class_mass_storage, useproto, usetrans ),\

136. driver_info = (usb_us_type_stor <24 )}

Note that we are looking at an array of structusb_device_id struct, and each of them must be a struct variable of struct usb_device_id. Let's take a look at usb_device_ver and usb_interface_info. Obviously these two are macros from include/Linux/USB. h:

715 /**

716 * usb_device_ver-macro used to describe a specific USB device with

717 * version range

718 * @ vend: The 16-bit USB vendor ID

719 * @ prod: The 16-bit USB product ID

720 * @ lo: The bcddevice_lo Value

721 * @ Hi: The bcddevice_hi Value

722 *

723 * This macro is used to create a struct usb_device_id that matches

724 * specific device, with a version range.

725 */

726 # define usb_device_ver (vend, prod, lo, hi )\

727. match_flags = usb_device_id_match_device_and_version ,\

728. idvendor = (vend),. idproduct = (prod ),\

729. bcddevice_lo = (LO),. bcddevice_hi = (HI)

744 /**

745 * usb_interface_info-macro used to describe a class of USB Interfaces

746 * @ CL: binterfaceclass Value

747 * @ SC: binterfacesubclass Value

748 * @ PR: binterfaceprotocol Value

749 *

750 * This macro is used to create a struct usb_device_id that matches

751 * specific class of interfaces.

752 */

753 # define usb_interface_info (CL, SC, Pr )\

754. match_flags = usb_device_id_match_int_info,. binterfaceclass = (CL ),\

755. binterfacesubclass = (SC),. binterfaceprotocol = (PR)

756

Every usb_device_ver or usb_interface_info is a struct variable for constructing a struct usb_device_id. Let's look back at the definition of struct usb_device_id, which is actually assigned a value for the four elements, they are match_flags, binterfaceclass, binterfacesubclass, and binterfaceprotocol.

What I have to say here is that there are many USB devices in the world, each of which has its own characteristics. to distinguish them, USB specifications or USB protocols divide USB devices into many categories, however, each class is further divided into child classes. This is well understood. Our University is also like this. It is divided into many colleges, and then each school is divided into many departments, such as the Information School, the following is divided into the Electronic Engineering Department, microelectronics department, computer department, communication engineering department, and then may be divided into various majors under each department. The USB protocol is the same. First, each interface belongs to a class. (why do I classify interfaces instead of devices? As mentioned above, in the USB device driver, you do not need to mention the device because each device driver corresponds to an interface instead of a device.) then, The subclass class is divided into two parts, next, subclass is further subdivided based on the different communication protocols observed by various devices.

The USB protocol defines a value for each class, each subclass, and each protocol. For example, the mass storage class is 0x08, here, the usb_class_mass_storage macro is defined in include/Linux/USB/ch9.h, and its value is 8.

Let's take 1,477th rows as an example.

1477 usual_dev (us_ SC _rb, us_pr_cb, usb_us_type_stor ),

Expand this macro, that is, define such a usb_device_id struct variable, its match_flags = struct, and binterfaceclass = usb_class_mass_storage, binterfacesubclass = us_ SC _rb, and binterfaceprotocol = us_pr_cb.

Usb_class_mass_storage does not need to be mentioned. Every device supported by this driver belongs to this class, or this class. But this class contains different subclass, such as subclass 02 for the CD-ROM device, 04 for the floppy disk drive, 06 for general SCSI devices. Communication protocols mainly include the CBI protocol and the bulk-only protocol.

Subclass macros such as us_ SC _rbare defined in the file include/Linux/usb_usual.h:

74 # define us_ SC _rb0x01/* typically, flash devices */

75 # define us_ SC _8020 0x02/* CD-ROM */

76 # define us_ SC _qic 0x03/* QIC-157 tapes */

77 # define us_ SC _ufi 0x04/* floppy */

78 # define us_ SC _8070 0x05/* removable media */

79 # define us_ SC _scsi 0x06/* transparent */

80 # define us_ SC _isd200 0x07/* isd200 ata */

81 # define us_ SC _min us_ SC _rb

82 # define us_ SC _max us_ SC _isd200

83

84 # define us_ SC _device 0xff/* use device's value */

Macros about the transfer protocol, such as us_pr_cb, are also defined in the same file:

88 # define us_pr_cbi 0x00/* control/bulk/interrupt */

89 # define us_pr_cb 0x01/* control/bulk w/o interrupt */

90 # define us_pr_bulk 0x50/* Bulk only */

91 # ifdef config_usb_storage_usbat

92 # define us_pr_usbat 0x80/X SCM-ATAPI bridge */

93 # endif

94 # ifdef config_usb_storage_sddr09

95 # define us_pr_eusb_sddr09 0x81/* SCM-SCSI bridge for SDDR-09 */

96 # endif

97 # ifdef config_usb_storage_sddr55

98 # define us_pr_sddr55 0x82/* SDDR-55 (made up )*/

99 # endif

100 # define us_pr_dpcm_usb 0xf0/* combination CB/sddr09 */

101 # ifdef config_usb_storage_freecom

102 # define us_pr_freecom 0xf1/* freecom */

103 # endif

104 # ifdef config_usb_storage_datafab

105 # define us_pr_datafab 0xf2/* datafab chipsets */

106 # endif

107 # ifdef config_usb_storage_jumpshot

108 # define us_pr_jumpshot 0xf3/* lexar jumpshot */

109 # endif

110 # ifdef config_usb_storage_alauda

111 # define us_pr_alauda 0xf4/* Alauda chipsets */

112 # endif

113 # ifdef config_usb_storage_karma

114 # define us_pr_karma 0xf5/* Rio karma */

115 # endif

116

117 # define us_pr_device 0xff/* use device's value */

Which of the following is the type of USB flash drive? USB Protocol stipulates that the subclass of the USB flash disk belongs to us_ SC _scsi, and its communication protocol uses bulk-only, that is, the us_pr_bulk shown here. Obviously, we will use these things later.

Then there is a match_flag. What does it mean? The macro usb_interface_info seems to have set match_flag of all devices to usb_device_id_match_int_info. Why? This macro comes from include/Linux/USB. h:

699 # define usb_device_id_match_int_info \

700 (usb_device_id_match_int_class | \

701 usb_device_id_match_int_subclass | \

702 usb_device_id_match_int_protocol)

Match_flag is used for the USB core. The USB core is used to find the driver suitable for the device and the device suitable for the driver, it compares the variables of struct usb_device_id. There are many Members in the struct usb_device_id struct. Do you have to compare each member? In fact, you only need to compare binterfaceclass, binterfacesubclass, and binterfaceprotocol to USB core. Include/Linux/mod_devicetable.h for struct
Each item in usb_device_id defines a macro:

122/* some useful macros to use to create structusb_device_id */

123 # define usb_device_id_match_vendor 0x0001

124 # define usb_device_id_match_product 0x0002

125 # define usb_device_id_match_dev_lo 0x0004

126 # define usb_device_id_match_dev_hi 0x0008

127 # define usb_device_id_match_dev_class 0x0010

128 # define usb_device_id_match_dev_subclass 0x0020

129 # define usb_device_id_match_dev_protocol 0x0040

130 # define usb_device_id_match_int_class 0x0080

131 # define usb_device_id_match_int_subclass 0x0100

132 # define usb_device_id_match_int_protocol 0x0200

Let's go back and compare structusb_device_id to see what these macros mean.

But you must have a question, that is, why are there two macros such as usual_dev and unusual_dev? What is the difference between them? As the name suggests, some devices belong to ordinary devices, but some are not ordinary devices. They either have characteristics that other devices do not possess, or the communication protocols they follow are somewhat different. For example, it is neither bulk-only nor CBI. For devices that do not play cards as common sense, code writers list them separately. Of course, from the Big classification perspective, they still belong to the USB Mass Storage category, otherwise they do not need to be placed under this directory.

To accommodate these alternative devices, great Linux kernel developers have prepared a file for them, which is the unusual_devs.h, which is encouraging many USB mass storage device manufacturers, manufacturers no longer have to worry about their devices being supported by the Linux kernel.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.