Linux I'm a SCSI hard drive (4) Three Mountains (1)

Source: Internet
Author: User
Tags format definition

It was hard to end sd_spinup_disk (). Now we met three mountains. they are sd_read_capacity (), sd_read_write_protect_flag (), sd_read_cache_type (). To continue reading them, we have to overturn these three mountains first. the old three mountains have been successfully overturned under the wise leadership of Chairman Mao, but today our people are under the oppression of the New Three mountains. These three functions are comparable to the notorious reform of housing reform. you need to know the entire SD. the file C contains only 1900 rows, but all three functions account for 360 rows!

The first Dashan, sd_read_capacity. 1130/* 1131 * read disk capacity 1132 */1133 static void 1134 sd_read_capacity (struct scsi_disk * sdkp, unsigned char * buffer) 1135 {1136 unsigned char cmd [16]; 1137 int the_result, retries; 1138 int sector_size = 0; 1139 int longrc = 0; 1140 struct scsi_sense_hdr sshdr; 1141 int sense_valid = 0; 1142 struct scsi_device * SDP = sdkp-> device; 1143 1144 repeat: 1145 retries = 3; 1146 do {1147 if (longrc) {1148 memset (void *) cmd, 0, 16); 1149 cmd [0] = service_action_in; 1150 cmd [1] = sai_read_capacity_16; 1151 cmd [13] = 12; 1152 memset (void *) buffer, 0, 12 ); 1153} else {1154 cmd [0] = read_capacity; 1155 memset (void *) & cmd [1], 0, 9); 1156 memset (void *) buffer, 0, 8); 1157} 1158 1159 the_result = scsi_execute_req (SDP, CMD, dma_from_device, 1160 buffer, longr C? 12: 8, & sshdr, 1161 sd_timeout, sd_max_retries); 1162 1163 if (media_not_present (sdkp, & sshdr) 1164 return; 1165 1166 if (the_result) 1167 sense_valid = scsi_sense_valid (& sshdr); 1168 retries --; 1169 1170} while (the_result & retries); 1171 1172 if (the_result &&! Longrc) {1173 sd_printk (kern_notice, sdkp, "Read capacity failed/N"); 1174 sd_print_result (sdkp, the_result); 1175 if (driver_byte (the_result) & driver_sense) 1176 sd_print_sense_hdr (sdkp, & sshdr); 1177 else 1178 sd_printk (kern_notice, sdkp, "sense not available. /n "); 1179 1180/* Set dirty bit for removable devices if not ready-1181 * sometimes drives will not report this properly. /1182 if (SDP-> removable & 1183 sense_valid & sshdr. sense_key = not_ready) 1184 SDP-> changed = 1; 1185 1186/* either no media are present but the drive didn't tell us, 1187 or they are present but the read capacity command fails */1188/* sdkp-> media_present = 0; -- not always correct */1189 sdkp-> capacity = 0; /* unknown mapped to zero-as usual */1190 1191 return; 1192} else if (the_result & lon GRC) {1193/* read capacity (16) has been failed */1194 sd_printk (kern_notice, sdkp, "Read capacity (16) failed/N"); 1195 sd_print_result (sdkp, the_result); 1196 sd_printk (kern_notice, sdkp, "use 0 xffffffff as device size/N"); 1197 1198 sdkp-> capacity = 1 + (sector_t) 0 xffffffff; 1199 goto got_data; 1200} 1201 1202 if (! Longrc) {1203 sector_size = (buffer [4] <24) | 1204 (buffer [5] <16) | (buffer [6] <8) | buffer [7]; 1205 if (buffer [0] = 0xff & buffer [1] = 0xff & 1206 buffer [2] = 0xff & buffer [3] = 0xff) {1207 if (sizeof (sdkp-> capacity)> 4) {1208 sd_printk (kern_notice, sdkp, "very big device. & quot; 1209 & quot; trying to use read capacity (16 ). /n "); 1210 longrc = 1; 1211 goto repeat; 1212} 1213 sd_printk (kern_e RR, sdkp, "too big for this kernel. use "1214" A kernel compiled with support for large "1215" Block devices. /n "); 1216 sdkp-> capacity = 0; 1217 goto got_data; 1218} 1219 sdkp-> capacity = 1 + (sector_t) buffer [0] <24) | 1220 (buffer [1] <16) | 1221 (buffer [2] <8) | 1222 buffer [3]); 1223} else {1224 sdkp-> capacity = 1 + (u64) buffer [0] <56) | 1225 (u64) buffer [1] <48) | 1226 (u64) B Uffer [2] <40) | 1227 (u64) buffer [3] <32) | 1228 (sector_t) buffer [4] <24) | 1229 (sector_t) buffer [5] <16) | 1230 (sector_t) buffer [6] <8) | 1231 (sector_t) buffer [7]); 1232 1233 sector_size = (buffer [8] <24) | 1234 (buffer [9] <16) | (buffer [10] <8) | buffer [11]; 1235} 1236 1237/* Some devices return the total number of sectors, not the 1238 * highest sector number. make the nece Ssary adjustment. */1239 if (SDP-> fix_capacity) {1240 -- sdkp-> capacity; 1241 1242/* Some devices have version which report the correct sizes 1243 * and others which do not. we guess size according to a heuristic 1244 * and err on the side of lowering the capacity. */1245} else {1246 if (SDP-> guess_capacity) 1247 if (sdkp-> capacity & 0x01) /* odd sizes are odd */1248 -- sdkp-> capacity; 1249} 1250 1251 got_data: 1252 if (sector_size = 0) {1253 sector_size = 512; 1254 sd_printk (kern_notice, sdkp, "sector size 0 reported," 1255 "Assuming 512. /n "); 1256} 1257 1258 if (sector_size! = 512 & 1259 sector_size! = 1024 & 1260 sector_size! = 2048 & 1261 sector_size! = 4096 & 1262 sector_size! = 256) {1263 sd_printk (kern_notice, sdkp, "unsupported sector size % d. /n ", 1264 sector_size); 1265/* 1266 * the user might want to re-format the drive with 1267 * A supported sectorsize. once this happens, it 1268 * wocould be relatively trivial to set the thing up. 1269 * For this reason, we leave the thing in the table. 1270 */1271 sdkp-> capacity = 0; 1272/* 1273 * set a bogus sector size so th E normal read/write 1274 * logic in the block layer will eventually refuse any 1275 * request on this device without tripping over power 1276 * of two sector size assumptions 1277 */1278 sector_size = 512; 1279} 1280 {1281/* 1282 * The msdos FS needs to know the hardware sector size 1283 * So I have created this table. see ll_rw_blk.c 1284 * Jacques gelinas (Jacques@solucorp.qc.ca) 1285 */128 6 int hard_sector = sector_size; 1287 sector_t SZ = (sdkp-> capacity/2) * (hard_sector/256); 1288 request_queue_t * queue = SDP-> request_queue; 1289 sector_t MB = SZ; 1290 1291 blk_queue_hardsect_size (queue, hard_sector); 1292/* avoid 64-bit division on 32-bit platforms */1293 sector_div (SZ, 625 ); 1294 MB-= SZ-974; 1295 sector_div (MB, 1950); 1296 1297 sd_printk (kern_notice, sdkp, 1298 "% LlU % d- Byte hardware sectors (% LlU MB)/n ", 1299 (unsigned long) sdkp-> capacity, 1300 hard_sector, (unsigned long) MB ); 1301} 1302 1303/* rescale capacity to 512-byte units */1304 if (sector_size = 4096) 1305 sdkp-> capacity <= 3; 1306 else if (sector_size = 2048) 1307 sdkp-> capacity <= 2; 1308 else if (sector_size = 1024) 1309 sdkp-> capacity <= 1; 1310 else if (sector_size = 256) 1311 SD KP-> capacity> = 1; 1312 1313 sdkp-> device-> sector_size = sector_size; 1314} more than 200 rows. in short, this function is expressed in one sentence as knowing the disk capacity, or specifically, sending the read capacity command. brothers familiar with the SCSI command set should know that many SCSI commands have at least two versions. The command formats of different versions are different, and of course the returned information is different, for example, the read capacity command has two versions: 10 bytes and 16 bytes. the read capacity (10) command and read capacity (16) command are described respectively in sections 5.10 and 5.11 Of The SBC-2. the latter has more protection information than the former. however, we do not know which command to use before reading it. Therefore, the basic idea here is to use a short command first. If it fails, try the long command. This is the 1211-line goto repea command. T. set longrc to 1 in row 1210 before goto repeat. here we first give the format definition of the read capacity command from the SBC-2: We can use an instance to describe this command, sg_readcap can manually send the read capacity command. the following is the result of sending this command to one of my m USB flash drives. [root @ localhost ~] # Sg_readcap/dev/sdcread capacity results: last logical block address = 257535 (0x3edff), number of blocks = 257536 Logical Block length = 512 byteshence: device size: 131858432 bytes, 125.8 MiB, 0.13 GB at the same time, we can see from the code that this function is actually more troublesome in the judgment of the buffer array. in fact, the buffer array loads the returned information of the read capacity command. starting from row 3, we know that this buffer was applied in sd_revalidate_disk. the size is sd_buf_size, Which is 512 bytes. so what exactly does the buffer data look like? In the SBC-2, table-35 gives the returned data of read capacity (10)

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.