kernels/linux-2.4.0/arch/parisc/kernel/lba_pci.c
/*
** The algorithm is generic code.
** But it needs to access local data structures to get the IRQ base.
** Could make this a "pci_fixup_irq(bus, region)" but not sure
** it's worth it.
**
** Called by do_pci_scan_bus() immediately after each PCI bus is walked.
** Resources aren't allocated until recursive buswalk below HBA is completed.
*/
The algorithm is generic code.
But it needs to access local data structures to get the IRQ base.
Could make this a "pci_fixup_irq(bus, region)" but not sure
it's worth it.

Called by do_pci_scan_bus() immediately after each PCI bus is walked.
Resources aren't allocated until recursive buswalk below HBA is completed.
The algorithm is generic code . But it needs to access local data structures to get the IRQ base . Could make this a " pci_fixup_irq ( bus region ) " but not sure it ' s worth it . Called by do_pci_scan_bus () immediately after each PCI bus is walked . Resources aren ' t allocated until recursive buswalk below HBA is completed .
static void
lba_fixup_bus(struct pci_bus *bus)
{
	struct list_head *ln;
        struct pci_dev *dev;
	u16 fbb_enable = PCI_STATUS_FAST_BACK;
	u16 status;
	struct lba_device *ldev = LBA_DEV(bus->sysdata);
#ifdef __LP64__
	int i;
#endif
	DBG("lba_fixup_bus(0x%p) bus %d sysdata 0x%p\n",
				bus, bus->secondary, bus->sysdata);
	if (NULL == bus->self) {
		int err;
		DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
			ldev->hba.io_space.name,
			ldev->hba.io_space.start,
			ldev->hba.io_space.end,
			(int) ldev->hba.io_space.flags);
		DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
			ldev->hba.mem_space.name,
			ldev->hba.mem_space.start,
			ldev->hba.mem_space.end,
			(int) ldev->hba.mem_space.flags);
		err = request_resource(&ioport_resource, &(ldev->hba.io_space));
		if (err < 0) {
			BUG();
			lba_dump_res(&ioport_resource, 2);
		}
		err = request_resource(&iomem_resource, &(ldev->hba.mem_space));
		if (err < 0) {
			BUG();
			lba_dump_res(&iomem_resource, 2);
		}
		bus->resource[0] = &(ldev->hba.io_space);
		bus->resource[1] = &(ldev->hba.mem_space);
	}
	list_for_each(ln, &bus->devices) {
		dev = pci_dev_b(ln);
#ifdef __LP64__
		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
			struct resource *res = &(dev->resource[i]);
			if (res->flags & IORESOURCE_MEM) {
				res->start |= ldev->lmmio_base;
				res->end   |= ldev->lmmio_base;
			}
		}
#endif
		(void) lba_cfg_read16(dev, PCI_STATUS, &status);
		fbb_enable &= status;
#ifdef __LP64__
		if (pdc_pat) {
			lba_claim_dev_resources(dev);
		}
#endif	
		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
			continue;
		iosapic_fixup_irq(LBA_DEV(bus->sysdata)->iosapic_obj, dev);
	}
#if 0
	if (fbb_enable) {
		if (bus->self) {
			u8 control;
			(void) lba_cfg_read8(bus->self, PCI_BRIDGE_CONTROL, &control);
			(void) lba_cfg_write8(bus->self, PCI_BRIDGE_CONTROL, control | PCI_STATUS_FAST_BACK);
		} else {
		}
		fbb_enable = PCI_COMMAND_FAST_BACK;
	}
	list_for_each(ln, &bus->devices) {
		(void) lba_cfg_read16(dev, PCI_COMMAND, &status);
		status |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR | fbb_enable;
		(void) lba_cfg_write16(dev, PCI_COMMAND, status);
	}
