]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Shaohua Li <shaohua.li@intel.com> |
2 | Subject: libata hotplug to align with dock driver | |
3 | Patch-mainline: submitted 2008-08-28 | |
4 | References: fate#304731,bnc#401740 | |
5 | ||
6 | dock driver can handle ata(bay) hotplug now. dock driver already handles | |
7 | _EJ0 and _STA, so remove them. Also libata doesn't need register | |
8 | notification handler anymore. | |
9 | ||
10 | Signed-off-by: Shaohua Li <shaohua.li@intel.com> | |
11 | Signed-off-by: Holger Macht <hmacht@suse.de> | |
12 | --- | |
13 | ||
14 | diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c | |
15 | index 4b395b1..f19f643 100644 | |
16 | --- a/drivers/acpi/dock.c | |
17 | +++ b/drivers/acpi/dock.c | |
18 | @@ -738,7 +738,8 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |
19 | /* Fall back */ | |
20 | case ACPI_NOTIFY_EJECT_REQUEST: | |
21 | begin_undock(ds); | |
22 | - if (immediate_undock || surprise_removal) | |
23 | + if ((immediate_undock && !(ds->flags & DOCK_IS_ATA)) | |
24 | + || surprise_removal) | |
25 | handle_eject_request(ds, event); | |
26 | else | |
27 | dock_event(ds, event, UNDOCK_EVENT); | |
28 | diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c | |
29 | index 9330b79..97727be 100644 | |
30 | --- a/drivers/ata/libata-acpi.c | |
31 | +++ b/drivers/ata/libata-acpi.c | |
32 | @@ -120,21 +120,6 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) | |
33 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; | |
34 | } | |
35 | ||
36 | -static void ata_acpi_eject_device(acpi_handle handle) | |
37 | -{ | |
38 | - struct acpi_object_list arg_list; | |
39 | - union acpi_object arg; | |
40 | - | |
41 | - arg_list.count = 1; | |
42 | - arg_list.pointer = &arg; | |
43 | - arg.type = ACPI_TYPE_INTEGER; | |
44 | - arg.integer.value = 1; | |
45 | - | |
46 | - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0", | |
47 | - &arg_list, NULL))) | |
48 | - printk(KERN_ERR "Failed to evaluate _EJ0!\n"); | |
49 | -} | |
50 | - | |
51 | /* @ap and @dev are the same as ata_acpi_handle_hotplug() */ | |
52 | static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) | |
53 | { | |
54 | @@ -157,7 +142,6 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) | |
55 | * @ap: ATA port ACPI event occurred | |
56 | * @dev: ATA device ACPI event occurred (can be NULL) | |
57 | * @event: ACPI event which occurred | |
58 | - * @is_dock_event: boolean indicating whether the event was a dock one | |
59 | * | |
60 | * All ACPI bay / device realted events end up in this function. If | |
61 | * the event is port-wide @dev is NULL. If the event is specific to a | |
62 | @@ -171,115 +155,58 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) | |
63 | * ACPI notify handler context. May sleep. | |
64 | */ | |
65 | static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, | |
66 | - u32 event, int is_dock_event) | |
67 | + u32 event) | |
68 | { | |
69 | - char event_string[12]; | |
70 | - char *envp[] = { event_string, NULL }; | |
71 | struct ata_eh_info *ehi = &ap->link.eh_info; | |
72 | - struct kobject *kobj = NULL; | |
73 | int wait = 0; | |
74 | unsigned long flags; | |
75 | - acpi_handle handle, tmphandle; | |
76 | - unsigned long long sta; | |
77 | - acpi_status status; | |
78 | + acpi_handle handle; | |
79 | ||
80 | - if (dev) { | |
81 | - if (dev->sdev) | |
82 | - kobj = &dev->sdev->sdev_gendev.kobj; | |
83 | + if (dev) | |
84 | handle = dev->acpi_handle; | |
85 | - } else { | |
86 | - kobj = &ap->dev->kobj; | |
87 | + else | |
88 | handle = ap->acpi_handle; | |
89 | - } | |
90 | - | |
91 | - status = acpi_get_handle(handle, "_EJ0", &tmphandle); | |
92 | - if (ACPI_FAILURE(status)) | |
93 | - /* This device does not support hotplug */ | |
94 | - return; | |
95 | - | |
96 | - if (event == ACPI_NOTIFY_BUS_CHECK || | |
97 | - event == ACPI_NOTIFY_DEVICE_CHECK) | |
98 | - status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | |
99 | ||
100 | spin_lock_irqsave(ap->lock, flags); | |
101 | - | |
102 | + /* | |
103 | + * When dock driver calls into the routine, it will always use | |
104 | + * ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and | |
105 | + * ACPI_NOTIFY_EJECT_REQUEST for remove | |
106 | + */ | |
107 | switch (event) { | |
108 | case ACPI_NOTIFY_BUS_CHECK: | |
109 | case ACPI_NOTIFY_DEVICE_CHECK: | |
110 | ata_ehi_push_desc(ehi, "ACPI event"); | |
111 | ||
112 | - if (ACPI_FAILURE(status)) { | |
113 | - ata_port_printk(ap, KERN_ERR, | |
114 | - "acpi: failed to determine bay status (0x%x)\n", | |
115 | - status); | |
116 | - break; | |
117 | - } | |
118 | - | |
119 | - if (sta) { | |
120 | - ata_ehi_hotplugged(ehi); | |
121 | - ata_port_freeze(ap); | |
122 | - } else { | |
123 | - /* The device has gone - unplug it */ | |
124 | - ata_acpi_detach_device(ap, dev); | |
125 | - wait = 1; | |
126 | - } | |
127 | + ata_ehi_hotplugged(ehi); | |
128 | + ata_port_freeze(ap); | |
129 | break; | |
130 | case ACPI_NOTIFY_EJECT_REQUEST: | |
131 | ata_ehi_push_desc(ehi, "ACPI event"); | |
132 | ||
133 | - if (!is_dock_event) | |
134 | - break; | |
135 | - | |
136 | - /* undock event - immediate unplug */ | |
137 | ata_acpi_detach_device(ap, dev); | |
138 | wait = 1; | |
139 | break; | |
140 | } | |
141 | ||
142 | - /* make sure kobj doesn't go away while ap->lock is released */ | |
143 | - kobject_get(kobj); | |
144 | - | |
145 | spin_unlock_irqrestore(ap->lock, flags); | |
146 | ||
147 | - if (wait) { | |
148 | + if (wait) | |
149 | ata_port_wait_eh(ap); | |
150 | - ata_acpi_eject_device(handle); | |
151 | - } | |
152 | - | |
153 | - if (kobj && !is_dock_event) { | |
154 | - sprintf(event_string, "BAY_EVENT=%d", event); | |
155 | - kobject_uevent_env(kobj, KOBJ_CHANGE, envp); | |
156 | - } | |
157 | - | |
158 | - kobject_put(kobj); | |
159 | } | |
160 | ||
161 | static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) | |
162 | { | |
163 | struct ata_device *dev = data; | |
164 | ||
165 | - ata_acpi_handle_hotplug(dev->link->ap, dev, event, 1); | |
166 | + ata_acpi_handle_hotplug(dev->link->ap, dev, event); | |
167 | } | |
168 | ||
169 | static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data) | |
170 | { | |
171 | struct ata_port *ap = data; | |
172 | ||
173 | - ata_acpi_handle_hotplug(ap, NULL, event, 1); | |
174 | -} | |
175 | - | |
176 | -static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) | |
177 | -{ | |
178 | - struct ata_device *dev = data; | |
179 | - | |
180 | - ata_acpi_handle_hotplug(dev->link->ap, dev, event, 0); | |
181 | -} | |
182 | - | |
183 | -static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) | |
184 | -{ | |
185 | - struct ata_port *ap = data; | |
186 | - | |
187 | - ata_acpi_handle_hotplug(ap, NULL, event, 0); | |
188 | + ata_acpi_handle_hotplug(ap, NULL, event); | |
189 | } | |
190 | ||
191 | /** | |
192 | @@ -315,9 +242,6 @@ void ata_acpi_associate(struct ata_host *host) | |
193 | ata_acpi_associate_ide_port(ap); | |
194 | ||
195 | if (ap->acpi_handle) { | |
196 | - acpi_install_notify_handler(ap->acpi_handle, | |
197 | - ACPI_SYSTEM_NOTIFY, | |
198 | - ata_acpi_ap_notify, ap); | |
199 | /* we might be on a docking station */ | |
200 | register_hotplug_dock_device(ap->acpi_handle, | |
201 | ata_acpi_ap_notify_dock, ap); | |
202 | @@ -327,9 +251,6 @@ void ata_acpi_associate(struct ata_host *host) | |
203 | struct ata_device *dev = &ap->link.device[j]; | |
204 | ||
205 | if (dev->acpi_handle) { | |
206 | - acpi_install_notify_handler(dev->acpi_handle, | |
207 | - ACPI_SYSTEM_NOTIFY, | |
208 | - ata_acpi_dev_notify, dev); | |
209 | /* we might be on a docking station */ | |
210 | register_hotplug_dock_device(dev->acpi_handle, | |
211 | ata_acpi_dev_notify_dock, dev); |