Author: mav
Date: Fri Nov 16 03:04:30 2012
New Revision: 243125
URL: http://svnweb.freebsd.org/changeset/base/243125

Log:
  MFC r242156:
  Implement CAM_ATAIO_NEEDRESULT (fetching full set of result registers) for
  ata(4) driver in ATA_CAM mode.  That slighty improves error reporting and
  also should fix `smartctl -l scterc /dev/adaX` operation.

Modified:
  stable/9/sys/dev/ata/ata-all.c
  stable/9/sys/dev/ata/ata-all.h
  stable/9/sys/dev/ata/ata-lowlevel.c
  stable/9/sys/dev/ata/chipsets/ata-ahci.c
  stable/9/sys/dev/ata/chipsets/ata-siliconimage.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/ata/ata-all.c
==============================================================================
--- stable/9/sys/dev/ata/ata-all.c      Fri Nov 16 03:02:07 2012        
(r243124)
+++ stable/9/sys/dev/ata/ata-all.c      Fri Nov 16 03:04:30 2012        
(r243125)
@@ -1492,6 +1492,8 @@ ata_cam_begin_transaction(device_t dev, 
                request->u.ata.lba |= ((uint64_t)ccb->ataio.cmd.lba_high << 16) 
|
                                      ((uint64_t)ccb->ataio.cmd.lba_mid << 8) |
                                       (uint64_t)ccb->ataio.cmd.lba_low;
+               if (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT)
+                       request->flags |= ATA_R_NEEDRESULT;
                if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE &&
                    ccb->ataio.cmd.flags & CAM_ATAIO_DMA)
                        request->flags |= ATA_R_DMA;

Modified: stable/9/sys/dev/ata/ata-all.h
==============================================================================
--- stable/9/sys/dev/ata/ata-all.h      Fri Nov 16 03:02:07 2012        
(r243124)
+++ stable/9/sys/dev/ata/ata-all.h      Fri Nov 16 03:04:30 2012        
(r243125)
@@ -397,6 +397,7 @@ struct ata_request {
 #define         ATA_R_REQUEUE           0x00000400
 #define         ATA_R_THREAD            0x00000800
 #define         ATA_R_DIRECT            0x00001000
+#define         ATA_R_NEEDRESULT        0x00002000
 
 #define         ATA_R_ATAPI16           0x00010000
 #define         ATA_R_ATAPI_INTR        0x00020000

Modified: stable/9/sys/dev/ata/ata-lowlevel.c
==============================================================================
--- stable/9/sys/dev/ata/ata-lowlevel.c Fri Nov 16 03:02:07 2012        
(r243124)
+++ stable/9/sys/dev/ata/ata-lowlevel.c Fri Nov 16 03:04:30 2012        
(r243125)
@@ -116,6 +116,7 @@ ata_begin_transaction(struct ata_request
                } while (request->status & ATA_S_BUSY && timeout--);
                if (request->status & ATA_S_ERROR)
                    request->error = ATA_IDX_INB(ch, ATA_ERROR);
+               ch->hw.tf_read(request);
                goto begin_finished;
            }
 
@@ -253,8 +254,9 @@ ata_end_transaction(struct ata_request *
        if (request->flags & ATA_R_TIMEOUT)
            goto end_finished;
 
-       /* on control commands read back registers to the request struct */
-       if (request->flags & ATA_R_CONTROL) {
+       /* Read back registers to the request struct. */
+       if ((request->status & ATA_S_ERROR) ||
+           (request->flags & (ATA_R_CONTROL | ATA_R_NEEDRESULT))) {
            ch->hw.tf_read(request);
        }
 
@@ -332,6 +334,12 @@ ata_end_transaction(struct ata_request *
        else if (!(request->flags & ATA_R_TIMEOUT))
            request->donecount = request->bytecount;
 
+       /* Read back registers to the request struct. */
+       if ((request->status & ATA_S_ERROR) ||
+           (request->flags & (ATA_R_CONTROL | ATA_R_NEEDRESULT))) {
+           ch->hw.tf_read(request);
+       }
+
        /* release SG list etc */
        ch->dma.unload(request);
 

Modified: stable/9/sys/dev/ata/chipsets/ata-ahci.c
==============================================================================
--- stable/9/sys/dev/ata/chipsets/ata-ahci.c    Fri Nov 16 03:02:07 2012        
(r243124)
+++ stable/9/sys/dev/ata/chipsets/ata-ahci.c    Fri Nov 16 03:04:30 2012        
(r243125)
@@ -555,8 +555,10 @@ ata_ahci_end_transaction(struct ata_requ
     if (request->status & ATA_S_ERROR)  
        request->error = tf_data >> 8;
 
-    /* on control commands read back registers to the request struct */
-    if (request->flags & ATA_R_CONTROL) {
+    /* Read back registers to the request struct. */
+    if ((request->flags & ATA_R_ATAPI) == 0 &&
+       ((request->status & ATA_S_ERROR) ||
+        (request->flags & (ATA_R_CONTROL | ATA_R_NEEDRESULT)))) {
        u_int8_t *fis = ch->dma.work + ATA_AHCI_FB_OFFSET + 0x40;
 
        request->u.ata.count = fis[12] | ((u_int16_t)fis[13] << 8);

Modified: stable/9/sys/dev/ata/chipsets/ata-siliconimage.c
==============================================================================
--- stable/9/sys/dev/ata/chipsets/ata-siliconimage.c    Fri Nov 16 03:02:07 
2012        (r243124)
+++ stable/9/sys/dev/ata/chipsets/ata-siliconimage.c    Fri Nov 16 03:04:30 
2012        (r243125)
@@ -658,8 +658,10 @@ ata_siiprb_end_transaction(struct ata_re
        }
     }
 
-    /* on control commands read back registers to the request struct */
-    if (request->flags & ATA_R_CONTROL) {
+    /* Read back registers to the request struct. */
+    if ((request->flags & ATA_R_ATAPI) == 0 &&
+       ((request->status & ATA_S_ERROR) ||
+        (request->flags & (ATA_R_CONTROL | ATA_R_NEEDRESULT)))) {
        request->u.ata.count = prb->fis[12] | ((u_int16_t)prb->fis[13] << 8);
        request->u.ata.lba = prb->fis[4] | ((u_int64_t)prb->fis[5] << 8) |
                             ((u_int64_t)prb->fis[6] << 16);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to