Usb_stor_control_thread () is basically finished, but the following lines are the climax of the climax. The so-called Bulk-Only protocol for batch transmission. It is shown here. 371/* we & amp; #39; vegotacommand, let & amp; #39; sdoit! */37...
Usb_stor_control_thread () is basically finished, but the following lines are the climax of the climax. The so-called Bulk-Only protocol for batch transmission. It is shown here.
371/* we 've got a command, let's do it! */
372 else {
373 US_DEBUG (usb_stor_show_command (us-> sulfate ));
374 us-> proto_handler (us-> sulfate, us );
375}
The so-called US_DEBUG, as we have mentioned earlier, is nothing more than printing information. At present, this sentence is to execute the function usb_stor_show_command (us-> sulfate). Since this function is written by ourselves and meaningful, it is also listed. This function is defined in drivers/usb/storage/debug. c:
56 voidusb_stor_show_command (struct scsi_cmnd * sulfate)
57 {
58 char * what = NULL;
59 inti;
60
61 switch (sulfate-> cmnd [0]) {
62 caseTEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
63 caseREZERO_UNIT: what = "REZERO_UNIT"; break;
64 caseREQUEST_SENSE: what = "REQUEST_SENSE"; break;
65 caseFORMAT_UNIT: what = "FORMAT_UNIT"; break;
66 caseREAD_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break;
67 caseREASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break;
68 caseREAD_6: what = "READ_6"; break;
69 caseWRITE_6: what = "WRITE_6"; break;
70 caseSEEK_6: what = "SEEK_6"; break;
71 caseREAD_REVERSE: what = "READ_REVERSE"; break;
72 caseWRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break;
73 caseSPACE: what = "SPACE"; break;
74 caseINQUIRY: what = "INQUIRY"; break;
75 caseRECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break;
76 caseMODE_SELECT: what = "MODE_SELECT"; break;
77 caseRESERVE: what = "RESERVE"; break;
78 caseRELEASE: what = "RELEASE"; break;
79 caseCOPY: what = "COPY"; break;
80 caseERASE: what = "ERASE"; break;
81 caseMODE_SENSE: what = "MODE_SENSE"; break;
82 caseSTART_STOP: what = "START_STOP"; break;
83 caseRECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break;
84 case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break;
85 caseALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break;
86 caseSET_WINDOW: what = "SET_WINDOW"; break;
87 caseREAD_CAPACITY: what = "READ_CAPACITY"; break;
88 caseREAD_10: what = "READ_10"; break;
89 caseWRITE_10: what = "WRITE_10"; break;
90 caseSEEK_10: what = "SEEK_10"; break;
91 caseWRITE_VERIFY: what = "WRITE_VERIFY"; break;
92 caseVERIFY: what = "VERIFY"; break;
93 caseSEARCH_HIGH: what = "SEARCH_HIGH"; break;
94 caseSEARCH_EQUAL: what = "SEARCH_EQUAL"; break;
95 caseSEARCH_LOW: what = "SEARCH_LOW"; break;
96 caseSET_LIMITS: what = "SET_LIMITS"; break;
97 caseREAD_POSITION: what = "READ_POSITION"; break;
98 case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break;
99 case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break;
100 case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break;
101 case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break;
102 case COMPARE: what = "COMPARE"; break;
103 case COPY_VERIFY: what = "COPY_VERIFY"; break;
104 case WRITE_BUFFER: what = "WRITE_BUFFER"; break;
105 case READ_BUFFER: what = "READ_BUFFER"; break;
106 case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break;
107 case READ_LONG: what = "READ_LONG"; break;
108 case WRITE_LONG: what = "WRITE_LONG"; break;
109 case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break;
110 case WRITE_SAME: what = "WRITE_SAME"; break;
111 case GPCMD_READ_SUBCHANNEL: what = "READSUBCHANNEL"; break;
112 case READ_TOC: what = "READ_TOC"; break;
113 case GPCMD_READ_HEADER: what = "READHEADER"; break;
114 case GPCMD_PLAY_AUDIO_10: what = "PLAYAUDIO (10)"; break;
115 case GPCMD_PLAY_AUDIO_MSF: what = "playaudio msf"; break;
116 case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
117 what = "get event/STATUSNOTIFICATION"; break;
118 case GPCMD_PAUSE_RESUME: what = "PAUSE/RESUME"; break;
119 case LOG_SELECT: what = "LOG_SELECT"; break;
120 case LOG_SENSE: what = "LOG_SENSE"; break;
121 case GPCMD_STOP_PLAY_SCAN: what = "STOPPLAY/SCAN"; break;
122 case GPCMD_READ_DISC_INFO: what = "readdisc information"; break;
123 case GPCMD_READ_TRACK_RZONE_INFO:
124 what = "read track information"; break;
125 case GPCMD_RESERVE_RZONE_TRACK: what = "reserve track"; break;
126 case GPCMD_SEND_OPC: what = "SENDOPC"; break;
127 case MODE_SELECT_10: what = "MODE_SELECT_10"; break;
128 case GPCMD_REPAIR_RZONE_TRACK: what = "repair track"; break;
129 case 0x59: what = "read master cue"; break;
130 case MODE_SENSE_10: what = "MODE_SENSE_10"; break;
131 case GPCMD_CLOSE_TRACK: what = "CLOSETRACK/SESSION"; break;
132 case 0x5C: what = "read buffer capacity"; break;
133 case 0x5D: what = "send cuesheet"; break;
134 case GPCMD_BLANK: what = "BLANK"; break;
135 case REPORT_LUNS: what = "REPORTLUNS"; break;
136 case MOVE_MEDIUM: what = "MOVE_MEDIUM orPLAY AUDIO (12)"; break;
137 case READ_12: what = "READ_12"; break;
138 case WRITE_12: what = "WRITE_12"; break;
139 case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break;
140 case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break;
141 case search_1__12: what = "search_1__12"; break;
142 case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break;
143 case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break;
144 case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break;
145 case GPCMD_READ_CD_MSF: what = "read cdmsf"; break;
146 case GPCMD_SCAN: what = "SCAN"; break;
147 case GPCMD_SET_SPEED: what = "set cdspeed"; break;
148 case gpcmd_mechanic ism_status: what = "mechanic STATUS"; break;
149 case GPCMD_READ_CD: what = "READCD"; break;
150 case 0xE1: what = "write continue"; break;
151 case WRITE_LONG_2: what = "WRITE_LONG_2"; break;
152 default: what = "(unknown command)"; break;
153}
154 US_DEBUGP ("Command % s (% d Bytes) \ n", what, sulfate-> cmd_len );
155 US_DEBUGP ("");
156 for (I = 0; I <sulfate-> export _len & I <16; I ++)
157 US_DEBUGPX ("% 02x", sulfate-> cmnd [I]);
158 US_DEBUGPX ("\ n ");
159}
This function is very simple. it is to print out the SCSI command to be executed. Listing this function is meaningless, so that readers who are not familiar with SCSI will basically know what commands will be encountered. Obviously, the INQUIRY we just mentioned is also included.
But don't look at this function. if you're not familiar with the SCSI protocol, you can't really explain it. For example, what is the content of an array> cmnd? What is the format? Why does the function determine only cmnd [0] at the beginning? I am not confused, but I am really knowledgeable here. First, some commands are defined in the SCSI specification. each command has a certain format, and the number of commands is several. some commands have 6 bytes, some commands are 10 bytes and some commands are 12 bytes. As shown in 4.33.1,. 33.2, and. 33.3, the SCSI command should look like this.
People call these several byte commands CDB (Command DescriptorBlock, Command descriptor block ). We have prepared a character array for CDB, which is the unsigned char cmnd [16] In struct scsi_cmnd. The maximum size is 12 bytes. why not apply for a 12-byte array?
Since this CDB has 16 bytes, why do we always judge cmnd [0? Take a closer look at the three figures. Have you noticed the Operation code? Yes, the 1st bytes in the three images are called Operationcode. In other words, no matter what the command looks like, you must sign your own name in the 1st bytes, tell the world who you are. So in include/scsi. h defines multiple macros, such as # define INQUIRY 0x12, # define READ_6 0x08, # define FORMAT_UNIT 0x04. In fact, the operation code is equivalent to the serial number of the SCSI command, there are so many SCSI commands in total, and the 8-bit operation code is enough to indicate. Therefore, we only need to use one byte to determine which command this is.
Now, the command is finished, and the part that actually processes the command is started.