summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2004-04-21 20:03:26 +0000
committersos <sos@FreeBSD.org>2004-04-21 20:03:26 +0000
commit5e6e9f86ba2eecaf9fad0dc0561f03d04fb59244 (patch)
tree0708f156c417a076d7643c69feaa20860cd6c4f5 /sys/dev/ata
parent45b9d63d5e73edda079486278d753880417fba0e (diff)
downloadFreeBSD-src-5e6e9f86ba2eecaf9fad0dc0561f03d04fb59244.zip
FreeBSD-src-5e6e9f86ba2eecaf9fad0dc0561f03d04fb59244.tar.gz
Make the test for ATA PCI legacy addressing mode more robust.
Add code (currently ifdef'd out) to allow ATA PCI native addressing. Fix the altio offset for ATA PCI devices.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-chipset.c2
-rw-r--r--sys/dev/ata/ata-pci.c52
-rw-r--r--sys/dev/ata/ata-pci.h5
3 files changed, 44 insertions, 15 deletions
diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c
index a94982c..72852dc 100644
--- a/sys/dev/ata/ata-chipset.c
+++ b/sys/dev/ata/ata-chipset.c
@@ -2662,7 +2662,7 @@ ata_setup_interrupt(device_t dev)
struct ata_pci_controller *ctlr = device_get_softc(dev);
int rid = ATA_IRQ_RID;
- if (!ATA_MASTERDEV(dev)) {
+ if (!ata_legacy(dev)) {
if (!(ctlr->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE))) {
device_printf(dev, "unable to map interrupt\n");
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index 471d640..7a5cb75 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -62,6 +62,15 @@ static int ata_pci_allocate(device_t, struct ata_channel *);
static void ata_pci_dmainit(struct ata_channel *);
static void ata_pci_locknoop(struct ata_channel *, int);
+int
+ata_legacy(device_t dev)
+{
+ return ((pci_read_config(dev, PCIR_PROGIF, 1)&PCIP_STORAGE_IDE_MASTERDEV) &&
+ ((pci_read_config(dev, PCIR_PROGIF, 1) &
+ (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC)) !=
+ (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC)));
+}
+
static int
ata_pci_probe(device_t dev)
{
@@ -155,10 +164,11 @@ ata_pci_attach(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(dev);
u_int32_t cmd;
- int unit;
+ u_int8_t progif;
+ int unit, prisec = 0;
/* do chipset specific setups only needed once */
- if (ATA_MASTERDEV(dev) || pci_read_config(dev, 0x18, 4) & IOMASK)
+ if (ata_legacy(dev) || pci_read_config(dev, 0x18, 4) & IOMASK)
ctlr->channels = 2;
else
ctlr->channels = 1;
@@ -166,6 +176,26 @@ ata_pci_attach(device_t dev)
ctlr->dmainit = ata_pci_dmainit;
ctlr->locking = ata_pci_locknoop;
+ progif = pci_read_config(dev, PCIR_PROGIF, 1);
+ if ((progif & 0x85) == 0x80)
+ prisec = 1;
+
+ /* if this device supports PCI native addressing use it */
+#if 0
+ if ((progif & 0x8a) == 0x8a) {
+ if (pci_read_config(dev, PCIR_BAR(0), 4) &&
+ pci_read_config(dev, PCIR_BAR(2), 4)) {
+ device_printf(dev, "setting native PCI addressing mode ");
+ pci_write_config(dev, PCIR_PROGIF, progif | 0x05, 1);
+ if ((pci_read_config(dev, PCIR_PROGIF, 1) & 0x05) != 0x05) {
+ pci_write_config(dev, PCIR_PROGIF, progif & ~0x05, 1);
+ printf("failed, using compat method\n");
+ }
+ else
+ printf("succeded\n");
+ }
+ }
+#endif
/* if needed try to enable busmastering */
cmd = pci_read_config(dev, PCIR_COMMAND, 2);
if (!(cmd & PCIM_CMD_BUSMASTEREN)) {
@@ -185,7 +215,7 @@ ata_pci_attach(device_t dev)
/* attach all channels on this controller */
for (unit = 0; unit < ctlr->channels; unit++)
- device_add_child(dev, "ata", ATA_MASTERDEV(dev) ?
+ device_add_child(dev, "ata", prisec ?
unit : devclass_find_free_unit(ata_devclass, 2));
return bus_generic_attach(dev);
@@ -227,7 +257,7 @@ ata_pci_print_child(device_t dev, device_t child)
retval += bus_print_child_header(dev, child);
retval += printf(": at 0x%lx", rman_get_start(ch->r_io[ATA_IDX_ADDR].res));
- if (ATA_MASTERDEV(dev))
+ if (ata_legacy(dev))
retval += printf(" irq %d", 14 + ch->unit);
retval += bus_print_child_footer(dev, child);
@@ -247,7 +277,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
if (type == SYS_RES_IOPORT) {
switch (*rid) {
case ATA_IOADDR_RID:
- if (ATA_MASTERDEV(dev)) {
+ if (ata_legacy(dev)) {
start = (unit ? ATA_SECONDARY : ATA_PRIMARY);
count = ATA_IOSIZE;
end = start + count - 1;
@@ -259,7 +289,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
break;
case ATA_ALTADDR_RID:
- if (ATA_MASTERDEV(dev)) {
+ if (ata_legacy(dev)) {
start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_ALTOFFSET;
count = ATA_ALTIOSIZE;
end = start + count - 1;
@@ -274,7 +304,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
}
if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) {
- if (ATA_MASTERDEV(dev)) {
+ if (ata_legacy(dev)) {
#ifdef __alpha__
return alpha_platform_alloc_ide_intr(unit);
#else
@@ -316,7 +346,7 @@ ata_pci_release_resource(device_t dev, device_t child, int type, int rid,
if (rid != ATA_IRQ_RID)
return ENOENT;
- if (ATA_MASTERDEV(dev)) {
+ if (ata_legacy(dev)) {
#ifdef __alpha__
return alpha_platform_release_ide_intr(unit, r);
#else
@@ -335,7 +365,7 @@ ata_pci_setup_intr(device_t dev, device_t child, struct resource *irq,
int flags, driver_intr_t *function, void *argument,
void **cookiep)
{
- if (ATA_MASTERDEV(dev)) {
+ if (ata_legacy(dev)) {
#ifdef __alpha__
return alpha_platform_setup_ide_intr(child, irq, function, argument,
cookiep);
@@ -359,7 +389,7 @@ static int
ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
void *cookie)
{
- if (ATA_MASTERDEV(dev)) {
+ if (ata_legacy(dev)) {
#ifdef __alpha__
return alpha_platform_teardown_ide_intr(child, irq, cookie);
#else
@@ -402,7 +432,7 @@ ata_pci_allocate(device_t dev, struct ata_channel *ch)
ch->r_io[i].offset = i;
}
ch->r_io[ATA_ALTSTAT].res = altio;
- ch->r_io[ATA_ALTSTAT].offset = 0;
+ ch->r_io[ATA_ALTSTAT].offset = ata_legacy(device_get_parent(dev)) ? 0 : 2;
ch->r_io[ATA_IDX_ADDR].res = io;
if (ctlr->r_res1) {
diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index 88569e7..4329a09 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -63,9 +63,6 @@ struct ata_pci_controller {
void *driver;
};
-#define ATA_MASTERDEV(dev) ((pci_get_progif(dev) & 0x80) && \
- (pci_get_progif(dev) & 0x05) != 0x05)
-
/* defines for known chipset PCI id's */
#define ATA_ACARD_ID 0x1191
#define ATA_ATP850 0x00021191
@@ -295,6 +292,8 @@ struct ata_pci_controller {
#define VIABUG 0x10
/* global prototypes */
+int ata_legacy(device_t);
+
void ata_dmainit(struct ata_channel *);
int ata_dmastart(struct ata_channel *, caddr_t, int32_t, int);
int ata_dmastop(struct ata_channel *);
OpenPOWER on IntegriCloud