Commit b66fa17c authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.99pre5

parent de0d207b
VERSION = 2
PATCHLEVEL = 3
SUBLEVEL = 99
EXTRAVERSION = -pre4
EXTRAVERSION = -pre5
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
......
......@@ -24,7 +24,7 @@ O_OBJS += pci-i386.o
ifdef CONFIG_VISWS
O_OBJS += pci-visws.o
else
O_OBJS += pci-pc.o
O_OBJS += pci-pc.o pci-irq.o
endif
endif
......
......@@ -18,7 +18,6 @@
#define PCI_NO_SORT 0x100
#define PCI_BIOS_SORT 0x200
#define PCI_NO_CHECKS 0x400
#define PCI_PEER_FIXUP 0x800
#define PCI_ASSIGN_ROMS 0x1000
#define PCI_BIOS_IRQ_SCAN 0x2000
......@@ -28,3 +27,42 @@ extern unsigned int pci_probe;
void pcibios_resource_survey(void);
int pcibios_enable_resources(struct pci_dev *);
/* pci-pc.c */
extern int pcibios_last_bus;
extern struct pci_bus *pci_root_bus;
extern struct pci_ops *pci_root_ops;
struct irq_routing_table *pcibios_get_irq_routing_table(void);
int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
/* pci-irq.c */
struct irq_info {
u8 bus, devfn; /* Bus, device and function */
struct {
u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
u16 bitmap; /* Available IRQs */
} __attribute__((packed)) irq[4];
u8 slot; /* Slot number, 0=onboard */
u8 rfu;
} __attribute__((packed));
struct irq_routing_table {
u32 signature; /* PIRQ_SIGNATURE should be here */
u16 version; /* PIRQ_VERSION */
u16 size; /* Table size in bytes */
u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
u32 miniport_data; /* Crap */
u8 rfu[11];
u8 checksum; /* Modulo 256 checksum must give zero */
struct irq_info slots[0];
} __attribute__((packed));
extern unsigned int pcibios_irq_mask;
void pcibios_fixup_irqs(void);
int pcibios_lookup_irq(struct pci_dev *dev, int assign);
/*
* Low-Level PCI Support for PC -- Routing of Interrupts
*
* (c) 1999--2000 Martin Mares <mj@suse.cz>
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/io.h>
#include "pci-i386.h"
extern int skip_ioapic_setup;
#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
#define PIRQ_VERSION 0x0100
static struct irq_routing_table *pirq_table;
/*
* Never use: 0, 1, 2 (timer, keyboard, and cascade)
* Avoid using: 13, 14 and 15 (FP error and IDE).
* Penalize: 3, 4, 7, 12 (known ISA uses: serial, parallel and mouse)
*/
unsigned int pcibios_irq_mask = ~0;
static unsigned pirq_penalty[16] = {
10000, 10000, 10000, 100, 100, 0, 0, 100,
0, 0, 0, 0, 100, 1000, 1000, 1000
};
struct irq_router {
char *name;
u16 vendor, device;
int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq);
int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new);
};
/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
static struct irq_routing_table * __init pirq_find_routing_table(void)
{
u8 *addr;
struct irq_routing_table *rt;
int i;
u8 sum;
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
rt = (struct irq_routing_table *) addr;
if (rt->signature != PIRQ_SIGNATURE ||
rt->version != PIRQ_VERSION ||
rt->size % 16 ||
rt->size < sizeof(struct irq_routing_table))
continue;
sum = 0;
for(i=0; i<rt->size; i++)
sum += addr[i];
if (!sum) {
DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
return rt;
}
}
return NULL;
}
/*
* If we have a IRQ routing table, use it to search for peer host
* bridges. It's a gross hack, but since there are no other known
* ways how to get a list of buses, we have to go this way.
*/
static void __init pirq_peer_trick(void)
{
struct irq_routing_table *rt = pirq_table;
u8 busmap[256];
int i;
struct irq_info *e;
memset(busmap, 0, sizeof(busmap));
for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) {
e = &rt->slots[i];
#ifdef DEBUG
{
int j;
DBG("%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot);
for(j=0; j<4; j++)
DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap);
DBG("\n");
}
#endif
busmap[e->bus] = 1;
}
for(i=1; i<256; i++)
/*
* It might be a secondary bus, but in this case its parent is already
* known (ascending bus order) and therefore pci_scan_bus returns immediately.
*/
if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL))
printk("PCI: Discovered primary peer bus %02x [IRQ]\n", i);
pcibios_last_bus = -1;
}
/*
* Code for querying and setting of IRQ routes on various interrupt routers.
*/
static void eisa_set_level_irq(unsigned int irq)
{
unsigned char mask = 1 << (irq & 7);
unsigned int port = 0x4d0 + (irq >> 3);
unsigned char val = inb(port);
if (!(val & mask)) {
DBG(" -> edge");
outb(val | mask, port);
}
}
static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
static unsigned char irqmap[16] = {
0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15
};
unsigned int val = irqmap[irq];
pirq--;
if (val && pirq < 8) {
u8 x;
unsigned reg = 0x48 + (pirq >> 1);
pci_read_config_byte(router, reg, &x);
x = (pirq & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val);
pci_write_config_byte(router, reg, x);
eisa_set_level_irq(irq);
return 1;
}
return 0;
}
static int pirq_piix_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
u8 x;
pci_read_config_byte(router, pirq, &x);
return (x < 16) ? x : 0;
}
static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
pci_write_config_byte(router, pirq, irq);
return 1;
}
static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
u8 x;
int reg = 0x55 + (pirq >> 1);
pci_read_config_byte(router, reg, &x);
return (pirq & 1) ? (x >> 4) : (x & 0x0f);
}
static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
u8 x;
int reg = 0x55 + (pirq >> 1);
pci_read_config_byte(router, reg, &x);
x = (pirq & 1) ? ((x & 0x0f) | (irq << 4)) : ((x & 0xf0) | irq);
pci_write_config_byte(router, reg, x);
return 1;
}
static int pirq_opti_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
{
u8 x;
int reg = 0xb8 + (pirq >> 5);
pci_read_config_byte(router, reg, &x);
return (pirq & 0x10) ? (x >> 4) : (x & 0x0f);
}
static int pirq_opti_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
u8 x;
int reg = 0xb8 + (pirq >> 5);
pci_read_config_byte(router, reg, &x);
x = (pirq & 0x10) ? ((x & 0x0f) | (irq << 4)) : ((x & 0xf0) | irq);
pci_write_config_byte(router, reg, x);
return 1;
}
#ifdef CONFIG_PCI_BIOS
static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
struct pci_dev *bridge;
int pin = pci_get_interrupt_pin(dev, &bridge);
return pcibios_set_irq_routing(bridge, pin, irq);
}
static struct irq_router pirq_bios_router =
{ "BIOS", 0, 0, NULL, pirq_bios_set };
#endif
static struct irq_router pirq_routers[] = {
{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, pirq_piix_get, pirq_piix_set },
{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, pirq_piix_get, pirq_piix_set },
{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL, pirq_ali_set },
{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set },
{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set },
{ "OPTI", PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700, pirq_opti_get, pirq_opti_set },
{ "default", 0, 0, NULL, NULL }
};
static struct irq_router *pirq_router;
static struct pci_dev *pirq_router_dev;
static void __init pirq_find_router(void)
{
struct irq_routing_table *rt = pirq_table;
u16 rvendor, rdevice;
struct irq_router *r;
#ifdef CONFIG_PCI_BIOS
if (!rt->signature) {
printk("PCI: Using BIOS for IRQ routing\n");
pirq_router = &pirq_bios_router;
return;
}
#endif
if (!(pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn))) {
DBG("PCI: Interrupt router not found\n");
return;
}
if (rt->rtr_vendor) {
rvendor = rt->rtr_vendor;
rdevice = rt->rtr_device;
} else {
/*
* Several BIOSes forget to set the router type. In such cases, we
* use chip vendor/device. This doesn't guarantee us semantics of
* PIRQ values, but was found to work in practice and it's still
* better than not trying.
*/
DBG("PCI: Guessed interrupt router ID from %s\n", pirq_router_dev->slot_name);
rvendor = pirq_router_dev->vendor;
rdevice = pirq_router_dev->device;
}
for(r=pirq_routers; r->vendor; r++)
if (r->vendor == rvendor && r->device == rdevice)
break;
pirq_router = r;
printk("PCI: Using IRQ router %s [%04x/%04x] at %s\n", r->name,
rvendor, rdevice, pirq_router_dev->slot_name);
}
static struct irq_info *pirq_get_info(struct pci_dev *dev, int pin)
{
struct irq_routing_table *rt = pirq_table;
int entries = (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
struct irq_info *info;
for (info = rt->slots; entries--; info++)
if (info->bus == dev->bus->number && PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn))
return info;
return NULL;
}
int pcibios_lookup_irq(struct pci_dev *dev, int assign)
{
struct irq_info *info;
int i, pirq, pin, newirq;
int irq = 0;
u32 mask;
struct irq_router *r = pirq_router;
struct pci_dev *dev2, *d;
char *msg = NULL;
if (!pirq_table)
return 0;
/* Find IRQ routing entry */
pin = pci_get_interrupt_pin(dev, &d);
if (pin < 0) {
DBG(" -> no interrupt pin\n");
return 0;
}
DBG("IRQ for %s(%d) via %s", dev->slot_name, pin, d->slot_name);
info = pirq_get_info(d, pin);
if (!info) {
DBG(" -> not found in routing table\n");
return 0;
}
pirq = info->irq[pin].link;
mask = info->irq[pin].bitmap;
if (!pirq) {
DBG(" -> not routed\n");
return 0;
}
DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
if (pcibios_irq_mask != ~0)
mask &= pcibios_irq_mask;
else
mask &= pirq_table->exclusive_irqs;
/* Find the best IRQ to assign */
newirq = 0;
for (i = 0; i < 16; i++) {
if (!(mask & (1 << i)))
continue;
if (pirq_penalty[i] < pirq_penalty[newirq])
newirq = i;
}
DBG(" -> newirq=%d", newirq);
/* Try to get current IRQ */
if (r->get && (irq = r->get(pirq_router_dev, d, pirq))) {
DBG(" -> got IRQ %d\n", irq);
msg = "Found";
} else if (assign && newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
DBG(" -> assigning IRQ %d", newirq);
if (r->set(pirq_router_dev, d, pirq, newirq)) {
DBG(" ... OK\n");
msg = "Assigned";
irq = newirq;
}
}
if (!irq) {
DBG(" ... failed\n");
if (newirq && mask == (1 << newirq)) {
msg = "Guessed";
irq = newirq;
} else
return 0;
}
printk("PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
/* Update IRQ for all devices with the same pirq value */
pci_for_each_dev(dev2) {
if ((pin = pci_get_interrupt_pin(dev2, &d)) >= 0 &&
(info = pirq_get_info(d, pin)) &&
info->irq[pin].link == pirq) {
dev2->irq = irq;
pirq_penalty[irq]++;
if (dev != dev2)
printk("PCI: The same IRQ used for device %s\n", dev2->slot_name);
}
}
return 1;
}
void __init pcibios_fixup_irqs(void)
{
struct pci_dev *dev;
u8 pin;
DBG("PCI: IRQ fixup\n");
pirq_table = pirq_find_routing_table();
#ifdef CONFIG_PCI_BIOS
if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN))
pirq_table = pcibios_get_irq_routing_table();
#endif
if (pirq_table) {
pirq_peer_trick();
pirq_find_router();
}
pci_for_each_dev(dev) {
/*
* If the BIOS has set an out of range IRQ number, just ignore it.
* Also keep track of which IRQ's are already in use.
*/
if (dev->irq >= 16) {
DBG("%s: ignoring bogus IRQ %d\n", dev->slot_name, dev->irq);
dev->irq = 0;
}
pirq_penalty[dev->irq]++;
}
pci_for_each_dev(dev) {
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
#if defined(CONFIG_X86_IO_APIC)
/*
* Recalculate IRQ numbers if we use the I/O APIC.
*/
if (!skip_ioapic_setup)
{
int irq;
if (pin) {
pin--; /* interrupt pins are numbered starting from 1 */
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
/*
* Will be removed completely if things work out well with fuzzy parsing
*/
#if 0
if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
struct pci_dev * bridge = dev->bus->self;
pin = (pin + PCI_SLOT(dev->devfn)) % 4;
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
PCI_SLOT(bridge->devfn), pin);
if (irq >= 0)
printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n",
bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
}
#endif
if (irq >= 0) {
printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
dev->irq = irq;
}
}
pirq_table = NULL; /* Avoid automatic IRQ assignment */
}
#endif
/*
* Still no IRQ? Try to lookup one...
*/
if (pin && !dev->irq)
pcibios_lookup_irq(dev, 0);
}
}
......@@ -10,9 +10,6 @@
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/segment.h>
#include <asm/io.h>
......@@ -22,35 +19,9 @@
unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
static struct pci_bus *pci_root_bus;
static struct pci_ops *pci_root_ops;
/*
* IRQ routing table provided by the BIOS
*/
struct irq_info {
u8 bus, devfn; /* Bus, device and function */
struct {
u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
u16 bitmap; /* Available IRQs */
} __attribute__((packed)) irq[4];
u8 slot; /* Slot number, 0=onboard */
u8 rfu;
} __attribute__((packed));
struct irq_routing_table {
u32 signature; /* PIRQ_SIGNATURE should be here */
u16 version; /* PIRQ_VERSION */
u16 size; /* Table size in bytes */
u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
u32 miniport_data; /* Crap */
u8 rfu[11];
u8 checksum; /* Modulo 256 checksum must give zero */
struct irq_info slots[0];
} __attribute__((packed));
int pcibios_last_bus = -1;
struct pci_bus *pci_root_bus;
struct pci_ops *pci_root_ops;
/*
* Direct access to PCI hardware...
......@@ -378,7 +349,7 @@ static int pci_bios_present;
static int __init check_pcibios(void)
{
u32 signature, eax, ebx, ecx;
u8 status, major_ver, minor_ver, hw_mech, last_bus;
u8 status, major_ver, minor_ver, hw_mech;
unsigned long flags, pcibios_entry;
if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
......@@ -403,16 +374,17 @@ static int __init check_pcibios(void)
hw_mech = eax & 0xff;
major_ver = (ebx >> 8) & 0xff;
minor_ver = ebx & 0xff;
last_bus = ecx & 0xff;
if (pcibios_last_bus < 0)
pcibios_last_bus = ecx & 0xff;
DBG("PCI: BIOS probe returned s=%02x hw=%02x ver=%02x.%02x l=%02x\n",
status, hw_mech, major_ver, minor_ver, last_bus);
status, hw_mech, major_ver, minor_ver, pcibios_last_bus);
if (status || signature != PCI_SIGNATURE) {
printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] found, report to <mj@suse.cz>\n",
status, signature);
return 0;
}
printk("PCI: PCI BIOS revision %x.%02x entry at 0x%lx\n",
major_ver, minor_ver, pcibios_entry);
printk("PCI: PCI BIOS revision %x.%02x entry at 0x%lx, last bus=%d\n",
major_ver, minor_ver, pcibios_entry, pcibios_last_bus);
#ifdef CONFIG_PCI_DIRECT
if (!(hw_mech & PCIBIOS_HW_TYPE1))
pci_probe &= ~PCI_PROBE_CONF1;
......@@ -670,7 +642,7 @@ static void __init pcibios_sort(void)
}
/*
* Ask BIOS for IRQ Routing Table
* BIOS Functions for IRQ Routing
*/
struct irq_routing_options {
......@@ -679,28 +651,20 @@ struct irq_routing_options {
u16 segment;
} __attribute__((packed));
static unsigned long pcibios_irq_page __initdata = 0;
static inline void __init pcibios_free_irq_routing_table(void)
{
if (pcibios_irq_page)
free_page(pcibios_irq_page);
}
static struct irq_routing_table * __init pcibios_get_irq_routing_table(void)
struct irq_routing_table * __init pcibios_get_irq_routing_table(void)
{
struct irq_routing_options opt;
struct irq_routing_table *rt;
struct irq_routing_table *rt = NULL;
int ret, map;
unsigned long page;
if (!(pci_probe & PCI_BIOS_IRQ_SCAN))
if (!pci_bios_present)
return NULL;
page = __get_free_page(GFP_KERNEL);
if (!page)
return NULL;
pcibios_irq_page = __get_free_page(GFP_KERNEL);
if (!pcibios_irq_page)
return 0;
rt = (void *) pcibios_irq_page;
opt.table = rt->slots;
opt.size = PAGE_SIZE - sizeof(struct irq_routing_table);
opt.table = (struct irq_info *) page;
opt.size = PAGE_SIZE;
opt.segment = __KERNEL_DS;
DBG("PCI: Fetching IRQ routing table... ");
......@@ -719,17 +683,39 @@ static struct irq_routing_table * __init pcibios_get_irq_routing_table(void)
"D" ((long) &opt),
"S" (&pci_indirect));
DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
if (ret & 0xff00) {
if (ret & 0xff00)
printk(KERN_ERR "PCI: Error %02x when fetching IRQ routing table.\n", (ret >> 8) & 0xff);
return 0;
else if (opt.size) {
rt = kmalloc(sizeof(struct irq_routing_table) + opt.size, GFP_KERNEL);
if (rt) {
memset(rt, 0, sizeof(struct irq_routing_table));
rt->size = opt.size + sizeof(struct irq_routing_table);
rt->exclusive_irqs = map;
memcpy(rt->slots, (void *) page, opt.size);
printk("PCI: Using BIOS Interrupt Routing Table\n");
}
}
memset(rt, 0, sizeof(struct irq_routing_table));
rt->size = opt.size + sizeof(struct irq_routing_table);
printk("PCI: Using BIOS Interrupt Routing Table\n");
free_page(page);
return rt;
}
int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
{
int ret;
__asm__("lcall (%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=a" (ret)
: "0" (PCIBIOS_SET_PCI_HW_INT),
"b" ((dev->bus->number << 8) | dev->devfn),
"c" ((irq << 8) | (pin + 10)),
"S" (&pci_indirect));
return !(ret & 0xff00);
}
#endif
/*
......@@ -786,75 +772,33 @@ static void __init pcibios_fixup_ghosts(struct pci_bus *b)
}
/*
* In case there are peer host bridges, scan bus behind each of them.
* Although several sources claim that the host bridges should have
* header type 1 and be assigned a bus number as for PCI2PCI bridges,
* the reality doesn't pass this test and the bus number is usually
* set by BIOS to the first free value.
* Discover remaining PCI buses in case there are peer host bridges.
* We use the number of last PCI bus provided by the PCI BIOS.
*/
static void __init pcibios_fixup_peer_bridges(void)
{
struct list_head *ln;
struct pci_bus *b = pci_root_bus;
int n, cnt=-1;
struct pci_ops *ops = pci_root_bus->ops;
int n;
struct pci_bus bus;
struct pci_dev dev;
u16 l;
#ifdef CONFIG_PCI_DIRECT
/*
* Don't search for peer host bridges if we use config type 2
* since it reads bogus values for non-existent buses and
* chipsets supporting multiple primary buses use conf1 anyway.
*/
if (ops == &pci_direct_conf2)
if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
return;
#endif
DBG("PCI: Peer bridge fixup\n");
for(ln=b->devices.next; ln != &b->devices; ln=ln->next)
if ((pci_dev_b(ln)->class >> 8) == PCI_CLASS_BRIDGE_HOST)
cnt++;
n = b->subordinate + 1;
while (n <= 0xff) {
int found = 0;
u16 l;
struct pci_bus bus;
struct pci_dev dev;
for (n=0; n <= pcibios_last_bus; n++) {
if (pci_bus_exists(&pci_root_buses, n))
continue;
bus.number = n;
bus.ops = ops;
bus.ops = pci_root_ops;
dev.bus = &bus;
for(dev.devfn=0; dev.devfn<256; dev.devfn += 8)
if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) &&
l != 0x0000 && l != 0xffff) {
#ifdef CONFIG_PCI_BIOS
if (pci_bios_present) {
int err, idx = 0;
u8 bios_bus, bios_dfn;
u16 d;
pci_read_config_word(&dev, PCI_DEVICE_ID, &d);
DBG("BIOS test for %02x:%02x (%04x:%04x)\n", n, dev.devfn, l, d);
while (!(err = pci_bios_find_device(l, d, idx, &bios_bus, &bios_dfn)) &&
(bios_bus != n || bios_dfn != dev.devfn))
idx++;
if (err)
break;
}
#endif
DBG("Found device at %02x:%02x\n", n, dev.devfn);
found++;
if (!pci_read_config_word(&dev, PCI_CLASS_DEVICE, &l) &&
l == PCI_CLASS_BRIDGE_HOST)
cnt++;
DBG("Found device at %02x:%02x [%04x]\n", n, dev.devfn, l);
printk("PCI: Discovered peer bus %02x\n", n);
pci_scan_bus(n, pci_root_ops, NULL);
break;
}
if (cnt-- <= 0)
break;
if (found) {
printk("PCI: Discovered primary peer bus %02x\n", n);
b = pci_scan_bus(n, ops, NULL);
if (b)
n = b->subordinate;
}
n++;
}
}
......@@ -881,6 +825,7 @@ static void __init pci_fixup_i450nx(struct pci_dev *d)
if (suba < subb)
pci_scan_bus(suba+1, pci_root_ops, NULL); /* Bus B */
}
pcibios_last_bus = -1;
}
static void __init pci_fixup_i450gx(struct pci_dev *d)
......@@ -893,6 +838,7 @@ static void __init pci_fixup_i450gx(struct pci_dev *d)
pci_read_config_byte(d, 0x4a, &busno);
printk("PCI: i440KX/GX host bridge %s: secondary bus %02x\n", d->slot_name, busno);
pci_scan_bus(busno, pci_root_ops, NULL);
pcibios_last_bus = -1;
}
static void __init pci_fixup_rcc(struct pci_dev *d)
......@@ -905,6 +851,7 @@ static void __init pci_fixup_rcc(struct pci_dev *d)
pci_read_config_byte(d, 0x44, &busno);
printk("PCI: RCC host bridge: secondary bus %02x\n", busno);
pci_scan_bus(busno, pci_root_ops, NULL);
pcibios_last_bus = -1;
}
static void __init pci_fixup_compaq(struct pci_dev *d)
......@@ -917,6 +864,7 @@ static void __init pci_fixup_compaq(struct pci_dev *d)
pci_read_config_byte(d, 0xc8, &busno);
printk("PCI: Compaq host bridge: secondary bus %02x\n", busno);
pci_scan_bus(busno, pci_root_ops, NULL);
pcibios_last_bus = -1;
}
static void __init pci_fixup_umc_ide(struct pci_dev *d)
......@@ -976,333 +924,6 @@ struct pci_fixup pcibios_fixups[] = {
{ 0 }
};
/*
* Fix up IRQs of all PCI devices.
*/
extern int skip_ioapic_setup;
#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
#define PIRQ_VERSION 0x0100
static struct irq_routing_table *pirq_table;
/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
static struct irq_routing_table * __init pcibios_find_irq_routing_table(void)
{
u8 *addr;
struct irq_routing_table *rt;
int i;
u8 sum;
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
rt = (struct irq_routing_table *) addr;
if (rt->signature != PIRQ_SIGNATURE ||
rt->version != PIRQ_VERSION ||
rt->size % 16 ||
rt->size < sizeof(struct irq_routing_table))
continue;
sum = 0;
for(i=0; i<rt->size; i++)
sum += addr[i];
if (!sum) {
printk("PCI: Interrupt Routing Table found at 0x%p [router type %04x/%04x]\n",
rt, rt->rtr_vendor, rt->rtr_device);
return rt;
}
}
return NULL;
}
/*
* If we have a IRQ routing table, use it to search for peer host
* bridges. It's a gross hack, but since there are no other known
* ways how to get a list of buses, we have to go this way.
*/
static void __init pcibios_irq_peer_trick(struct irq_routing_table *rt)
{
u8 busmap[256];
int i;
struct irq_info *e;
memset(busmap, 0, sizeof(busmap));
for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) {
e = &rt->slots[i];
DBG("b=%02x d=%02x s=%02x\n", e->bus, e->devfn, e->slot);
busmap[e->bus] = 1;
}
for(i=1; i<256; i++)
/*
* It might be a secondary bus, but in this case its parent is already
* known (ascending bus order) and therefore pci_scan_bus returns immediately.
*/
if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL))
printk("PCI: Discovered primary peer bus %02x [IRQ]\n", i);
}
static void ali_set_level_irq(unsigned irq)
{
unsigned char mask = 1 << (irq & 7);
unsigned int port = 0x4d0 + (irq >> 3);
unsigned char val = inb(port);
if (val & mask) {
DBG("PCI irq %d was level\n", irq);
return;
}
DBG("PCI irq %d was edge, turning into level-triggered\n", irq);
outb(val | mask, port);
}
static int ali_set_irq(struct pci_dev *router, unsigned pirq, unsigned irq)
{
if (irq < 15) {
static unsigned char irqmap[16] = {
0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15
};
unsigned char val = irqmap[irq];
if (val && pirq < 8) {
u8 byte;
unsigned offset = 0x48 + (pirq >> 1);
unsigned shift = (pirq & 1) << 2;
pci_read_config_byte(router, offset, &byte);
DBG("ALI: old %04x=%02x\n", offset, byte);
byte &= ~(0xf << shift);
byte |= val << shift;
DBG("ALI: new %04x=%02x\n", offset, byte);
pci_write_config_byte(router, offset, byte);
ali_set_level_irq(irq);
return irq;
}
}
return 0;
}
/*
* In case BIOS forgets to tell us about IRQ, we try to look it up in the routing
* table, but unfortunately we have to know the interrupt router chip.
*/
/*
* Never use: 0, 1, 2 (timer, keyboard, and cascade)
* Avoid using: 13, 14 and 15 (FP error and IDE).
* Penalize: 3, 4, 7, 12 (known ISA uses: serial, parallel and mouse)
*/
static unsigned int pcibios_irq_mask = 0xfff8;
static unsigned pcibios_irq_penalty[16] = {
10000, 10000, 10000, 100, 100, 0, 0, 100,
0, 0, 0, 0, 100, 1000, 1000, 1000
};
static char *pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_table *rt, int pin, int assign)
{
struct irq_info *q;
struct pci_dev *router;
int i, pirq, newirq, reg;
u32 rtrid, mask;
u8 x, y;
char *msg = NULL;
pin--;
DBG("IRQ for %s(%d)", dev->slot_name, pin);
while (dev->bus->self) {
pin = (pin + PCI_SLOT(dev->devfn)) % 4;
dev = dev->bus->self;
DBG(" -> %s(%d)", dev->slot_name, pin);
}
for(q = rt->slots, i = rt->size - sizeof(struct irq_routing_table);
i && (q->bus != dev->bus->number || PCI_SLOT(q->devfn) != PCI_SLOT(dev->devfn));
i -= sizeof(struct irq_info), q++)
;
if (!i) {
DBG(" -> not found in routing table\n");
return NULL;
}
pirq = q->irq[pin].link;
mask = q->irq[pin].bitmap;
if (!pirq) {
DBG(" -> not routed\n");
return NULL;
}
DBG(" -> PIRQ %02x, mask %04x", pirq, mask);
newirq = 0;
if (assign && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
for (i = 0; i < 16; i++) {
if (!(mask & pcibios_irq_mask & (1 << i)))
continue;
if (pcibios_irq_penalty[i] < pcibios_irq_penalty[newirq])
newirq = i;
}
}
if (!(router = pci_find_slot(rt->rtr_bus, rt->rtr_devfn))) {
DBG(" -> router not found\n");
return NULL;
}
#define ID(x,y) ((x << 16) | y)
rtrid = ID(rt->rtr_vendor, rt->rtr_device);
if (!rtrid) {
/*
* Several BIOSes forget to set the router type. In such cases, we
* use chip vendor/device. This doesn't guarantee us semantics of
* PIRQ values, but was found to work in practice and it's still
* better than not trying.
*/
DBG(" [%s]", router->slot_name);
rtrid = ID(router->vendor, router->device);
}
switch (rtrid) {
case ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0):
case ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0):
case ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0):
/* Intel PIIX: PIRQ holds configuration register address */
pci_read_config_byte(router, pirq, &x);
if (x < 16) {
DBG(" -> [PIIX] %02x\n", x);
newirq = x;
msg = "PIIX";
} else if (newirq) {
DBG(" -> [PIIX] set to %02x\n", newirq);
pci_write_config_byte(router, pirq, newirq);
msg = "PIIX-NEW";
} else DBG(" -> [PIIX] sink\n");
break;
case ID(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533):
newirq = ali_set_irq(router, pirq-1, newirq);
if (newirq)
msg = "ALI";
break;
case ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596):
case ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686):
reg = 0x55 + (pirq >> 1);
pci_read_config_byte(router, reg, &x);
y = (pirq & 1) ? (x >> 4) : (x & 0x0f);
if (y) {
DBG(" -> [VIA] %02x\n", y);
newirq = y;
msg = "VIA";
} else if (newirq) {
DBG(" -> [VIA] set to %02x\n", newirq);
x = (pirq & 1) ? ((x & 0x0f) | (newirq << 4)) : ((x & 0xf0) | newirq);
pci_write_config_byte(router, reg, x);
msg = "VIA-NEW";
} else DBG(" -> [VIA] sink\n");
break;
case ID(PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700):
reg = 0xb8 + (pirq >> 5);
pci_read_config_byte(router, reg, &x);
y = (pirq & 0x10) ? (x >> 4) : (x & 0x0f);
if (y) {
DBG(" -> [OPTI] %02x\n", y);
newirq = y;
msg = "OPTI";
} else if (newirq) {
DBG(" -> [OPTI] set to %02x\n", newirq);
x = (pirq & 0x10) ? ((x & 0x0f) | (newirq << 4)) : ((x & 0xf0) | newirq);
pci_write_config_byte(router, reg, y);
msg = "OPTI-NEW";
} else DBG(" -> [OPTI] sink\n");
break;
default:
DBG(" -> unknown router %04x/%04x\n", rt->rtr_vendor, rt->rtr_device);
if (newirq && mask == (1 << newirq)) {
/* Only one IRQ available -> use it */
msg = "guess";
}
}
#undef ID
if (msg) {
dev->irq = newirq;
pcibios_irq_penalty[newirq]++;
}
return msg;
}
static void __init pcibios_fixup_irqs(void)
{
struct irq_routing_table *rtable;
struct pci_dev *dev;
u8 pin;
DBG("PCI: IRQ fixup\n");
rtable = pirq_table = pcibios_find_irq_routing_table();
#ifdef CONFIG_PCI_BIOS
if (!rtable && pci_bios_present)
rtable = pcibios_get_irq_routing_table();
#endif
if (rtable)
pcibios_irq_peer_trick(rtable);
pci_for_each_dev(dev) {
/*
* If the BIOS has set an out of range IRQ number, just ignore it.
* Also keep track of which IRQ's are already in use.
*/
if (dev->irq >= 16) {
DBG("%s: ignoring bogus IRQ %d\n", dev->slot_name, dev->irq);
dev->irq = 0;
}
pcibios_irq_penalty[dev->irq]++;
}
pci_for_each_dev(dev) {
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
#if defined(CONFIG_X86_IO_APIC)
/*
* Recalculate IRQ numbers if we use the I/O APIC.
*/
if(!skip_ioapic_setup)
{
int irq;
if (pin) {
pin--; /* interrupt pins are numbered starting from 1 */
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
/*
* Will be removed completely if things work out well with fuzzy parsing
*/
#if 0
if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
struct pci_dev * bridge = dev->bus->self;
pin = (pin + PCI_SLOT(dev->devfn)) % 4;
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
PCI_SLOT(bridge->devfn), pin);
if (irq >= 0)
printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n",
bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
}
#endif
if (irq >= 0) {
printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
dev->irq = irq;
}
}
pirq_table = NULL; /* Avoid automatic IRQ assignment */
}
#endif
/*
* Still no IRQ? Try to assign one...
*/
if (pin && !dev->irq && pirq_table) {
char *msg = pcibios_lookup_irq(dev, pirq_table, pin, 0);
if (msg)
printk("PCI: Found IRQ %d for device %s [%s]\n", dev->irq, dev->slot_name, msg);
}
}
#ifdef CONFIG_PCI_BIOS
pcibios_free_irq_routing_table();
#endif
}
/*
* Called after each bus is probed, but before its children
* are examined.
......@@ -1349,8 +970,7 @@ void __init pcibios_init(void)
pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
pcibios_fixup_irqs();
if (pci_probe & PCI_PEER_FIXUP)
pcibios_fixup_peer_bridges();
pcibios_fixup_peer_bridges();
pcibios_resource_survey();
#ifdef CONFIG_PCI_BIOS
......@@ -1390,15 +1010,15 @@ char * __init pcibios_setup(char *str)
return NULL;
}
#endif
else if (!strcmp(str, "peer")) {
pci_probe |= PCI_PEER_FIXUP;
return NULL;
} else if (!strcmp(str, "rom")) {
else if (!strcmp(str, "rom")) {
pci_probe |= PCI_ASSIGN_ROMS;
return NULL;
} else if (!strncmp(str, "irqmask=", 8)) {
pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
return NULL;
} else if (!strncmp(str, "lastbus=", 8)) {
pcibios_last_bus = simple_strtol(str+8, NULL, 0);
return NULL;
}
return str;
}
......@@ -1412,15 +1032,10 @@ int pcibios_enable_device(struct pci_dev *dev)
if (!dev->irq) {
u8 pin;
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
if (pin) {
char *msg;
if (pirq_table && ((msg = pcibios_lookup_irq(dev, pirq_table, pin, 1))))
printk("PCI: Assigned IRQ %d to device %s [%s]\n", dev->irq, dev->slot_name, msg);
else
printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
'A' + pin - 1, dev->slot_name,
(pci_probe & PCI_BIOS_IRQ_SCAN) ? "" : " Please try using pci=biosirq.");
}
if (pin && !pcibios_lookup_irq(dev, 1))
printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
'A' + pin - 1, dev->slot_name,
(pci_probe & PCI_BIOS_IRQ_SCAN) ? "" : " Please try using pci=biosirq.");
}
return 0;
}
......@@ -186,7 +186,7 @@ struct devprobe eisa_probes[] __initdata = {
{ne3210_probe, 0},
#endif
#ifdef CONFIG_DEFXX
{dfx_probe, 0}.
{dfx_probe, 0},
#endif
{NULL, 0},
};
......
......@@ -254,6 +254,23 @@ pci_enable_device(struct pci_dev *dev)
return 0;
}
int
pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
{
u8 pin;
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
if (!pin)
return -1;
pin--;
while (dev->bus->self) {
pin = (pin + PCI_SLOT(dev->devfn)) % 4;
dev = dev->bus->self;
}
*bridge = dev;
return pin;
}
/*
* Registration of PCI drivers and handling of hot-pluggable devices.
*/
......@@ -961,7 +978,7 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
return max;
}
static int __init pci_bus_exists(const struct list_head *list, int nr)
int __init pci_bus_exists(const struct list_head *list, int nr)
{
const struct list_head *l;
......
......@@ -1720,11 +1720,15 @@ int usb_new_device(struct usb_device *dev)
info("USB new device connect, assigned device number %d", dev->devnum);
dev->maxpacketsize = 0; /* Default to 8 byte max packet size */
/* USB v1.1 5.5.3 */
/* We read the first 8 bytes from the device descriptor to get to */
/* the bMaxPacketSize0 field. Then we set the maximum packet size */
/* for the control pipe, and retrieve the rest */
dev->epmaxpacketin [0] = 8;
dev->epmaxpacketout[0] = 8;
/* We still haven't set the Address yet */
/* Even though we have assigned an address for the device, we */
/* haven't told it what it's address is yet */
addr = dev->devnum;
dev->devnum = 0;
......@@ -1740,12 +1744,6 @@ int usb_new_device(struct usb_device *dev)
}
dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
switch (dev->descriptor.bMaxPacketSize0) {
case 8: dev->maxpacketsize = 0; break;
case 16: dev->maxpacketsize = 1; break;
case 32: dev->maxpacketsize = 2; break;
case 64: dev->maxpacketsize = 3; break;
}
dev->devnum = addr;
......
......@@ -522,7 +522,7 @@ static inline int
walk_init_root(const char *name, unsigned flags, struct nameidata *nd)
{
if (current->personality != PER_LINUX)
if (__emul_lookup_dentry(name,flags,nd));
if (__emul_lookup_dentry(name,flags,nd))
return 0;
nd->mnt = mntget(current->fs->rootmnt);
nd->dentry = dget(current->fs->root);
......
......@@ -198,7 +198,7 @@ nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
static inline unsigned long
nfs_calc_block_size(u64 tsize)
{
loff_t used = (tsize + 511) / 512;
loff_t used = (tsize + 511) >> 9;
return (used > ULONG_MAX) ? ULONG_MAX : used;
}
......
......@@ -465,6 +465,7 @@ int pcibios_find_device (unsigned short vendor, unsigned short dev_id,
/* Generic PCI functions used internally */
void pci_init(void);
int pci_bus_exists(const struct list_head *list, int nr);
struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
struct pci_bus *pci_alloc_primary_bus(int bus);
struct pci_dev *pci_scan_slot(struct pci_dev *temp);
......@@ -474,7 +475,8 @@ void pci_name_device(struct pci_dev *dev);
char *pci_class_name(u32 class);
void pci_read_bridge_bases(struct pci_bus *child);
struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res);
int pci_setup_device(struct pci_dev * dev);
int pci_setup_device(struct pci_dev *dev);
int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);
/* Generic PCI functions exported to card drivers */
......
......@@ -539,7 +539,6 @@ struct usb_device {
atomic_t refcnt; /* Reference count */
int maxpacketsize; /* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */
unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */
unsigned int halted[2]; /* endpoint halts; one bit per endpoint # & direction; */
/* [0] = IN, [1] = OUT */
......@@ -686,7 +685,7 @@ int usb_get_current_frame_number (struct usb_device *usb_dev);
static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint)
{
return (dev->devnum << 8) | (endpoint << 15) | (dev->slow << 26) | dev->maxpacketsize;
return (dev->devnum << 8) | (endpoint << 15) | (dev->slow << 26);
}
static inline unsigned int __default_pipe(struct usb_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment