Michael Luetz wrote: > Hi, > > today's (Apr 19th) CURRENT can't find the root fs anymore Thats because of the PCI code changes, it does not properly handle the BAR's on ATA controllers (they are special and an exception of the worser kind :) ) I have two patches that solves this is different ways (both attached below). The first one just makes the PCI code aware of the specialness of the ATA BAR's and takes the right action on it. The second one is not really for mass consumption yet, as it will try to use you ATA controller in "native PCI" mode if its possible. This hasn't been tested much yet, and I sure there are HW out there that breaks with this, but it would be interesting to gain more knowledge on it by getting it tested especially on platforms thats broken with the current code. -- -Søren Index: ata/ata-pci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-pci.c,v retrieving revision 1.78 diff -u -r1.78 ata-pci.c --- ata/ata-pci.c 13 Apr 2004 09:44:20 -0000 1.78 +++ ata/ata-pci.c 17 Apr 2004 18:40:10 -0000 _at__at_ -260,8 +260,8 _at__at_ case ATA_ALTADDR_RID: if (ATA_MASTERDEV(dev)) { - start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_ALTOFFSET-2; - count = 4; + start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_ALTOFFSET; + count = ATA_ALTIOSIZE; end = start + count - 1; } myrid = 0x14 + 8 * unit; _at__at_ -402,7 +402,7 _at__at_ ch->r_io[i].offset = i; } ch->r_io[ATA_ALTSTAT].res = altio; - ch->r_io[ATA_ALTSTAT].offset = 2; + ch->r_io[ATA_ALTSTAT].offset = 0; ch->r_io[ATA_IDX_ADDR].res = io; if (ctlr->r_res1) { Index: pci/pci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/pci/pci.c,v retrieving revision 1.245 diff -u -r1.245 pci.c --- pci/pci.c 16 Apr 2004 15:01:54 -0000 1.245 +++ pci/pci.c 17 Apr 2004 18:59:20 -0000 _at__at_ -824,6 +824,15 _at__at_ */ if (base == 0) return 1; + + /* if this is an ATA MASTERDEV on std addresses, resources are bogus */ + if ((pci_get_class(dev) == PCIC_STORAGE) && + (pci_get_subclass(dev) == PCIS_STORAGE_IDE) && + (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) && + !(pci_get_progif(dev) & + (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC))) + return 1; + start = base; end = base + (1 << ln2size) - 1; count = 1 << ln2size; Index: pci/pci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/pci/pci.c,v retrieving revision 1.245 diff -u -r1.245 pci.c --- pci/pci.c 16 Apr 2004 15:01:54 -0000 1.245 +++ pci/pci.c 19 Apr 2004 06:17:37 -0000 _at__at_ -1455,15 +1455,11 _at__at_ struct resource_list_entry *rle; struct resource *res; uint32_t map, testval; - int mapsize; + //int mapsize; /* - * Weed out the bogons, and figure out how large the BAR/map - * is. Note: some devices have been found that are '0' after - * a write of 0xffffffff. We view these as 'special' and - * allow drivers to allocate whatever they want with them. So - * far, these BARs have only appeared in certain south bridges - * and ata controllers made by VIA, nVidia and AMD. + * Weed out the bogons, and figure out how large the BAR/map is. + * Note: we must skip these checks on ZERO BAR's. */ res = NULL; map = pci_read_config(child, *rid, 4); _at__at_ -1472,16 +1468,18 _at__at_ if (testval != 0) { if (pci_maptype(testval) & PCI_MAPMEM) { if (type != SYS_RES_MEMORY) { - device_printf(child, - "failed: rid %#x is memory, requested %d\n", - *rid, type); + if (bootverbose) + device_printf(child, + "failed: rid %#x is memory, " + "requested %d\n", *rid, type); goto out; } } else { if (type != SYS_RES_IOPORT) { - device_printf(child, - "failed: rid %#x is ioport, requested %d\n", - *rid, type); + if (bootverbose) + device_printf(child, + "failed: rid %#x is ioport, " + "requested %d\n", *rid, type); goto out; } } _at__at_ -1491,11 +1489,11 _at__at_ * actually uses and we would otherwise have a * situation where we might allocate the excess to * another driver, which won't work. - */ mapsize = pci_mapsize(testval); count = 1 << mapsize; if (RF_ALIGNMENT(flags) < mapsize) flags = (flags & ~RF_ALIGNMENT_MASK) | RF_ALIGNMENT_LOG2(mapsize); + */ } else { if (bootverbose) _at__at_ -1590,11 +1588,12 _at__at_ */ rle = resource_list_find(rl, type, *rid); if (rle != NULL && rle->res != NULL) { - /* if (bootverbose) */ - device_printf(child, - "Reserved %#lx bytes for rid %#x type %d at %#lx\n", - rman_get_size(rle->res), *rid, type, - rman_get_start(rle->res)); + if (bootverbose) + device_printf(child, + "Reserved %#lx bytes for rid %#x " + "type %d at %#lx\n", + rman_get_size(rle->res), *rid, type, + rman_get_start(rle->res)); if ((flags & RF_ACTIVE) && bus_generic_activate_resource(dev, child, type, *rid, rle->res) != 0) Index: ata/ata-chipset.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-chipset.c,v retrieving revision 1.68 diff -u -r1.68 ata-chipset.c --- ata/ata-chipset.c 13 Apr 2004 09:44:20 -0000 1.68 +++ ata/ata-chipset.c 18 Apr 2004 15:36:56 -0000 _at__at_ -2350,15 +2350,15 _at__at_ break; case SIS66: case SIS100OLD: - pci_write_config(dev, 0x52, pci_read_config(dev, 0x52, 1) | 0x04, 1); + pci_write_config(dev, 0x52, pci_read_config(dev, 0x52, 1) & ~0x04, 1); break; case SIS100NEW: case SIS133OLD: - pci_write_config(dev, 0x49, pci_read_config(dev, 0x49, 1) | 0x01, 1); + pci_write_config(dev, 0x49, pci_read_config(dev, 0x49, 1) & ~0x01, 1); break; case SIS133NEW: - pci_write_config(dev, 0x50, pci_read_config(dev, 0x50, 2) & 0xfff7, 2); - pci_write_config(dev, 0x52, pci_read_config(dev, 0x52, 2) & 0xfff7, 2); + pci_write_config(dev, 0x50, pci_read_config(dev, 0x50, 2) | 0x0008, 2); + pci_write_config(dev, 0x52, pci_read_config(dev, 0x52, 2) | 0x0008, 2); break; case SISSATA: pci_write_config(dev, 0x04, pci_read_config(dev, 0x04, 2) & ~0x0400, 2); _at__at_ -2662,7 +2662,7 _at__at_ struct ata_pci_controller *ctlr = device_get_softc(dev); int rid = ATA_IRQ_RID; - if (!ATA_MASTERDEV(dev)) { + if (!ata_pci_compat(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"); Index: ata/ata-lowlevel.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-lowlevel.c,v retrieving revision 1.32 diff -u -r1.32 ata-lowlevel.c --- ata/ata-lowlevel.c 13 Apr 2004 09:44:20 -0000 1.32 +++ ata/ata-lowlevel.c 18 Apr 2004 13:16:39 -0000 _at__at_ -563,15 +563,15 _at__at_ } } + if (bootverbose) + ata_printf(ch, -1, "reset tp1 mask=%02x ostat0=%02x ostat1=%02x\n", + mask, ostat0, ostat1); + /* if nothing showed up there is no need to get any further */ /* SOS is that too strong?, we just might loose devices here XXX */ ch->devices = 0; if (!mask) return; - - if (bootverbose) - ata_printf(ch, -1, "reset tp1 mask=%02x ostat0=%02x ostat1=%02x\n", - mask, ostat0, ostat1); /* reset (both) devices on this channel */ ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER); Index: ata/ata-pci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-pci.c,v retrieving revision 1.78 diff -u -r1.78 ata-pci.c --- ata/ata-pci.c 13 Apr 2004 09:44:20 -0000 1.78 +++ ata/ata-pci.c 19 Apr 2004 06:15:35 -0000 _at__at_ -62,6 +62,15 _at__at_ static void ata_pci_dmainit(struct ata_channel *); static void ata_pci_locknoop(struct ata_channel *, int); +int +ata_pci_compat(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) { _at__at_ -155,10 +164,29 _at__at_ { struct ata_pci_controller *ctlr = device_get_softc(dev); u_int32_t cmd; - int unit; + u_int8_t progif; + int unit, prisec = 0; + + /* if this device supports PCI native addressing use it */ + progif = pci_read_config(dev, PCIR_PROGIF, 1); + if ((progif & 0x85) == 0x80) + prisec = 1; + 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"); + } + } /* do chipset specific setups only needed once */ - if (ATA_MASTERDEV(dev) || pci_read_config(dev, 0x18, 4) & IOMASK) + if (ata_pci_compat(dev) || pci_read_config(dev, 0x18, 4) & IOMASK) ctlr->channels = 2; else ctlr->channels = 1; _at__at_ -185,7 +213,7 _at__at_ /* 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); _at__at_ -227,7 +255,7 _at__at_ 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_pci_compat(dev)) retval += printf(" irq %d", 14 + ch->unit); retval += bus_print_child_footer(dev, child); _at__at_ -247,7 +275,7 _at__at_ if (type == SYS_RES_IOPORT) { switch (*rid) { case ATA_IOADDR_RID: - if (ATA_MASTERDEV(dev)) { + if (ata_pci_compat(dev)) { start = (unit ? ATA_SECONDARY : ATA_PRIMARY); count = ATA_IOSIZE; end = start + count - 1; _at__at_ -259,9 +287,9 _at__at_ break; case ATA_ALTADDR_RID: - if (ATA_MASTERDEV(dev)) { - start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_ALTOFFSET-2; - count = 4; + if (ata_pci_compat(dev)) { + start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_ALTOFFSET; + count = ATA_ALTIOSIZE; end = start + count - 1; } myrid = 0x14 + 8 * unit; _at__at_ -274,7 +302,7 _at__at_ } if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) { - if (ATA_MASTERDEV(dev)) { + if (ata_pci_compat(dev)) { #ifdef __alpha__ return alpha_platform_alloc_ide_intr(unit); #else _at__at_ -316,7 +344,7 _at__at_ if (rid != ATA_IRQ_RID) return ENOENT; - if (ATA_MASTERDEV(dev)) { + if (ata_pci_compat(dev)) { #ifdef __alpha__ return alpha_platform_release_ide_intr(unit, r); #else _at__at_ -335,7 +363,7 _at__at_ int flags, driver_intr_t *function, void *argument, void **cookiep) { - if (ATA_MASTERDEV(dev)) { + if (ata_pci_compat(dev)) { #ifdef __alpha__ return alpha_platform_setup_ide_intr(child, irq, function, argument, cookiep); _at__at_ -359,7 +387,7 _at__at_ ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie) { - if (ATA_MASTERDEV(dev)) { + if (ata_pci_compat(dev)) { #ifdef __alpha__ return alpha_platform_teardown_ide_intr(child, irq, cookie); #else _at__at_ -402,7 +430,7 _at__at_ ch->r_io[i].offset = i; } ch->r_io[ATA_ALTSTAT].res = altio; - ch->r_io[ATA_ALTSTAT].offset = 2; + ch->r_io[ATA_ALTSTAT].offset = ata_pci_compat(device_get_parent(dev)) ? 0:2; ch->r_io[ATA_IDX_ADDR].res = io; if (ctlr->r_res1) { Index: ata/ata-pci.h =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-pci.h,v retrieving revision 1.29 diff -u -r1.29 ata-pci.h --- ata/ata-pci.h 13 Apr 2004 09:44:20 -0000 1.29 +++ ata/ata-pci.h 18 Apr 2004 15:39:37 -0000 _at__at_ -63,9 +63,6 _at__at_ 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 _at__at_ -295,6 +292,7 _at__at_ #define VIABUG 0x10 /* global prototypes */ +int ata_pci_compat(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 *);Received on Mon Apr 19 2004 - 03:29:41 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:51 UTC