summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>1999-11-08 21:36:00 +0000
committersos <sos@FreeBSD.org>1999-11-08 21:36:00 +0000
commit0c7be9be3ad1b0286a410199433dac7e84a8c0d4 (patch)
treee0ff512f867e08a0f952161668759ab470cf3599 /sys
parent63c4c3e1daae7f753524e0d7262a5f8c182807dc (diff)
downloadFreeBSD-src-0c7be9be3ad1b0286a410199433dac7e84a8c0d4.zip
FreeBSD-src-0c7be9be3ad1b0286a410199433dac7e84a8c0d4.tar.gz
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..
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ata/ata-all.c48
-rw-r--r--sys/dev/ata/ata-all.h4
-rw-r--r--sys/dev/ata/ata-disk.c9
-rw-r--r--sys/dev/ata/ata-dma.c63
4 files changed, 63 insertions, 61 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index e6e1046..99f677c 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 f91b21c..00fdc73 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 9f4bba5..49d5c79 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 ab46df4..f85949c 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",
OpenPOWER on IntegriCloud