mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
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..
This commit is contained in:
parent
031911c604
commit
838b8e23b9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=53029
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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),
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user