Jeff,

Patch 3/3: Fix pdc2027x ATAPI DMA lost irq problem

Description:
  Sometimes pdc2027x will lost irq after ATAPI DMA data transfer.
  With the previous rule (cmd->request_bufflen % 256), the ATAPI DMA irq lost
problem still occurs during the test.

  Root cause for the irq lost is unknown. I've tried your ATAPI DMA alignment
patch, but the problem still occurs, even the buffer is aligned. I guess it is 
pdc2027x hardware problem.

  The following workarounds are adapted from the Promise pdc618 GPL driver.
They seems know about the problem and has the workaround.

Changes:
  - Only turn on ATAPI DMA for READ, WRITE, READ_CD and READ_DVD_STRUCTURE 
commands.
  - For WRITE_10, if LBA -45150 (FFFF4FA2h) to  -1 (FFFFFFFFh) then use PIO 
mode.

For your review, thanks.

Albert

Signed-off-by: Albert Lee <[EMAIL PROTECTED]>



--- 02_pdc_micro/drivers/scsi/pata_pdc2027x.c   2005-08-03 15:44:16.000000000 
+0800
+++ 03_pdc_atapi_dma/drivers/scsi/pata_pdc2027x.c       2005-08-05 
00:41:53.000000000 +0800
@@ -29,7 +29,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "pata_pdc2027x"
-#define DRV_VERSION    "0.71"
+#define DRV_VERSION    "0.72"
 #undef PDC_DEBUG
 
 #ifdef PDC_DEBUG
@@ -467,11 +467,40 @@
 static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc)
 {
        struct scsi_cmnd *cmd = qc->scsicmd;
-       int rc = 0;
+       u8 *scsicmd = cmd->cmnd;
+       int rc = 1; /* atapi dma off by default */
+       u32 lba;
 
-       /* pdc2027x can only do ATAPI DMA for specific buffer size */
-       if (cmd->request_bufflen % 256)
-               rc = 1;
+       /*
+        * pdc2027x might lost irq if ATAPI DMA is used
+        * for commands not in the white list.
+        */
+       switch (scsicmd[0]) {
+       case READ_10:
+       case READ_12:
+       case READ_6:
+       case WRITE_12:
+       case WRITE_6:
+       case 0xad: /* READ_DVD_STRUCTURE */
+       case 0xbe: /* READ_CD */
+               /* ATAPI DMA is ok */
+               rc = 0;
+               break;
+       case WRITE_10:
+               /* LBA -45150 (FFFF4FA2h) to 
+                * -1 (FFFFFFFFh) shall use PIO mode
+                */
+               lba = (scsicmd[2] << 24) | (scsicmd[3] << 16) |
+                       (scsicmd[4] << 8) | scsicmd[5]; 
+
+               if (lba < 0xffff4fa2)
+                       /* ATAPI DMA is ok */
+                       rc = 0;
+
+               break;
+       default:
+               ;
+       }
 
        return rc;
 }

Reply via email to