]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.arch/acpi-dock-introduce-.uevent-for-devices-in-dock.patch
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / acpi-dock-introduce-.uevent-for-devices-in-dock.patch
CommitLineData
2cb7cef9
BS
1From: Shaohua Li <shaohua.li@intel.com>
2Subject: introduce .uevent for devices in dock
3Patch-mainline: submitted 2008-08-28
4References: fate#304731,bnc#401740
5
6dock's uevent reported itself, not ata. It might be difficult to find an
7ata device just according to a dock. This patch introduces docking ops
8for each device in a dock. when docking, dock driver can send device
9specific uevent. This should help dock station too (not just bay)
10
11Signed-off-by: Shaohua Li <shaohua.li@intel.com>
12Signed-off-by: Holger Macht <hmacht@suse.de>
13---
14
15diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
16index f19f643..ac7dfef 100644
17--- a/drivers/acpi/dock.c
18+++ b/drivers/acpi/dock.c
19@@ -75,7 +75,7 @@ struct dock_dependent_device {
20 struct list_head list;
21 struct list_head hotplug_list;
22 acpi_handle handle;
23- acpi_notify_handler handler;
24+ struct acpi_dock_ops *ops;
25 void *context;
26 };
27
28@@ -385,8 +385,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
29 * First call driver specific hotplug functions
30 */
31 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
32- if (dd->handler)
33- dd->handler(dd->handle, event, dd->context);
34+ if (dd->ops && dd->ops->handler)
35+ dd->ops->handler(dd->handle, event, dd->context);
36 }
37
38 /*
39@@ -409,6 +409,7 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
40 struct device *dev = &ds->dock_device->dev;
41 char event_string[13];
42 char *envp[] = { event_string, NULL };
43+ struct dock_dependent_device *dd;
44
45 if (num == UNDOCK_EVENT)
46 sprintf(event_string, "EVENT=undock");
47@@ -419,7 +420,14 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
48 * Indicate that the status of the dock station has
49 * changed.
50 */
51- kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
52+ if (num == DOCK_EVENT)
53+ kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
54+
55+ list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
56+ if (dd->ops && dd->ops->uevent)
57+ dd->ops->uevent(dd->handle, event, dd->context);
58+ if (num != DOCK_EVENT)
59+ kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
60 }
61
62 /**
63@@ -588,7 +596,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
64 /**
65 * register_hotplug_dock_device - register a hotplug function
66 * @handle: the handle of the device
67- * @handler: the acpi_notifier_handler to call after docking
68+ * @ops: handlers to call after docking
69 * @context: device specific data
70 *
71 * If a driver would like to perform a hotplug operation after a dock
72@@ -596,7 +604,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
73 * the dock driver after _DCK is executed.
74 */
75 int
76-register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
77+register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
78 void *context)
79 {
80 struct dock_dependent_device *dd;
81@@ -612,7 +620,7 @@ register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
82 list_for_each_entry(dock_station, &dock_stations, sibiling) {
83 dd = find_dock_dependent_device(dock_station, handle);
84 if (dd) {
85- dd->handler = handler;
86+ dd->ops = ops;
87 dd->context = context;
88 dock_add_hotplug_device(dock_station, dd);
89 return 0;
90diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
91index 97727be..c012307 100644
92--- a/drivers/ata/libata-acpi.c
93+++ b/drivers/ata/libata-acpi.c
94@@ -209,6 +209,46 @@ static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
95 ata_acpi_handle_hotplug(ap, NULL, event);
96 }
97
98+static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
99+ u32 event)
100+{
101+ struct kobject *kobj = NULL;
102+ char event_string[20];
103+ char *envp[] = { event_string, NULL };
104+
105+ if (dev) {
106+ if (dev->sdev)
107+ kobj = &dev->sdev->sdev_gendev.kobj;
108+ } else
109+ kobj = &ap->dev->kobj;
110+
111+ if (kobj) {
112+ snprintf(event_string, 20, "BAY_EVENT=%d", event);
113+ kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
114+ }
115+}
116+
117+static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data)
118+{
119+ ata_acpi_uevent(data, NULL, event);
120+}
121+
122+static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data)
123+{
124+ struct ata_device *dev = data;
125+ ata_acpi_uevent(dev->link->ap, dev, event);
126+}
127+
128+static struct acpi_dock_ops ata_acpi_dev_dock_ops = {
129+ .handler = ata_acpi_dev_notify_dock,
130+ .uevent = ata_acpi_dev_uevent,
131+};
132+
133+static struct acpi_dock_ops ata_acpi_ap_dock_ops = {
134+ .handler = ata_acpi_ap_notify_dock,
135+ .uevent = ata_acpi_ap_uevent,
136+};
137+
138 /**
139 * ata_acpi_associate - associate ATA host with ACPI objects
140 * @host: target ATA host
141@@ -244,7 +284,7 @@ void ata_acpi_associate(struct ata_host *host)
142 if (ap->acpi_handle) {
143 /* we might be on a docking station */
144 register_hotplug_dock_device(ap->acpi_handle,
145- ata_acpi_ap_notify_dock, ap);
146+ &ata_acpi_ap_dock_ops, ap);
147 }
148
149 for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
150@@ -253,7 +293,7 @@ void ata_acpi_associate(struct ata_host *host)
151 if (dev->acpi_handle) {
152 /* we might be on a docking station */
153 register_hotplug_dock_device(dev->acpi_handle,
154- ata_acpi_dev_notify_dock, dev);
155+ &ata_acpi_dev_dock_ops, dev);
156 }
157 }
158 }
159diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
160index a3e4705..db54c5e 100644
161--- a/drivers/pci/hotplug/acpiphp_glue.c
162+++ b/drivers/pci/hotplug/acpiphp_glue.c
163@@ -169,7 +169,9 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
164 }
165
166
167-
168+static struct acpi_dock_ops acpiphp_dock_ops = {
169+ .handler = handle_hotplug_event_func,
170+};
171
172 /* callback routine to register each ACPI PCI slot object */
173 static acpi_status
174@@ -285,7 +287,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
175 */
176 newfunc->flags &= ~FUNC_HAS_EJ0;
177 if (register_hotplug_dock_device(handle,
178- handle_hotplug_event_func, newfunc))
179+ &acpiphp_dock_ops, newfunc))
180 dbg("failed to register dock device\n");
181
182 /* we need to be notified when dock events happen
183diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
184index e5f38e5..4f5042a 100644
185--- a/include/acpi/acpi_drivers.h
186+++ b/include/acpi/acpi_drivers.h
187@@ -115,12 +115,17 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
188 /*--------------------------------------------------------------------------
189 Dock Station
190 -------------------------------------------------------------------------- */
191+struct acpi_dock_ops {
192+ acpi_notify_handler handler;
193+ acpi_notify_handler uevent;
194+};
195+
196 #if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
197 extern int is_dock_device(acpi_handle handle);
198 extern int register_dock_notifier(struct notifier_block *nb);
199 extern void unregister_dock_notifier(struct notifier_block *nb);
200 extern int register_hotplug_dock_device(acpi_handle handle,
201- acpi_notify_handler handler,
202+ struct acpi_dock_ops *ops,
203 void *context);
204 extern void unregister_hotplug_dock_device(acpi_handle handle);
205 #else
206@@ -136,7 +141,7 @@ static inline void unregister_dock_notifier(struct notifier_block *nb)
207 {
208 }
209 static inline int register_hotplug_dock_device(acpi_handle handle,
210- acpi_notify_handler handler,
211+ struct acpi_dock_ops *ops,
212 void *context)
213 {
214 return -ENODEV;