--- 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 #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; }