AHCI - ATAPI adjustments.
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 1 Jul 2009 17:43:15 +0000 (10:43 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 1 Jul 2009 17:43:15 +0000 (10:43 -0700)
Restrict the sense length to what ATAPI expects and add more legacy
initialization to the packet FIS.

This was an attempt to fix some reported issues with ATAPI, but it didn't
fix anything.  However, it didn't hurt either and the adjustments are at
least as good as the old ones.

sys/dev/disk/ahci/ahci.c
sys/dev/disk/ahci/ahci_cam.c

index b213743..e529f13 100644 (file)
@@ -2602,8 +2602,10 @@ ahci_get_err_ccb(struct ahci_port *ap)
 
        /* No commands may be active on the chip. */
        sact = ahci_pread(ap, AHCI_PREG_SACT);
-       if (sact != 0)
-               kprintf("ahci_get_err_ccb but SACT %08x != 0?\n", sact);
+       if (sact != 0) {
+               kprintf("%s: ahci_get_err_ccb but SACT %08x != 0?\n",
+                       PORTNAME(ap), sact);
+       }
        KKASSERT(ahci_pread(ap, AHCI_PREG_CI) == 0);
        KKASSERT((ap->ap_flags & AP_F_ERR_CCB_RESERVED) == 0);
        ap->ap_flags |= AP_F_ERR_CCB_RESERVED;
index b105006..1aab2a6 100644 (file)
@@ -1225,7 +1225,7 @@ ahci_xpt_scsi_atapi_io(struct ahci_port *ap, struct ata_port *atx,
 
        /*
         * Special handling to get the rfis back into host memory while
-        * still allowing the Sili chip to run commands in parallel to
+        * still allowing the chip to run commands in parallel to
         * ATAPI devices behind a PM.
         */
        flags |= ATA_F_AUTOSENSE;
@@ -1240,7 +1240,8 @@ ahci_xpt_scsi_atapi_io(struct ahci_port *ap, struct ata_port *atx,
        }
 
        /*
-        * Initialize the XA and FIS.
+        * Initialize the XA and FIS.  It is unclear how much of
+        * this has to mimic the equivalent ATA command.
         *
         * XXX not passing NULL at for direct attach!
         */
@@ -1249,13 +1250,21 @@ ahci_xpt_scsi_atapi_io(struct ahci_port *ap, struct ata_port *atx,
 
        fis->flags = ATA_H2D_FLAGS_CMD | at->at_target;
        fis->command = ATA_C_PACKET;
-       fis->device = 0;
+       fis->device = ATA_H2D_DEVICE_LBA;
        fis->sector_count = xa->tag << 3;
-       fis->features = ATA_H2D_FEATURES_DMA |
-                   ((flags & ATA_F_WRITE) ?
-                   ATA_H2D_FEATURES_DIR_WRITE : ATA_H2D_FEATURES_DIR_READ);
-       fis->lba_mid = 0x00;
-       fis->lba_high = 0x20;
+       if (flags & (ATA_F_READ | ATA_F_WRITE)) {
+               if (flags & ATA_F_WRITE) {
+                       fis->features = ATA_H2D_FEATURES_DMA |
+                                      ATA_H2D_FEATURES_DIR_WRITE;
+               } else {
+                       fis->features = ATA_H2D_FEATURES_DMA |
+                                      ATA_H2D_FEATURES_DIR_READ;
+               }
+       } else {
+               fis->lba_mid = 0;
+               fis->lba_high = 0;
+       }
+       fis->control = ATA_FIS_CONTROL_4BIT;
 
        xa->flags = flags;
        xa->data = csio->data_ptr;
@@ -1285,6 +1294,19 @@ ahci_xpt_scsi_atapi_io(struct ahci_port *ap, struct ata_port *atx,
        cdbd = (void *)xa->packetcmd;
 
        switch(cdbd->generic.opcode) {
+       case REQUEST_SENSE:
+               /*
+                * Force SENSE requests to the ATAPI sense length.
+                *
+                * It is unclear if this is needed or not.
+                */
+               if (cdbd->sense.length == SSD_FULL_SIZE) {
+                       kprintf("%s: Shortening sense request\n",
+                               PORTNAME(ap));
+                       cdbd->sense.length = offsetof(struct scsi_sense_data,
+                                                     extra_bytes[0]);
+               }
+               break;
        case INQUIRY:
                /*
                 * Some ATAPI devices can't handle long inquiry lengths,