The patch titled acpi: dock driver v6 has been added to the -mm tree. Its filename is acpi-dock-driver-v6.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: acpi: dock driver v6 From: Kristen Accardi <kristen.c.accardi@xxxxxxxxx> * fixed kernel oops where is_dock_device can be called on systems with no dock station from acpiphp and cause panic * finished _EJD support - dependent devices are now added/removed causing any drivers that may exist to be called during a dock. Unfortunately, I do not have a system which has drivers for any of the dependent devices on my dock, so I can't actually test this. * changed link order of the driver to make sure dock is searched for prior to any devices querying for it. * fixed bug where driver would not compile while in debug mode Open issue: still having problems tracking down a system lockup on x32 when compiled statically. Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@xxxxxxxxx> Cc: "Brown, Len" <len.brown@xxxxxxxxx> Cc: Dave Hansen <haveblue@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- drivers/acpi/dock.c | 107 ++++++++++++++++++++++++++++++++---------- drivers/acpi/scan.c | 2 2 files changed, 85 insertions(+), 24 deletions(-) diff -puN drivers/acpi/dock.c~acpi-dock-driver-v6 drivers/acpi/dock.c --- 25/drivers/acpi/dock.c~acpi-dock-driver-v6 Thu Jun 1 16:16:50 2006 +++ 25-akpm/drivers/acpi/dock.c Thu Jun 1 16:16:50 2006 @@ -190,6 +190,9 @@ static int is_dock(acpi_handle handle) */ int is_dock_device(acpi_handle handle) { + if (!dock_station) + return 0; + if (is_dock(handle) || find_dock_dependent_device(dock_station, handle)) return 1; @@ -218,6 +221,66 @@ static int dock_present(struct dock_stat return 0; } + + +/** + * dock_create_acpi_device - add new devices to acpi + * @handle - handle of the device to add + * + * This function will create a new acpi_device for the given + * handle if one does not exist already. This should cause + * acpi to scan for drivers for the given devices, and call + * matching driver's add routine. + * + * Returns a pointer to the acpi_device corresponding to the handle. + */ +static struct acpi_device * dock_create_acpi_device(acpi_handle handle) +{ + struct acpi_device *device = NULL; + struct acpi_device *parent_device; + acpi_handle parent; + int ret; + + if (acpi_bus_get_device(handle, &device)) { + /* + * no device created for this object, + * so we should create one. + */ + acpi_get_parent(handle, &parent); + if (acpi_bus_get_device(parent, &parent_device)) + parent_device = NULL; + + ret = acpi_bus_add(&device, parent_device, handle, + ACPI_BUS_TYPE_DEVICE); + if (ret) { + pr_debug("error adding bus, %x\n", + -ret); + return NULL; + } + } + return device; +} + +/** + * dock_remove_acpi_device - remove the acpi_device struct from acpi + * @handle - the handle of the device to remove + * + * Tell acpi to remove the acpi_device. This should cause any loaded + * driver to have it's remove routine called. + */ +static void dock_remove_acpi_device(acpi_handle handle) +{ + struct acpi_device *device; + int ret; + + if (acpi_bus_get_device(handle, &device)) { + ret = acpi_bus_trim(device, 1); + if (ret) + pr_debug("error removing bus, %x\n", -ret); + } +} + + /** * hotplug_dock_devices - insert or remove devices on the dock station * @ds: the dock station @@ -233,39 +296,37 @@ static void hotplug_dock_devices(struct struct dock_dependent_device *dd; spin_lock(&ds->hp_lock); + + /* + * First call driver specific hotplug functions + */ list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) { if (dd->handler) dd->handler(dd->handle, event, dd->context); } + + /* + * Now make sure that an acpi_device is created for each + * dependent device, or removed if this is an eject request. + * This will cause acpi_drivers to be stopped/started if they + * exist + */ + list_for_each_entry(dd, &ds->dependent_devices, list) { + if (event == ACPI_NOTIFY_EJECT_REQUEST) + dock_remove_acpi_device(dd->handle); + else + dock_create_acpi_device(dd->handle); + } spin_unlock(&ds->hp_lock); } - static void dock_event(struct dock_station *ds, u32 event, int num) { struct acpi_device *device; - struct acpi_device *parent_device; - acpi_handle parent; - int ret; - if (acpi_bus_get_device(ds->handle, &device)) { - /* - * no device created for this object, - * so we should create one. - */ - acpi_get_parent(ds->handle, &parent); - if (acpi_bus_get_device(parent, &parent_device)) - parent_device = NULL; - - ret = acpi_bus_add(&device, parent_device, ds->handle, - ACPI_BUS_TYPE_DEVICE); - if (ret) { - pr_debug("error adding bus, %x\n", - -ret_val); - return; - } - } - kobject_uevent(&device->kobj, num); + device = dock_create_acpi_device(ds->handle); + if (device) + kobject_uevent(&device->kobj, num); } /** @@ -674,5 +735,5 @@ static void __exit dock_exit(void) dock_remove(); } -module_init(dock_init); +postcore_initcall(dock_init); module_exit(dock_exit); diff -puN drivers/acpi/scan.c~acpi-dock-driver-v6 drivers/acpi/scan.c --- 25/drivers/acpi/scan.c~acpi-dock-driver-v6 Thu Jun 1 16:16:50 2006 +++ 25-akpm/drivers/acpi/scan.c Thu Jun 1 16:20:42 2006 @@ -670,7 +670,7 @@ acpi_bus_get_ejd(acpi_handle handle, acp if (ACPI_SUCCESS(status)) { obj = buffer.pointer; status = acpi_get_handle(NULL, obj->string.pointer, ejd); - kfree(buffer.pointer); + acpi_os_free(buffer.pointer); } return status; } _ Patches currently in -mm which might be from kristen.c.accardi@xxxxxxxxx are acpi-dock-driver.patch acpi-dock-driver-v3.patch acpi-dock-driver-v4.patch acpi-dock-driver-interface-fixups.patch acpi-dock-driver-v6.patch acpi-dock-driver-v6-fix.patch acpiphp-use-new-dock-driver.patch acpiphp-use-new-dock-driver-v2.patch acpiphp-prevent-duplicate-slot-numbers-when-no-_sun.patch fix-pciehp-compile-issue-when-config_acpi-is-not.patch fix-recovery-path-from-errors-during-pcie_init.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html