Add support for ServerWorks ROSB4 ATA33 chipset.
Add support for CMD 648 ATA66 & CMD 649 ATA100 chipsets. Fix the "resource already allocated" panic with the CMD and other braindead controllers. Add options ATA_ENABLE_TAGS, without this option tagged queuing will not be attempted.
This commit is contained in:
parent
60f9125458
commit
162080b465
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=66583
@ -71,6 +71,7 @@
|
||||
#define ATA_IOADDR_RID 0
|
||||
#define ATA_ALTADDR_RID 1
|
||||
#define ATA_BMADDR_RID 2
|
||||
#define ATA_MASTERDEV(dev) ((pci_get_progif(dev) & 0x8f) == 0x8a)
|
||||
|
||||
/* prototypes */
|
||||
static int ata_probe(device_t);
|
||||
@ -275,6 +276,12 @@ ata_pci_match(device_t dev)
|
||||
case 0x55131039:
|
||||
return "SiS 5591 ATA33 controller";
|
||||
|
||||
case 0x06491095:
|
||||
return "CMD 649 ATA100 controller";
|
||||
|
||||
case 0x06481095:
|
||||
return "CMD 648 ATA66 controller";
|
||||
|
||||
case 0x06461095:
|
||||
return "CMD 646 ATA controller";
|
||||
|
||||
@ -289,6 +296,9 @@ ata_pci_match(device_t dev)
|
||||
case 0x74091022:
|
||||
return "AMD 756 ATA66 controller";
|
||||
|
||||
case 0x02111166:
|
||||
return "ServerWorks ROSB4 ATA33 controller";
|
||||
|
||||
case 0x4d33105a:
|
||||
return "Promise ATA33 controller";
|
||||
|
||||
@ -349,7 +359,7 @@ ata_pci_add_child(device_t dev, int unit)
|
||||
device_t child;
|
||||
|
||||
/* check if this is located at one of the std addresses */
|
||||
if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) {
|
||||
if (ATA_MASTERDEV(dev)) {
|
||||
if (!(child = device_add_child(dev, "ata", unit)))
|
||||
return ENOMEM;
|
||||
}
|
||||
@ -375,33 +385,16 @@ ata_pci_attach(device_t dev)
|
||||
subclass = pci_get_subclass(dev);
|
||||
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
|
||||
|
||||
/* is this controller busmaster DMA capable ? */
|
||||
if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) {
|
||||
/* is busmastering support turned on ? */
|
||||
if ((cmd & (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN)) ==
|
||||
(PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN)) {
|
||||
/* is busmastering supported ? */
|
||||
if ((cmd & (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN)) ==
|
||||
(PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN)) {
|
||||
|
||||
/* is there a valid port range to connect to ? */
|
||||
rid = 0x20;
|
||||
sc->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
if (!sc->bmio)
|
||||
device_printf(dev, "Busmastering DMA not configured\n");
|
||||
}
|
||||
else
|
||||
device_printf(dev, "Busmastering DMA not enabled\n");
|
||||
}
|
||||
else {
|
||||
if (type == 0x4d33105a || type == 0x4d38105a ||
|
||||
type == 0x4d30105a || type == 0x0d30105a || type == 0x00041103) {
|
||||
/* Promise and HighPoint controllers support busmastering DMA */
|
||||
rid = 0x20;
|
||||
sc->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
}
|
||||
else
|
||||
/* we dont know this controller, no busmastering DMA */
|
||||
device_printf(dev, "Busmastering DMA not supported\n");
|
||||
/* is there a valid port range to connect to ? */
|
||||
rid = 0x20;
|
||||
sc->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
|
||||
0, ~0, 1, RF_ACTIVE);
|
||||
device_printf(dev, "Busmastering DMA %s\n",
|
||||
sc->bmio ? "enabled" : "not supported");
|
||||
}
|
||||
|
||||
/* do extra chipset specific setups */
|
||||
@ -488,8 +481,7 @@ ata_pci_attach(device_t dev)
|
||||
|
||||
ata_pci_add_child(dev, 0);
|
||||
|
||||
if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV ||
|
||||
pci_read_config(dev, 0x18, 4) & IOMASK)
|
||||
if (ATA_MASTERDEV(dev) || pci_read_config(dev, 0x18, 4) & IOMASK)
|
||||
ata_pci_add_child(dev, 1);
|
||||
|
||||
return bus_generic_attach(dev);
|
||||
@ -505,7 +497,7 @@ ata_pci_print_child(device_t dev, device_t child)
|
||||
retval += bus_print_child_header(dev, child);
|
||||
retval += printf(": at 0x%x", scp->ioaddr);
|
||||
|
||||
if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV)
|
||||
if (ATA_MASTERDEV(dev))
|
||||
retval += printf(" irq %d", 14 + unit);
|
||||
|
||||
retval += bus_print_child_footer(dev, child);
|
||||
@ -518,14 +510,13 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
u_long start, u_long end, u_long count, u_int flags)
|
||||
{
|
||||
struct ata_pci_softc *sc = device_get_softc(dev);
|
||||
int masterdev = pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV;
|
||||
int unit = (intptr_t)device_get_ivars(child);
|
||||
int myrid;
|
||||
|
||||
if (type == SYS_RES_IOPORT) {
|
||||
switch (*rid) {
|
||||
case ATA_IOADDR_RID:
|
||||
if (masterdev) {
|
||||
if (ATA_MASTERDEV(dev)) {
|
||||
myrid = 0;
|
||||
start = (unit == 0 ? IO_WD1 : IO_WD2);
|
||||
end = start + ATA_IOSIZE - 1;
|
||||
@ -536,7 +527,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
break;
|
||||
|
||||
case ATA_ALTADDR_RID:
|
||||
if (masterdev) {
|
||||
if (ATA_MASTERDEV(dev)) {
|
||||
myrid = 0;
|
||||
start = (unit == 0 ? IO_WD1 : IO_WD2) + ATA_ALTOFFSET;
|
||||
end = start + ATA_ALTIOSIZE - 1;
|
||||
@ -566,7 +557,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (masterdev)
|
||||
if (ATA_MASTERDEV(dev))
|
||||
/* make the parent just pass through the allocation. */
|
||||
return BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
|
||||
SYS_RES_IOPORT, &myrid,
|
||||
@ -582,7 +573,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
if (*rid != 0)
|
||||
return 0;
|
||||
|
||||
if (masterdev) {
|
||||
if (ATA_MASTERDEV(dev)) {
|
||||
#ifdef __alpha__
|
||||
return alpha_platform_alloc_ide_intr(unit);
|
||||
#else
|
||||
@ -610,20 +601,19 @@ ata_pci_release_resource(device_t dev, device_t child, int type, int rid,
|
||||
{
|
||||
struct ata_pci_softc *sc = device_get_softc(dev);
|
||||
int unit = (uintptr_t) device_get_ivars(child);
|
||||
int masterdev = pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV;
|
||||
int myrid = 0;
|
||||
|
||||
if (type == SYS_RES_IOPORT) {
|
||||
switch (rid) {
|
||||
case ATA_IOADDR_RID:
|
||||
if (masterdev)
|
||||
if (ATA_MASTERDEV(dev))
|
||||
myrid = 0;
|
||||
else
|
||||
myrid = 0x10 + 8 * unit;
|
||||
break;
|
||||
|
||||
case ATA_ALTADDR_RID:
|
||||
if (masterdev)
|
||||
if (ATA_MASTERDEV(dev))
|
||||
myrid = 0;
|
||||
else
|
||||
myrid = 0x14 + 8 * unit;
|
||||
@ -636,7 +626,7 @@ ata_pci_release_resource(device_t dev, device_t child, int type, int rid,
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (masterdev)
|
||||
if (ATA_MASTERDEV(dev))
|
||||
/* make the parent just pass through the allocation. */
|
||||
return BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
|
||||
SYS_RES_IOPORT, myrid, r);
|
||||
@ -649,7 +639,7 @@ ata_pci_release_resource(device_t dev, device_t child, int type, int rid,
|
||||
if (rid != 0)
|
||||
return ENOENT;
|
||||
|
||||
if (masterdev) {
|
||||
if (ATA_MASTERDEV(dev)) {
|
||||
#ifdef __alpha__
|
||||
return alpha_platform_release_ide_intr(unit, r);
|
||||
#else
|
||||
@ -673,7 +663,7 @@ ata_pci_setup_intr(device_t dev, device_t child, struct resource *irq,
|
||||
int flags, driver_intr_t *intr, void *arg,
|
||||
void **cookiep)
|
||||
{
|
||||
if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) {
|
||||
if (ATA_MASTERDEV(dev)) {
|
||||
#ifdef __alpha__
|
||||
return alpha_platform_setup_ide_intr(irq, intr, arg, cookiep);
|
||||
#else
|
||||
@ -690,7 +680,7 @@ static int
|
||||
ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
|
||||
void *cookie)
|
||||
{
|
||||
if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) {
|
||||
if (ATA_MASTERDEV(dev)) {
|
||||
#ifdef __alpha__
|
||||
return alpha_platform_teardown_ide_intr(irq, cookie);
|
||||
#else
|
||||
@ -788,7 +778,7 @@ ata_probe(device_t dev)
|
||||
altio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
|
||||
ATA_ALTIOSIZE, RF_ACTIVE);
|
||||
if (altio) {
|
||||
if (pci_get_progif(device_get_parent(dev)) & PCIP_STORAGE_IDE_MASTERDEV)
|
||||
if (ATA_MASTERDEV(device_get_parent(dev)))
|
||||
altioaddr = rman_get_start(altio);
|
||||
else
|
||||
altioaddr = rman_get_start(altio) + 0x02;
|
||||
@ -1087,6 +1077,14 @@ ata_intr(void *data)
|
||||
outb(scp->bmaddr + ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT);
|
||||
break;
|
||||
|
||||
case 0x06461095: /* CMD 646 */
|
||||
case 0x06481095: /* CMD 648 */
|
||||
case 0x06491095: /* CMD 649 */
|
||||
if (!(pci_read_config(device_get_parent(scp->dev), 0x71, 1) &
|
||||
(scp->unit ? 0x08 : 0x04)))
|
||||
return;
|
||||
goto out;
|
||||
|
||||
case 0x4d33105a: /* Promise Ultra/Fasttrak 33 */
|
||||
case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */
|
||||
case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */
|
||||
@ -1095,10 +1093,11 @@ ata_intr(void *data)
|
||||
struct ata_pci_softc *sc=device_get_softc(device_get_parent(scp->dev));
|
||||
|
||||
if (!(inl(rman_get_start(sc->bmio) + 0x1c) &
|
||||
((scp->unit) ? 0x00004000 : 0x00000400)))
|
||||
(scp->unit ? 0x00004000 : 0x00000400)))
|
||||
return;
|
||||
}
|
||||
|
||||
out:
|
||||
#endif
|
||||
default:
|
||||
if (scp->flags & ATA_DMA_ACTIVE) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
#define ATA_FLUSHCACHE_ON
|
||||
/*-
|
||||
* Copyright (c) 1998,1999,2000 Søren Schmidt
|
||||
* All rights reserved.
|
||||
@ -87,6 +86,9 @@ MALLOC_DEFINE(M_AD, "AD driver", "ATA disk driver");
|
||||
#define AD_MAX_RETRIES 3
|
||||
#define AD_PARAM ATA_PARAM(adp->controller, adp->unit)
|
||||
|
||||
/* experimental cache flush on BIO_ORDERED */
|
||||
#define ATA_FLUSHCACHE_ON
|
||||
|
||||
void
|
||||
ad_attach(struct ata_softc *scp, int device)
|
||||
{
|
||||
@ -790,6 +792,7 @@ ad_invalidatequeue(struct ad_softc *adp, struct ad_request *request)
|
||||
static int
|
||||
ad_tagsupported(struct ad_softc *adp)
|
||||
{
|
||||
#ifdef ATA_ENABLE_TAGS
|
||||
const char *drives[] = {"IBM-DPTA", "IBM-DTLA", NULL};
|
||||
int i = 0;
|
||||
|
||||
@ -805,6 +808,7 @@ ad_tagsupported(struct ad_softc *adp)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -442,13 +442,73 @@ ata_dmainit(struct ata_softc *scp, int device,
|
||||
/* we could set PIO mode timings, but we assume the BIOS did that */
|
||||
break;
|
||||
|
||||
case 0x06491095: /* CMD 649 ATA100 controller */
|
||||
if (udmamode >= 5) {
|
||||
u_int8_t umode;
|
||||
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device, "%s setting UDMA5 on CMD chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
umode = pci_read_config(parent, scp->unit ? 0x7b : 0x73, 1);
|
||||
umode &= ~(device == ATA_MASTER ? 0x35 : 0xca);
|
||||
umode |= (device == ATA_MASTER ? 0x05 : 0x0a);
|
||||
pci_write_config(parent, scp->unit ? 0x7b : 0x73, umode, 1);
|
||||
scp->mode[ATA_DEV(device)] = ATA_UDMA5;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 0x06481095: /* CMD 648 ATA66 controller */
|
||||
if (udmamode >= 4) {
|
||||
u_int8_t umode;
|
||||
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device, "%s setting UDMA4 on CMD chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
umode = pci_read_config(parent, scp->unit ? 0x7b : 0x73, 1);
|
||||
umode &= ~(device == ATA_MASTER ? 0x35 : 0xca);
|
||||
umode |= (device == ATA_MASTER ? 0x15 : 0x4a);
|
||||
pci_write_config(parent, scp->unit ? 0x7b : 0x73, umode, 1);
|
||||
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (udmamode >= 2) {
|
||||
u_int8_t umode;
|
||||
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device, "%s setting UDMA2 on CMD chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
umode = pci_read_config(parent, scp->unit ? 0x7b : 0x73, 1);
|
||||
umode &= ~(device == ATA_MASTER ? 0x35 : 0xca);
|
||||
umode |= (device == ATA_MASTER ? 0x11 : 0x42);
|
||||
pci_write_config(parent, scp->unit ? 0x7b : 0x73, umode, 1);
|
||||
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* make sure eventual UDMA mode from the BIOS is disabled */
|
||||
pci_write_config(parent, scp->unit ? 0x7b : 0x73,
|
||||
pci_read_config(parent, scp->unit ? 0x7b : 0x73, 1) &
|
||||
~(device == ATA_MASTER ? 0x35 : 0xca), 1);
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 0x06461095: /* CMD 646 ATA controller */
|
||||
if (wdmamode >= 2 && apiomode >= 4) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device,
|
||||
"%s setting WDMA2 on CMD646 chip\n",
|
||||
ata_printf(scp, device, "%s setting WDMA2 on CMD chip\n",
|
||||
error ? "failed" : "success");
|
||||
if (!error) {
|
||||
int32_t offset = (devno < 3) ? (devno << 1) : 7;
|
||||
@ -478,13 +538,13 @@ ata_dmainit(struct ata_softc *scp, int device,
|
||||
/* we could set PIO mode timings, but we assume the BIOS did that */
|
||||
break;
|
||||
|
||||
case 0x01021078:
|
||||
case 0x01021078: /* Cyrix 5530 ATA33 controller */
|
||||
scp->alignment = 0xf; /* DMA engine requires 16 byte alignment */
|
||||
if (udmamode >= 2) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device, "%s setting UDMA2 on Cyrix chip\n",
|
||||
ata_printf(scp, device, "%s setting UDMA2 on Cyrix chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
cyrix_timing(scp, devno, ATA_UDMA2);
|
||||
@ -515,6 +575,52 @@ ata_dmainit(struct ata_softc *scp, int device,
|
||||
scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
|
||||
return;
|
||||
|
||||
case 0x02111166: /* ServerWorks ROSB4 ATA33 controller */
|
||||
if (udmamode >= 2) {
|
||||
u_int16_t reg56;
|
||||
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device,
|
||||
"%s setting UDMA2 on ServerWorks chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
pci_write_config(parent, 0x54,
|
||||
pci_read_config(parent, 0x54, 1) |
|
||||
(0x01 << devno), 1);
|
||||
reg56 = pci_read_config(parent, 0x56, 2);
|
||||
reg56 &= ~(0xf << (devno * 4));
|
||||
reg56 |= (0x2 << (devno * 4));
|
||||
pci_write_config(parent, 0x56, reg56, 2);
|
||||
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (wdmamode >= 2 && apiomode >= 4) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device,
|
||||
"%s setting WDMA2 on ServerWorks chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
int offset = (scp->unit * 2) + (device == ATA_MASTER);
|
||||
int word44 = pci_read_config(parent, 0x44, 4);
|
||||
|
||||
pci_write_config(parent, 0x54,
|
||||
pci_read_config(parent, 0x54, 1) &
|
||||
~(0x01 << devno), 1);
|
||||
word44 &= ~(0xff << (offset << 8));
|
||||
word44 |= (0x20 << (offset << 8));
|
||||
pci_write_config(parent, 0x44, 0x20, 4);
|
||||
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* we could set PIO mode timings, but we assume the BIOS did that */
|
||||
break;
|
||||
|
||||
case 0x4d33105a: /* Promise Ultra/FastTrak 33 controllers */
|
||||
case 0x4d38105a: /* Promise Ultra/FastTrak 66 controllers */
|
||||
case 0x4d30105a: /* Promise Ultra/FastTrak 100 controllers */
|
||||
|
Loading…
Reference in New Issue
Block a user