static unsigned int ata_msense_caching(struct ata_device *dev, u8 **ptr_io,
const u8 *last)
{
- u8 page[7] = { 0xf, 0, 0x10, 0, 0x8, 0xa, 0 };
- if (dev->flags & ATA_DFLAG_WCACHE)
- page[6] = 0x4;
+ u8 page[] = {
+ 0x8, /* page code */
+ 0x12, /* page length */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 zeroes */
+ 0, 0, 0, 0, 0, 0, 0, 0 /* 8 zeroes */
+ };
+
+ if (ata_id_wcache_enabled(dev))
+ page[2] |= (1 << 2); /* write cache enable */
+ if (!ata_id_rahead_enabled(dev))
+ page[12] |= (1 << 5); /* disable read ahead */
ata_msense_push(ptr_io, last, page, sizeof(page));
return sizeof(page);
return sizeof(page);
}
+/**
+ * ata_msense_rw_recovery - Simulate MODE SENSE r/w error recovery page
+ * @dev: Device associated with this MODE SENSE command
+ * @ptr_io: (input/output) Location to store more output data
+ * @last: End of output data buffer
+ *
+ * Generate a generic MODE SENSE r/w error recovery page.
+ *
+ * LOCKING:
+ * None.
+ */
+
+static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
+{
+ const u8 page[] = {
+ 0x1, /* page code */
+ 0xa, /* page length */
+ (1 << 7) | (1 << 6), /* note auto r/w reallocation */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 9 zeroes */
+ };
+
+ ata_msense_push(ptr_io, last, page, sizeof(page));
+ return sizeof(page);
+}
+
/**
* ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands
* @args: Port / device / SCSI command of interest.
last = rbuf + buflen - 1;
switch(scsicmd[2] & 0x3f) {
+ case 0x01: /* r/w error recovery */
+ output_len += ata_msense_rw_recovery(&p, last);
+ break;
+
case 0x08: /* caching */
output_len += ata_msense_caching(dev, &p, last);
break;
}
case 0x3f: /* all pages */
+ output_len += ata_msense_rw_recovery(&p, last);
output_len += ata_msense_caching(dev, &p, last);
output_len += ata_msense_ctl_mode(&p, last);
break;
args.done = done;
switch(scsicmd[0]) {
+ /* no-op's, complete with success */
+ case REZERO_UNIT:
+ case SEEK_6:
+ case SEEK_10:
case TEST_UNIT_READY:
case FORMAT_UNIT: /* FIXME: correct? */
case SEND_DIAGNOSTIC: /* FIXME: correct? */