]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.arch/acpi-dock-introduce-.uevent-for-devices-in-dock.patch
Add a patch to fix Intel E100 wake-on-lan problems.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / acpi-dock-introduce-.uevent-for-devices-in-dock.patch
1 From: Shaohua Li <shaohua.li@intel.com>
2 Subject: introduce .uevent for devices in dock
3 Patch-mainline: submitted 2008-08-28
4 References: fate#304731,bnc#401740
5
6 dock's uevent reported itself, not ata. It might be difficult to find an
7 ata device just according to a dock. This patch introduces docking ops
8 for each device in a dock. when docking, dock driver can send device
9 specific uevent. This should help dock station too (not just bay)
10
11 Signed-off-by: Shaohua Li <shaohua.li@intel.com>
12 Signed-off-by: Holger Macht <hmacht@suse.de>
13 ---
14
15 diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
16 index 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;
90 diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
91 index 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 }
159 diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
160 index 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
183 diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
184 index 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;