Date: Mon, 19 Apr 2004 14:29:31 +0200 From: =?ISO-8859-1?Q?S=F8ren_Schmidt?= <sos@DeepCore.dk> To: Michael Luetz <miluetz@hotmail.com> Cc: freebsd-current@freebsd.org Subject: Re: no root fs in CURRENT kernel Message-ID: <4083C62B.10900@DeepCore.dk> In-Reply-To: <BAY7-F116qMkYrDebVC0005f63c@hotmail.com> References: <BAY7-F116qMkYrDebVC0005f63c@hotmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------030407090800060002090601 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit 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 --------------030407090800060002090601 Content-Type: text/plain; name="diff-first-cut" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diff-first-cut" 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 @@ -260,8 +260,8 @@ 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; @@ -402,7 +402,7 @@ 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 @@ -824,6 +824,15 @@ */ 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; --------------030407090800060002090601 Content-Type: text/plain; name="diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diff" 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 @@ -1455,15 +1455,11 @@ 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); @@ -1472,16 +1468,18 @@ 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; } } @@ -1491,11 +1489,11 @@ * 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) @@ -1590,11 +1588,12 @@ */ 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 @@ -2350,15 +2350,15 @@ 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); @@ -2662,7 +2662,7 @@ 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 @@ -563,15 +563,15 @@ } } + 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 @@ -62,6 +62,15 @@ 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) { @@ -155,10 +164,29 @@ { 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; @@ -185,7 +213,7 @@ /* 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 +255,7 @@ 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); @@ -247,7 +275,7 @@ 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; @@ -259,9 +287,9 @@ 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; @@ -274,7 +302,7 @@ } 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 @@ -316,7 +344,7 @@ 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 @@ -335,7 +363,7 @@ 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); @@ -359,7 +387,7 @@ 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 @@ -402,7 +430,7 @@ 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 @@ -63,9 +63,6 @@ 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,7 @@ #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 *); --------------030407090800060002090601--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4083C62B.10900>