From b5849a353834172c4e11b494aa5df5c7bd37bd55 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 28 Jan 2004 22:26:16 -0800 Subject: [PATCH] Prevent PCI driver registration failure oopsing Greg, As discussed about six or so months ago, we agreed to hold off this patch until fairly late, due to its ability to catch duplicate PCI driver names. Please note that I haven't attempted to reproduce the problem with recent kernels, and that all ARM kernel patches released since then have had this patch in. I'm guessing this will actually be 2.6.1 material since it probably doesn't show for PCI drivers which are part of the kernel tree. If pci_register_driver fails, the register the PCI driver structure will not be registered with the driver model. pci_register_driver returns with negative value, and we then attempt to unregister the driver structure. This leads to an oops in the driver model. The driver model does not return the number of devices it successfully bound the driver to, and neither does pci_register_driver() return this information. Therefore, all of the code below is redundant. (There's a little redundancy left in drivers/pci/pci-driver.c but it is harmless unlike this block.) --- include/linux/pci.h | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index b88b9d3f5bfc..d6a87a2eb263 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -785,26 +785,7 @@ static inline int pci_module_init(struct pci_driver *drv) { int rc = pci_register_driver (drv); - if (rc > 0) - return 0; - - /* iff CONFIG_HOTPLUG and built into kernel, we should - * leave the driver around for future hotplug events. - * For the module case, a hotplug daemon of some sort - * should load a module in response to an insert event. */ -#if defined(CONFIG_HOTPLUG) && !defined(MODULE) - if (rc == 0) - return 0; -#else - if (rc == 0) - rc = -ENODEV; -#endif - - /* if we get here, we need to clean up pci driver instance - * and return some sort of error */ - pci_unregister_driver (drv); - - return rc; + return rc < 0 ? rc : 0; } /* -- cgit v1.2.3 From 68b308e82cafcd64e2a102b410b8db3077aae44d Mon Sep 17 00:00:00 2001 From: Matthew Dobson Date: Wed, 28 Jan 2004 22:28:51 -0800 Subject: [PATCH] PCI: add pci_bus sysfs class This is needed to show pci bus topology to userspace properly. --- drivers/pci/bus.c | 2 + drivers/pci/probe.c | 114 ++++++++++++++++++++++++++++++++++++---------------- include/linux/pci.h | 6 ++- 3 files changed, 85 insertions(+), 37 deletions(-) (limited to 'include/linux') diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index ea4b43068b23..969ec4237fb2 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -116,6 +116,8 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus) list_add_tail(&dev->subordinate->node, &dev->bus->children); spin_unlock(&pci_bus_lock); pci_bus_add_devices(dev->subordinate); + + sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge"); } } } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 9c91eaf646e3..749ddecd47af 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -6,6 +6,7 @@ #include #include #include +#include #undef DEBUG @@ -24,6 +25,39 @@ EXPORT_SYMBOL(pci_root_buses); LIST_HEAD(pci_devices); +/* + * PCI Bus Class + */ +static void release_pcibus_dev(struct class_device *class_dev) +{ + struct pci_bus *pci_bus = to_pci_bus(class_dev); + if (pci_bus->bridge) + put_device(pci_bus->bridge); + kfree(pci_bus); +} + +static struct class pcibus_class = { + .name = "pci_bus", + .release = &release_pcibus_dev, +}; + +static int __init pcibus_class_init(void) +{ + return class_register(&pcibus_class); +} +postcore_initcall(pcibus_class_init); + +/* + * PCI Bus Class Devices + */ +static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, char *buf) +{ + cpumask_t cpumask = pcibus_to_cpumask((to_pci_bus(class_dev))->number); + + return sprintf(buf, "%lx\n", (unsigned long)cpumask); +} +static CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL); + /* * Translate the low bits of the PCI base * to the resource type @@ -238,37 +272,40 @@ static struct pci_bus * __devinit pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) { struct pci_bus *child; + int i; /* * Allocate a new bus, and inherit stuff from the parent.. */ child = pci_alloc_bus(); + if (!child) + return NULL; - if (child) { - int i; - - child->self = bridge; - child->parent = parent; - child->ops = parent->ops; - child->sysdata = parent->sysdata; - child->dev = &bridge->dev; + child->self = bridge; + child->parent = parent; + child->ops = parent->ops; + child->sysdata = parent->sysdata; + child->bridge = get_device(&bridge->dev); - /* - * Set up the primary, secondary and subordinate - * bus numbers. - */ - child->number = child->secondary = busnr; - child->primary = parent->secondary; - child->subordinate = 0xff; - - /* Set up default resource pointers and names.. */ - for (i = 0; i < 4; i++) { - child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; - child->resource[i]->name = child->name; - } + child->class_dev.class = &pcibus_class; + sprintf(child->class_dev.class_id, "%04x:%02x", pci_domain_nr(child), busnr); + class_device_register(&child->class_dev); + class_device_create_file(&child->class_dev, &class_device_attr_cpuaffinity); - bridge->subordinate = child; + /* + * Set up the primary, secondary and subordinate + * bus numbers. + */ + child->number = child->secondary = busnr; + child->primary = parent->secondary; + child->subordinate = 0xff; + + /* Set up default resource pointers and names.. */ + for (i = 0; i < 4; i++) { + child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; + child->resource[i]->name = child->name; } + bridge->subordinate = child; return child; } @@ -307,18 +344,17 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max pci_name(dev), buses & 0xffffff, pass); if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus) { - unsigned int cmax; + unsigned int cmax, busnr; /* * Bus already configured by firmware, process it in the first * pass and just note the configuration. */ if (pass) return max; - child = pci_alloc_child_bus(bus, dev, 0); + busnr = (buses >> 8) & 0xFF; + child = pci_alloc_child_bus(bus, dev, busnr); child->primary = buses & 0xFF; - child->secondary = (buses >> 8) & 0xFF; child->subordinate = (buses >> 16) & 0xFF; - child->number = child->secondary; cmax = pci_scan_child_bus(child); if (cmax > max) max = cmax; } else { @@ -508,7 +544,7 @@ pci_scan_device(struct pci_bus *bus, int devfn) memset(dev, 0, sizeof(struct pci_dev)); dev->bus = bus; dev->sysdata = bus->sysdata; - dev->dev.parent = bus->dev; + dev->dev.parent = bus->bridge; dev->dev.bus = &pci_bus_type; dev->devfn = devfn; dev->hdr_type = hdr_type & 0x7f; @@ -635,13 +671,14 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) { struct pci_bus *b; + struct device *dev; b = pci_alloc_bus(); if (!b) return NULL; - b->dev = kmalloc(sizeof(*(b->dev)),GFP_KERNEL); - if (!b->dev){ + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (!dev){ kfree(b); return NULL; } @@ -652,17 +689,24 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, if (pci_find_bus(pci_domain_nr(b), bus)) { /* If we already got to this bus through a different bridge, ignore it */ DBG("PCI: Bus %02x already known\n", bus); - kfree(b->dev); + kfree(dev); kfree(b); return NULL; } - list_add_tail(&b->node, &pci_root_buses); - memset(b->dev,0,sizeof(*(b->dev))); - b->dev->parent = parent; - sprintf(b->dev->bus_id,"pci%04x:%02x", pci_domain_nr(b), bus); - device_register(b->dev); + memset(dev, 0, sizeof(*dev)); + dev->parent = parent; + sprintf(dev->bus_id, "pci%04x:%02x", pci_domain_nr(b), bus); + device_register(dev); + b->bridge = get_device(dev); + + b->class_dev.class = &pcibus_class; + sprintf(b->class_dev.class_id, "%04x:%02x", pci_domain_nr(b), bus); + class_device_register(&b->class_dev); + class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity); + + sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge"); b->number = b->secondary = bus; b->resource[0] = &ioport_resource; diff --git a/include/linux/pci.h b/include/linux/pci.h index d6a87a2eb263..33980d0a753c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -473,10 +473,12 @@ struct pci_bus { char name[48]; - struct device * dev; + struct device *bridge; + struct class_device class_dev; }; -#define pci_bus_b(n) list_entry(n, struct pci_bus, node) +#define pci_bus_b(n) list_entry(n, struct pci_bus, node) +#define to_pci_bus(n) container_of(n, struct pci_bus, class_dev) /* * Error values that may be returned by PCI functions. -- cgit v1.2.3 From 9648e089aaba09d60282558c69e598ae40254160 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 28 Jan 2004 22:32:13 -0800 Subject: [PATCH] PCI: add pci_get_slot() function tg3.c has a bug where it can find the wrong 5704 peer on a machine with PCI domains. The problem is that pci_find_slot() can't distinguish whether it has the correct domain or not. This patch fixes that problem by introducing pci_get_slot(). --- drivers/pci/search.c | 36 ++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 2 ++ 2 files changed, 38 insertions(+) (limited to 'include/linux') diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 366f1f16fb2f..aa900b17f2f7 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -103,6 +103,41 @@ pci_find_slot(unsigned int bus, unsigned int devfn) return NULL; } +/** + * pci_get_slot - locate PCI device for a given PCI slot + * @bus: PCI bus on which desired PCI device resides + * @devfn: encodes number of PCI slot in which the desired PCI + * device resides and the logical device number within that slot + * in case of multi-function devices. + * + * Given a PCI bus and slot/function number, the desired PCI device + * is located in the list of PCI devices. + * If the device is found, its reference count is increased and this + * function returns a pointer to its data structure. The caller must + * decrement the reference count by calling pci_dev_put(). + * If no device is found, %NULL is returned. + */ +struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) +{ + struct list_head *tmp; + struct pci_dev *dev; + + WARN_ON(in_interrupt()); + spin_lock(&pci_bus_lock); + + list_for_each(tmp, &bus->children) { + dev = pci_dev_b(tmp); + if (dev->devfn == devfn) + goto out; + } + + dev = NULL; + out: + pci_dev_get(dev); + spin_unlock(&pci_bus_lock); + return dev; +} + /** * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids @@ -319,3 +354,4 @@ EXPORT_SYMBOL(pci_find_slot); EXPORT_SYMBOL(pci_find_subsys); EXPORT_SYMBOL(pci_get_device); EXPORT_SYMBOL(pci_get_subsys); +EXPORT_SYMBOL(pci_get_slot); diff --git a/include/linux/pci.h b/include/linux/pci.h index 33980d0a753c..4178a8b148bb 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -614,6 +614,8 @@ struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from); +struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); + int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val); int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val); int pci_bus_read_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 *val); -- cgit v1.2.3 From b323e1dfd14fa4fed77f9360f16e80f23ed917f3 Mon Sep 17 00:00:00 2001 From: John Rose Date: Thu, 29 Jan 2004 00:54:22 -0800 Subject: [PATCH] PCI: Allow pci hotplug drivers to initialize individual devices. This lets the PPC pci hotplug driver initialize single devices, not just entire slots. --- drivers/pci/probe.c | 66 ++++++++++++++++++++++++++++++++--------------------- include/linux/pci.h | 1 + 2 files changed, 41 insertions(+), 26 deletions(-) (limited to 'include/linux') diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index be87193cff59..50391a0fd11e 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -580,6 +580,30 @@ pci_scan_device(struct pci_bus *bus, int devfn) return dev; } +struct pci_dev * __devinit +pci_scan_single_device(struct pci_bus *bus, int devfn) +{ + struct pci_dev *dev; + + dev = pci_scan_device(bus, devfn); + pci_scan_msi_device(dev); + + if (!dev) + return NULL; + + /* Fix up broken headers */ + pci_fixup_device(PCI_FIXUP_HEADER, dev); + + /* + * Add the device to our list of discovered devices + * and the bus list for fixup functions, etc. + */ + INIT_LIST_HEAD(&dev->global_list); + list_add_tail(&dev->bus_list, &bus->devices); + + return dev; +} + /** * pci_scan_slot - scan a PCI slot on a bus for devices. * @bus: PCI bus to scan @@ -596,34 +620,23 @@ int __devinit pci_scan_slot(struct pci_bus *bus, int devfn) for (func = 0; func < 8; func++, devfn++) { struct pci_dev *dev; - dev = pci_scan_device(bus, devfn); - pci_scan_msi_device(dev); - if (func == 0) { - if (!dev) - break; + dev = pci_scan_single_device(bus, devfn); + if (dev) { + nr++; + + /* + * If this is a single function device, + * don't scan past the first function. + */ + if (!dev->multifunction) + if (func > 0) + dev->multifunction = 1; + else + break; } else { - if (!dev) - continue; - dev->multifunction = 1; + if (func == 0) + break; } - - /* Fix up broken headers */ - pci_fixup_device(PCI_FIXUP_HEADER, dev); - - /* - * Add the device to our list of discovered devices - * and the bus list for fixup functions, etc. - */ - INIT_LIST_HEAD(&dev->global_list); - list_add_tail(&dev->bus_list, &bus->devices); - nr++; - - /* - * If this is a single function device, - * don't scan past the first function. - */ - if (!dev->multifunction) - break; } return nr; } @@ -734,4 +747,5 @@ EXPORT_SYMBOL(pci_add_new_bus); EXPORT_SYMBOL(pci_do_scan_bus); EXPORT_SYMBOL(pci_scan_slot); EXPORT_SYMBOL(pci_scan_bridge); +EXPORT_SYMBOL(pci_scan_single_device); #endif diff --git a/include/linux/pci.h b/include/linux/pci.h index 4178a8b148bb..3ffb95a8f4d2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -587,6 +587,7 @@ static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *s return pci_scan_bus_parented(NULL, bus, ops, sysdata); } int pci_scan_slot(struct pci_bus *bus, int devfn); +struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); void pci_bus_add_devices(struct pci_bus *bus); void pci_name_device(struct pci_dev *dev); char *pci_class_name(u32 class); -- cgit v1.2.3 From 6a1bd1266701eb84c11c5da96ec03fb1c0debc2c Mon Sep 17 00:00:00 2001 From: Kieran Morrissey Date: Thu, 29 Jan 2004 01:12:59 -0800 Subject: [PATCH] PCI: name length change - Changes gen-devlist.c to truncate long device names rather than reject the database - Changes PCI_NAME_SIZE to 96 (and PCI_NAME_HALF to 43) to allow all current pci.ids names to fit - Modifies gen-devlist.c to truncate at 89 characters rather than 79 - allows for two digit instance numbers to be added to the name as well while staying within the 96 characters allocated. No names in the current pci.ids are any longer than this. - Modifies names.c to no longer limit device name length when displaying both vendor and device name; the truncation is done by gen-devlist.c. --- drivers/pci/gen-devlist.c | 16 +++++++++------- drivers/pci/names.c | 3 +-- include/linux/pci.h | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/drivers/pci/gen-devlist.c b/drivers/pci/gen-devlist.c index c0c242010eba..372e2102581d 100644 --- a/drivers/pci/gen-devlist.c +++ b/drivers/pci/gen-devlist.c @@ -7,12 +7,13 @@ #include #include -#define MAX_NAME_SIZE 79 +#define MAX_NAME_SIZE 89 static void -pq(FILE *f, const char *c) +pq(FILE *f, const char *c, int len) { - while (*c) { + int i = 1; + while (*c && i != len) { if (*c == '"') fprintf(f, "\\\""); else { @@ -23,6 +24,7 @@ pq(FILE *f, const char *c) } } c++; + i++; } } @@ -72,13 +74,13 @@ main(void) if (bra && bra > c && bra[-1] == ' ') bra[-1] = 0; if (vendor_len + strlen(c) + 1 > MAX_NAME_SIZE) { - fprintf(stderr, "Line %d: Device name too long\n", lino); + fprintf(stderr, "Line %d: Device name too long. Name truncated.\n", lino); fprintf(stderr, "%s\n", c); - return 1; + /*return 1;*/ } } fprintf(devf, "\tDEVICE(%s,%s,\"", vend, line+1); - pq(devf, c); + pq(devf, c, MAX_NAME_SIZE - vendor_len - 1); fputs("\")\n", devf); } else goto err; break; @@ -107,7 +109,7 @@ main(void) return 1; } fprintf(devf, "VENDOR(%s,\"", vend); - pq(devf, c); + pq(devf, c, 0); fputs("\")\n", devf); mode = 1; } else { diff --git a/drivers/pci/names.c b/drivers/pci/names.c index eb707bf79dda..ad224aada7c9 100644 --- a/drivers/pci/names.c +++ b/drivers/pci/names.c @@ -86,8 +86,7 @@ void __devinit pci_name_device(struct pci_dev *dev) /* Full match */ match_device: { - char *n = name + sprintf(name, "%." PCI_NAME_HALF - "s %." PCI_NAME_HALF "s", + char *n = name + sprintf(name, "%s %s", vendor_p->name, device_p->name); int nr = device_p->seen + 1; device_p->seen = nr; diff --git a/include/linux/pci.h b/include/linux/pci.h index 3ffb95a8f4d2..bc51ca9edef1 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -425,8 +425,8 @@ struct pci_dev { unsigned int transparent:1; /* Transparent PCI bridge */ unsigned int multifunction:1;/* Part of multi-function device */ #ifdef CONFIG_PCI_NAMES -#define PCI_NAME_SIZE 50 -#define PCI_NAME_HALF __stringify(20) /* less than half to handle slop */ +#define PCI_NAME_SIZE 96 +#define PCI_NAME_HALF __stringify(43) /* less than half to handle slop */ char pretty_name[PCI_NAME_SIZE]; /* pretty name for users to see */ #endif }; -- cgit v1.2.3 From 13bbb0504ae0b319dc7082c1a746db622f068f79 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 30 Jan 2004 17:56:46 -0800 Subject: [PATCH] ppc64: fixes for compile with CONFIG_PROC_DEVICETREE=n, from Nathan Lynch From: Anton Blanchard - nop out proc_device_tree_add_node if CONFIG_PROC_DEVICETREE=n - stubs for procfs-related functions when CONFIG_PROC_DEVICETREE=n --- arch/ppc64/kernel/prom.c | 12 ++++++++++++ include/linux/proc_fs.h | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index fc8cf79ca315..6ca6e63cd5f3 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -2560,6 +2560,7 @@ int of_remove_node(struct device_node *np) return 0; } +#ifdef CONFIG_PROC_DEVICETREE /* * Add a node to /proc/device-tree. */ @@ -2592,6 +2593,17 @@ static void remove_node_proc_entries(struct device_node *np) if (np->pde) remove_proc_entry(np->pde->name, parent->pde); } +#else /* !CONFIG_PROC_DEVICETREE */ +static void add_node_proc_entries(struct device_node *np) +{ + return; +} + +static void remove_node_proc_entries(struct device_node *np) +{ + return; +} +#endif /* CONFIG_PROC_DEVICETREE */ /* * Fix up the uninitialized fields in a new device node: diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 2b3c8dadb1fb..8b8a6c0b37f3 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -133,8 +133,14 @@ extern void proc_tty_unregister_driver(struct tty_driver *driver); */ struct device_node; extern void proc_device_tree_init(void); +#ifdef CONFIG_PROC_DEVICETREE extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *); - +#else /* !CONFIG_PROC_DEVICETREE */ +static inline void proc_device_tree_add_node(struct device_node *np, struct proc_dir_entry *pde) +{ + return; +} +#endif /* CONFIG_PROC_DEVICETREE */ /* * proc_rtas.c */ -- cgit v1.2.3 From a50de1c422207d617a063da7c89d25593c362705 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 31 Jan 2004 20:50:52 -0800 Subject: [PATCH] fix issues with loading PCI IDE drivers as modules From: Davin McCall Set hwif->chipset to ide_forced if it was forced by kernel parameters. Set hwif->chipset to ide_generic for hwifs controlled by generic IDE code, so they wont be taken by setup_pci.c:ide_match_hwif(). Patch also fixes /proc/ide/ideX/model to report "generic" instead of "(none)" for default hwifs. This has been in -mm since 2.6.1-mm1. --- drivers/ide/ide-probe.c | 2 ++ drivers/ide/ide-proc.c | 4 +++- drivers/ide/ide.c | 2 +- drivers/ide/pci/cmd640.c | 2 +- drivers/ide/setup-pci.c | 2 +- include/linux/ide.h | 2 +- 6 files changed, 9 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index ef80249cda49..59d3da8c6e48 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1343,6 +1343,8 @@ int ideprobe_init (void) int unit; if (!hwif->present) continue; + if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced) + hwif->chipset = ide_generic; for (unit = 0; unit < MAX_DRIVES; ++unit) if (hwif->drives[unit].present) ata_attach(&hwif->drives[unit]); diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 49b754b86efa..323eeb79f0eb 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -348,8 +348,10 @@ static int proc_ide_read_imodel int len; const char *name; + /* + * Neither ide_unknown nor ide_forced should be set at this point. + */ switch (hwif->chipset) { - case ide_unknown: name = "(none)"; break; case ide_generic: name = "generic"; break; case ide_pci: name = "pci"; break; case ide_cmd640: name = "cmd640"; break; diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index bf2282aa9c7a..01134b2e1bb0 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -2179,7 +2179,7 @@ int __init ide_setup (char *s) memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->irq = vals[2]; hwif->noprobe = 0; - hwif->chipset = ide_generic; + hwif->chipset = ide_forced; goto done; case 0: goto bad_option; diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index 08a74cdb6605..0eac8ee64d2e 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c @@ -419,7 +419,7 @@ static void __init setup_device_ptrs (void) cmd_hwif1 = &ide_hwifs[1]; /* default, if not found below */ for (i = 0; i < MAX_HWIFS; i++) { ide_hwif_t *hwif = &ide_hwifs[i]; - if (hwif->chipset == ide_unknown || hwif->chipset == ide_generic) { + if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced) { if (hwif->io_ports[IDE_DATA_OFFSET] == 0x1f0) cmd_hwif0 = hwif; else if (hwif->io_ports[IDE_DATA_OFFSET] == 0x170) diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index e0ed9c0493f9..a2ff75859e45 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -59,7 +59,7 @@ static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char for (h = 0; h < MAX_HWIFS; ++h) { hwif = &ide_hwifs[h]; if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) { - if (hwif->chipset == ide_generic) + if (hwif->chipset == ide_forced) return hwif; /* a perfect match */ } } diff --git a/include/linux/ide.h b/include/linux/ide.h index a9c107b8716d..ea10e916d9eb 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -279,7 +279,7 @@ typedef enum { ide_unknown, ide_generic, ide_pci, ide_pdc4030, ide_rz1000, ide_trm290, ide_cmd646, ide_cy82c693, ide_4drives, ide_pmac, ide_etrax100, ide_acorn, - ide_pc9800 + ide_pc9800, ide_forced } hwif_chipset_t; /* -- cgit v1.2.3 From ff9e1135aec3bd1e9230593880e24a018dbdf789 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 1 Feb 2004 00:17:10 -0800 Subject: [COMPAT]: Fix TUNSETIFF ioctl compat, it takes an ifreq ptr not an int. Thanks to Eric Brower for spotting this. --- fs/compat_ioctl.c | 1 + include/linux/compat_ioctl.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index e8b5a1330506..b2048a804995 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -3093,6 +3093,7 @@ HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc) HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc) HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc) HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc) +HANDLE_IOCTL(TUNSETIFF, dev_ifsioc) HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl) HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl) HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl) diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h index 553442de3ecf..3c2fb5fae259 100644 --- a/include/linux/compat_ioctl.h +++ b/include/linux/compat_ioctl.h @@ -192,7 +192,6 @@ COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI) /* Big T */ COMPATIBLE_IOCTL(TUNSETNOCSUM) COMPATIBLE_IOCTL(TUNSETDEBUG) -COMPATIBLE_IOCTL(TUNSETIFF) COMPATIBLE_IOCTL(TUNSETPERSIST) COMPATIBLE_IOCTL(TUNSETOWNER) /* Big V */ -- cgit v1.2.3 From b1c76c1cb272f5dedf0264a58904b544c6ce56fb Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sun, 1 Feb 2004 02:17:14 -0800 Subject: [PATCH] fix/improve modular IDE This has been in -mm since 2.6.1-mm5 - IDE can be used as module again (compiles and works), this fixes bugzilla bugs #576 and #1700 - separate module for probing is no longer required - generic/default host driver is available as ide_generic module This contains the build fixes by Adrian Bunk and Andrew Morton. --- drivers/block/ll_rw_blk.c | 2 ++ drivers/ide/Kconfig | 6 ++++++ drivers/ide/Makefile | 38 +++++++++++++++++++++++++---------- drivers/ide/ide-generic.c | 34 +++++++++++++++++++++++++++++++ drivers/ide/ide-probe.c | 25 ++--------------------- drivers/ide/ide.c | 49 ++++++--------------------------------------- drivers/ide/legacy/Makefile | 7 ------- drivers/ide/pci/Makefile | 1 - drivers/ide/ppc/Makefile | 6 ------ include/linux/ide.h | 1 - 10 files changed, 77 insertions(+), 92 deletions(-) create mode 100644 drivers/ide/ide-generic.c delete mode 100644 drivers/ide/ppc/Makefile (limited to 'include/linux') diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index c23382abd4f5..c3974ba569ae 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -145,6 +145,8 @@ void blk_queue_activity_fn(request_queue_t *q, activity_fn *fn, void *data) q->activity_data = data; } +EXPORT_SYMBOL(blk_queue_activity_fn); + /** * blk_queue_prep_rq - set a prepare_request function for queue * @q: queue diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 7889c28de3db..f58c227813c5 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -296,6 +296,12 @@ config IDE_TASKFILE_IO comment "IDE chipset support/bugfixes" +config IDE_GENERIC + tristate "generic/default IDE chipset support" + default y + help + If unsure, say Y. + config BLK_DEV_CMD640 bool "CMD640 chipset bugfix/support" depends on X86 diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index ac76a4308ed1..488c784ce670 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -13,22 +13,38 @@ EXTRA_CFLAGS += -Idrivers/ide obj-$(CONFIG_BLK_DEV_IDE) += pci/ +ide-core-y += ide.o ide-default.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ + ide-taskfile.o + +ide-core-$(CONFIG_BLK_DEV_CMD640) += pci/cmd640.o + # Core IDE code - must come before legacy +ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o +ide-core-$(CONFIG_BLK_DEV_IDEDMA_PCI) += ide-dma.o +ide-core-$(CONFIG_BLK_DEV_IDE_TCQ) += ide-tcq.o +ide-core-$(CONFIG_PROC_FS) += ide-proc.o +ide-core-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o + +# built-in only drivers from legacy/ +ide-core-$(CONFIG_BLK_DEV_IDE_PC9800) += legacy/pc9800.o +ide-core-$(CONFIG_BLK_DEV_BUDDHA) += legacy/buddha.o +ide-core-$(CONFIG_BLK_DEV_FALCON_IDE) += legacy/falconide.o +ide-core-$(CONFIG_BLK_DEV_GAYLE) += legacy/gayle.o +ide-core-$(CONFIG_BLK_DEV_MAC_IDE) += legacy/macide.o +ide-core-$(CONFIG_BLK_DEV_Q40IDE) += legacy/q40ide.o + +# built-in only drivers from ppc/ +ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ppc/mpc8xx.o +ide-core-$(CONFIG_BLK_DEV_IDE_PMAC) += ppc/pmac.o +ide-core-$(CONFIG_BLK_DEV_IDE_SWARM) += ppc/swarm.o + +obj-$(CONFIG_BLK_DEV_IDE) += ide-core.o +obj-$(CONFIG_IDE_GENERIC) += ide-generic.o -obj-$(CONFIG_BLK_DEV_IDE) += ide-io.o ide-probe.o ide-iops.o ide-taskfile.o ide.o ide-lib.o ide-default.o obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o -obj-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o -obj-$(CONFIG_BLK_DEV_IDEDMA_PCI) += ide-dma.o -obj-$(CONFIG_BLK_DEV_IDE_TCQ) += ide-tcq.o -obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o - -ifeq ($(CONFIG_BLK_DEV_IDE),y) -obj-$(CONFIG_PROC_FS) += ide-proc.o -endif - -obj-$(CONFIG_BLK_DEV_IDE) += legacy/ ppc/ arm/ +obj-$(CONFIG_BLK_DEV_IDE) += legacy/ arm/ obj-$(CONFIG_BLK_DEV_HD) += legacy/ diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c new file mode 100644 index 000000000000..ee27933152d1 --- /dev/null +++ b/drivers/ide/ide-generic.c @@ -0,0 +1,34 @@ +/* + * generic/default IDE host driver + * + * Copyright (C) 2004 Bartlomiej Zolnierkiewicz + * This code was split off from ide.c. See it for original copyrights. + * + * May be copied or modified under the terms of the GNU General Public License. + */ + +#include +#include +#include +#include + +static int __init ide_generic_init(void) +{ + MOD_INC_USE_COUNT; + if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) + ide_get_lock(NULL, NULL); /* for atari only */ + + (void)ideprobe_init(); + + if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) + ide_release_lock(); /* for atari only */ + +#ifdef CONFIG_PROC_FS + create_proc_ide_interfaces(); +#endif + return 0; +} + +module_init(ide_generic_init); + +MODULE_LICENSE("GPL"); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 59d3da8c6e48..2d75b2cf8bb5 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1322,8 +1322,7 @@ int ideprobe_init (void) { unsigned int index; int probe[MAX_HWIFS]; - - MOD_INC_USE_COUNT; + memset(probe, 0, MAX_HWIFS * sizeof(int)); for (index = 0; index < MAX_HWIFS; ++index) probe[index] = !ide_hwifs[index].present; @@ -1350,27 +1349,7 @@ int ideprobe_init (void) ata_attach(&hwif->drives[unit]); } } - if (!ide_probe) - ide_probe = &ideprobe_init; - MOD_DEC_USE_COUNT; return 0; } -#ifdef MODULE -int init_module (void) -{ - unsigned int index; - - for (index = 0; index < MAX_HWIFS; ++index) - ide_unregister(index); - ideprobe_init(); - create_proc_ide_interfaces(); - return 0; -} - -void cleanup_module (void) -{ - ide_probe = NULL; -} -MODULE_LICENSE("GPL"); -#endif /* MODULE */ +EXPORT_SYMBOL_GPL(ideprobe_init); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 01134b2e1bb0..25b79a70ee02 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -153,7 +153,6 @@ #include #include #include -#include #include #include @@ -191,8 +190,6 @@ int noautodma = 1; EXPORT_SYMBOL(noautodma); EXPORT_SYMBOL(ide_bus_type); -int (*ide_probe)(void); - /* * This is declared extern in ide.h, for access by other IDE modules: */ @@ -443,21 +440,6 @@ u8 ide_dump_status (ide_drive_t *drive, const char *msg, u8 stat) EXPORT_SYMBOL(ide_dump_status); - - -void ide_probe_module (void) -{ - if (!ide_probe) { -#if defined(CONFIG_KMOD) && defined(CONFIG_BLK_DEV_IDE_MODULE) - (void) request_module("ide-probe-mod"); -#endif /* (CONFIG_KMOD) && (CONFIG_BLK_DEV_IDE_MODULE) */ - } else { - (void)ide_probe(); - } -} - -EXPORT_SYMBOL(ide_probe_module); - static int ide_open (struct inode * inode, struct file * filp) { return -ENXIO; @@ -1033,7 +1015,7 @@ found: hwif->chipset = hw->chipset; if (!initializing) { - ide_probe_module(); + probe_hwif_init(hwif); #ifdef CONFIG_PROC_FS create_proc_ide_interfaces(); #endif @@ -2276,28 +2258,6 @@ static void __init probe_for_hwifs (void) #endif /* CONFIG_BLK_DEV_IDEPNP */ } -void __init ide_init_builtin_drivers (void) -{ - /* - * Probe for special PCI and other "known" interface chipsets - */ - probe_for_hwifs (); - -#ifdef CONFIG_BLK_DEV_IDE - if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) - ide_get_lock(NULL, NULL); /* for atari only */ - - (void) ideprobe_init(); - - if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) - ide_release_lock(); /* for atari only */ -#endif /* CONFIG_BLK_DEV_IDE */ - -#ifdef CONFIG_PROC_FS - proc_ide_create(); -#endif -} - /* * Actually unregister the subdriver. Called with the * request lock dropped. @@ -2558,7 +2518,6 @@ EXPORT_SYMBOL(ide_fops); */ EXPORT_SYMBOL(ide_lock); -EXPORT_SYMBOL(ide_probe); struct bus_type ide_bus_type = { .name = "ide", @@ -2601,9 +2560,13 @@ int __init ide_init (void) #endif initializing = 1; - ide_init_builtin_drivers(); + /* Probe for special PCI and other "known" interface chipsets. */ + probe_for_hwifs(); initializing = 0; +#ifdef CONFIG_PROC_FS + proc_ide_create(); +#endif return 0; } diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile index 9d3feaf52fb4..ad8ae32b8193 100644 --- a/drivers/ide/legacy/Makefile +++ b/drivers/ide/legacy/Makefile @@ -2,17 +2,10 @@ obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o -obj-$(CONFIG_BLK_DEV_IDE_PC9800) += pc9800.o obj-$(CONFIG_BLK_DEV_PDC4030) += pdc4030.o obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o -obj-$(CONFIG_BLK_DEV_BUDDHA) += buddha.o -obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o -obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o -obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o -obj-$(CONFIG_BLK_DEV_Q40IDE) += q40ide.o - obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o # Last of all diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index 3d2e1213fa11..ddaee15b1d52 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile @@ -3,7 +3,6 @@ obj-$(CONFIG_BLK_DEV_ADMA100) += adma100.o obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o -obj-$(CONFIG_BLK_DEV_CMD640) += cmd640.o obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o diff --git a/drivers/ide/ppc/Makefile b/drivers/ide/ppc/Makefile deleted file mode 100644 index 6fc3fa38f1c7..000000000000 --- a/drivers/ide/ppc/Makefile +++ /dev/null @@ -1,6 +0,0 @@ - -obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += mpc8xx.o -obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o -obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o - -EXTRA_CFLAGS := -Idrivers/ide diff --git a/include/linux/ide.h b/include/linux/ide.h index ea10e916d9eb..ef73baf33fc8 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1231,7 +1231,6 @@ typedef struct ide_devices_s { */ #ifndef _IDE_C extern ide_hwif_t ide_hwifs[]; /* master data repository */ -extern int (*ide_probe)(void); extern ide_devices_t *idedisk; extern ide_devices_t *idecd; -- cgit v1.2.3