aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-acpi.c
diff options
context:
space:
mode:
authorAaron Lu <aaron.lu@intel.com>2013-08-22 22:17:54 -0400
committerTejun Heo <tj@kernel.org>2013-08-23 12:09:23 -0400
commitf1bc1e4c44b1b78fe34431936c60759b5aad5e3f (patch)
tree8412ab2e71faa0e8d55be7a4565090af6669d4fa /drivers/ata/libata-acpi.c
parent2b79c56fb41d3956f672990fe83e342a809c89ab (diff)
ata: acpi: rework the ata acpi bind support
Binding ACPI handle to SCSI device has several drawbacks, namely: 1 During ATA device initialization time, ACPI handle will be needed while SCSI devices are not created yet. So each time ACPI handle is needed, instead of retrieving the handle by ACPI_HANDLE macro, a namespace scan is performed to find the handle for the corresponding ATA device. This is inefficient, and also expose a restriction on calling path not holding any lock. 2 The binding to SCSI device tree makes code complex, while at the same time doesn't bring us any benefit. All ACPI handlings are still done in ATA module, not in SCSI. Rework the ATA ACPI binding code to bind ACPI handle to ATA transport devices(ATA port and ATA device). The binding needs to be done only once, since the ATA transport devices do not go away with hotplug. And due to this, the flush_work call in hotplug handler for ATA bay is no longer needed. Tested on an Intel test platform for binding and runtime power off for ODD(ZPODD) and hard disk; on an ASUS S400C for binding and normal boot and S3, where its SATA port node has _SDD and _GTF control methods when configured as an AHCI controller and its PATA device node has _GTF control method when configured as an IDE controller. SATA PMP binding and ATA hotplug is not tested. Signed-off-by: Aaron Lu <aaron.lu@intel.com> Tested-by: Dirk Griesbach <spamthis@freenet.de> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata/libata-acpi.c')
-rw-r--r--drivers/ata/libata-acpi.c278
1 files changed, 79 insertions, 199 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index cf4e7020adac..2377a32861dc 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -34,14 +34,6 @@ struct ata_acpi_gtf {
34 u8 tf[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */ 34 u8 tf[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
35} __packed; 35} __packed;
36 36
37/*
38 * Helper - belongs in the PCI layer somewhere eventually
39 */
40static int is_pci_dev(struct device *dev)
41{
42 return (dev->bus == &pci_bus_type);
43}
44
45static void ata_acpi_clear_gtf(struct ata_device *dev) 37static void ata_acpi_clear_gtf(struct ata_device *dev)
46{ 38{
47 kfree(dev->gtf_cache); 39 kfree(dev->gtf_cache);
@@ -49,47 +41,18 @@ static void ata_acpi_clear_gtf(struct ata_device *dev)
49} 41}
50 42
51/** 43/**
52 * ata_ap_acpi_handle - provide the acpi_handle for an ata_port
53 * @ap: the acpi_handle returned will correspond to this port
54 *
55 * Returns the acpi_handle for the ACPI namespace object corresponding to
56 * the ata_port passed into the function, or NULL if no such object exists
57 */
58acpi_handle ata_ap_acpi_handle(struct ata_port *ap)
59{
60 if (ap->flags & ATA_FLAG_ACPI_SATA)
61 return NULL;
62
63 return ap->scsi_host ?
64 DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev) : NULL;
65}
66EXPORT_SYMBOL(ata_ap_acpi_handle);
67
68/**
69 * ata_dev_acpi_handle - provide the acpi_handle for an ata_device 44 * ata_dev_acpi_handle - provide the acpi_handle for an ata_device
70 * @dev: the acpi_device returned will correspond to this port 45 * @dev: the acpi_handle returned will correspond to this device
71 * 46 *
72 * Returns the acpi_handle for the ACPI namespace object corresponding to 47 * Returns the acpi_handle for the ACPI namespace object corresponding to
73 * the ata_device passed into the function, or NULL if no such object exists 48 * the ata_device passed into the function, or NULL if no such object exists
49 * or ACPI is disabled for this device due to consecutive errors.
74 */ 50 */
75acpi_handle ata_dev_acpi_handle(struct ata_device *dev) 51acpi_handle ata_dev_acpi_handle(struct ata_device *dev)
76{ 52{
77 acpi_integer adr; 53 return dev->flags & ATA_DFLAG_ACPI_DISABLED ?
78 struct ata_port *ap = dev->link->ap; 54 NULL : ACPI_HANDLE(&dev->tdev);
79
80 if (libata_noacpi || dev->flags & ATA_DFLAG_ACPI_DISABLED)
81 return NULL;
82
83 if (ap->flags & ATA_FLAG_ACPI_SATA) {
84 if (!sata_pmp_attached(ap))
85 adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
86 else
87 adr = SATA_ADR(ap->port_no, dev->link->pmp);
88 return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), adr);
89 } else
90 return acpi_get_child(ata_ap_acpi_handle(ap), dev->devno);
91} 55}
92EXPORT_SYMBOL(ata_dev_acpi_handle);
93 56
94/* @ap and @dev are the same as ata_acpi_handle_hotplug() */ 57/* @ap and @dev are the same as ata_acpi_handle_hotplug() */
95static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) 58static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
@@ -156,10 +119,8 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
156 119
157 spin_unlock_irqrestore(ap->lock, flags); 120 spin_unlock_irqrestore(ap->lock, flags);
158 121
159 if (wait) { 122 if (wait)
160 ata_port_wait_eh(ap); 123 ata_port_wait_eh(ap);
161 flush_work(&ap->hotplug_task.work);
162 }
163} 124}
164 125
165static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) 126static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
@@ -216,37 +177,55 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
216 .uevent = ata_acpi_ap_uevent, 177 .uevent = ata_acpi_ap_uevent,
217}; 178};
218 179
219void ata_acpi_hotplug_init(struct ata_host *host) 180/* bind acpi handle to pata port */
181void ata_acpi_bind_port(struct ata_port *ap)
220{ 182{
221 int i; 183 acpi_handle host_handle = ACPI_HANDLE(ap->host->dev);
222 184
223 for (i = 0; i < host->n_ports; i++) { 185 if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_handle)
224 struct ata_port *ap = host->ports[i]; 186 return;
225 acpi_handle handle;
226 struct ata_device *dev;
227 187
228 if (!ap) 188 ACPI_HANDLE_SET(&ap->tdev, acpi_get_child(host_handle, ap->port_no));
229 continue;
230 189
231 handle = ata_ap_acpi_handle(ap); 190 if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
232 if (handle) { 191 ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
233 /* we might be on a docking station */
234 register_hotplug_dock_device(handle,
235 &ata_acpi_ap_dock_ops, ap,
236 NULL, NULL);
237 }
238 192
239 ata_for_each_dev(dev, &ap->link, ALL) { 193 /* we might be on a docking station */
240 handle = ata_dev_acpi_handle(dev); 194 register_hotplug_dock_device(ACPI_HANDLE(&ap->tdev),
241 if (!handle) 195 &ata_acpi_ap_dock_ops, ap, NULL, NULL);
242 continue; 196}
243 197
244 /* we might be on a docking station */ 198void ata_acpi_bind_dev(struct ata_device *dev)
245 register_hotplug_dock_device(handle, 199{
246 &ata_acpi_dev_dock_ops, 200 struct ata_port *ap = dev->link->ap;
247 dev, NULL, NULL); 201 acpi_handle port_handle = ACPI_HANDLE(&ap->tdev);
248 } 202 acpi_handle host_handle = ACPI_HANDLE(ap->host->dev);
203 acpi_handle parent_handle;
204 u64 adr;
205
206 /*
207 * For both sata/pata devices, host handle is required.
208 * For pata device, port handle is also required.
209 */
210 if (libata_noacpi || !host_handle ||
211 (!(ap->flags & ATA_FLAG_ACPI_SATA) && !port_handle))
212 return;
213
214 if (ap->flags & ATA_FLAG_ACPI_SATA) {
215 if (!sata_pmp_attached(ap))
216 adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
217 else
218 adr = SATA_ADR(ap->port_no, dev->link->pmp);
219 parent_handle = host_handle;
220 } else {
221 adr = dev->devno;
222 parent_handle = port_handle;
249 } 223 }
224
225 ACPI_HANDLE_SET(&dev->tdev, acpi_get_child(parent_handle, adr));
226
227 register_hotplug_dock_device(ata_dev_acpi_handle(dev),
228 &ata_acpi_dev_dock_ops, dev, NULL, NULL);
250} 229}
251 230
252/** 231/**
@@ -270,18 +249,34 @@ void ata_acpi_dissociate(struct ata_host *host)
270 struct ata_port *ap = host->ports[i]; 249 struct ata_port *ap = host->ports[i];
271 const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); 250 const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
272 251
273 if (ata_ap_acpi_handle(ap) && gtm) 252 if (ACPI_HANDLE(&ap->tdev) && gtm)
274 ata_acpi_stm(ap, gtm); 253 ata_acpi_stm(ap, gtm);
275 } 254 }
276} 255}
277 256
278static int __ata_acpi_gtm(struct ata_port *ap, acpi_handle handle, 257/**
279 struct ata_acpi_gtm *gtm) 258 * ata_acpi_gtm - execute _GTM
259 * @ap: target ATA port
260 * @gtm: out parameter for _GTM result
261 *
262 * Evaluate _GTM and store the result in @gtm.
263 *
264 * LOCKING:
265 * EH context.
266 *
267 * RETURNS:
268 * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
269 */
270int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
280{ 271{
281 struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER }; 272 struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER };
282 union acpi_object *out_obj; 273 union acpi_object *out_obj;
283 acpi_status status; 274 acpi_status status;
284 int rc = 0; 275 int rc = 0;
276 acpi_handle handle = ACPI_HANDLE(&ap->tdev);
277
278 if (!handle)
279 return -EINVAL;
285 280
286 status = acpi_evaluate_object(handle, "_GTM", NULL, &output); 281 status = acpi_evaluate_object(handle, "_GTM", NULL, &output);
287 282
@@ -317,27 +312,6 @@ static int __ata_acpi_gtm(struct ata_port *ap, acpi_handle handle,
317 return rc; 312 return rc;
318} 313}
319 314
320/**
321 * ata_acpi_gtm - execute _GTM
322 * @ap: target ATA port
323 * @gtm: out parameter for _GTM result
324 *
325 * Evaluate _GTM and store the result in @gtm.
326 *
327 * LOCKING:
328 * EH context.
329 *
330 * RETURNS:
331 * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure.
332 */
333int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
334{
335 if (ata_ap_acpi_handle(ap))
336 return __ata_acpi_gtm(ap, ata_ap_acpi_handle(ap), gtm);
337 else
338 return -EINVAL;
339}
340
341EXPORT_SYMBOL_GPL(ata_acpi_gtm); 315EXPORT_SYMBOL_GPL(ata_acpi_gtm);
342 316
343/** 317/**
@@ -374,8 +348,8 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm)
374 input.count = 3; 348 input.count = 3;
375 input.pointer = in_params; 349 input.pointer = in_params;
376 350
377 status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_STM", &input, 351 status = acpi_evaluate_object(ACPI_HANDLE(&ap->tdev), "_STM",
378 NULL); 352 &input, NULL);
379 353
380 if (status == AE_NOT_FOUND) 354 if (status == AE_NOT_FOUND)
381 return -ENOENT; 355 return -ENOENT;
@@ -850,7 +824,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
850 const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); 824 const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
851 struct ata_device *dev; 825 struct ata_device *dev;
852 826
853 if (ata_ap_acpi_handle(ap) && gtm) { 827 if (ACPI_HANDLE(&ap->tdev) && gtm) {
854 /* _GTM valid */ 828 /* _GTM valid */
855 829
856 /* restore timing parameters */ 830 /* restore timing parameters */
@@ -894,8 +868,7 @@ static int ata_acpi_choose_suspend_state(struct ata_device *dev, bool runtime)
894 d_max_in = ACPI_STATE_D3_HOT; 868 d_max_in = ACPI_STATE_D3_HOT;
895 869
896out: 870out:
897 return acpi_pm_device_sleep_state(&dev->sdev->sdev_gendev, 871 return acpi_pm_device_sleep_state(&dev->tdev, NULL, d_max_in);
898 NULL, d_max_in);
899} 872}
900 873
901static void sata_acpi_set_state(struct ata_port *ap, pm_message_t state) 874static void sata_acpi_set_state(struct ata_port *ap, pm_message_t state)
@@ -932,7 +905,7 @@ static void pata_acpi_set_state(struct ata_port *ap, pm_message_t state)
932 struct ata_device *dev; 905 struct ata_device *dev;
933 acpi_handle port_handle; 906 acpi_handle port_handle;
934 907
935 port_handle = ata_ap_acpi_handle(ap); 908 port_handle = ACPI_HANDLE(&ap->tdev);
936 if (!port_handle) 909 if (!port_handle)
937 return; 910 return;
938 911
@@ -1063,109 +1036,16 @@ void ata_acpi_on_disable(struct ata_device *dev)
1063 ata_acpi_clear_gtf(dev); 1036 ata_acpi_clear_gtf(dev);
1064} 1037}
1065 1038
1066static int compat_pci_ata(struct ata_port *ap) 1039void ata_scsi_acpi_bind(struct ata_device *dev)
1067{
1068 struct device *dev = ap->tdev.parent;
1069 struct pci_dev *pdev;
1070
1071 if (!is_pci_dev(dev))
1072 return 0;
1073
1074 pdev = to_pci_dev(dev);
1075
1076 if ((pdev->class >> 8) != PCI_CLASS_STORAGE_SATA &&
1077 (pdev->class >> 8) != PCI_CLASS_STORAGE_IDE)
1078 return 0;
1079
1080 return 1;
1081}
1082
1083static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle)
1084{
1085 if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA)
1086 return -ENODEV;
1087
1088 *handle = acpi_get_child(DEVICE_ACPI_HANDLE(ap->tdev.parent),
1089 ap->port_no);
1090
1091 if (!*handle)
1092 return -ENODEV;
1093
1094 if (__ata_acpi_gtm(ap, *handle, &ap->__acpi_init_gtm) == 0)
1095 ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
1096
1097 return 0;
1098}
1099
1100static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev,
1101 acpi_handle *handle)
1102{
1103 struct ata_device *ata_dev;
1104
1105 if (ap->flags & ATA_FLAG_ACPI_SATA) {
1106 if (!sata_pmp_attached(ap))
1107 ata_dev = &ap->link.device[sdev->id];
1108 else
1109 ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id];
1110 }
1111 else {
1112 ata_dev = &ap->link.device[sdev->id];
1113 }
1114
1115 *handle = ata_dev_acpi_handle(ata_dev);
1116
1117 if (!*handle)
1118 return -ENODEV;
1119
1120 return 0;
1121}
1122
1123static int is_ata_port(const struct device *dev)
1124{
1125 return dev->type == &ata_port_type;
1126}
1127
1128static struct ata_port *dev_to_ata_port(struct device *dev)
1129{
1130 while (!is_ata_port(dev)) {
1131 if (!dev->parent)
1132 return NULL;
1133 dev = dev->parent;
1134 }
1135 return to_ata_port(dev);
1136}
1137
1138static int ata_acpi_find_device(struct device *dev, acpi_handle *handle)
1139{
1140 struct ata_port *ap = dev_to_ata_port(dev);
1141
1142 if (!ap)
1143 return -ENODEV;
1144
1145 if (!compat_pci_ata(ap))
1146 return -ENODEV;
1147
1148 if (scsi_is_host_device(dev))
1149 return ata_acpi_bind_host(ap, handle);
1150 else if (scsi_is_sdev_device(dev)) {
1151 struct scsi_device *sdev = to_scsi_device(dev);
1152
1153 return ata_acpi_bind_device(ap, sdev, handle);
1154 } else
1155 return -ENODEV;
1156}
1157
1158static struct acpi_bus_type ata_acpi_bus = {
1159 .name = "ATA",
1160 .find_device = ata_acpi_find_device,
1161};
1162
1163int ata_acpi_register(void)
1164{ 1040{
1165 return scsi_register_acpi_bus_type(&ata_acpi_bus); 1041 acpi_handle handle = ata_dev_acpi_handle(dev);
1042 if (handle)
1043 acpi_dev_pm_add_dependent(handle, &dev->sdev->sdev_gendev);
1166} 1044}
1167 1045
1168void ata_acpi_unregister(void) 1046void ata_scsi_acpi_unbind(struct ata_device *dev)
1169{ 1047{
1170 scsi_unregister_acpi_bus_type(&ata_acpi_bus); 1048 acpi_handle handle = ata_dev_acpi_handle(dev);
1049 if (handle)
1050 acpi_dev_pm_remove_dependent(handle, &dev->sdev->sdev_gendev);
1171} 1051}