]> git.hungrycats.org Git - linux/commitdiff
[libata] scsi simulator improvements: MODE SENSE, SEEK(6,10), REZERO_UNIT
authorJeff Garzik <jgarzik@redhat.com>
Sun, 16 May 2004 20:21:15 +0000 (16:21 -0400)
committerJeff Garzik <jgarzik@redhat.com>
Sun, 16 May 2004 20:21:15 +0000 (16:21 -0400)
* SEEK(6), SEEK(10), and REZERO_UNIT are no-ops.  Unconditionally
  complete these commands with success.
* MODE SENSE caching page work:
* correct page length
* set bit, if read-ahead is disabled
* set bit, if writeback caching is enabled
  (previously, this bit was never set, even if
   writeback caching was enabled)
* add MODE SENSE r/w error recovery page

drivers/scsi/libata-scsi.c
include/linux/ata.h

index 947f9ed366728aafe49f01f0ed4a0469cfc0df7a..f5a1cd723a958a2fb399917886a5da1f8a44e71d 100644 (file)
@@ -695,9 +695,17 @@ static void ata_msense_push(u8 **ptr_io, const u8 *last,
 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);
@@ -723,6 +731,31 @@ static unsigned int ata_msense_ctl_mode(u8 **ptr_io, const u8 *last)
        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.
@@ -762,6 +795,10 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
        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;
@@ -772,6 +809,7 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
                }
 
        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;
@@ -1118,6 +1156,10 @@ static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
        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? */
index 45c2b4670739cfb707730f176279b2009715e09f..919509f32327d6a591d56e32a8ece5bca95ed394 100644 (file)
@@ -202,6 +202,7 @@ struct ata_taskfile {
 };
 
 #define ata_id_is_ata(dev)     (((dev)->id[0] & (1 << 15)) == 0)
+#define ata_id_rahead_enabled(dev) ((dev)->id[85] & (1 << 6))
 #define ata_id_wcache_enabled(dev) ((dev)->id[85] & (1 << 5))
 #define ata_id_has_lba48(dev)  ((dev)->id[83] & (1 << 10))
 #define ata_id_has_wcache(dev) ((dev)->id[82] & (1 << 5))