1385 /*
1386 * sd_read_cache_type – called only from sd_revalidate_disk()
1387 * called with buffer of length SD_BUF_SIZE
1388 */
1389 static void
1390 sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
1391 {
1392 int len = 0, res;
1393 struct scsi_device *sdp = sdkp->device;
1394
1395 int dbd;
1396 int modepage;
1397 struct scsi_mode_data data;
1398 struct scsi_sense_hdr sshdr;
1399
1400 if (sdp->skip_ms_page_8)
1401 goto defaults;
1402
1403 if (sdp->type == TYPE_RBC) {
1404 modepage = 6;
1405 dbd = 8;
1406 } else {
1407 modepage = 8;
1408 dbd = 0;
1409 }
1410
1411 /* cautiously ask */
1412 res = sd_do_mode_sense(sdp, dbd, modepage, buffer, 4, &data, &sshdr);
1413
1414 if (!scsi_status_is_good(res))
1415 goto bad_sense;
1416
1417 if (!data.header_length) {
1418 modepage = 6;
1419 sd_printk(KERN_ERR, sdkp, "Missing header in MODE_SENSE response/n");
1420 }
1421
1422 /* that went OK, now ask for the proper length */
1423 len = data.length;
1424
1425 /*
1426 * We’re only interested in the first three bytes, actually.
1427 * But the data cache page is defined for the first 20.
1428 */
1429 if (len < 3)
1430 goto bad_sense;
1431 if (len > 20)
1432 len = 20;
1433
1434 /* Take headers and block descriptors into account */
1435 len += data.header_length + data.block_descriptor_length;
1436 if (len > SD_BUF_SIZE)
1437 goto bad_sense;
1438
1439 /* Get the data */
1440 res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr);
1441
1442 if (scsi_status_is_good(res)) {
1443 int offset = data.header_length + data.block_descriptor_length;
1444
1445 if (offset >= SD_BUF_SIZE – 2) {
1446 sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response/n");
1447 goto defaults;
1448 }
1449
1450 if ((buffer[offset] & 0x3f) != modepage) {
1451 sd_printk(KERN_ERR, sdkp, "Got wrong page/n");
1452 goto defaults;
1453 }
1454
1455 if (modepage == 8) {
1456 sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
1457 sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);
1458 } else {
1459 sdkp->WCE = ((buffer[offset + 2] & 0x01) == 0);
1460 sdkp->RCD = 0;
1461 }
1462
1463 sdkp->DPOFUA = (data.device_specific & 0x10) != 0;
1464 if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) {
1465 sd_printk(KERN_NOTICE, sdkp,
1466 "Uses READ/WRITE(6), disabling FUA/n");
1467 sdkp->DPOFUA = 0;
1468 }
1469
1470 sd_printk(KERN_NOTICE, sdkp,
1471 "Write cache: %s, read cache: %s, %s/n",
1472 sdkp->WCE ? "enabled" : "disabled",
1473 sdkp->RCD ? "disabled" : "enabled",
1474 sdkp->DPOFUA ? "supports DPO and FUA"
1475 : "doesn’t support DPO or FUA");
1476
1477 return;
1478 }
1479
1480 bad_sense:
1481 if (scsi_sense_valid(&sshdr) &&
1482 sshdr.sense_key == ILLEGAL_REQUEST &&
1483 sshdr.asc == 0x24 && sshdr.ascq == 0x0)
1484 /* Invalid field in CDB */
1485 sd_printk(KERN_NOTICE, sdkp, "Cache data unavailable/n");
1486 else
1487 sd_printk(KERN_ERR, sdkp, "Asking for cache data failed/n");
1488
1489 defaults:
1490 sd_printk(KERN_ERR, sdkp, "Assuming drive cache: write through/n");
1491 sdkp->WCE = 0;
1492 sdkp->RCD = 0;
1493 sdkp->DPOFUA = 0;
1494 }
理想的路总是为有信心的人预备着