#endif
}
static void lba_fixup_bus ( struct pci_bus * bus ) { struct list_head * ln ; struct pci_dev * dev ; u16 fbb_enable = PCI_STATUS_FAST_BACK ; u16 status ; struct lba_device * ldev = LBA_DEV ( bus -> sysdata ) ; #ifdef __LP64__ int i ; #endif DBG ( " \n " , bus , bus -> secondary , bus -> sysdata ) ; if ( NULL == bus -> self ) { int err ; DBG ( " \n " , ldev -> hba . io_space . name , ldev -> hba . io_space . start , ldev -> hba . io_space . end , ( int ) ldev -> hba . io_space . flags ) ; DBG ( " \n " , ldev -> hba . mem_space . name , ldev -> hba . mem_space . start , ldev -> hba . mem_space . end , ( int ) ldev -> hba . mem_space . flags ) ; err = request_resource ( & ioport_resource , & ( ldev -> hba . io_space ) ) ; if ( err < 0 ) { BUG ( ) ; lba_dump_res ( & ioport_resource , 2 ) ; } err = request_resource ( & iomem_resource , & ( ldev -> hba . mem_space ) ) ; if ( err < 0 ) { BUG ( ) ; lba_dump_res ( & iomem_resource , 2 ) ; } bus -> resource [ 0 ] = & ( ldev -> hba . io_space ) ; bus -> resource [ 1 ] = & ( ldev -> hba . mem_space ) ; } list_for_each ( ln , & bus -> devices ) { dev = pci_dev_b ( ln ) ; #ifdef __LP64__ for ( i = 0 ; i <= PCI_ROM_RESOURCE ; i ++ ) { struct resource * res = & ( dev -> resource [ i ] ) ; if ( res -> flags & IORESOURCE_MEM ) { res -> start |= ldev -> lmmio_base ; res -> end |= ldev -> lmmio_base ; } } #endif ( void ) lba_cfg_read16 ( dev , PCI_STATUS , & status ) ; fbb_enable &= status ; #ifdef __LP64__ if ( pdc_pat ) { lba_claim_dev_resources ( dev ) ; } #endif if ( ( dev -> class >> 8 ) == PCI_CLASS_BRIDGE_PCI ) continue ; iosapic_fixup_irq ( LBA_DEV ( bus -> sysdata ) -> iosapic_obj , dev ) ; } #if 0 if ( fbb_enable ) { if ( bus -> self ) { u8 control ; ( void ) lba_cfg_read8 ( bus -> self , PCI_BRIDGE_CONTROL , & control ) ; ( void ) lba_cfg_write8 ( bus -> self , PCI_BRIDGE_CONTROL , control | PCI_STATUS_FAST_BACK ) ; } else { } fbb_enable = PCI_COMMAND_FAST_BACK ; } list_for_each ( ln , & bus -> devices ) { ( void ) lba_cfg_read16 ( dev , PCI_COMMAND , & status ) ; status |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR | fbb_enable ; ( void ) lba_cfg_write16 ( dev , PCI_COMMAND , status ) ; } #endif }
The algorithm is generic code.
The algorithm is generic code .
/*
	** Properly Setup MMIO resources for this bus.
	** pci_alloc_primary_bus() mangles this.
	*/ /*
		** 0-5 are the "standard PCI regions"
		** (see comments near PCI_NUM_RESOURCES in include/linux/pci.h)
		*/ /* "Globalize" PCI address */ /*
		** If one device does not support FBB transfers,
		** No one on the bus can be allowed to use them.
		*/ /* Claim resources for PDC's devices */ /* __LP64__ */ /*
		** P2PB's have no IRQs. ignore them.
		*/ /* Adjust INTERRUPT_LINE for this dev */ /* FIXME/REVISIT - finish figuring out to set FBB on both
** pbus_set_ranges() clobbers PCI_BRIDGE_CONTROL.
** Can't fixup here anyway....garr...
*/ /* enable on PPB */ /* enable on LBA */ /* Lastly enable FBB/PERR/SERR on all devices too */