summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2000-10-03 13:12:36 +0000
committersos <sos@FreeBSD.org>2000-10-03 13:12:36 +0000
commit98f1b14abae6bcc470fa2be3a0284923272e0b5a (patch)
tree37db860150c2f35fa6201d96c929fc325ceaa232 /sys
parent6922fb3fac2572ba001a739d9a4ae7d549e370d6 (diff)
downloadFreeBSD-src-98f1b14abae6bcc470fa2be3a0284923272e0b5a.zip
FreeBSD-src-98f1b14abae6bcc470fa2be3a0284923272e0b5a.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ata/ata-all.c89
-rw-r--r--sys/dev/ata/ata-disk.c6
-rw-r--r--sys/dev/ata/ata-dma.c114
3 files changed, 159 insertions, 50 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index c79fba2..2040ef2 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -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 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 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);
+ 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) {
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 6391982..4b2c87b 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -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;
}
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 46ebbd1..9d3a025 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -442,13 +442,73 @@ via_82c586:
/* 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 @@ via_82c586:
/* 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 @@ via_82c586:
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 */
OpenPOWER on IntegriCloud