Subject: Promise Ultra60/100 vs 48-bit LBA compliant drives
To: None <tech-kern@netbsd.org>
From: Takeshi Nakayama <tn@catvmics.ne.jp>
List: tech-kern
Date: 04/27/2003 07:41:57
----Next_Part(Sun_Apr_27_07:41:10_2003_914)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Hello,
I have i386 machine which has on-board Promise Ultra100 ATA
controller. When I connect 48-bit LBA compliant drive (IBM
IC35L120AVV207-0) to it, it does not work with any DMA mode (see
attached dmesg.log).
According to FreeBSD driver, it needs some extra operation in
48-bit LBA mode with some old Promise controllers. So I wrote an
attached patch, then works fine with DMA mode.
Could someone please review this patch?
-- Takeshi Nakayama
----Next_Part(Sun_Apr_27_07:41:10_2003_914)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="dmesg.log"
pciide0 at pci0 dev 6 function 0: Promise Ultra100/ATA Bus Master IDE Accelerator (rev. 0x02)
pciide0: bus-master DMA support present
pciide0: primary channel configured to native-PCI mode
pciide0: using irq 9 for native-PCI interrupt
wd0 at pciide0 channel 0 drive 0: <IC35L120AVV207-0>
wd0: drive supports 16-sector PIO transfers, LBA48 addressing
wd0: 115 GB, 16383 cyl, 16 head, 63 sec, 512 bytes/sect x 241254720 sectors
wd0: 32-bit data port
wd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 5 (Ultra/100)
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 5 (Ultra/100) (using DMA data transfers)
pciide0: secondary channel configured to native-PCI mode
wd1 at pciide0 channel 1 drive 0: <IC35L060AVER07-0>
wd1: drive supports 16-sector PIO transfers, LBA addressing
wd1: 58644 MB, 16383 cyl, 16 head, 63 sec, 512 bytes/sect x 120103200 sectors
wd1: 32-bit data port
wd1: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 5 (Ultra/100)
wd1(pciide0:1:0): using PIO mode 4, Ultra-DMA mode 5 (Ultra/100) (using DMA data transfers)
:
:
pciide0:0:0: lost interrupt
type: ata tc_bcount: 512 tc_skip: 0
pciide0:0:0: bus-master DMA error: missing interrupt, status=0x21
wd0: transfer error, downgrading to Ultra-DMA mode 2
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 2 (Ultra/33) (using DMA data transfers)
wd0d: DMA error reading fsbn 0 (wd0 bn 0; cn 0 tn 0 sn 0), retrying
pciide0:0:0: lost interrupt
type: ata tc_bcount: 512 tc_skip: 0
pciide0:0:0: bus-master DMA error: missing interrupt, status=0x21
wd0: transfer error, downgrading to Ultra-DMA mode 1
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 1 (using DMA data transfers)
wd0d: DMA error reading fsbn 0 (wd0 bn 0; cn 0 tn 0 sn 0), retrying
pciide0:0:0: lost interrupt
type: ata tc_bcount: 512 tc_skip: 0
pciide0:0:0: bus-master DMA error: missing interrupt, status=0x21
wd0: transfer error, downgrading to DMA mode 2
wd0(pciide0:0:0): using PIO mode 4, DMA mode 2 (using DMA data transfers)
wd0d: DMA error reading fsbn 0 (wd0 bn 0; cn 0 tn 0 sn 0), retrying
pciide0:0:0: lost interrupt
type: ata tc_bcount: 512 tc_skip: 0
pciide0:0:0: bus-master DMA error: missing interrupt, status=0x21
wd0: transfer error, downgrading to PIO mode 4
wd0(pciide0:0:0): using PIO mode 4
wd0d: DMA error reading fsbn 0 (wd0 bn 0; cn 0 tn 0 sn 0), retrying
wd0: soft error (corrected)
boot device: wd0
root on wd0a dumps on wd0b
root file system type: ffs
----Next_Part(Sun_Apr_27_07:41:10_2003_914)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="promise-ultra60_100-lba48.diff"
Index: sys/dev/ata/ata_wdc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata_wdc.c,v
retrieving revision 1.38
diff -u -d -r1.38 ata_wdc.c
--- sys/dev/ata/ata_wdc.c 2002/09/27 15:37:09 1.38
+++ sys/dev/ata/ata_wdc.c 2003/04/26 22:20:40
@@ -271,6 +271,8 @@
if (drvp->n_xfers <= NXFER)
drvp->n_xfers++;
dma_flags = (ata_bio->flags & ATA_READ) ? WDC_DMA_READ : 0;
+ if (ata_bio->flags & ATA_LBA48)
+ dma_flags |= WDC_DMA_LBA48;
}
if (ata_bio->flags & ATA_SINGLE)
ata_delay = ATA_DELAY;
Index: sys/dev/ic/wdcvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdcvar.h,v
retrieving revision 1.35
diff -u -d -r1.35 wdcvar.h
--- sys/dev/ic/wdcvar.h 2003/01/27 18:21:26 1.35
+++ sys/dev/ic/wdcvar.h 2003/04/26 22:20:41
@@ -124,8 +124,9 @@
void (*dma_start) __P((void *, int, int));
int (*dma_finish) __P((void *, int, int, int));
/* flags passed to dma_init */
-#define WDC_DMA_READ 0x01
-#define WDC_DMA_IRQW 0x02
+#define WDC_DMA_READ 0x01
+#define WDC_DMA_IRQW 0x02
+#define WDC_DMA_LBA48 0x04
int dma_status; /* status returned from dma_finish() */
#define WDC_DMAST_NOIRQ 0x01 /* missing IRQ */
#define WDC_DMAST_ERR 0x02 /* DMA error */
Index: sys/dev/pci/pciide.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pciide.c,v
retrieving revision 1.190
diff -u -d -r1.190 pciide.c
--- sys/dev/pci/pciide.c 2003/04/19 23:37:26 1.190
+++ sys/dev/pci/pciide.c 2003/04/26 22:20:44
@@ -210,6 +210,8 @@
void pdc20268_setup_channel __P((struct channel_softc*));
int pdc202xx_pci_intr __P((void *));
int pdc20265_pci_intr __P((void *));
+static void pdc20262_dma_start __P((void*, int, int));
+static int pdc20262_dma_finish __P((void*, int, int, int));
void opti_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void opti_setup_channel __P((struct channel_softc*));
@@ -4337,6 +4339,13 @@
sc->sc_wdcdev.channels = sc->wdc_chanarray;
sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
+ if (sc->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA66 ||
+ sc->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100 ||
+ sc->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100X) {
+ sc->sc_wdcdev.dma_start = pdc20262_dma_start;
+ sc->sc_wdcdev.dma_finish = pdc20262_dma_finish;
+ }
+
if (!PDC_IS_268(sc)) {
/* setup failsafe defaults */
mode = 0;
@@ -4661,6 +4670,61 @@
rv = 1;
}
return rv;
+}
+
+static void
+pdc20262_dma_start(v, channel, drive)
+ void *v;
+ int channel, drive;
+{
+ struct pciide_softc *sc = v;
+ struct pciide_dma_maps *dma_maps =
+ &sc->pciide_channels[channel].dma_maps[drive];
+ int atapi;
+
+ if (dma_maps->dma_flags & WDC_DMA_LBA48) {
+ atapi = (dma_maps->dma_flags & WDC_DMA_READ) ?
+ PDC262_ATAPI_LBA48_READ : PDC262_ATAPI_LBA48_WRITE;
+ atapi |= dma_maps->dmamap_xfer->dm_mapsize >> 1;
+ bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
+ PDC262_ATAPI(channel), atapi);
+ }
+
+ pciide_dma_start(v, channel, drive);
+}
+
+int
+pdc20262_dma_finish(v, channel, drive, force)
+ void *v;
+ int channel, drive;
+ int force;
+{
+ struct pciide_softc *sc = v;
+ struct pciide_dma_maps *dma_maps =
+ &sc->pciide_channels[channel].dma_maps[drive];
+ struct channel_softc *chp;
+ int atapi, error;
+
+ error = pciide_dma_finish(v, channel, drive, force);
+
+ if (dma_maps->dma_flags & WDC_DMA_LBA48) {
+ chp = sc->wdc_chanarray[channel];
+ atapi = 0;
+ if (chp->ch_drive[0].drive_flags & DRIVE_ATAPI ||
+ chp->ch_drive[1].drive_flags & DRIVE_ATAPI) {
+ if ((!(chp->ch_drive[0].drive_flags & DRIVE_UDMA) ||
+ (chp->ch_drive[1].drive_flags & DRIVE_UDMA) ||
+ !(chp->ch_drive[1].drive_flags & DRIVE_DMA)) &&
+ (!(chp->ch_drive[1].drive_flags & DRIVE_UDMA) ||
+ (chp->ch_drive[0].drive_flags & DRIVE_UDMA) ||
+ !(chp->ch_drive[0].drive_flags & DRIVE_DMA)))
+ atapi = PDC262_ATAPI_UDMA;
+ }
+ bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
+ PDC262_ATAPI(channel), atapi);
+ }
+
+ return error;
}
void
Index: sys/dev/pci/pciide_pdc202xx_reg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pciide_pdc202xx_reg.h,v
retrieving revision 1.8
diff -u -d -r1.8 pciide_pdc202xx_reg.h
--- sys/dev/pci/pciide_pdc202xx_reg.h 2002/07/26 14:11:35 1.8
+++ sys/dev/pci/pciide_pdc202xx_reg.h 2003/04/26 22:20:45
@@ -99,6 +99,8 @@
#define PDC262_ATAPI_DMA_READ 0x00001000
#define PDC262_ATAPI_DMA_WRITE 0x00002000
#define PDC262_ATAPI_UDMA 0x00004000
+#define PDC262_ATAPI_LBA48_READ 0x05000000
+#define PDC262_ATAPI_LBA48_WRITE 0x06000000
/*
* The timings provided here cmoes from the PDC20262 docs. I hope they are
----Next_Part(Sun_Apr_27_07:41:10_2003_914)----