Commit 6ed83574 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.35pre6

parent 159f5e24
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
struct pci_bus *pci_root; struct pci_bus *pci_root;
struct pci_dev *pci_devices = NULL; struct pci_dev *pci_devices = NULL;
static struct pci_dev **pci_last_dev_p = &pci_devices; static struct pci_dev **pci_last_dev_p = &pci_devices;
static int pci_reverse __initdata = 0;
struct pci_dev * struct pci_dev *
pci_find_slot(unsigned int bus, unsigned int devfn) pci_find_slot(unsigned int bus, unsigned int devfn)
...@@ -270,7 +269,7 @@ static inline unsigned int pci_resource_flags(unsigned int flags) ...@@ -270,7 +269,7 @@ static inline unsigned int pci_resource_flags(unsigned int flags)
return IORESOURCE_MEM; return IORESOURCE_MEM;
} }
void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) static void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
{ {
unsigned int pos, reg, next; unsigned int pos, reg, next;
u32 l, sz, tmp; u32 l, sz, tmp;
...@@ -433,7 +432,7 @@ static __init struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci ...@@ -433,7 +432,7 @@ static __init struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci
/* /*
* Set up the primary, secondary and subordinate * Set up the primary, secondary and subordinate
* bus numbers. Read resource ranges behind the bridge. * bus numbers.
*/ */
child->number = child->secondary = busnr; child->number = child->secondary = busnr;
child->primary = parent->secondary; child->primary = parent->secondary;
...@@ -578,24 +577,29 @@ static __init void pci_read_irq(struct pci_dev *dev) ...@@ -578,24 +577,29 @@ static __init void pci_read_irq(struct pci_dev *dev)
} }
/* /*
* Read the config data for a PCI device * Read the config data for a PCI device, sanity-check it
* and sanity-check it and fill in the dev * and fill in the dev structure...
* structure...
*/ */
static __init int pci_scan_device(struct pci_bus *bus, struct pci_dev *dev, unsigned int devfn) static struct pci_dev * __init pci_scan_device(struct pci_dev *temp)
{ {
unsigned int l, class; struct pci_dev *dev;
u32 l, class;
if (pci_read_config_dword(dev, PCI_VENDOR_ID, &l)) if (pci_read_config_dword(temp, PCI_VENDOR_ID, &l))
return -1; return NULL;
/* some broken boards return 0 if a slot is empty: */ /* some broken boards return 0 or ~0 if a slot is empty: */
if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000)
return -1; return NULL;
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return NULL;
memcpy(dev, temp, sizeof(*dev));
dev->vendor = l & 0xffff; dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff; dev->device = (l >> 16) & 0xffff;
sprintf(dev->slot_name, "%02x:%02x.%d", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); sprintf(dev->slot_name, "%02x:%02x.%d", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
pci_name_device(dev); pci_name_device(dev);
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
...@@ -631,7 +635,8 @@ static __init int pci_scan_device(struct pci_bus *bus, struct pci_dev *dev, unsi ...@@ -631,7 +635,8 @@ static __init int pci_scan_device(struct pci_bus *bus, struct pci_dev *dev, unsi
default: /* unknown header */ default: /* unknown header */
printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n", printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
dev->slot_name, dev->hdr_type); dev->slot_name, dev->hdr_type);
return -1; kfree(dev);
return NULL;
bad: bad:
printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n", printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n",
...@@ -640,47 +645,32 @@ static __init int pci_scan_device(struct pci_bus *bus, struct pci_dev *dev, unsi ...@@ -640,47 +645,32 @@ static __init int pci_scan_device(struct pci_bus *bus, struct pci_dev *dev, unsi
} }
/* We found a fine healthy device, go go go... */ /* We found a fine healthy device, go go go... */
return 0; return dev;
} }
struct pci_dev * __init pci_scan_slot(struct pci_dev *temp)
static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
{ {
unsigned int devfn, max; struct pci_bus *bus = temp->bus;
struct pci_dev *dev, **bus_last; struct pci_dev *dev;
struct pci_dev *first_dev = NULL;
int func = 0;
int is_multi = 0; int is_multi = 0;
u8 hdr_type;
DBG("pci_do_scan_bus for bus %d\n", bus->number); for (func = 0; func < 8; func++, temp->devfn++) {
bus_last = &bus->devices; if (func && !is_multi) /* not a multi-function device */
max = bus->secondary;
/* Allocate the device ahead of time.. */
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return max;
/* Go find them, Rover! */
for (devfn = 0; devfn < 0xff; ++devfn) {
unsigned char hdr_type;
/* not a multi-function device */
if (PCI_FUNC(devfn) && !is_multi)
continue; continue;
if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
memset(dev, 0, sizeof(*dev));
dev->bus = bus;
dev->sysdata = bus->sysdata;
dev->devfn = devfn;
if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
continue; continue;
temp->hdr_type = hdr_type & 0x7f;
if (!PCI_FUNC(devfn)) dev = pci_scan_device(temp);
is_multi = hdr_type & 0x80; if (!dev)
dev->hdr_type = hdr_type & 0x7f;
if (pci_scan_device(bus, dev, devfn))
continue; continue;
if (!func) {
is_multi = hdr_type & 0x80;
first_dev = dev;
}
DBG("PCI: %02x:%02x [%04x/%04x] %06x %02x\n", bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type); DBG("PCI: %02x:%02x [%04x/%04x] %06x %02x\n", bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type);
...@@ -688,37 +678,41 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus) ...@@ -688,37 +678,41 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
* Put it into the global PCI device chain. It's used to * Put it into the global PCI device chain. It's used to
* find devices once everything is set up. * find devices once everything is set up.
*/ */
if (!pci_reverse) {
*pci_last_dev_p = dev; *pci_last_dev_p = dev;
pci_last_dev_p = &dev->next; pci_last_dev_p = &dev->next;
} else {
dev->next = pci_devices;
pci_devices = dev;
}
/* /*
* Now insert it into the list of devices held * Now insert it into the list of devices held
* by the parent bus. * by the parent bus.
*/ */
*bus_last = dev; *bus->last_dev_p = dev;
bus_last = &dev->sibling; bus->last_dev_p = &dev->sibling;
/* Fix up broken headers */ /* Fix up broken headers */
pci_fixup_device(PCI_FIXUP_HEADER, dev); pci_fixup_device(PCI_FIXUP_HEADER, dev);
}
return first_dev;
}
#if 0 static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
/* {
* Setting of latency timer in case it was less than 32 was unsigned int devfn, max;
* a great idea, but it confused several broken devices. Grrr. struct pci_dev *dev, dev0;
*/
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp);
if (tmp < 32)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
#endif
dev = kmalloc(sizeof(*dev), GFP_KERNEL); DBG("pci_do_scan_bus for bus %d\n", bus->number);
bus->last_dev_p = &bus->devices;
max = bus->secondary;
/* Create a device template */
memset(&dev0, 0, sizeof(dev0));
dev0.bus = bus;
dev0.sysdata = bus->sysdata;
/* Go find them, Rover! */
for (devfn = 0; devfn < 0x100; devfn += 8) {
dev0.devfn = devfn;
pci_scan_slot(&dev0);
} }
kfree(dev);
/* /*
* After performing arch-dependent fixup of the bus, look behind * After performing arch-dependent fixup of the bus, look behind
...@@ -759,7 +753,7 @@ static int __init pci_bus_exists(struct pci_bus *b, int nr) ...@@ -759,7 +753,7 @@ static int __init pci_bus_exists(struct pci_bus *b, int nr)
return 0; return 0;
} }
struct pci_bus * __init pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) struct pci_bus * __init pci_alloc_primary_bus(int bus)
{ {
struct pci_bus *b, **r; struct pci_bus *b, **r;
...@@ -779,11 +773,19 @@ struct pci_bus * __init pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata ...@@ -779,11 +773,19 @@ struct pci_bus * __init pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata
*r = b; *r = b;
b->number = b->secondary = bus; b->number = b->secondary = bus;
b->sysdata = sysdata;
b->ops = ops;
b->resource[0] = &ioport_resource; b->resource[0] = &ioport_resource;
b->resource[1] = &iomem_resource; b->resource[1] = &iomem_resource;
return b;
}
struct pci_bus * __init pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
{
struct pci_bus *b = pci_alloc_primary_bus(bus);
if (b) {
b->sysdata = sysdata;
b->ops = ops;
b->subordinate = pci_do_scan_bus(b); b->subordinate = pci_do_scan_bus(b);
}
return b; return b;
} }
...@@ -804,9 +806,8 @@ static int __init pci_setup(char *str) ...@@ -804,9 +806,8 @@ static int __init pci_setup(char *str)
if (k) if (k)
*k++ = 0; *k++ = 0;
if (*str && (str = pcibios_setup(str)) && *str) { if (*str && (str = pcibios_setup(str)) && *str) {
if (!strcmp(str, "reverse")) /* PCI layer options should be handled here */
pci_reverse = 1; printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
else printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
} }
str = k; str = k;
} }
......
...@@ -25,6 +25,8 @@ EXPORT_SYMBOL(pci_find_device); ...@@ -25,6 +25,8 @@ EXPORT_SYMBOL(pci_find_device);
EXPORT_SYMBOL(pci_find_slot); EXPORT_SYMBOL(pci_find_slot);
EXPORT_SYMBOL(pci_set_master); EXPORT_SYMBOL(pci_set_master);
EXPORT_SYMBOL(pci_simple_probe); EXPORT_SYMBOL(pci_simple_probe);
EXPORT_SYMBOL(pci_set_power_state);
EXPORT_SYMBOL(pci_assign_resource);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
EXPORT_SYMBOL(pci_proc_attach_device); EXPORT_SYMBOL(pci_proc_attach_device);
EXPORT_SYMBOL(pci_proc_detach_device); EXPORT_SYMBOL(pci_proc_detach_device);
......
...@@ -283,20 +283,21 @@ int cb_alloc(socket_info_t *s) ...@@ -283,20 +283,21 @@ int cb_alloc(socket_info_t *s)
u_char i, hdr, fn, bus = s->cap.cardbus; u_char i, hdr, fn, bus = s->cap.cardbus;
cb_config_t *c; cb_config_t *c;
memset(&tmp, 0, sizeof(tmp));
tmp.bus = s->cap.cb_bus; tmp.devfn = 0; tmp.bus = s->cap.cb_bus; tmp.devfn = 0;
tmp.next = pci_devices; pci_devices = &tmp;
pci_readw(bus, 0, PCI_VENDOR_ID, &vend);
pci_readw(bus, 0, PCI_DEVICE_ID, &dev); pci_read_config_word(&tmp, PCI_VENDOR_ID, &vend);
pci_read_config_word(&tmp, PCI_DEVICE_ID, &dev);
printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, " printk(KERN_INFO "cs: cb_alloc(bus %d): vendor 0x%04x, "
"device 0x%04x\n", bus, vend, dev); "device 0x%04x\n", bus, vend, dev);
pci_readb(bus, 0, PCI_HEADER_TYPE, &hdr); pci_read_config_byte(&tmp, PCI_HEADER_TYPE, &hdr);
if (hdr & 0x80) { if (hdr & 0x80) {
/* Count functions */ /* Count functions */
for (fn = 0; fn < 8; fn++) { for (fn = 0; fn < 8; fn++) {
tmp.devfn = fn; tmp.devfn = fn;
pci_readw(bus, fn, PCI_VENDOR_ID, &v); pci_read_config_word(&tmp, PCI_VENDOR_ID, &v);
if (v != vend) break; if (v != vend) break;
} }
} else fn = 1; } else fn = 1;
...@@ -307,7 +308,6 @@ int cb_alloc(socket_info_t *s) ...@@ -307,7 +308,6 @@ int cb_alloc(socket_info_t *s)
memset(c, 0, fn * sizeof(struct cb_config_t)); memset(c, 0, fn * sizeof(struct cb_config_t));
s->cb_config = c; s->cb_config = c;
pci_devices = tmp.next;
for (i = 0; i < fn; i++) { for (i = 0; i < fn; i++) {
c[i].dev.bus = s->cap.cb_bus; c[i].dev.bus = s->cap.cb_bus;
c[i].dev.devfn = i; c[i].dev.devfn = i;
...@@ -317,7 +317,7 @@ int cb_alloc(socket_info_t *s) ...@@ -317,7 +317,7 @@ int cb_alloc(socket_info_t *s)
} }
s->cap.cb_bus->devices = &c[0].dev; s->cap.cb_bus->devices = &c[0].dev;
/* Link into PCI device chain */ /* Link into PCI device chain */
c[s->functions-1].dev.next = pci_devices; c[fn-1].dev.next = pci_devices;
pci_devices = &c[0].dev; pci_devices = &c[0].dev;
for (i = 0; i < fn; i++) { for (i = 0; i < fn; i++) {
c[i].dev.vendor = vend; c[i].dev.vendor = vend;
...@@ -338,17 +338,17 @@ void cb_free(socket_info_t *s) ...@@ -338,17 +338,17 @@ void cb_free(socket_info_t *s)
cb_config_t *c = s->cb_config; cb_config_t *c = s->cb_config;
if (c) { if (c) {
struct pci_dev **p, *q; struct pci_dev **p;
/* Unlink from PCI device chain */ /* Unlink from PCI device chain */
for (p = &pci_devices; *p; p = &((*p)->next)) for (p = &pci_devices; *p; p = &((*p)->next)) {
if (*p == &c[0].dev) break; struct pci_dev * dev = *p;
for (q = *p; q; q = q->next) { if (dev->bus != s->cap.cb_bus)
if (q->bus != (*p)->bus) break; continue;
*p = dev->next;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
pci_proc_detach_device(q); pci_proc_detach_device(dev);
#endif #endif
} }
if (*p) *p = q;
s->cap.cb_bus->devices = NULL; s->cap.cb_bus->devices = NULL;
kfree(s->cb_config); kfree(s->cb_config);
s->cb_config = NULL; s->cb_config = NULL;
......
...@@ -159,8 +159,6 @@ MODULE_PARM(recov_time, "i"); ...@@ -159,8 +159,6 @@ MODULE_PARM(recov_time, "i");
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
/* Scan PCI bus? */ /* Scan PCI bus? */
static int do_pci_probe = 1; static int do_pci_probe = 1;
/* Default memory base address for CardBus controllers */
static u_int cb_mem_base[] = { 0x68000000, 0xf8000000 };
static int fast_pci = -1; static int fast_pci = -1;
static int hold_time = -1; static int hold_time = -1;
/* Override BIOS interrupt routing mode? */ /* Override BIOS interrupt routing mode? */
...@@ -173,7 +171,6 @@ static int cb_bus_base = 0; ...@@ -173,7 +171,6 @@ static int cb_bus_base = 0;
static int cb_bus_step = 2; static int cb_bus_step = 2;
static int cb_write_post = -1; static int cb_write_post = -1;
MODULE_PARM(do_pci_probe, "i"); MODULE_PARM(do_pci_probe, "i");
MODULE_PARM(cb_mem_base, "i");
MODULE_PARM(fast_pci, "i"); MODULE_PARM(fast_pci, "i");
MODULE_PARM(hold_time, "i"); MODULE_PARM(hold_time, "i");
MODULE_PARM(irq_mode, "i"); MODULE_PARM(irq_mode, "i");
...@@ -249,11 +246,11 @@ typedef struct socket_info_t { ...@@ -249,11 +246,11 @@ typedef struct socket_info_t {
struct proc_dir_entry *proc; struct proc_dir_entry *proc;
#endif #endif
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
u_short vendor, device; struct pci_dev *pdev;
u_char revision, bus, devfn; u_char revision;
u_short bcr; u_short bcr;
u_char pci_lat, cb_lat, sub_bus; u_char pci_lat, cb_lat, sub_bus;
u_char cache, pmcs; u_char cache;
u_int cb_phys; u_int cb_phys;
char *cb_virt; char *cb_virt;
#endif #endif
...@@ -294,24 +291,10 @@ static struct timer_list poll_timer; ...@@ -294,24 +291,10 @@ static struct timer_list poll_timer;
/*====================================================================*/ /*====================================================================*/
#ifdef CONFIG_PCI
#ifndef PCI_VENDOR_ID_INTEL
#define PCI_VENDOR_ID_INTEL 0x8086
#endif
#ifndef PCI_VENDOR_ID_OMEGA
#define PCI_VENDOR_ID_OMEGA 0x119b
#endif
#ifndef PCI_DEVICE_ID_OMEGA_PCMCIA
#define PCI_DEVICE_ID_OMEGA_PCMCIA 0x1221
#endif
/* Default settings for PCI command configuration register */ /* Default settings for PCI command configuration register */
#define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \ #define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \
PCI_COMMAND_MASTER|PCI_COMMAND_WAIT) PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)
#endif
/* These definitions must match the pcic table! */ /* These definitions must match the pcic table! */
typedef enum pcic_id { typedef enum pcic_id {
#ifdef CONFIG_ISA #ifdef CONFIG_ISA
...@@ -379,9 +362,9 @@ static pcic_t pcic[] = { ...@@ -379,9 +362,9 @@ static pcic_t pcic[] = {
{ "O2Micro OZ6730", IS_O2MICRO|IS_PCI|IS_VG_PWR, { "O2Micro OZ6730", IS_O2MICRO|IS_PCI|IS_VG_PWR,
PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_6730 }, PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_6730 },
{ "Intel 82092AA", IS_PCI, { "Intel 82092AA", IS_PCI,
PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_OMEGA_PCMCIA }, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82092AA_0 },
{ "Omega Micro 82C092G", IS_PCI, { "Omega Micro 82C092G", IS_PCI,
PCI_VENDOR_ID_OMEGA, PCI_DEVICE_ID_OMEGA_PCMCIA }, PCI_VENDOR_ID_OMEGA, PCI_DEVICE_ID_OMEGA_82C092G },
{ "Cirrus PD6832", IS_CIRRUS|IS_CARDBUS, { "Cirrus PD6832", IS_CIRRUS|IS_CARDBUS,
PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832 }, PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832 },
{ "O2Micro OZ6832/OZ6833", IS_O2MICRO|IS_CARDBUS|IS_VG_PWR, { "O2Micro OZ6832/OZ6833", IS_O2MICRO|IS_CARDBUS|IS_VG_PWR,
...@@ -443,12 +426,12 @@ static pcic_t pcic[] = { ...@@ -443,12 +426,12 @@ static pcic_t pcic[] = {
/* Some PCI shortcuts */ /* Some PCI shortcuts */
#define pci_readb pcibios_read_config_byte #define config_readb(sock, r, v) pci_read_config_byte((sock)->pdev, r, v)
#define pci_writeb pcibios_write_config_byte #define config_readw(sock, r, v) pci_read_config_word((sock)->pdev, r, v)
#define pci_readw pcibios_read_config_word #define config_readl(sock, r, v) pci_read_config_dword((sock)->pdev, r, v)
#define pci_writew pcibios_write_config_word #define config_writeb(sock, r, v) pci_write_config_byte((sock)->pdev, r, v)
#define pci_readl pcibios_read_config_dword #define config_writew(sock, r, v) pci_write_config_word((sock)->pdev, r, v)
#define pci_writel pcibios_write_config_dword #define config_writel(sock, r, v) pci_write_config_dword((sock)->pdev, r, v)
#define cb_readb(s, r) readb(socket[s].cb_virt + (r)) #define cb_readb(s, r) readb(socket[s].cb_virt + (r))
#define cb_readl(s, r) readl(socket[s].cb_virt + (r)) #define cb_readl(s, r) readl(socket[s].cb_virt + (r))
...@@ -701,21 +684,21 @@ static void ti113x_get_state(u_short s) ...@@ -701,21 +684,21 @@ static void ti113x_get_state(u_short s)
{ {
socket_info_t *t = &socket[s]; socket_info_t *t = &socket[s];
ti113x_state_t *p = &socket[s].state.ti113x; ti113x_state_t *p = &socket[s].state.ti113x;
pci_readl(t->bus, t->devfn, TI113X_SYSTEM_CONTROL, &p->sysctl); config_readl(t, TI113X_SYSTEM_CONTROL, &p->sysctl);
pci_readb(t->bus, t->devfn, TI113X_CARD_CONTROL, &p->cardctl); config_readb(t, TI113X_CARD_CONTROL, &p->cardctl);
pci_readb(t->bus, t->devfn, TI113X_DEVICE_CONTROL, &p->devctl); config_readb(t, TI113X_DEVICE_CONTROL, &p->devctl);
pci_readb(t->bus, t->devfn, TI1250_DIAGNOSTIC, &p->diag); config_readb(t, TI1250_DIAGNOSTIC, &p->diag);
} }
static void ti113x_set_state(u_short s) static void ti113x_set_state(u_short s)
{ {
socket_info_t *t = &socket[s]; socket_info_t *t = &socket[s];
ti113x_state_t *p = &socket[s].state.ti113x; ti113x_state_t *p = &socket[s].state.ti113x;
pci_writel(t->bus, t->devfn, TI113X_SYSTEM_CONTROL, p->sysctl); config_writel(t, TI113X_SYSTEM_CONTROL, p->sysctl);
pci_writeb(t->bus, t->devfn, TI113X_CARD_CONTROL, p->cardctl); config_writeb(t, TI113X_CARD_CONTROL, p->cardctl);
pci_writeb(t->bus, t->devfn, TI113X_DEVICE_CONTROL, p->devctl); config_writeb(t, TI113X_DEVICE_CONTROL, p->devctl);
pci_writeb(t->bus, t->devfn, TI1250_MULTIMEDIA_CTL, 0); config_writeb(t, TI1250_MULTIMEDIA_CTL, 0);
pci_writeb(t->bus, t->devfn, TI1250_DIAGNOSTIC, p->diag); config_writeb(t, TI1250_DIAGNOSTIC, p->diag);
i365_set_pair(s, TI113X_IO_OFFSET(0), 0); i365_set_pair(s, TI113X_IO_OFFSET(0), 0);
i365_set_pair(s, TI113X_IO_OFFSET(1), 0); i365_set_pair(s, TI113X_IO_OFFSET(1), 0);
} }
...@@ -822,20 +805,20 @@ static void rl5c4xx_get_state(u_short s) ...@@ -822,20 +805,20 @@ static void rl5c4xx_get_state(u_short s)
{ {
socket_info_t *t = &socket[s]; socket_info_t *t = &socket[s];
rl5c4xx_state_t *p = &socket[s].state.rl5c4xx; rl5c4xx_state_t *p = &socket[s].state.rl5c4xx;
pci_readw(t->bus, t->devfn, RL5C4XX_MISC, &p->misc); config_readw(t, RL5C4XX_MISC, &p->misc);
pci_readw(t->bus, t->devfn, RL5C4XX_16BIT_CTL, &p->ctl); config_readw(t, RL5C4XX_16BIT_CTL, &p->ctl);
pci_readw(t->bus, t->devfn, RL5C4XX_16BIT_IO_0, &p->io); config_readw(t, RL5C4XX_16BIT_IO_0, &p->io);
pci_readw(t->bus, t->devfn, RL5C4XX_16BIT_MEM_0, &p->mem); config_readw(t, RL5C4XX_16BIT_MEM_0, &p->mem);
} }
static void rl5c4xx_set_state(u_short s) static void rl5c4xx_set_state(u_short s)
{ {
socket_info_t *t = &socket[s]; socket_info_t *t = &socket[s];
rl5c4xx_state_t *p = &socket[s].state.rl5c4xx; rl5c4xx_state_t *p = &socket[s].state.rl5c4xx;
pci_writew(t->bus, t->devfn, RL5C4XX_MISC, p->misc); config_writew(t, RL5C4XX_MISC, p->misc);
pci_writew(t->bus, t->devfn, RL5C4XX_16BIT_CTL, p->ctl); config_writew(t, RL5C4XX_16BIT_CTL, p->ctl);
pci_writew(t->bus, t->devfn, RL5C4XX_16BIT_IO_0, p->io); config_writew(t, RL5C4XX_16BIT_IO_0, p->io);
pci_writew(t->bus, t->devfn, RL5C4XX_16BIT_MEM_0, p->mem); config_writew(t, RL5C4XX_16BIT_MEM_0, p->mem);
} }
static u_int __init rl5c4xx_set_opts(u_short s, char *buf) static u_int __init rl5c4xx_set_opts(u_short s, char *buf)
...@@ -986,20 +969,20 @@ static void topic_get_state(u_short s) ...@@ -986,20 +969,20 @@ static void topic_get_state(u_short s)
{ {
socket_info_t *t = &socket[s]; socket_info_t *t = &socket[s];
topic_state_t *p = &socket[s].state.topic; topic_state_t *p = &socket[s].state.topic;
pci_readb(t->bus, t->devfn, TOPIC_SLOT_CONTROL, &p->slot); config_readb(t, TOPIC_SLOT_CONTROL, &p->slot);
pci_readb(t->bus, t->devfn, TOPIC_CARD_CONTROL, &p->ccr); config_readb(t, TOPIC_CARD_CONTROL, &p->ccr);
pci_readb(t->bus, t->devfn, TOPIC_CARD_DETECT, &p->cdr); config_readb(t, TOPIC_CARD_DETECT, &p->cdr);
pci_readl(t->bus, t->devfn, TOPIC_REGISTER_CONTROL, &p->rcr); config_readl(t, TOPIC_REGISTER_CONTROL, &p->rcr);
} }
static void topic_set_state(u_short s) static void topic_set_state(u_short s)
{ {
socket_info_t *t = &socket[s]; socket_info_t *t = &socket[s];
topic_state_t *p = &socket[s].state.topic; topic_state_t *p = &socket[s].state.topic;
pci_writeb(t->bus, t->devfn, TOPIC_SLOT_CONTROL, p->slot); config_writeb(t, TOPIC_SLOT_CONTROL, p->slot);
pci_writeb(t->bus, t->devfn, TOPIC_CARD_CONTROL, p->ccr); config_writeb(t, TOPIC_CARD_CONTROL, p->ccr);
pci_writeb(t->bus, t->devfn, TOPIC_CARD_DETECT, p->cdr); config_writeb(t, TOPIC_CARD_DETECT, p->cdr);
pci_writel(t->bus, t->devfn, TOPIC_REGISTER_CONTROL, p->rcr); config_writel(t, TOPIC_REGISTER_CONTROL, p->rcr);
} }
static int topic_set_irq_mode(u_short s, int pcsc, int pint) static int topic_set_irq_mode(u_short s, int pcsc, int pint)
...@@ -1040,33 +1023,28 @@ static void cb_get_state(u_short s) ...@@ -1040,33 +1023,28 @@ static void cb_get_state(u_short s)
{ {
socket_info_t *t = &socket[s]; socket_info_t *t = &socket[s];
pci_readb(t->bus, t->devfn, PCI_CACHE_LINE_SIZE, &t->cache); config_readb(t, PCI_CACHE_LINE_SIZE, &t->cache);
pci_readb(t->bus, t->devfn, PCI_LATENCY_TIMER, &t->pci_lat); config_readb(t, PCI_LATENCY_TIMER, &t->pci_lat);
pci_readb(t->bus, t->devfn, CB_LATENCY_TIMER, &t->cb_lat); config_readb(t, CB_LATENCY_TIMER, &t->cb_lat);
pci_readb(t->bus, t->devfn, CB_CARDBUS_BUS, &t->cap.cardbus); config_readb(t, CB_CARDBUS_BUS, &t->cap.cardbus);
pci_readb(t->bus, t->devfn, CB_SUBORD_BUS, &t->sub_bus); config_readb(t, CB_SUBORD_BUS, &t->sub_bus);
pci_readw(t->bus, t->devfn, CB_BRIDGE_CONTROL, &t->bcr); config_readw(t, CB_BRIDGE_CONTROL, &t->bcr);
{ t->cap.pci_irq = t->pdev->irq;
struct pci_dev *pdev = pci_find_slot(t->bus, t->devfn);
t->cap.pci_irq = (pdev) ? pdev->irq : 0;
}
if (t->cap.pci_irq >= NR_IRQS) t->cap.pci_irq = 0;
} }
static void cb_set_state(u_short s) static void cb_set_state(u_short s)
{ {
socket_info_t *t = &socket[s]; socket_info_t *t = &socket[s];
if (t->pmcs) pci_set_power_state(t->pdev, 0); /* FIXME: Do we really need all of this? */
pci_writew(t->bus, t->devfn, t->pmcs, PCI_PMCS_PWR_STATE_D0); config_writel(t, CB_LEGACY_MODE_BASE, 0);
pci_writel(t->bus, t->devfn, CB_LEGACY_MODE_BASE, 0); config_writel(t, PCI_BASE_ADDRESS_0, t->cb_phys);
pci_writel(t->bus, t->devfn, PCI_BASE_ADDRESS_0, t->cb_phys); config_writew(t, PCI_COMMAND, CMD_DFLT);
pci_writew(t->bus, t->devfn, PCI_COMMAND, CMD_DFLT); config_writeb(t, PCI_CACHE_LINE_SIZE, t->cache);
pci_writeb(t->bus, t->devfn, PCI_CACHE_LINE_SIZE, t->cache); config_writeb(t, PCI_LATENCY_TIMER, t->pci_lat);
pci_writeb(t->bus, t->devfn, PCI_LATENCY_TIMER, t->pci_lat); config_writeb(t, CB_LATENCY_TIMER, t->cb_lat);
pci_writeb(t->bus, t->devfn, CB_LATENCY_TIMER, t->cb_lat); config_writeb(t, CB_CARDBUS_BUS, t->cap.cardbus);
pci_writeb(t->bus, t->devfn, CB_CARDBUS_BUS, t->cap.cardbus); config_writeb(t, CB_SUBORD_BUS, t->sub_bus);
pci_writeb(t->bus, t->devfn, CB_SUBORD_BUS, t->sub_bus); config_writew(t, CB_BRIDGE_CONTROL, t->bcr);
pci_writew(t->bus, t->devfn, CB_BRIDGE_CONTROL, t->bcr);
} }
static int cb_get_irq_mode(u_short s) static int cb_get_irq_mode(u_short s)
...@@ -1500,13 +1478,11 @@ static void __init add_pcic(int ns, int type) ...@@ -1500,13 +1478,11 @@ static void __init add_pcic(int ns, int type)
printk(KERN_INFO " %s", pcic[type].name); printk(KERN_INFO " %s", pcic[type].name);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
if (t->flags & IS_UNKNOWN) if (t->flags & IS_UNKNOWN)
printk(" [0x%04x 0x%04x]", t->vendor, t->device); printk(" [0x%04x 0x%04x]", t->pdev->vendor, t->pdev->device);
if (t->flags & IS_CARDBUS) if (t->flags & IS_CARDBUS)
printk(" PCI-to-CardBus at bus %d slot %d, mem 0x%08x", printk(" PCI-to-CardBus at %s, mem 0x%08x", t->pdev->slot_name, t->cb_phys);
t->bus, PCI_SLOT(t->devfn), t->cb_phys);
else if (t->flags & IS_PCI) else if (t->flags & IS_PCI)
printk(" PCI-to-PCMCIA at bus %d slot %d, port %#x", printk(" PCI-to-PCMCIA at %s, port %#x", t->pdev->slot_name, t->ioaddr);
t->bus, PCI_SLOT(t->devfn), t->ioaddr);
else else
#endif #endif
printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x", printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x",
...@@ -1596,107 +1572,50 @@ static void __init add_pcic(int ns, int type) ...@@ -1596,107 +1572,50 @@ static void __init add_pcic(int ns, int type)
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
typedef struct pci_dev *pci_id_t; static void __init add_pci_bridge(int type, struct pci_dev *dev)
static int __init pci_lookup(u_int class, pci_id_t *id,
u_char *bus, u_char *devfn)
{
if ((*id = pci_find_class(class<<8, *id)) != NULL) {
*bus = (*id)->bus->number;
*devfn = (*id)->devfn;
return 0;
} else return -1;
}
static void __init add_pci_bridge(int type, u_char bus, u_char devfn,
u_short v, u_short d)
{ {
socket_info_t *s = &socket[sockets]; socket_info_t *s = &socket[sockets];
u_short i, ns; u_short i, ns;
u_int addr; u32 addr = dev->resource[0].start;
if (type == PCIC_COUNT) type = IS_UNK_PCI; if (type == PCIC_COUNT) type = IS_UNK_PCI;
pci_readl(bus, devfn, PCI_BASE_ADDRESS_0, &addr); pci_write_config_word(dev, PCI_COMMAND, CMD_DFLT);
addr &= ~0x1;
pci_writew(bus, devfn, PCI_COMMAND, CMD_DFLT);
for (i = ns = 0; i < ((type == IS_I82092AA) ? 4 : 2); i++) { for (i = ns = 0; i < ((type == IS_I82092AA) ? 4 : 2); i++) {
s->bus = bus; s->devfn = devfn; s->pdev = dev;
s->vendor = v; s->device = d;
add_socket(addr, i, type); add_socket(addr, i, type);
ns++; s++; ns++; s++;
} }
add_pcic(ns, type); add_pcic(ns, type);
} }
static void __init add_cb_bridge(int type, u_char bus, u_char devfn, static void __init add_cb_bridge(int type, struct pci_dev *dev0)
u_short v, u_short d0)
{ {
socket_info_t *s = &socket[sockets]; socket_info_t *s = &socket[sockets];
u_short d, ns, i; u_short i, ns;
u_char a, b, r, max; u_char a, b;
/* PCI bus enumeration is broken on some systems */ if (type == PCIC_COUNT)
for (ns = 0; ns < sockets; ns++) type = IS_UNK_CARDBUS;
if ((socket[ns].bus == bus) && (socket[ns].devfn == devfn))
return;
if (type == PCIC_COUNT) type = IS_UNK_CARDBUS; for (ns = 0; ns < 8; ns++, s++) {
pci_readb(bus, devfn, PCI_HEADER_TYPE, &a); struct pci_dev *dev;
pci_readb(bus, devfn, PCI_CLASS_REVISION, &r);
max = (a & 0x80) ? 8 : 1; dev = pci_find_slot(dev0->bus->number, dev0->devfn + ns);
for (ns = 0; ns < max; ns++, s++, devfn++) { if (!dev)
if (pci_readw(bus, devfn, PCI_DEVICE_ID, &d) || (d != d0))
break;
s->bus = bus; s->devfn = devfn;
s->vendor = v; s->device = d; s->revision = r;
/* Check for power management capabilities */
pci_readb(bus, devfn, PCI_STATUS, &a);
if (a & PCI_STATUS_CAPLIST) {
pci_readb(bus, devfn, PCI_CB_CAPABILITY_POINTER, &b);
while (b != 0) {
pci_readb(bus, devfn, b+PCI_CAPABILITY_ID, &a);
if (a == PCI_CAPABILITY_PM) {
s->pmcs = b + PCI_PM_CONTROL_STATUS;
break; break;
} s->pdev = dev;
pci_readb(bus, devfn, b+PCI_NEXT_CAPABILITY, &b); pci_read_config_byte(dev, PCI_CLASS_REVISION, &s->revision);
}
}
/* If capability exists, make sure we're in D0 state */
if (s->pmcs)
pci_writew(bus, devfn, s->pmcs, PCI_PMCS_PWR_STATE_D0);
/* Map CardBus registers if they are not already mapped */ /* Map CardBus registers if they are not already mapped */
pci_writel(bus, devfn, CB_LEGACY_MODE_BASE, 0); pci_write_config_dword(dev, CB_LEGACY_MODE_BASE, 0);
pci_readl(bus, devfn, PCI_BASE_ADDRESS_0, &s->cb_phys); s->cb_phys = dev->resource[0].start;
if (s->cb_phys == 0) { if (!s->cb_phys || !(s->cb_virt = ioremap(s->cb_phys, 0x1000))) {
pci_writew(bus, devfn, PCI_COMMAND, CMD_DFLT);
for (i = 0; i < sizeof(cb_mem_base)/sizeof(u_int); i++) {
s->cb_phys = cb_mem_base[i];
s->cb_virt = ioremap(s->cb_phys, 0x1000);
pci_writel(bus, devfn, PCI_BASE_ADDRESS_0, s->cb_phys);
/* Simple sanity checks */
if (!(readb(s->cb_virt+0x800+I365_IDENT) & 0x70) &&
!(readb(s->cb_virt+0x800+I365_CSC) &&
readb(s->cb_virt+0x800+I365_CSC) &&
readb(s->cb_virt+0x800+I365_CSC)))
break;
iounmap(s->cb_virt);
}
if (i == sizeof(cb_mem_base)/sizeof(u_int)) {
pci_writel(bus, devfn, PCI_BASE_ADDRESS_0, 0);
s->cb_phys = 0; s->cb_virt = NULL;
printk("\n"); printk("\n");
printk(KERN_NOTICE " Bridge register mapping failed:" printk(KERN_ERR " No control registers found!\n");
" check cb_mem_base setting\n");
break; break;
} }
cb_mem_base[0] = cb_mem_base[i] + PAGE_SIZE;
} else {
s->cb_virt = ioremap(s->cb_phys, 0x1000);
}
request_mem_region(s->cb_phys, 0x1000, "i82365"); request_mem_region(s->cb_phys, 0x1000, "i82365");
s->cap.cb_bus = dev->subordinate;
add_socket(0, 0, type); add_socket(0, 0, type);
} }
if (ns == 0) return; if (ns == 0) return;
...@@ -1704,11 +1623,11 @@ static void __init add_cb_bridge(int type, u_char bus, u_char devfn, ...@@ -1704,11 +1623,11 @@ static void __init add_cb_bridge(int type, u_char bus, u_char devfn,
s -= ns; s -= ns;
if (ns == 2) { if (ns == 2) {
/* Nasty special check for bad bus mapping */ /* Nasty special check for bad bus mapping */
pci_readb(bus, s[0].devfn, CB_CARDBUS_BUS, &a); config_readb(&s[0], CB_CARDBUS_BUS, &a);
pci_readb(bus, s[1].devfn, CB_CARDBUS_BUS, &b); config_readb(&s[1], CB_CARDBUS_BUS, &b);
if (a == b) { if (a == b) {
pci_writeb(bus, s[0].devfn, CB_CARDBUS_BUS, 0); config_writeb(&s[0], CB_CARDBUS_BUS, 0);
pci_writeb(bus, s[1].devfn, CB_CARDBUS_BUS, 0); config_writeb(&s[1], CB_CARDBUS_BUS, 0);
} }
} }
add_pcic(ns, type); add_pcic(ns, type);
...@@ -1728,43 +1647,19 @@ static void __init add_cb_bridge(int type, u_char bus, u_char devfn, ...@@ -1728,43 +1647,19 @@ static void __init add_cb_bridge(int type, u_char bus, u_char devfn,
if (i == 200) if (i == 200)
printk(KERN_NOTICE "i82365: card voltage interrogation" printk(KERN_NOTICE "i82365: card voltage interrogation"
" timed out!\n"); " timed out!\n");
}
/* Set up PCI bus bridge structures if needed */ static void __init pci_probe(u_int class, void (add_fn)(int, struct pci_dev *))
for (a = 0; a < ns; a++) { {
struct pci_dev *self = pci_find_slot(bus, s[a].devfn); struct pci_dev *dev = NULL;
struct pci_bus *child, *parent = self->bus; u_short i;
for (child = parent->children; child; child = child->next)
if (child->number == s[a].cap.cardbus) break; while ((dev = pci_find_class(class << 8, dev))) {
if (!child) { pci_enable_device(dev);
child = kmalloc(sizeof(struct pci_bus), GFP_KERNEL); if (PCI_FUNC(dev->devfn) != 0) continue;
memset(child, 0, sizeof(struct pci_bus));
child->self = self;
child->primary = bus;
child->number = child->secondary = s[a].cap.cardbus;
child->subordinate = s[a].sub_bus;
child->parent = parent;
child->ops = parent->ops;
child->next = parent->children;
}
s[a].cap.cb_bus = parent->children = child;
}
}
static void __init pci_probe(u_int class, void (add_fn)
(int, u_char, u_char, u_short, u_short))
{
u_short i, v, d;
u_char bus, devfn;
pci_id_t id;
id = 0;
while (pci_lookup(class, &id, &bus, &devfn) == 0) {
if (PCI_FUNC(devfn) != 0) continue;
pci_readw(bus, devfn, PCI_VENDOR_ID, &v);
pci_readw(bus, devfn, PCI_DEVICE_ID, &d);
for (i = 0; i < PCIC_COUNT; i++) for (i = 0; i < PCIC_COUNT; i++)
if ((pcic[i].vendor == v) && (pcic[i].device == d)) break; if ((pcic[i].vendor == dev->vendor) && (pcic[i].device == dev->device)) break;
add_fn(i, bus, devfn, v, d); add_fn(i, dev);
} }
} }
...@@ -2397,7 +2292,7 @@ static int cb_get_socket(u_short sock, socket_state_t *state) ...@@ -2397,7 +2292,7 @@ static int cb_get_socket(u_short sock, socket_state_t *state)
u_short bcr; u_short bcr;
cb_get_power(sock, state); cb_get_power(sock, state);
pci_readw(s->bus, s->devfn, CB_BRIDGE_CONTROL, &bcr); config_readw(s, CB_BRIDGE_CONTROL, &bcr);
state->flags |= (bcr & CB_BCR_CB_RESET) ? SS_RESET : 0; state->flags |= (bcr & CB_BCR_CB_RESET) ? SS_RESET : 0;
if (cb_get_irq_mode(sock) != 0) if (cb_get_irq_mode(sock) != 0)
state->io_irq = s->cap.pci_irq; state->io_irq = s->cap.pci_irq;
...@@ -2454,15 +2349,15 @@ static int cb_get_bridge(u_short sock, struct cb_bridge_map *m) ...@@ -2454,15 +2349,15 @@ static int cb_get_bridge(u_short sock, struct cb_bridge_map *m)
if (map > 1) return -EINVAL; if (map > 1) return -EINVAL;
m->flags &= MAP_IOSPACE; m->flags &= MAP_IOSPACE;
map += (m->flags & MAP_IOSPACE) ? 2 : 0; map += (m->flags & MAP_IOSPACE) ? 2 : 0;
pci_readl(s->bus, s->devfn, CB_MEM_BASE(map), &m->start); config_readl(s, CB_MEM_BASE(map), &m->start);
pci_readl(s->bus, s->devfn, CB_MEM_LIMIT(map), &m->stop); config_readl(s, CB_MEM_LIMIT(map), &m->stop);
if (m->start || m->stop) { if (m->start || m->stop) {
m->flags |= MAP_ACTIVE; m->flags |= MAP_ACTIVE;
m->stop |= (map > 1) ? 3 : 0x0fff; m->stop |= (map > 1) ? 3 : 0x0fff;
} }
if (map > 1) { if (map > 1) {
u_short bcr; u_short bcr;
pci_readw(s->bus, s->devfn, CB_BRIDGE_CONTROL, &bcr); config_readw(s, CB_BRIDGE_CONTROL, &bcr);
m->flags |= (bcr & CB_BCR_PREFETCH(map)) ? MAP_PREFETCH : 0; m->flags |= (bcr & CB_BCR_PREFETCH(map)) ? MAP_PREFETCH : 0;
} }
DEBUG(1, "yenta: GetBridge(%d, %d) = %#2.2x, %#4.4x-%#4.4x\n", DEBUG(1, "yenta: GetBridge(%d, %d) = %#2.2x, %#4.4x-%#4.4x\n",
...@@ -2489,17 +2384,17 @@ static int cb_set_bridge(u_short sock, struct cb_bridge_map *m) ...@@ -2489,17 +2384,17 @@ static int cb_set_bridge(u_short sock, struct cb_bridge_map *m)
u_short bcr; u_short bcr;
if ((m->start & 0x0fff) || ((m->stop & 0x0fff) != 0x0fff)) if ((m->start & 0x0fff) || ((m->stop & 0x0fff) != 0x0fff))
return -EINVAL; return -EINVAL;
pci_readw(s->bus, s->devfn, CB_BRIDGE_CONTROL, &bcr); config_readw(s, CB_BRIDGE_CONTROL, &bcr);
bcr &= ~CB_BCR_PREFETCH(map); bcr &= ~CB_BCR_PREFETCH(map);
bcr |= (m->flags & MAP_PREFETCH) ? CB_BCR_PREFETCH(map) : 0; bcr |= (m->flags & MAP_PREFETCH) ? CB_BCR_PREFETCH(map) : 0;
pci_writew(s->bus, s->devfn, CB_BRIDGE_CONTROL, bcr); config_writew(s, CB_BRIDGE_CONTROL, bcr);
} }
if (m->flags & MAP_ACTIVE) { if (m->flags & MAP_ACTIVE) {
pci_writel(s->bus, s->devfn, CB_MEM_BASE(map), m->start); config_writel(s, CB_MEM_BASE(map), m->start);
pci_writel(s->bus, s->devfn, CB_MEM_LIMIT(map), m->stop); config_writel(s, CB_MEM_LIMIT(map), m->stop);
} else { } else {
pci_writel(s->bus, s->devfn, CB_IO_BASE(map), 0); config_writel(s, CB_MEM_BASE(map), 0);
pci_writel(s->bus, s->devfn, CB_IO_LIMIT(map), 0); config_writel(s, CB_MEM_LIMIT(map), 0);
} }
return 0; return 0;
} }
...@@ -2525,7 +2420,7 @@ static int proc_read_info(char *buf, char **start, off_t pos, ...@@ -2525,7 +2420,7 @@ static int proc_read_info(char *buf, char **start, off_t pos,
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
if (s->flags & (IS_PCI|IS_CARDBUS)) if (s->flags & (IS_PCI|IS_CARDBUS))
p += sprintf(p, "bus: %02x\ndevfn: %02x.%1x\n", p += sprintf(p, "bus: %02x\ndevfn: %02x.%1x\n",
s->bus, PCI_SLOT(s->devfn), PCI_FUNC(s->devfn)); s->pdev->bus->number, PCI_SLOT(s->pdev->devfn), PCI_FUNC(s->pdev->devfn));
if (s->flags & IS_CARDBUS) if (s->flags & IS_CARDBUS)
p += sprintf(p, "cardbus: %02x\n", s->cap.cardbus); p += sprintf(p, "cardbus: %02x\n", s->cap.cardbus);
#endif #endif
...@@ -2565,16 +2460,15 @@ static int proc_read_pci(char *buf, char **start, off_t pos, ...@@ -2565,16 +2460,15 @@ static int proc_read_pci(char *buf, char **start, off_t pos,
int count, int *eof, void *data) int count, int *eof, void *data)
{ {
socket_info_t *s = data; socket_info_t *s = data;
u_char bus = s->bus, devfn = s->devfn;
char *p = buf; char *p = buf;
u_int a, b, c, d; u_int a, b, c, d;
int i; int i;
for (i = 0; i < 0xc0; i += 0x10) { for (i = 0; i < 0xc0; i += 0x10) {
pci_readl(bus, devfn, i, &a); config_readl(s, i, &a);
pci_readl(bus, devfn, i+4, &b); config_readl(s, i+4, &b);
pci_readl(bus, devfn, i+8, &c); config_readl(s, i+8, &c);
pci_readl(bus, devfn, i+12, &d); config_readl(s, i+12, &d);
p += sprintf(p, "%08x %08x %08x %08x\n", a, b, c, d); p += sprintf(p, "%08x %08x %08x %08x\n", a, b, c, d);
} }
return (p - buf); return (p - buf);
...@@ -2801,7 +2695,7 @@ static int __init init_i82365(void) ...@@ -2801,7 +2695,7 @@ static int __init init_i82365(void)
sockets = 0; sockets = 0;
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
if (do_pci_probe && pcibios_present()) { if (do_pci_probe) {
pci_probe(PCI_CLASS_BRIDGE_CARDBUS, add_cb_bridge); pci_probe(PCI_CLASS_BRIDGE_CARDBUS, add_cb_bridge);
pci_probe(PCI_CLASS_BRIDGE_PCMCIA, add_pci_bridge); pci_probe(PCI_CLASS_BRIDGE_PCMCIA, add_pci_bridge);
} }
...@@ -2892,4 +2786,3 @@ module_init(init_i82365); ...@@ -2892,4 +2786,3 @@ module_init(init_i82365);
module_exit(exit_i82365); module_exit(exit_i82365);
/*====================================================================*/ /*====================================================================*/
...@@ -437,6 +437,8 @@ struct Scsi_Device_Template ...@@ -437,6 +437,8 @@ struct Scsi_Device_Template
struct module * module; /* Used for loadable modules */ struct module * module; /* Used for loadable modules */
unsigned char scsi_type; unsigned char scsi_type;
unsigned char major; unsigned char major;
unsigned char min_major; /* Minimum major in range. */
unsigned char max_major; /* Maximum major in range. */
unsigned char nr_dev; /* Number currently attached */ unsigned char nr_dev; /* Number currently attached */
unsigned char dev_noticed; /* Number of devices detected. */ unsigned char dev_noticed; /* Number of devices detected. */
unsigned char dev_max; /* Current size of arrays */ unsigned char dev_max; /* Current size of arrays */
...@@ -447,7 +449,8 @@ struct Scsi_Device_Template ...@@ -447,7 +449,8 @@ struct Scsi_Device_Template
void (*finish)(void); /* Perform initialization after attachment */ void (*finish)(void); /* Perform initialization after attachment */
int (*attach)(Scsi_Device *); /* Attach devices to arrays */ int (*attach)(Scsi_Device *); /* Attach devices to arrays */
void (*detach)(Scsi_Device *); void (*detach)(Scsi_Device *);
int (*init_command)(Scsi_Cmnd *); /* Used by new queueing code. */ int (*init_command)(Scsi_Cmnd *); /* Used by new queueing code.
Selects command for blkdevs */
}; };
extern struct Scsi_Device_Template sd_template; extern struct Scsi_Device_Template sd_template;
......
...@@ -1470,9 +1470,6 @@ void scsi_do_cmd(Scsi_Cmnd * SCpnt, const void *cmnd, ...@@ -1470,9 +1470,6 @@ void scsi_do_cmd(Scsi_Cmnd * SCpnt, const void *cmnd,
*/ */
host->host_busy++;
device->device_busy++;
/* /*
* Our own function scsi_done (which marks the host as not busy, disables * Our own function scsi_done (which marks the host as not busy, disables
* the timeout counter, etc) will be called by us or by the * the timeout counter, etc) will be called by us or by the
...@@ -1575,6 +1572,9 @@ void scsi_done(Scsi_Cmnd * SCpnt) ...@@ -1575,6 +1572,9 @@ void scsi_done(Scsi_Cmnd * SCpnt)
* Since serial_number is now 0, the error handler cound detect this * Since serial_number is now 0, the error handler cound detect this
* situation and avoid to call the the low level driver abort routine. * situation and avoid to call the the low level driver abort routine.
* (DB) * (DB)
*
* FIXME(eric) - I believe that this test is now redundant, due to
* the test of the return status of del_timer().
*/ */
if (SCpnt->state == SCSI_STATE_TIMEOUT) { if (SCpnt->state == SCSI_STATE_TIMEOUT) {
SCSI_LOG_MLCOMPLETE(1, printk("Ignoring completion of %p due to timeout status", SCpnt)); SCSI_LOG_MLCOMPLETE(1, printk("Ignoring completion of %p due to timeout status", SCpnt));
......
...@@ -1778,6 +1778,17 @@ STATIC int scsi_unjam_host(struct Scsi_Host *host) ...@@ -1778,6 +1778,17 @@ STATIC int scsi_unjam_host(struct Scsi_Host *host)
for (SCpnt = SCdone; SCpnt != NULL; SCpnt = SCdone) { for (SCpnt = SCdone; SCpnt != NULL; SCpnt = SCdone) {
SCdone = SCpnt->bh_next; SCdone = SCpnt->bh_next;
SCpnt->bh_next = NULL; SCpnt->bh_next = NULL;
/*
* Oh, this is a vile hack. scsi_done() expects a timer
* to be running on the command. If there isn't, it assumes
* that the command has actually timed out, and a timer
* handler is running. That may well be how we got into
* this fix, but right now things are stable. We add
* a timer back again so that we can report completion.
* scsi_done() will immediately remove said timer from
* the command, and then process it.
*/
scsi_add_timer(SCpnt, 100, scsi_eh_times_out);
scsi_done(SCpnt); scsi_done(SCpnt);
} }
...@@ -1809,7 +1820,14 @@ void scsi_error_handler(void *data) ...@@ -1809,7 +1820,14 @@ void scsi_error_handler(void *data)
int rtn; int rtn;
DECLARE_MUTEX_LOCKED(sem); DECLARE_MUTEX_LOCKED(sem);
/*
* We only listen to signals if the HA was loaded as a module.
* If the HA was compiled into the kernel, then we don't listen
* to any signals.
*/
if( host->loaded_as_module ) {
siginitsetinv(&current->blocked, SHUTDOWN_SIGS); siginitsetinv(&current->blocked, SHUTDOWN_SIGS);
}
lock_kernel(); lock_kernel();
...@@ -1844,10 +1862,14 @@ void scsi_error_handler(void *data) ...@@ -1844,10 +1862,14 @@ void scsi_error_handler(void *data)
* trying to unload a module. * trying to unload a module.
*/ */
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler sleeping\n")); SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler sleeping\n"));
if( host->loaded_as_module ) {
down_interruptible(&sem); down_interruptible(&sem);
if (signal_pending(current)) if (signal_pending(current))
break; break;
} else {
down(&sem);
}
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler waking up\n")); SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler waking up\n"));
......
...@@ -607,6 +607,22 @@ struct Scsi_Device_Template *scsi_get_request_dev(struct request *req) ...@@ -607,6 +607,22 @@ struct Scsi_Device_Template *scsi_get_request_dev(struct request *req)
if (spnt->blk && spnt->major == major) { if (spnt->blk && spnt->major == major) {
return spnt; return spnt;
} }
/*
* I am still not entirely satisfied with this solution,
* but it is good enough for now. Disks have a number of
* major numbers associated with them, the primary
* 8, which we test above, and a secondary range of 7
* different consecutive major numbers. If this ever
* becomes insufficient, then we could add another function
* to the structure, and generalize this completely.
*/
if( spnt->min_major != 0
&& spnt->max_major != 0
&& major >= spnt->min_major
&& major <= spnt->max_major )
{
return spnt;
}
} }
return NULL; return NULL;
} }
...@@ -742,9 +758,14 @@ void scsi_request_fn(request_queue_t * q) ...@@ -742,9 +758,14 @@ void scsi_request_fn(request_queue_t * q)
if (!SCpnt) { if (!SCpnt) {
break; break;
} }
}
/*
* Now bump the usage count for both the host and the
* device.
*/
SHpnt->host_busy++; SHpnt->host_busy++;
SDpnt->device_busy++; SDpnt->device_busy++;
}
/* /*
* FIXME(eric) * FIXME(eric)
......
...@@ -290,6 +290,30 @@ __inline static int __scsi_merge_fn(request_queue_t * q, ...@@ -290,6 +290,30 @@ __inline static int __scsi_merge_fn(request_queue_t * q,
count = bh->b_size >> 9; count = bh->b_size >> 9;
sector = bh->b_rsector; sector = bh->b_rsector;
#if CONFIG_HIGHMEM
/*
* This is a temporary hack for the time being.
* In some cases, the ll_rw_blk layer is creating
* bounce buffers for us - this implies that we don't
* need to down here, but queue management becomes quite
* difficult otherwise. When the ll_rw_blk layer gets
* cleaned up to handle bounce buffers better, then
* this hack can be cleaned up.
*/
if( sector == -1 )
{
struct buffer_head * bh_new;
bh_new = (struct buffer_head *) bh->b_dev_id;
if( bh_new != NULL )
{
sector = bh_new->b_rsector;
}
if( sector == -1 )
{
panic("Unable to merge ambiguous block request");
}
}
#endif
/* /*
* We come in here in one of two cases. The first is that we * We come in here in one of two cases. The first is that we
...@@ -765,7 +789,8 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt, ...@@ -765,7 +789,8 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
if( scsi_dma_free_sectors > 30 ) { if( scsi_dma_free_sectors > 30 ) {
for (this_count = 0, bh = SCpnt->request.bh; for (this_count = 0, bh = SCpnt->request.bh;
bh; bh = bh->b_reqnext) { bh; bh = bh->b_reqnext) {
if( scsi_dma_free_sectors < 30 || this_count == sectors ) if( scsi_dma_free_sectors - this_count < 30
|| this_count == sectors )
{ {
break; break;
} }
...@@ -831,24 +856,11 @@ static int _FUNCTION(Scsi_Cmnd * SCpnt) \ ...@@ -831,24 +856,11 @@ static int _FUNCTION(Scsi_Cmnd * SCpnt) \
* We always force "_VALID" to 1. Eventually clean this up * We always force "_VALID" to 1. Eventually clean this up
* and get rid of the extra argument. * and get rid of the extra argument.
*/ */
#if 0
/* Old definitions */
INITIO(scsi_init_io_, 0, 0, 0)
INITIO(scsi_init_io_d, 0, 0, 1)
INITIO(scsi_init_io_c, 0, 1, 0)
INITIO(scsi_init_io_dc, 0, 1, 1)
/* Newer redundant definitions. */
INITIO(scsi_init_io_, 1, 0, 0)
INITIO(scsi_init_io_d, 1, 0, 1)
INITIO(scsi_init_io_c, 1, 1, 0)
INITIO(scsi_init_io_dc, 1, 1, 1)
#endif
INITIO(scsi_init_io_v, 1, 0, 0) INITIO(scsi_init_io_v, 1, 0, 0)
INITIO(scsi_init_io_vd, 1, 0, 1) INITIO(scsi_init_io_vd, 1, 0, 1)
INITIO(scsi_init_io_vc, 1, 1, 0) INITIO(scsi_init_io_vc, 1, 1, 0)
INITIO(scsi_init_io_vdc, 1, 1, 1) INITIO(scsi_init_io_vdc, 1, 1, 1)
/* /*
* Function: initialize_merge_fn() * Function: initialize_merge_fn()
* *
...@@ -881,21 +893,12 @@ void initialize_merge_fn(Scsi_Device * SDpnt) ...@@ -881,21 +893,12 @@ void initialize_merge_fn(Scsi_Device * SDpnt)
* If this host has an unlimited tablesize, then don't bother with a * If this host has an unlimited tablesize, then don't bother with a
* merge manager. The whole point of the operation is to make sure * merge manager. The whole point of the operation is to make sure
* that requests don't grow too large, and this host isn't picky. * that requests don't grow too large, and this host isn't picky.
*/ *
if (SHpnt->sg_tablesize == SG_ALL) { * Note that ll_rw_blk.c is effectively maintaining a segment
if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) { * count which is only valid if clustering is used, and it obviously
SDpnt->scsi_init_io_fn = scsi_init_io_v; * doesn't handle the DMA case. In the end, it
} else if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) { * is simply easier to do it ourselves with our own functions
SDpnt->scsi_init_io_fn = scsi_init_io_vd; * rather than rely upon the default behavior of ll_rw_blk.
} else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) {
SDpnt->scsi_init_io_fn = scsi_init_io_vc;
} else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) {
SDpnt->scsi_init_io_fn = scsi_init_io_vdc;
}
return;
}
/*
* Now pick out the correct function.
*/ */
if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) { if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) {
q->merge_fn = scsi_merge_fn_; q->merge_fn = scsi_merge_fn_;
......
...@@ -202,6 +202,11 @@ struct Scsi_Device_Template sd_template = { ...@@ -202,6 +202,11 @@ struct Scsi_Device_Template sd_template = {
tag:"sd", tag:"sd",
scsi_type:TYPE_DISK, scsi_type:TYPE_DISK,
major:SCSI_DISK0_MAJOR, major:SCSI_DISK0_MAJOR,
/*
* Secondary range of majors that this driver handles.
*/
min_major:SCSI_DISK1_MAJOR,
max_major:SCSI_DISK7_MAJOR,
blk:1, blk:1,
detect:sd_detect, detect:sd_detect,
init:sd_init, init:sd_init,
...@@ -229,7 +234,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt) ...@@ -229,7 +234,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
Scsi_Disk *dpnt; Scsi_Disk *dpnt;
char nbuff[6]; char nbuff[6];
devm = MINOR(SCpnt->request.rq_dev); devm = SD_PARTITION(SCpnt->request.rq_dev);
dev = DEVICE_NR(SCpnt->request.rq_dev); dev = DEVICE_NR(SCpnt->request.rq_dev);
block = SCpnt->request.sector; block = SCpnt->request.sector;
...@@ -561,7 +566,7 @@ static void rw_intr(Scsi_Cmnd * SCpnt) ...@@ -561,7 +566,7 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
default: default:
break; break;
} }
error_sector -= sd[MINOR(SCpnt->request.rq_dev)].start_sect; error_sector -= sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect;
error_sector &= ~(block_sectors - 1); error_sector &= ~(block_sectors - 1);
good_sectors = error_sector - SCpnt->request.sector; good_sectors = error_sector - SCpnt->request.sector;
if (good_sectors < 0 || good_sectors >= this_count) if (good_sectors < 0 || good_sectors >= this_count)
......
...@@ -101,10 +101,17 @@ static int sg_detect(Scsi_Device *); ...@@ -101,10 +101,17 @@ static int sg_detect(Scsi_Device *);
static void sg_detach(Scsi_Device *); static void sg_detach(Scsi_Device *);
struct Scsi_Device_Template sg_template = {NULL, NULL, "sg", NULL, 0xff, struct Scsi_Device_Template sg_template =
SCSI_GENERIC_MAJOR, 0, 0, 0, 0, {
sg_detect, sg_init, tag:"sg",
sg_finish, sg_attach, sg_detach}; scsi_type:0xff,
major:SCSI_GENERIC_MAJOR,
detect:sg_detect,
init:sg_init,
finish:sg_finish,
attach:sg_attach,
detach:sg_detach
};
typedef struct sg_scatter_hold /* holding area for scsi scatter gather info */ typedef struct sg_scatter_hold /* holding area for scsi scatter gather info */
......
...@@ -147,10 +147,16 @@ static int st_detect(Scsi_Device *); ...@@ -147,10 +147,16 @@ static int st_detect(Scsi_Device *);
static void st_detach(Scsi_Device *); static void st_detach(Scsi_Device *);
struct Scsi_Device_Template st_template = struct Scsi_Device_Template st_template =
{NULL, "tape", "st", NULL, TYPE_TAPE, {
SCSI_TAPE_MAJOR, 0, 0, 0, 0, name:"tape",
st_detect, st_init, tag:"st",
NULL, st_attach, st_detach}; scsi_type:TYPE_TAPE,
major:SCSI_TAPE_MAJOR,
detect:st_detect,
init:st_init,
attach:st_attach,
detach:st_detach
};
static int st_compression(Scsi_Tape *, int); static int st_compression(Scsi_Tape *, int);
......
...@@ -360,6 +360,7 @@ struct pci_bus { ...@@ -360,6 +360,7 @@ struct pci_bus {
struct pci_dev *self; /* bridge device as seen by parent */ struct pci_dev *self; /* bridge device as seen by parent */
struct pci_dev *devices; /* devices behind this bridge */ struct pci_dev *devices; /* devices behind this bridge */
struct pci_dev **last_dev_p; /* where should next device be linked to */
struct resource *resource[4]; /* address space routed to this bus */ struct resource *resource[4]; /* address space routed to this bus */
void *sysdata; /* hook for sys-specific extension */ void *sysdata; /* hook for sys-specific extension */
...@@ -449,6 +450,8 @@ int pcibios_find_device (unsigned short vendor, unsigned short dev_id, ...@@ -449,6 +450,8 @@ int pcibios_find_device (unsigned short vendor, unsigned short dev_id,
void pci_init(void); void pci_init(void);
struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); 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);
int pci_proc_attach_device(struct pci_dev *dev); int pci_proc_attach_device(struct pci_dev *dev);
int pci_proc_detach_device(struct pci_dev *dev); int pci_proc_detach_device(struct pci_dev *dev);
void pci_name_device(struct pci_dev *dev); void pci_name_device(struct pci_dev *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