From 6ed83574bb9da444b851212cd856cb4c420578a8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:29:36 -0500 Subject: [PATCH] Import 2.3.35pre6 --- drivers/pci/pci.c | 147 ++++++++--------- drivers/pci/pcisyms.c | 2 + drivers/pcmcia/cardbus.c | 28 ++-- drivers/pcmcia/i82365.c | 331 +++++++++++++------------------------- drivers/scsi/hosts.h | 5 +- drivers/scsi/scsi.c | 6 +- drivers/scsi/scsi_error.c | 22 +++ drivers/scsi/scsi_lib.c | 25 ++- drivers/scsi/scsi_merge.c | 63 ++++---- drivers/scsi/sd.c | 9 +- drivers/scsi/sg.c | 15 +- drivers/scsi/st.c | 14 +- include/linux/pci.h | 3 + 13 files changed, 318 insertions(+), 352 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c157b5b32f4c..bcec975153c6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -30,7 +30,6 @@ struct pci_bus *pci_root; struct pci_dev *pci_devices = NULL; static struct pci_dev **pci_last_dev_p = &pci_devices; -static int pci_reverse __initdata = 0; struct pci_dev * pci_find_slot(unsigned int bus, unsigned int devfn) @@ -270,7 +269,7 @@ static inline unsigned int pci_resource_flags(unsigned int flags) 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; u32 l, sz, tmp; @@ -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 - * bus numbers. Read resource ranges behind the bridge. + * bus numbers. */ child->number = child->secondary = busnr; child->primary = parent->secondary; @@ -578,24 +577,29 @@ static __init void pci_read_irq(struct pci_dev *dev) } /* - * Read the config data for a PCI device - * and sanity-check it and fill in the dev - * structure... + * Read the config data for a PCI device, sanity-check it + * and fill in the dev 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)) - return -1; + if (pci_read_config_dword(temp, PCI_VENDOR_ID, &l)) + 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) - return -1; + return NULL; + + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + memcpy(dev, temp, sizeof(*dev)); dev->vendor = l & 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_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 default: /* unknown header */ printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n", dev->slot_name, dev->hdr_type); - return -1; + kfree(dev); + return NULL; bad: 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 } /* We found a fine healthy device, go go go... */ - return 0; + return dev; } - -static unsigned int __init pci_do_scan_bus(struct pci_bus *bus) +struct pci_dev * __init pci_scan_slot(struct pci_dev *temp) { - unsigned int devfn, max; - struct pci_dev *dev, **bus_last; + struct pci_bus *bus = temp->bus; + struct pci_dev *dev; + struct pci_dev *first_dev = NULL; + int func = 0; int is_multi = 0; + u8 hdr_type; - DBG("pci_do_scan_bus for bus %d\n", bus->number); - bus_last = &bus->devices; - 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) + for (func = 0; func < 8; func++, temp->devfn++) { + if (func && !is_multi) /* not a multi-function device */ continue; - - 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)) + if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) continue; + temp->hdr_type = hdr_type & 0x7f; - if (!PCI_FUNC(devfn)) - is_multi = hdr_type & 0x80; - dev->hdr_type = hdr_type & 0x7f; - - if (pci_scan_device(bus, dev, devfn)) + dev = pci_scan_device(temp); + if (!dev) 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); @@ -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 * find devices once everything is set up. */ - if (!pci_reverse) { - *pci_last_dev_p = dev; - pci_last_dev_p = &dev->next; - } else { - dev->next = pci_devices; - pci_devices = dev; - } + *pci_last_dev_p = dev; + pci_last_dev_p = &dev->next; /* * Now insert it into the list of devices held * by the parent bus. */ - *bus_last = dev; - bus_last = &dev->sibling; + *bus->last_dev_p = dev; + bus->last_dev_p = &dev->sibling; /* Fix up broken headers */ pci_fixup_device(PCI_FIXUP_HEADER, dev); + } + return first_dev; +} -#if 0 - /* - * Setting of latency timer in case it was less than 32 was - * a great idea, but it confused several broken devices. Grrr. - */ - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp); - if (tmp < 32) - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32); -#endif +static unsigned int __init pci_do_scan_bus(struct pci_bus *bus) +{ + unsigned int devfn, max; + struct pci_dev *dev, dev0; - 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 @@ -759,7 +753,7 @@ static int __init pci_bus_exists(struct pci_bus *b, int nr) 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; @@ -779,11 +773,19 @@ struct pci_bus * __init pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata *r = b; b->number = b->secondary = bus; - b->sysdata = sysdata; - b->ops = ops; b->resource[0] = &ioport_resource; b->resource[1] = &iomem_resource; - b->subordinate = pci_do_scan_bus(b); + 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); + } return b; } @@ -804,9 +806,8 @@ static int __init pci_setup(char *str) if (k) *k++ = 0; if (*str && (str = pcibios_setup(str)) && *str) { - if (!strcmp(str, "reverse")) - pci_reverse = 1; - else printk(KERN_ERR "PCI: Unknown option `%s'\n", str); + /* PCI layer options should be handled here */ + printk(KERN_ERR "PCI: Unknown option `%s'\n", str); } str = k; } diff --git a/drivers/pci/pcisyms.c b/drivers/pci/pcisyms.c index 101728b72032..3c9d1caaead0 100644 --- a/drivers/pci/pcisyms.c +++ b/drivers/pci/pcisyms.c @@ -25,6 +25,8 @@ EXPORT_SYMBOL(pci_find_device); EXPORT_SYMBOL(pci_find_slot); EXPORT_SYMBOL(pci_set_master); EXPORT_SYMBOL(pci_simple_probe); +EXPORT_SYMBOL(pci_set_power_state); +EXPORT_SYMBOL(pci_assign_resource); #ifdef CONFIG_PROC_FS EXPORT_SYMBOL(pci_proc_attach_device); EXPORT_SYMBOL(pci_proc_detach_device); diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 3dcd34b8546e..a27827644c30 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -283,20 +283,21 @@ int cb_alloc(socket_info_t *s) u_char i, hdr, fn, bus = s->cap.cardbus; cb_config_t *c; + memset(&tmp, 0, sizeof(tmp)); 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, " "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) { /* Count functions */ for (fn = 0; fn < 8; 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; } } else fn = 1; @@ -307,7 +308,6 @@ int cb_alloc(socket_info_t *s) memset(c, 0, fn * sizeof(struct cb_config_t)); s->cb_config = c; - pci_devices = tmp.next; for (i = 0; i < fn; i++) { c[i].dev.bus = s->cap.cb_bus; c[i].dev.devfn = i; @@ -317,7 +317,7 @@ int cb_alloc(socket_info_t *s) } s->cap.cb_bus->devices = &c[0].dev; /* 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; for (i = 0; i < fn; i++) { c[i].dev.vendor = vend; @@ -338,17 +338,17 @@ void cb_free(socket_info_t *s) cb_config_t *c = s->cb_config; if (c) { - struct pci_dev **p, *q; + struct pci_dev **p; /* Unlink from PCI device chain */ - for (p = &pci_devices; *p; p = &((*p)->next)) - if (*p == &c[0].dev) break; - for (q = *p; q; q = q->next) { - if (q->bus != (*p)->bus) break; + for (p = &pci_devices; *p; p = &((*p)->next)) { + struct pci_dev * dev = *p; + if (dev->bus != s->cap.cb_bus) + continue; + *p = dev->next; #ifdef CONFIG_PROC_FS - pci_proc_detach_device(q); + pci_proc_detach_device(dev); #endif } - if (*p) *p = q; s->cap.cb_bus->devices = NULL; kfree(s->cb_config); s->cb_config = NULL; diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 8f45713eac68..d473a2f69c63 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -159,8 +159,6 @@ MODULE_PARM(recov_time, "i"); #ifdef CONFIG_PCI /* Scan PCI bus? */ 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 hold_time = -1; /* Override BIOS interrupt routing mode? */ @@ -173,7 +171,6 @@ static int cb_bus_base = 0; static int cb_bus_step = 2; static int cb_write_post = -1; MODULE_PARM(do_pci_probe, "i"); -MODULE_PARM(cb_mem_base, "i"); MODULE_PARM(fast_pci, "i"); MODULE_PARM(hold_time, "i"); MODULE_PARM(irq_mode, "i"); @@ -249,11 +246,11 @@ typedef struct socket_info_t { struct proc_dir_entry *proc; #endif #ifdef CONFIG_PCI - u_short vendor, device; - u_char revision, bus, devfn; + struct pci_dev *pdev; + u_char revision; u_short bcr; u_char pci_lat, cb_lat, sub_bus; - u_char cache, pmcs; + u_char cache; u_int cb_phys; char *cb_virt; #endif @@ -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 */ #define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \ PCI_COMMAND_MASTER|PCI_COMMAND_WAIT) -#endif - /* These definitions must match the pcic table! */ typedef enum pcic_id { #ifdef CONFIG_ISA @@ -379,9 +362,9 @@ static pcic_t pcic[] = { { "O2Micro OZ6730", IS_O2MICRO|IS_PCI|IS_VG_PWR, PCI_VENDOR_ID_O2, PCI_DEVICE_ID_O2_6730 }, { "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, - PCI_VENDOR_ID_OMEGA, PCI_DEVICE_ID_OMEGA_PCMCIA }, + PCI_VENDOR_ID_OMEGA, PCI_DEVICE_ID_OMEGA_82C092G }, { "Cirrus PD6832", IS_CIRRUS|IS_CARDBUS, PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832 }, { "O2Micro OZ6832/OZ6833", IS_O2MICRO|IS_CARDBUS|IS_VG_PWR, @@ -443,12 +426,12 @@ static pcic_t pcic[] = { /* Some PCI shortcuts */ -#define pci_readb pcibios_read_config_byte -#define pci_writeb pcibios_write_config_byte -#define pci_readw pcibios_read_config_word -#define pci_writew pcibios_write_config_word -#define pci_readl pcibios_read_config_dword -#define pci_writel pcibios_write_config_dword +#define config_readb(sock, r, v) pci_read_config_byte((sock)->pdev, r, v) +#define config_readw(sock, r, v) pci_read_config_word((sock)->pdev, r, v) +#define config_readl(sock, r, v) pci_read_config_dword((sock)->pdev, r, v) +#define config_writeb(sock, r, v) pci_write_config_byte((sock)->pdev, r, v) +#define config_writew(sock, r, v) pci_write_config_word((sock)->pdev, r, v) +#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_readl(s, r) readl(socket[s].cb_virt + (r)) @@ -701,21 +684,21 @@ static void ti113x_get_state(u_short s) { socket_info_t *t = &socket[s]; ti113x_state_t *p = &socket[s].state.ti113x; - pci_readl(t->bus, t->devfn, TI113X_SYSTEM_CONTROL, &p->sysctl); - pci_readb(t->bus, t->devfn, TI113X_CARD_CONTROL, &p->cardctl); - pci_readb(t->bus, t->devfn, TI113X_DEVICE_CONTROL, &p->devctl); - pci_readb(t->bus, t->devfn, TI1250_DIAGNOSTIC, &p->diag); + config_readl(t, TI113X_SYSTEM_CONTROL, &p->sysctl); + config_readb(t, TI113X_CARD_CONTROL, &p->cardctl); + config_readb(t, TI113X_DEVICE_CONTROL, &p->devctl); + config_readb(t, TI1250_DIAGNOSTIC, &p->diag); } static void ti113x_set_state(u_short s) { socket_info_t *t = &socket[s]; ti113x_state_t *p = &socket[s].state.ti113x; - pci_writel(t->bus, t->devfn, TI113X_SYSTEM_CONTROL, p->sysctl); - pci_writeb(t->bus, t->devfn, TI113X_CARD_CONTROL, p->cardctl); - pci_writeb(t->bus, t->devfn, TI113X_DEVICE_CONTROL, p->devctl); - pci_writeb(t->bus, t->devfn, TI1250_MULTIMEDIA_CTL, 0); - pci_writeb(t->bus, t->devfn, TI1250_DIAGNOSTIC, p->diag); + config_writel(t, TI113X_SYSTEM_CONTROL, p->sysctl); + config_writeb(t, TI113X_CARD_CONTROL, p->cardctl); + config_writeb(t, TI113X_DEVICE_CONTROL, p->devctl); + config_writeb(t, TI1250_MULTIMEDIA_CTL, 0); + config_writeb(t, TI1250_DIAGNOSTIC, p->diag); i365_set_pair(s, TI113X_IO_OFFSET(0), 0); i365_set_pair(s, TI113X_IO_OFFSET(1), 0); } @@ -822,20 +805,20 @@ static void rl5c4xx_get_state(u_short s) { socket_info_t *t = &socket[s]; rl5c4xx_state_t *p = &socket[s].state.rl5c4xx; - pci_readw(t->bus, t->devfn, RL5C4XX_MISC, &p->misc); - pci_readw(t->bus, t->devfn, RL5C4XX_16BIT_CTL, &p->ctl); - pci_readw(t->bus, t->devfn, RL5C4XX_16BIT_IO_0, &p->io); - pci_readw(t->bus, t->devfn, RL5C4XX_16BIT_MEM_0, &p->mem); + config_readw(t, RL5C4XX_MISC, &p->misc); + config_readw(t, RL5C4XX_16BIT_CTL, &p->ctl); + config_readw(t, RL5C4XX_16BIT_IO_0, &p->io); + config_readw(t, RL5C4XX_16BIT_MEM_0, &p->mem); } static void rl5c4xx_set_state(u_short s) { socket_info_t *t = &socket[s]; rl5c4xx_state_t *p = &socket[s].state.rl5c4xx; - pci_writew(t->bus, t->devfn, RL5C4XX_MISC, p->misc); - pci_writew(t->bus, t->devfn, RL5C4XX_16BIT_CTL, p->ctl); - pci_writew(t->bus, t->devfn, RL5C4XX_16BIT_IO_0, p->io); - pci_writew(t->bus, t->devfn, RL5C4XX_16BIT_MEM_0, p->mem); + config_writew(t, RL5C4XX_MISC, p->misc); + config_writew(t, RL5C4XX_16BIT_CTL, p->ctl); + config_writew(t, RL5C4XX_16BIT_IO_0, p->io); + config_writew(t, RL5C4XX_16BIT_MEM_0, p->mem); } static u_int __init rl5c4xx_set_opts(u_short s, char *buf) @@ -986,20 +969,20 @@ static void topic_get_state(u_short s) { socket_info_t *t = &socket[s]; topic_state_t *p = &socket[s].state.topic; - pci_readb(t->bus, t->devfn, TOPIC_SLOT_CONTROL, &p->slot); - pci_readb(t->bus, t->devfn, TOPIC_CARD_CONTROL, &p->ccr); - pci_readb(t->bus, t->devfn, TOPIC_CARD_DETECT, &p->cdr); - pci_readl(t->bus, t->devfn, TOPIC_REGISTER_CONTROL, &p->rcr); + config_readb(t, TOPIC_SLOT_CONTROL, &p->slot); + config_readb(t, TOPIC_CARD_CONTROL, &p->ccr); + config_readb(t, TOPIC_CARD_DETECT, &p->cdr); + config_readl(t, TOPIC_REGISTER_CONTROL, &p->rcr); } static void topic_set_state(u_short s) { socket_info_t *t = &socket[s]; topic_state_t *p = &socket[s].state.topic; - pci_writeb(t->bus, t->devfn, TOPIC_SLOT_CONTROL, p->slot); - pci_writeb(t->bus, t->devfn, TOPIC_CARD_CONTROL, p->ccr); - pci_writeb(t->bus, t->devfn, TOPIC_CARD_DETECT, p->cdr); - pci_writel(t->bus, t->devfn, TOPIC_REGISTER_CONTROL, p->rcr); + config_writeb(t, TOPIC_SLOT_CONTROL, p->slot); + config_writeb(t, TOPIC_CARD_CONTROL, p->ccr); + config_writeb(t, TOPIC_CARD_DETECT, p->cdr); + config_writel(t, TOPIC_REGISTER_CONTROL, p->rcr); } 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) { socket_info_t *t = &socket[s]; - pci_readb(t->bus, t->devfn, PCI_CACHE_LINE_SIZE, &t->cache); - pci_readb(t->bus, t->devfn, PCI_LATENCY_TIMER, &t->pci_lat); - pci_readb(t->bus, t->devfn, CB_LATENCY_TIMER, &t->cb_lat); - pci_readb(t->bus, t->devfn, CB_CARDBUS_BUS, &t->cap.cardbus); - pci_readb(t->bus, t->devfn, CB_SUBORD_BUS, &t->sub_bus); - pci_readw(t->bus, t->devfn, CB_BRIDGE_CONTROL, &t->bcr); - { - 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; + config_readb(t, PCI_CACHE_LINE_SIZE, &t->cache); + config_readb(t, PCI_LATENCY_TIMER, &t->pci_lat); + config_readb(t, CB_LATENCY_TIMER, &t->cb_lat); + config_readb(t, CB_CARDBUS_BUS, &t->cap.cardbus); + config_readb(t, CB_SUBORD_BUS, &t->sub_bus); + config_readw(t, CB_BRIDGE_CONTROL, &t->bcr); + t->cap.pci_irq = t->pdev->irq; } static void cb_set_state(u_short s) { socket_info_t *t = &socket[s]; - if (t->pmcs) - pci_writew(t->bus, t->devfn, t->pmcs, PCI_PMCS_PWR_STATE_D0); - pci_writel(t->bus, t->devfn, CB_LEGACY_MODE_BASE, 0); - pci_writel(t->bus, t->devfn, PCI_BASE_ADDRESS_0, t->cb_phys); - pci_writew(t->bus, t->devfn, PCI_COMMAND, CMD_DFLT); - pci_writeb(t->bus, t->devfn, PCI_CACHE_LINE_SIZE, t->cache); - pci_writeb(t->bus, t->devfn, PCI_LATENCY_TIMER, t->pci_lat); - pci_writeb(t->bus, t->devfn, CB_LATENCY_TIMER, t->cb_lat); - pci_writeb(t->bus, t->devfn, CB_CARDBUS_BUS, t->cap.cardbus); - pci_writeb(t->bus, t->devfn, CB_SUBORD_BUS, t->sub_bus); - pci_writew(t->bus, t->devfn, CB_BRIDGE_CONTROL, t->bcr); + pci_set_power_state(t->pdev, 0); /* FIXME: Do we really need all of this? */ + config_writel(t, CB_LEGACY_MODE_BASE, 0); + config_writel(t, PCI_BASE_ADDRESS_0, t->cb_phys); + config_writew(t, PCI_COMMAND, CMD_DFLT); + config_writeb(t, PCI_CACHE_LINE_SIZE, t->cache); + config_writeb(t, PCI_LATENCY_TIMER, t->pci_lat); + config_writeb(t, CB_LATENCY_TIMER, t->cb_lat); + config_writeb(t, CB_CARDBUS_BUS, t->cap.cardbus); + config_writeb(t, CB_SUBORD_BUS, t->sub_bus); + config_writew(t, CB_BRIDGE_CONTROL, t->bcr); } static int cb_get_irq_mode(u_short s) @@ -1500,13 +1478,11 @@ static void __init add_pcic(int ns, int type) printk(KERN_INFO " %s", pcic[type].name); #ifdef CONFIG_PCI 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) - printk(" PCI-to-CardBus at bus %d slot %d, mem 0x%08x", - t->bus, PCI_SLOT(t->devfn), t->cb_phys); + printk(" PCI-to-CardBus at %s, mem 0x%08x", t->pdev->slot_name, t->cb_phys); else if (t->flags & IS_PCI) - printk(" PCI-to-PCMCIA at bus %d slot %d, port %#x", - t->bus, PCI_SLOT(t->devfn), t->ioaddr); + printk(" PCI-to-PCMCIA at %s, port %#x", t->pdev->slot_name, t->ioaddr); else #endif printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x", @@ -1596,107 +1572,50 @@ static void __init add_pcic(int ns, int type) #ifdef CONFIG_PCI -typedef struct pci_dev *pci_id_t; -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) +static void __init add_pci_bridge(int type, struct pci_dev *dev) { socket_info_t *s = &socket[sockets]; u_short i, ns; - u_int addr; + u32 addr = dev->resource[0].start; if (type == PCIC_COUNT) type = IS_UNK_PCI; - pci_readl(bus, devfn, PCI_BASE_ADDRESS_0, &addr); - addr &= ~0x1; - pci_writew(bus, devfn, PCI_COMMAND, CMD_DFLT); + pci_write_config_word(dev, PCI_COMMAND, CMD_DFLT); for (i = ns = 0; i < ((type == IS_I82092AA) ? 4 : 2); i++) { - s->bus = bus; s->devfn = devfn; - s->vendor = v; s->device = d; + s->pdev = dev; add_socket(addr, i, type); ns++; s++; } add_pcic(ns, type); } -static void __init add_cb_bridge(int type, u_char bus, u_char devfn, - u_short v, u_short d0) +static void __init add_cb_bridge(int type, struct pci_dev *dev0) { socket_info_t *s = &socket[sockets]; - u_short d, ns, i; - u_char a, b, r, max; - - /* PCI bus enumeration is broken on some systems */ - for (ns = 0; ns < sockets; ns++) - if ((socket[ns].bus == bus) && (socket[ns].devfn == devfn)) - return; - - if (type == PCIC_COUNT) type = IS_UNK_CARDBUS; - pci_readb(bus, devfn, PCI_HEADER_TYPE, &a); - pci_readb(bus, devfn, PCI_CLASS_REVISION, &r); - max = (a & 0x80) ? 8 : 1; - for (ns = 0; ns < max; ns++, s++, devfn++) { - 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; - } - pci_readb(bus, devfn, b+PCI_NEXT_CAPABILITY, &b); - } - } - /* 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 */ - pci_writel(bus, devfn, CB_LEGACY_MODE_BASE, 0); - pci_readl(bus, devfn, PCI_BASE_ADDRESS_0, &s->cb_phys); - if (s->cb_phys == 0) { - 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(KERN_NOTICE " Bridge register mapping failed:" - " check cb_mem_base setting\n"); + u_short i, ns; + u_char a, b; + + if (type == PCIC_COUNT) + type = IS_UNK_CARDBUS; + + for (ns = 0; ns < 8; ns++, s++) { + struct pci_dev *dev; + + dev = pci_find_slot(dev0->bus->number, dev0->devfn + ns); + if (!dev) break; - } - cb_mem_base[0] = cb_mem_base[i] + PAGE_SIZE; - } else { - s->cb_virt = ioremap(s->cb_phys, 0x1000); + s->pdev = dev; + pci_read_config_byte(dev, PCI_CLASS_REVISION, &s->revision); + + /* Map CardBus registers if they are not already mapped */ + pci_write_config_dword(dev, CB_LEGACY_MODE_BASE, 0); + s->cb_phys = dev->resource[0].start; + if (!s->cb_phys || !(s->cb_virt = ioremap(s->cb_phys, 0x1000))) { + printk("\n"); + printk(KERN_ERR " No control registers found!\n"); + break; } - request_mem_region(s->cb_phys, 0x1000, "i82365"); + s->cap.cb_bus = dev->subordinate; add_socket(0, 0, type); } if (ns == 0) return; @@ -1704,11 +1623,11 @@ static void __init add_cb_bridge(int type, u_char bus, u_char devfn, s -= ns; if (ns == 2) { /* Nasty special check for bad bus mapping */ - pci_readb(bus, s[0].devfn, CB_CARDBUS_BUS, &a); - pci_readb(bus, s[1].devfn, CB_CARDBUS_BUS, &b); + config_readb(&s[0], CB_CARDBUS_BUS, &a); + config_readb(&s[1], CB_CARDBUS_BUS, &b); if (a == b) { - pci_writeb(bus, s[0].devfn, CB_CARDBUS_BUS, 0); - pci_writeb(bus, s[1].devfn, CB_CARDBUS_BUS, 0); + config_writeb(&s[0], CB_CARDBUS_BUS, 0); + config_writeb(&s[1], CB_CARDBUS_BUS, 0); } } add_pcic(ns, type); @@ -1728,43 +1647,19 @@ static void __init add_cb_bridge(int type, u_char bus, u_char devfn, if (i == 200) printk(KERN_NOTICE "i82365: card voltage interrogation" " timed out!\n"); - - /* Set up PCI bus bridge structures if needed */ - for (a = 0; a < ns; a++) { - struct pci_dev *self = pci_find_slot(bus, s[a].devfn); - struct pci_bus *child, *parent = self->bus; - for (child = parent->children; child; child = child->next) - if (child->number == s[a].cap.cardbus) break; - if (!child) { - child = kmalloc(sizeof(struct pci_bus), GFP_KERNEL); - 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)) +static void __init pci_probe(u_int class, void (add_fn)(int, struct pci_dev *)) { - 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); + struct pci_dev *dev = NULL; + u_short i; + + while ((dev = pci_find_class(class << 8, dev))) { + pci_enable_device(dev); + if (PCI_FUNC(dev->devfn) != 0) continue; for (i = 0; i < PCIC_COUNT; i++) - if ((pcic[i].vendor == v) && (pcic[i].device == d)) break; - add_fn(i, bus, devfn, v, d); + if ((pcic[i].vendor == dev->vendor) && (pcic[i].device == dev->device)) break; + add_fn(i, dev); } } @@ -2397,7 +2292,7 @@ static int cb_get_socket(u_short sock, socket_state_t *state) u_short bcr; 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; if (cb_get_irq_mode(sock) != 0) state->io_irq = s->cap.pci_irq; @@ -2454,15 +2349,15 @@ static int cb_get_bridge(u_short sock, struct cb_bridge_map *m) if (map > 1) return -EINVAL; m->flags &= MAP_IOSPACE; map += (m->flags & MAP_IOSPACE) ? 2 : 0; - pci_readl(s->bus, s->devfn, CB_MEM_BASE(map), &m->start); - pci_readl(s->bus, s->devfn, CB_MEM_LIMIT(map), &m->stop); + config_readl(s, CB_MEM_BASE(map), &m->start); + config_readl(s, CB_MEM_LIMIT(map), &m->stop); if (m->start || m->stop) { m->flags |= MAP_ACTIVE; m->stop |= (map > 1) ? 3 : 0x0fff; } if (map > 1) { 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; } 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) u_short bcr; if ((m->start & 0x0fff) || ((m->stop & 0x0fff) != 0x0fff)) 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 |= (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) { - pci_writel(s->bus, s->devfn, CB_MEM_BASE(map), m->start); - pci_writel(s->bus, s->devfn, CB_MEM_LIMIT(map), m->stop); + config_writel(s, CB_MEM_BASE(map), m->start); + config_writel(s, CB_MEM_LIMIT(map), m->stop); } else { - pci_writel(s->bus, s->devfn, CB_IO_BASE(map), 0); - pci_writel(s->bus, s->devfn, CB_IO_LIMIT(map), 0); + config_writel(s, CB_MEM_BASE(map), 0); + config_writel(s, CB_MEM_LIMIT(map), 0); } return 0; } @@ -2525,7 +2420,7 @@ static int proc_read_info(char *buf, char **start, off_t pos, #ifdef CONFIG_PCI if (s->flags & (IS_PCI|IS_CARDBUS)) 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) p += sprintf(p, "cardbus: %02x\n", s->cap.cardbus); #endif @@ -2565,16 +2460,15 @@ static int proc_read_pci(char *buf, char **start, off_t pos, int count, int *eof, void *data) { socket_info_t *s = data; - u_char bus = s->bus, devfn = s->devfn; char *p = buf; u_int a, b, c, d; int i; for (i = 0; i < 0xc0; i += 0x10) { - pci_readl(bus, devfn, i, &a); - pci_readl(bus, devfn, i+4, &b); - pci_readl(bus, devfn, i+8, &c); - pci_readl(bus, devfn, i+12, &d); + config_readl(s, i, &a); + config_readl(s, i+4, &b); + config_readl(s, i+8, &c); + config_readl(s, i+12, &d); p += sprintf(p, "%08x %08x %08x %08x\n", a, b, c, d); } return (p - buf); @@ -2801,7 +2695,7 @@ static int __init init_i82365(void) sockets = 0; #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_PCMCIA, add_pci_bridge); } @@ -2892,4 +2786,3 @@ module_init(init_i82365); module_exit(exit_i82365); /*====================================================================*/ - diff --git a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h index 18a9bf45c87e..31aacd0663a8 100644 --- a/drivers/scsi/hosts.h +++ b/drivers/scsi/hosts.h @@ -437,6 +437,8 @@ struct Scsi_Device_Template struct module * module; /* Used for loadable modules */ unsigned char scsi_type; 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 dev_noticed; /* Number of devices detected. */ unsigned char dev_max; /* Current size of arrays */ @@ -447,7 +449,8 @@ struct Scsi_Device_Template void (*finish)(void); /* Perform initialization after attachment */ int (*attach)(Scsi_Device *); /* Attach devices to arrays */ 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; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c49d7ef7a59c..cc671c0d3968 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -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 * the timeout counter, etc) will be called by us or by the @@ -1575,6 +1572,9 @@ void scsi_done(Scsi_Cmnd * SCpnt) * Since serial_number is now 0, the error handler cound detect this * situation and avoid to call the the low level driver abort routine. * (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) { SCSI_LOG_MLCOMPLETE(1, printk("Ignoring completion of %p due to timeout status", SCpnt)); diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 8ef70d4ac24f..feaa7ecfb55e 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1778,6 +1778,17 @@ STATIC int scsi_unjam_host(struct Scsi_Host *host) for (SCpnt = SCdone; SCpnt != NULL; SCpnt = SCdone) { SCdone = SCpnt->bh_next; 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); } @@ -1809,7 +1820,14 @@ void scsi_error_handler(void *data) int rtn; 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(¤t->blocked, SHUTDOWN_SIGS); + } lock_kernel(); @@ -1844,10 +1862,14 @@ void scsi_error_handler(void *data) * trying to unload a module. */ SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler sleeping\n")); + if( host->loaded_as_module ) { down_interruptible(&sem); if (signal_pending(current)) break; + } else { + down(&sem); + } SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler waking up\n")); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 56779f2e521b..c05ef60c97cc 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -607,6 +607,22 @@ struct Scsi_Device_Template *scsi_get_request_dev(struct request *req) if (spnt->blk && spnt->major == major) { 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; } @@ -742,10 +758,15 @@ void scsi_request_fn(request_queue_t * q) if (!SCpnt) { break; } - SHpnt->host_busy++; - SDpnt->device_busy++; } + /* + * Now bump the usage count for both the host and the + * device. + */ + SHpnt->host_busy++; + SDpnt->device_busy++; + /* * FIXME(eric) * I am not sure where the best place to do this is. We need diff --git a/drivers/scsi/scsi_merge.c b/drivers/scsi/scsi_merge.c index 1cb59caa76b8..1d29945dc3ee 100644 --- a/drivers/scsi/scsi_merge.c +++ b/drivers/scsi/scsi_merge.c @@ -290,6 +290,30 @@ __inline static int __scsi_merge_fn(request_queue_t * q, count = bh->b_size >> 9; 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 @@ -765,7 +789,8 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt, if( scsi_dma_free_sectors > 30 ) { for (this_count = 0, bh = SCpnt->request.bh; 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; } @@ -831,24 +856,11 @@ static int _FUNCTION(Scsi_Cmnd * SCpnt) \ * We always force "_VALID" to 1. Eventually clean this up * 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_vd, 1, 0, 1) INITIO(scsi_init_io_vc, 1, 1, 0) INITIO(scsi_init_io_vdc, 1, 1, 1) + /* * Function: initialize_merge_fn() * @@ -881,21 +893,12 @@ void initialize_merge_fn(Scsi_Device * SDpnt) * 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 * that requests don't grow too large, and this host isn't picky. - */ - if (SHpnt->sg_tablesize == SG_ALL) { - if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) { - SDpnt->scsi_init_io_fn = scsi_init_io_v; - } else if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) { - SDpnt->scsi_init_io_fn = scsi_init_io_vd; - } 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. + * + * Note that ll_rw_blk.c is effectively maintaining a segment + * count which is only valid if clustering is used, and it obviously + * doesn't handle the DMA case. In the end, it + * is simply easier to do it ourselves with our own functions + * rather than rely upon the default behavior of ll_rw_blk. */ if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) { q->merge_fn = scsi_merge_fn_; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c82391a01d5b..85ca3a0ccb0c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -202,6 +202,11 @@ struct Scsi_Device_Template sd_template = { tag:"sd", scsi_type:TYPE_DISK, major:SCSI_DISK0_MAJOR, + /* + * Secondary range of majors that this driver handles. + */ + min_major:SCSI_DISK1_MAJOR, + max_major:SCSI_DISK7_MAJOR, blk:1, detect:sd_detect, init:sd_init, @@ -229,7 +234,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt) Scsi_Disk *dpnt; char nbuff[6]; - devm = MINOR(SCpnt->request.rq_dev); + devm = SD_PARTITION(SCpnt->request.rq_dev); dev = DEVICE_NR(SCpnt->request.rq_dev); block = SCpnt->request.sector; @@ -561,7 +566,7 @@ static void rw_intr(Scsi_Cmnd * SCpnt) default: 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); good_sectors = error_sector - SCpnt->request.sector; if (good_sectors < 0 || good_sectors >= this_count) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index edcaa5fa5113..0ca7f2099445 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -101,10 +101,17 @@ static int sg_detect(Scsi_Device *); static void sg_detach(Scsi_Device *); -struct Scsi_Device_Template sg_template = {NULL, NULL, "sg", NULL, 0xff, - SCSI_GENERIC_MAJOR, 0, 0, 0, 0, - sg_detect, sg_init, - sg_finish, sg_attach, sg_detach}; +struct Scsi_Device_Template sg_template = +{ + tag:"sg", + 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 */ diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index fb8d5f4a1d01..aa8dee0c8330 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -147,10 +147,16 @@ static int st_detect(Scsi_Device *); static void st_detach(Scsi_Device *); struct Scsi_Device_Template st_template = -{NULL, "tape", "st", NULL, TYPE_TAPE, - SCSI_TAPE_MAJOR, 0, 0, 0, 0, - st_detect, st_init, - NULL, st_attach, st_detach}; +{ + name:"tape", + tag:"st", + 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); diff --git a/include/linux/pci.h b/include/linux/pci.h index 6b5c9bd6245b..bc3fe4e3dbda 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -360,6 +360,7 @@ struct pci_bus { struct pci_dev *self; /* bridge device as seen by parent */ 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 */ void *sysdata; /* hook for sys-specific extension */ @@ -449,6 +450,8 @@ int pcibios_find_device (unsigned short vendor, unsigned short dev_id, void pci_init(void); 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_detach_device(struct pci_dev *dev); void pci_name_device(struct pci_dev *dev); -- 2.39.5