From 838b8e23b90325043ffd420c4a5da472f0bee7e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Schmidt?= Date: Mon, 8 Nov 1999 21:36:00 +0000 Subject: [PATCH] Unbreak ATAPI on the Aladdin chipset, only DMA access worked. Try to use a 32bit mask on the IO addresses, this fixes the alpha and hopefully doesn't break on any i386 machines. Try to enable both read & write cache on disks, they should be as default, but better be sure.. --- sys/dev/ata/ata-all.c | 48 ++++++++++++++++++-------------- sys/dev/ata/ata-all.h | 4 ++- sys/dev/ata/ata-disk.c | 9 ++++++ sys/dev/ata/ata-dma.c | 63 +++++++++++++++--------------------------- 4 files changed, 63 insertions(+), 61 deletions(-) diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index e6e10462655b..99f677cf1e01 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -74,6 +74,7 @@ #if SMP == 0 #define isa_apic_irq(x) x #endif +#define IOMASK 0xfffffffc /* XXX SOS 0xfffc */ /* prototypes */ static int32_t ata_probe(int32_t, int32_t, int32_t, device_t, int32_t *); @@ -263,9 +264,9 @@ ata_pciattach(device_t dev) irq1 = 14; } else { - iobase_1 = pci_read_config(dev, 0x10, 4) & 0xfffc; - altiobase_1 = pci_read_config(dev, 0x14, 4) & 0xfffc; - bmaddr_1 = pci_read_config(dev, 0x20, 4) & 0xfffc; + iobase_1 = pci_read_config(dev, 0x10, 4) & IOMASK; + altiobase_1 = pci_read_config(dev, 0x14, 4) & IOMASK; + bmaddr_1 = pci_read_config(dev, 0x20, 4) & IOMASK; irq1 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff; } @@ -275,9 +276,9 @@ ata_pciattach(device_t dev) irq2 = 15; } else { - iobase_2 = pci_read_config(dev, 0x18, 4) & 0xfffc; - altiobase_2 = pci_read_config(dev, 0x1c, 4) & 0xfffc; - bmaddr_2 = (pci_read_config(dev, 0x20, 4) & 0xfffc) + ATA_BM_OFFSET1; + iobase_2 = pci_read_config(dev, 0x18, 4) & IOMASK; + altiobase_2 = pci_read_config(dev, 0x1c, 4) & IOMASK; + bmaddr_2 = (pci_read_config(dev, 0x20, 4) & IOMASK) + ATA_BM_OFFSET1; irq2 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff; } @@ -286,7 +287,7 @@ ata_pciattach(device_t dev) /* is busmastering support turned on ? */ if ((pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4) & 5) == 5) { /* is there a valid port range to connect to ? */ - if ((bmaddr_1 = pci_read_config(dev, 0x20, 4) & 0xfffc)) { + if ((bmaddr_1 = pci_read_config(dev, 0x20, 4) & IOMASK)) { bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1; printf("ata-pci%d: Busmastering DMA supported\n", unit); } @@ -297,20 +298,26 @@ ata_pciattach(device_t dev) printf("ata-pci%d: Busmastering DMA not enabled\n", unit); } else { - /* the Promise controllers need this to support burst mode */ - if (type == 0x4d33105a || type == 0x4d38105a) - outb(bmaddr_1 + 0x1f, inb(bmaddr_1 + 0x1f) | 0x01); - - /* Promise and HPT366 controllers support busmastering DMA */ - if (type == 0x4d33105a || type == 0x4d38105a || type == 0x00041103) + if (type == 0x4d33105a || type == 0x4d38105a || type == 0x00041103) { + /* Promise and HPT366 controllers support busmastering DMA */ printf("ata-pci%d: Busmastering DMA supported\n", unit); - - /* we dont know this controller, disable busmastering DMA */ + } else { + /* we dont know this controller, disable busmastering DMA */ bmaddr_1 = bmaddr_2 = 0; printf("ata-pci%d: Busmastering DMA not supported\n", unit); } } + + /* on the Aladdin activate the ATAPI FIFO */ + if (type == 0x522910b9) { + pci_write_config(dev, 0x53, + (pci_read_config(dev, 0x53, 1) & ~0x01) | 0x02, 1); + } + + /* the Promise controllers needs burst mode to be turned on explicitly */ + if (type == 0x4d33105a || type == 0x4d38105a) + outb(bmaddr_1 + 0x1f, inb(bmaddr_1 + 0x1f) | 0x01); /* now probe the addresse found for "real" ATA/ATAPI hardware */ lun = 0; @@ -512,10 +519,11 @@ ataintr(void *data) struct ata_softc *scp =(struct ata_softc *)data; /* is this interrupt really for this channel */ - if (scp->flags & ATA_DMA_ACTIVE) - if (!(ata_dmastatus(scp) & ATA_BMSTAT_INTERRUPT)) - return; - if ((scp->status = inb(scp->ioaddr + ATA_STATUS)) == ATA_S_BUSY) + if ((scp->flags & ATA_DMA_ACTIVE) && + !(ata_dmastatus(scp) & ATA_BMSTAT_INTERRUPT)) + return; + + if (((scp->status = inb(scp->ioaddr+ATA_STATUS)) & ATA_S_BUSY)==ATA_S_BUSY) return; /* find & call the responsible driver to process this interrupt */ @@ -530,7 +538,7 @@ ataintr(void *data) #endif #if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0 case ATA_ACTIVE_ATAPI: - if (!scp->running) + if (!scp->running) return; if (atapi_interrupt(scp->running) == ATA_OP_CONTINUES) return; diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index f91b21c70a59..00fdc7317226 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -64,7 +64,9 @@ #define ATA_C_WRITE_DMA 0xca /* write w/DMA command */ #define ATA_C_ATA_IDENTIFY 0xec /* get ATA params */ #define ATA_C_SETFEATURES 0xef /* features command */ -#define ATA_C_FEA_SETXFER 0x03 /* set transfer mode */ +#define ATA_C_F_SETXFER 0x03 /* set transfer mode */ +#define ATA_C_F_ENAB_RCACHE 0xaa /* enable readahead cache */ +#define ATA_C_F_ENAB_WCACHE 0x02 /* enable write cache */ #define ATA_STATUS 0x07 /* status register */ #define ATA_S_ERROR 0x01 /* error */ diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index 9f4bba5d7561..49d5c79a983a 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -179,6 +179,15 @@ ad_attach(void *notused) ata_wait(adp->controller, adp->unit, ATA_S_READY) >= 0) adp->transfersize *= secsperint; + /* enable read/write cacheing if not default on device */ + if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, + 0, 0, 0, 0, ATA_C_F_ENAB_RCACHE, ATA_WAIT_INTR)) + printf("ad%d: enabling readahead cache failed\n", adp->lun); + + if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, + 0, 0, 0, 0, ATA_C_F_ENAB_WCACHE, ATA_WAIT_INTR)) + printf("ad%d: enabling write cache failed\n", adp->lun); + /* use DMA if drive & controller supports it */ if (!ata_dmainit(adp->controller, adp->unit, apiomode(adp->ata_parm), diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index ab46df445698..f85949c15790 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -100,7 +100,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, int32_t mask48, new48; error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up UDMA2 mode on PIIX4 chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", @@ -139,7 +139,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, pci_write_config(scp->dev, 0x44, new44, 4); } error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up WDMA2 mode on PIIX4 chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", @@ -179,40 +179,17 @@ ata_dmainit(struct ata_softc *scp, int32_t device, break; case 0x522910b9: /* AcerLabs Aladdin IV/V */ - /* the Aladdin has to be setup specially for ATAPI devices */ - if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || - (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) { - int8_t word53 = pci_read_config(scp->dev, 0x53, 1); - - /* set atapi fifo, this should always work */ - pci_write_config(scp->dev, 0x53, (word53 & ~0x01) | 0x02, 1); - - /* if both master & slave are atapi devices dont allow DMA */ - if (scp->devices & ATA_ATAPI_MASTER && - scp->devices & ATA_ATAPI_SLAVE) { - printf("ata%d: Aladdin: two atapi devices on this channel, " - "DMA disabled\n", scp->lun); - break; - } - /* if needed set atapi fifo & dma */ - if ((udmamode >=2) || (wdmamode >= 2 && apiomode >= 4)) { - pci_write_config(scp->dev, 0x53, word53 | 0x03, 1); - scp->flags |= ATA_ATAPI_DMA_RO; - if (device == ATA_MASTER) - outb(scp->bmaddr + ATA_BMSTAT_PORT, - inb(scp->bmaddr + ATA_BMSTAT_PORT) | - ATA_BMSTAT_DMA_MASTER); - else - outb(scp->bmaddr + ATA_BMSTAT_PORT, - inb(scp->bmaddr + ATA_BMSTAT_PORT) | - ATA_BMSTAT_DMA_SLAVE); - } + /* the Aladdin doesn't support ATAPI DMA on both master & slave */ + if (scp->devices & ATA_ATAPI_MASTER && scp->devices & ATA_ATAPI_SLAVE) { + printf("ata%d: Aladdin: two atapi devices on this channel, " + "DMA disabled\n", scp->lun); + break; } if (udmamode >=2) { int32_t word54 = pci_read_config(scp->dev, 0x54, 4); error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up UDMA2 mode on Aladdin chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", @@ -222,19 +199,25 @@ ata_dmainit(struct ata_softc *scp, int32_t device, word54 |= 0x5555; word54 |= (0x0a << (16 + (scp->unit << 3) + (device << 2))); pci_write_config(scp->dev, 0x54, word54, 4); + pci_write_config(scp->dev, 0x53, + pci_read_config(scp->dev, 0x53, 1) | 0x03, 1); + scp->flags |= ATA_ATAPI_DMA_RO; scp->mode[(device == ATA_MASTER) ? 0 : 1] = ATA_MODE_UDMA2; return 0; } else if (wdmamode >= 2 && apiomode >= 4) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up WDMA2 mode on Aladdin chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", (error) ? "failed" : "success"); if (error) break; + pci_write_config(scp->dev, 0x53, + pci_read_config(scp->dev, 0x53, 1) | 0x03, 1); + scp->flags |= ATA_ATAPI_DMA_RO; scp->mode[(device == ATA_MASTER) ? 0 : 1] = ATA_MODE_WDMA2; return 0; } @@ -251,7 +234,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, if (udmamode >=4 && type == 0x4d38105a && !(pci_read_config(scp->dev, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_UDMA4, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up UDMA4 mode on Promise chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", @@ -265,7 +248,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, } if (udmamode >=2) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up UDMA2 mode on Promise chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", @@ -278,7 +261,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, } else if (wdmamode >= 2 && apiomode >= 4) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up WDMA2 mode on Promise chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", @@ -306,7 +289,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, devno = (device == ATA_MASTER) ? 0 : 1; if (udmamode >=4 && !(pci_read_config(scp->dev, 0x5a, 1) & 0x2)) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_UDMA4, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up UDMA4 mode on HPT366 chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", @@ -319,7 +302,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, } if (udmamode >=3 && !(pci_read_config(scp->dev, 0x5a, 1) & 0x2)) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_UDMA3, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_UDMA3, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up UDMA3 mode on HPT366 chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", @@ -332,7 +315,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, } if (udmamode >=2) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up UDMA2 mode on HPT366 chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", @@ -345,7 +328,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, } else if (wdmamode >= 2 && apiomode >= 4) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up WDMA2 mode on HPT366 chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave", @@ -376,7 +359,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, ((device == ATA_MASTER) ? ATA_BMSTAT_DMA_SLAVE : ATA_BMSTAT_DMA_MASTER))) { error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, - ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_READY); + ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); if (bootverbose) printf("ata%d: %s: %s setting up WDMA2 mode on generic chip\n", scp->lun, (device == ATA_MASTER) ? "master" : "slave",