Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 314426 Details for
Bug 438761
LTC:5.4:201049:DM-MP SCSI Hardware Handlers
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
ABI workaround for bus notifications
abi_workaround_for_bus_register_notification (text/plain), 7.31 KB, created by
IBM Bug Proxy
on 2008-08-16 04:21:36 UTC
(
hide
)
Description:
ABI workaround for bus notifications
Filename:
MIME Type:
Creator:
IBM Bug Proxy
Created:
2008-08-16 04:21:36 UTC
Size:
7.31 KB
patch
obsolete
>Previous patch breaks kernel ABI. > >This is the workaround to avoid the breakage. > >Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com> >----- >Index: linux-2.6.18.ppc64/include/linux/device.h >=================================================================== >--- linux-2.6.18.ppc64.orig/include/linux/device.h >+++ linux-2.6.18.ppc64/include/linux/device.h >@@ -41,8 +41,6 @@ struct bus_type { > struct klist klist_devices; > struct klist klist_drivers; > >- struct blocking_notifier_head bus_notifier; >- > struct bus_attribute * bus_attrs; > struct device_attribute * dev_attrs; > struct driver_attribute * drv_attrs; >@@ -85,6 +83,7 @@ extern int bus_register_notifier(struct > struct notifier_block *nb); > extern int bus_unregister_notifier(struct bus_type *bus, > struct notifier_block *nb); >+extern struct blocking_notifier_head *get_notifier_for_bus(struct bus_type *bus); > > /* All 4 notifers below get called with the target struct device * > * as an argument. Note that those functions are likely to be called >Index: linux-2.6.18.ppc64/drivers/base/bus.c >=================================================================== >--- linux-2.6.18.ppc64.orig/drivers/base/bus.c >+++ linux-2.6.18.ppc64/drivers/base/bus.c >@@ -671,6 +671,78 @@ static void klist_drivers_put(struct kli > put_driver(drv); > } > >+#define NUM_BUCKETS 64 >+#define MASK_BUCKETS (NUM_BUCKETS - 1) >+static struct list_head _bus_buckets[NUM_BUCKETS]; >+struct bus_type_nb { >+ struct list_head list; >+ struct bus_type *bus; >+ struct blocking_notifier_head notifier; >+}; >+ >+static void init_buckets(struct list_head *buckets) >+{ >+ unsigned int i; >+ >+ for (i = 0; i < NUM_BUCKETS; i++) >+ INIT_LIST_HEAD(buckets + i); >+} >+ >+static unsigned int hash_str(const void *bus) >+{ >+ const unsigned int hash_mult = 2654435387U; >+ unsigned int h = 0; >+ char *str = (char *) &bus; >+ int i; >+ >+ for (i = 0; i < sizeof(void *); i++) >+ h = (h + (unsigned int) str[i]) * hash_mult; >+ >+ return h & MASK_BUCKETS; >+} >+ >+static struct bus_type_nb *__get_cell(const void *bus) >+{ >+ struct bus_type_nb *cell; >+ unsigned int h = hash_str(bus); >+ >+ list_for_each_entry(cell, _bus_buckets + h, list) >+ if (cell->bus == bus) >+ return cell; >+ return NULL; >+} >+ >+static struct blocking_notifier_head *alloc_save_notifier_for_bus(struct bus_type *bus) >+{ >+ struct bus_type_nb *cell = __get_cell(bus); >+ >+ if (cell) { >+ printk(KERN_ERR "bus %p trying to reallocate notifier head\n", bus); >+ return NULL; >+ } >+ cell = kzalloc(sizeof(*cell), GFP_KERNEL); >+ if (!cell) >+ return NULL; >+ cell->bus = bus; >+ list_add(&cell->list, _bus_buckets + hash_str(bus)); >+ return &cell->notifier; >+} >+ >+static void free_notifier_for_bus(struct bus_type *bus) >+{ >+ struct bus_type_nb *cell = __get_cell(bus); >+ if (cell) { >+ list_del(&cell->list); >+ kfree(cell); >+ } >+} >+ >+struct blocking_notifier_head *get_notifier_for_bus(struct bus_type *bus) >+{ >+ struct bus_type_nb *cell = __get_cell(bus); >+ return cell ? &cell->notifier : NULL; >+} >+ > /** > * bus_register - register a bus with the system. > * @bus: bus. >@@ -681,9 +754,14 @@ static void klist_drivers_put(struct kli > */ > int bus_register(struct bus_type * bus) > { >- int retval; >+ int retval = -ENOMEM; >+ struct blocking_notifier_head *notifier_head; >+ >+ notifier_head = alloc_save_notifier_for_bus(bus); >+ if (!notifier_head) >+ goto out; > >- BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier); >+ BLOCKING_INIT_NOTIFIER_HEAD(notifier_head); > > retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name); > if (retval) >@@ -724,13 +802,23 @@ out: > > int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb) > { >- return blocking_notifier_chain_register(&bus->bus_notifier, nb); >+ struct blocking_notifier_head *notifier_head; >+ >+ notifier_head = get_notifier_for_bus(bus); >+ if (!notifier_head) >+ return 0; >+ return blocking_notifier_chain_register(notifier_head, nb); > } > EXPORT_SYMBOL_GPL(bus_register_notifier); > > int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb) > { >- return blocking_notifier_chain_unregister(&bus->bus_notifier, nb); >+ struct blocking_notifier_head *notifier_head; >+ >+ notifier_head = get_notifier_for_bus(bus); >+ if (!notifier_head) >+ return 0; >+ return blocking_notifier_chain_unregister(notifier_head, nb); > } > EXPORT_SYMBOL_GPL(bus_unregister_notifier); > >@@ -744,6 +832,7 @@ EXPORT_SYMBOL_GPL(bus_unregister_notifie > void bus_unregister(struct bus_type * bus) > { > pr_debug("bus %s: unregistering\n", bus->name); >+ free_notifier_for_bus(bus); > bus_remove_attrs(bus); > kset_unregister(&bus->drivers); > kset_unregister(&bus->devices); >@@ -752,10 +841,10 @@ void bus_unregister(struct bus_type * bu > > int __init buses_init(void) > { >+ init_buckets(_bus_buckets); > return subsystem_register(&bus_subsys); > } > >- > EXPORT_SYMBOL_GPL(bus_for_each_dev); > EXPORT_SYMBOL_GPL(bus_find_device); > EXPORT_SYMBOL_GPL(bus_for_each_drv); >Index: linux-2.6.18.ppc64/drivers/base/core.c >=================================================================== >--- linux-2.6.18.ppc64.orig/drivers/base/core.c >+++ linux-2.6.18.ppc64/drivers/base/core.c >@@ -370,9 +370,14 @@ int device_add(struct device *dev) > platform_notify(dev); > > /* notify clients of device entry (new way) */ >- if (dev->bus) >- blocking_notifier_call_chain(&dev->bus->bus_notifier, >+ if (dev->bus) { >+ struct blocking_notifier_head *notifier_head; >+ >+ notifier_head = get_notifier_for_bus(dev->bus); >+ if (notifier_head) >+ blocking_notifier_call_chain(notifier_head, > BUS_NOTIFY_ADD_DEVICE, dev); >+ } > Done: > kfree(class_name); > put_device(dev); >@@ -492,9 +497,15 @@ void device_del(struct device * dev) > if (platform_notify_remove) > platform_notify_remove(dev); > >- if (dev->bus) >- blocking_notifier_call_chain(&dev->bus->bus_notifier, >+ if (dev->bus) { >+ struct blocking_notifier_head *notifier_head; >+ >+ notifier_head = get_notifier_for_bus(dev->bus); >+ if (notifier_head) >+ blocking_notifier_call_chain(notifier_head, > BUS_NOTIFY_DEL_DEVICE, dev); >+ } >+ > device_pm_remove(dev); > kobject_uevent(&dev->kobj, KOBJ_REMOVE); > kobject_del(&dev->kobj); >Index: linux-2.6.18.ppc64/drivers/base/dd.c >=================================================================== >--- linux-2.6.18.ppc64.orig/drivers/base/dd.c >+++ linux-2.6.18.ppc64/drivers/base/dd.c >@@ -45,9 +45,14 @@ void device_bind_driver(struct device * > > pr_debug("bound device '%s' to driver '%s'\n", > dev->bus_id, dev->driver->name); >- if (dev->bus) >- blocking_notifier_call_chain(&dev->bus->bus_notifier, >+ if (dev->bus) { >+ struct blocking_notifier_head *notifier_head; >+ >+ notifier_head = get_notifier_for_bus(dev->bus); >+ if (notifier_head) >+ blocking_notifier_call_chain(notifier_head, > BUS_NOTIFY_BOUND_DRIVER, dev); >+ } > > klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); > sysfs_create_link(&dev->driver->kobj, &dev->kobj, >@@ -216,10 +221,14 @@ static void __device_release_driver(stru > sysfs_remove_link(&dev->kobj, "driver"); > klist_remove(&dev->knode_driver); > >- if (dev->bus) >- blocking_notifier_call_chain(&dev->bus->bus_notifier, >- BUS_NOTIFY_UNBIND_DRIVER, >- dev); >+ if (dev->bus) { >+ struct blocking_notifier_head *notifier_head; >+ >+ notifier_head = get_notifier_for_bus(dev->bus); >+ if (notifier_head) >+ blocking_notifier_call_chain(notifier_head, >+ BUS_NOTIFY_UNBIND_DRIVER, dev); >+ } > if (dev->bus && dev->bus->remove) > dev->bus->remove(dev); > else if (drv->remove)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 438761
:
314153
|
314154
|
314155
|
314156
|
314157
|
314158
|
314159
|
314160
|
314161
|
314162
|
314163
|
314339
| 314426 |
314828
|
314829
|
316641