aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-05-14 14:28:16 -0400
committerJeff Garzik <jeff@garzik.org>2007-07-09 12:17:31 -0400
commitfafbae87db88a73b166d3bc3294d209207f27056 (patch)
tree158217a52a396b2be110688f23eacbe25cf1c2d7 /drivers
parent7dcca30a32aadb0520417521b0c44f42d09fe05c (diff)
libata-acpi: implement ata_acpi_associate()
* Add acpi_handle to ata_host and ata_port. Rename ata_device->obj_handle to ->acpi_handle and move it above such that it doesn't get cleared on reconfiguration. * Replace ACPI node association which ata_acpi_associate() which is called once during host initialization. Unlike the previous implementation, ata_acpi_associate() uses ATA_FLAG_ACPI_SATA to choose between IDE or SATA ACPI hierarchy and uses simple child look up instead of recursive walk to match the nodes. This is way safer and simpler. Please read the following message for more info. http://article.gmane.org/gmane.linux.ide/17554 Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-acpi.c369
-rw-r--r--drivers/ata/libata-core.c3
-rw-r--r--drivers/ata/libata.h2
3 files changed, 54 insertions, 320 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 02236739b40f..eda4263b4017 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -24,10 +24,8 @@
24#include <acpi/acmacros.h> 24#include <acpi/acmacros.h>
25#include <acpi/actypes.h> 25#include <acpi/actypes.h>
26 26
27#define SATA_ROOT_PORT(x) (((x) >> 16) & 0xffff)
28#define SATA_PORT_NUMBER(x) ((x) & 0xffff) /* or NO_PORT_MULT */
29#define NO_PORT_MULT 0xffff 27#define NO_PORT_MULT 0xffff
30#define SATA_ADR_RSVD 0xffffffff 28#define SATA_ADR(root,pmp) (((root) << 16) | (pmp))
31 29
32#define REGS_PER_GTF 7 30#define REGS_PER_GTF 7
33struct taskfile_array { 31struct taskfile_array {
@@ -42,230 +40,64 @@ static int is_pci_dev(struct device *dev)
42 return (dev->bus == &pci_bus_type); 40 return (dev->bus == &pci_bus_type);
43} 41}
44 42
45/** 43static void ata_acpi_associate_sata_port(struct ata_port *ap)
46 * sata_get_dev_handle - finds acpi_handle and PCI device.function
47 * @dev: device to locate
48 * @handle: returned acpi_handle for @dev
49 * @pcidevfn: return PCI device.func for @dev
50 *
51 * This function is somewhat SATA-specific. Or at least the
52 * PATA & SATA versions of this function are different,
53 * so it's not entirely generic code.
54 *
55 * Returns 0 on success, <0 on error.
56 */
57static int sata_get_dev_handle(struct device *dev, acpi_handle *handle,
58 acpi_integer *pcidevfn)
59{ 44{
60 struct pci_dev *pci_dev; 45 acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
61 acpi_integer addr; 46
62 47 ap->device->acpi_handle = acpi_get_child(ap->host->acpi_handle, adr);
63 if (!is_pci_dev(dev))
64 return -ENODEV;
65
66 pci_dev = to_pci_dev(dev); /* NOTE: PCI-specific */
67 /* Please refer to the ACPI spec for the syntax of _ADR. */
68 addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
69 *pcidevfn = addr;
70 *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
71 if (!*handle)
72 return -ENODEV;
73 return 0;
74} 48}
75 49
76/** 50static void ata_acpi_associate_ide_port(struct ata_port *ap)
77 * pata_get_dev_handle - finds acpi_handle and PCI device.function
78 * @dev: device to locate
79 * @handle: returned acpi_handle for @dev
80 * @pcidevfn: return PCI device.func for @dev
81 *
82 * The PATA and SATA versions of this function are different.
83 *
84 * Returns 0 on success, <0 on error.
85 */
86static int pata_get_dev_handle(struct device *dev, acpi_handle *handle,
87 acpi_integer *pcidevfn)
88{ 51{
89 unsigned int bus, devnum, func; 52 int max_devices, i;
90 acpi_integer addr;
91 acpi_handle dev_handle, parent_handle;
92 struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
93 .pointer = NULL};
94 acpi_status status;
95 struct acpi_device_info *dinfo = NULL;
96 int ret = -ENODEV;
97 struct pci_dev *pdev;
98
99 if (!is_pci_dev(dev))
100 return -ENODEV;
101
102 pdev = to_pci_dev(dev);
103
104 bus = pdev->bus->number;
105 devnum = PCI_SLOT(pdev->devfn);
106 func = PCI_FUNC(pdev->devfn);
107
108 dev_handle = DEVICE_ACPI_HANDLE(dev);
109 parent_handle = DEVICE_ACPI_HANDLE(dev->parent);
110
111 status = acpi_get_object_info(parent_handle, &buffer);
112 if (ACPI_FAILURE(status))
113 goto err;
114
115 dinfo = buffer.pointer;
116 if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
117 dinfo->address == bus) {
118 /* ACPI spec for _ADR for PCI bus: */
119 addr = (acpi_integer)(devnum << 16 | func);
120 *pcidevfn = addr;
121 *handle = dev_handle;
122 } else {
123 goto err;
124 }
125 53
126 if (!*handle) 54 ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no);
127 goto err; 55 if (!ap->acpi_handle)
128 ret = 0; 56 return;
129err:
130 kfree(dinfo);
131 return ret;
132}
133
134struct walk_info { /* can be trimmed some */
135 struct device *dev;
136 struct acpi_device *adev;
137 acpi_handle handle;
138 acpi_integer pcidevfn;
139 unsigned int drivenum;
140 acpi_handle obj_handle;
141 struct ata_port *ataport;
142 struct ata_device *atadev;
143 u32 sata_adr;
144 int status;
145 char basepath[ACPI_PATHNAME_MAX];
146 int basepath_len;
147};
148 57
149static acpi_status get_devices(acpi_handle handle, 58 max_devices = 1;
150 u32 level, void *context, void **return_value) 59 if (ap->flags & ATA_FLAG_SLAVE_POSS)
151{ 60 max_devices++;
152 acpi_status status;
153 struct walk_info *winfo = context;
154 struct acpi_buffer namebuf = {ACPI_ALLOCATE_BUFFER, NULL};
155 char *pathname;
156 struct acpi_buffer buffer;
157 struct acpi_device_info *dinfo;
158
159 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &namebuf);
160 if (status)
161 goto ret;
162 pathname = namebuf.pointer;
163
164 buffer.length = ACPI_ALLOCATE_BUFFER;
165 buffer.pointer = NULL;
166 status = acpi_get_object_info(handle, &buffer);
167 if (ACPI_FAILURE(status))
168 goto out2;
169
170 dinfo = buffer.pointer;
171
172 /* find full device path name for pcidevfn */
173 if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
174 dinfo->address == winfo->pcidevfn) {
175 if (ata_msg_probe(winfo->ataport))
176 ata_dev_printk(winfo->atadev, KERN_DEBUG,
177 ":%s: matches pcidevfn (0x%llx)\n",
178 pathname, winfo->pcidevfn);
179 strlcpy(winfo->basepath, pathname,
180 sizeof(winfo->basepath));
181 winfo->basepath_len = strlen(pathname);
182 goto out;
183 }
184 61
185 /* if basepath is not yet known, ignore this object */ 62 for (i = 0; i < max_devices; i++) {
186 if (!winfo->basepath_len) 63 struct ata_device *dev = &ap->device[i];
187 goto out;
188 64
189 /* if this object is in scope of basepath, maybe use it */ 65 dev->acpi_handle = acpi_get_child(ap->acpi_handle, i);
190 if (strncmp(pathname, winfo->basepath,
191 winfo->basepath_len) == 0) {
192 if (!(dinfo->valid & ACPI_VALID_ADR))
193 goto out;
194 if (ata_msg_probe(winfo->ataport))
195 ata_dev_printk(winfo->atadev, KERN_DEBUG,
196 "GOT ONE: (%s) root_port = 0x%llx,"
197 " port_num = 0x%llx\n", pathname,
198 SATA_ROOT_PORT(dinfo->address),
199 SATA_PORT_NUMBER(dinfo->address));
200 /* heuristics: */
201 if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT)
202 if (ata_msg_probe(winfo->ataport))
203 ata_dev_printk(winfo->atadev,
204 KERN_DEBUG, "warning: don't"
205 " know how to handle SATA port"
206 " multiplier\n");
207 if (SATA_ROOT_PORT(dinfo->address) ==
208 winfo->ataport->port_no &&
209 SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) {
210 if (ata_msg_probe(winfo->ataport))
211 ata_dev_printk(winfo->atadev,
212 KERN_DEBUG,
213 "THIS ^^^^^ is the requested"
214 " SATA drive (handle = 0x%p)\n",
215 handle);
216 winfo->sata_adr = dinfo->address;
217 winfo->obj_handle = handle;
218 }
219 } 66 }
220out:
221 kfree(dinfo);
222out2:
223 kfree(pathname);
224
225ret:
226 return status;
227} 67}
228 68
229/* Get the SATA drive _ADR object. */ 69/**
230static int get_sata_adr(struct device *dev, acpi_handle handle, 70 * ata_acpi_associate - associate ATA host with ACPI objects
231 acpi_integer pcidevfn, unsigned int drive, 71 * @host: target ATA host
232 struct ata_port *ap, 72 *
233 struct ata_device *atadev, u32 *dev_adr) 73 * Look up ACPI objects associated with @host and initialize
74 * acpi_handle fields of @host, its ports and devices accordingly.
75 *
76 * LOCKING:
77 * EH context.
78 *
79 * RETURNS:
80 * 0 on success, -errno on failure.
81 */
82void ata_acpi_associate(struct ata_host *host)
234{ 83{
235 acpi_status status; 84 int i;
236 struct walk_info *winfo;
237 int err = -ENOMEM;
238 85
239 winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL); 86 if (!is_pci_dev(host->dev) || libata_noacpi)
240 if (!winfo) 87 return;
241 goto out;
242 88
243 winfo->dev = dev; 89 host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev);
244 winfo->atadev = atadev; 90 if (!host->acpi_handle)
245 winfo->ataport = ap; 91 return;
246 if (acpi_bus_get_device(handle, &winfo->adev) < 0)
247 if (ata_msg_probe(ap))
248 ata_dev_printk(winfo->atadev, KERN_DEBUG,
249 "acpi_bus_get_device failed\n");
250 winfo->handle = handle;
251 winfo->pcidevfn = pcidevfn;
252 winfo->drivenum = drive;
253 92
254 status = acpi_get_devices(NULL, get_devices, winfo, NULL); 93 for (i = 0; i < host->n_ports; i++) {
255 if (ACPI_FAILURE(status)) { 94 struct ata_port *ap = host->ports[i];
256 if (ata_msg_probe(ap)) 95
257 ata_dev_printk(winfo->atadev, KERN_DEBUG, 96 if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA)
258 "%s: acpi_get_devices failed\n", 97 ata_acpi_associate_sata_port(ap);
259 __FUNCTION__); 98 else
260 err = -ENODEV; 99 ata_acpi_associate_ide_port(ap);
261 } else {
262 *dev_adr = winfo->sata_adr;
263 atadev->obj_handle = winfo->obj_handle;
264 err = 0;
265 } 100 }
266 kfree(winfo);
267out:
268 return err;
269} 101}
270 102
271/** 103/**
@@ -290,20 +122,15 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
290{ 122{
291 struct ata_port *ap = dev->ap; 123 struct ata_port *ap = dev->ap;
292 acpi_status status; 124 acpi_status status;
293 acpi_handle dev_handle = NULL;
294 acpi_handle chan_handle, drive_handle;
295 acpi_integer pcidevfn = 0;
296 u32 dev_adr;
297 struct acpi_buffer output; 125 struct acpi_buffer output;
298 union acpi_object *out_obj; 126 union acpi_object *out_obj;
299 struct device *gdev = ap->host->dev;
300 int err = -ENODEV; 127 int err = -ENODEV;
301 128
302 *gtf_length = 0; 129 *gtf_length = 0;
303 *gtf_address = 0UL; 130 *gtf_address = 0UL;
304 *obj_loc = 0UL; 131 *obj_loc = 0UL;
305 132
306 if (libata_noacpi) 133 if (!dev->acpi_handle)
307 return 0; 134 return 0;
308 135
309 if (ata_msg_probe(ap)) 136 if (ata_msg_probe(ap))
@@ -319,78 +146,14 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
319 goto out; 146 goto out;
320 } 147 }
321 148
322 /* Don't continue if device has no _ADR method.
323 * _GTF is intended for known motherboard devices. */
324 if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
325 err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
326 if (err < 0) {
327 if (ata_msg_probe(ap))
328 ata_dev_printk(dev, KERN_DEBUG,
329 "%s: pata_get_dev_handle failed (%d)\n",
330 __FUNCTION__, err);
331 goto out;
332 }
333 } else {
334 err = sata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
335 if (err < 0) {
336 if (ata_msg_probe(ap))
337 ata_dev_printk(dev, KERN_DEBUG,
338 "%s: sata_get_dev_handle failed (%d\n",
339 __FUNCTION__, err);
340 goto out;
341 }
342 }
343
344 /* Get this drive's _ADR info. if not already known. */
345 if (!dev->obj_handle) {
346 if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
347 /* get child objects of dev_handle == channel objects,
348 * + _their_ children == drive objects */
349 /* channel is ap->port_no */
350 chan_handle = acpi_get_child(dev_handle,
351 ap->port_no);
352 if (ata_msg_probe(ap))
353 ata_dev_printk(dev, KERN_DEBUG,
354 "%s: chan adr=%d: chan_handle=0x%p\n",
355 __FUNCTION__, ap->port_no,
356 chan_handle);
357 if (!chan_handle) {
358 err = -ENODEV;
359 goto out;
360 }
361 /* TBD: could also check ACPI object VALID bits */
362 drive_handle = acpi_get_child(chan_handle, dev->devno);
363 if (!drive_handle) {
364 err = -ENODEV;
365 goto out;
366 }
367 dev_adr = dev->devno;
368 dev->obj_handle = drive_handle;
369 } else { /* for SATA mode */
370 dev_adr = SATA_ADR_RSVD;
371 err = get_sata_adr(gdev, dev_handle, pcidevfn, 0,
372 ap, dev, &dev_adr);
373 }
374 if (err < 0 || dev_adr == SATA_ADR_RSVD ||
375 !dev->obj_handle) {
376 if (ata_msg_probe(ap))
377 ata_dev_printk(dev, KERN_DEBUG,
378 "%s: get_sata/pata_adr failed: "
379 "err=%d, dev_adr=%u, obj_handle=0x%p\n",
380 __FUNCTION__, err, dev_adr,
381 dev->obj_handle);
382 goto out;
383 }
384 }
385
386 /* Setting up output buffer */ 149 /* Setting up output buffer */
387 output.length = ACPI_ALLOCATE_BUFFER; 150 output.length = ACPI_ALLOCATE_BUFFER;
388 output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ 151 output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
389 152
390 /* _GTF has no input parameters */ 153 /* _GTF has no input parameters */
391 err = -EIO; 154 err = -EIO;
392 status = acpi_evaluate_object(dev->obj_handle, "_GTF", 155 status = acpi_evaluate_object(dev->acpi_handle, "_GTF",
393 NULL, &output); 156 NULL, &output);
394 if (ACPI_FAILURE(status)) { 157 if (ACPI_FAILURE(status)) {
395 if (ata_msg_probe(ap)) 158 if (ata_msg_probe(ap))
396 ata_dev_printk(dev, KERN_DEBUG, 159 ata_dev_printk(dev, KERN_DEBUG,
@@ -528,7 +291,7 @@ static int do_drive_set_taskfiles(struct ata_device *dev,
528 ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", 291 ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
529 __FUNCTION__, ap->port_no); 292 __FUNCTION__, ap->port_no);
530 293
531 if (libata_noacpi || !(ap->flags & ATA_FLAG_ACPI_SATA)) 294 if (!(ap->flags & ATA_FLAG_ACPI_SATA))
532 return 0; 295 return 0;
533 296
534 if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) 297 if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED))
@@ -571,8 +334,6 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
571 unsigned long gtf_address; 334 unsigned long gtf_address;
572 unsigned long obj_loc; 335 unsigned long obj_loc;
573 336
574 if (libata_noacpi)
575 return 0;
576 /* 337 /*
577 * TBD - implement PATA support. For now, 338 * TBD - implement PATA support. For now,
578 * we should not run GTF on PATA devices since some 339 * we should not run GTF on PATA devices since some
@@ -624,16 +385,12 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
624int ata_acpi_push_id(struct ata_device *dev) 385int ata_acpi_push_id(struct ata_device *dev)
625{ 386{
626 struct ata_port *ap = dev->ap; 387 struct ata_port *ap = dev->ap;
627 acpi_handle handle;
628 acpi_integer pcidevfn;
629 int err; 388 int err;
630 struct device *gdev = ap->host->dev;
631 u32 dev_adr;
632 acpi_status status; 389 acpi_status status;
633 struct acpi_object_list input; 390 struct acpi_object_list input;
634 union acpi_object in_params[1]; 391 union acpi_object in_params[1];
635 392
636 if (libata_noacpi) 393 if (!dev->acpi_handle)
637 return 0; 394 return 0;
638 395
639 if (ata_msg_probe(ap)) 396 if (ata_msg_probe(ap))
@@ -648,34 +405,6 @@ int ata_acpi_push_id(struct ata_device *dev)
648 goto out; 405 goto out;
649 } 406 }
650 407
651 /* Don't continue if device has no _ADR method.
652 * _SDD is intended for known motherboard devices. */
653 err = sata_get_dev_handle(gdev, &handle, &pcidevfn);
654 if (err < 0) {
655 if (ata_msg_probe(ap))
656 ata_dev_printk(dev, KERN_DEBUG,
657 "%s: sata_get_dev_handle failed (%d\n",
658 __FUNCTION__, err);
659 goto out;
660 }
661
662 /* Get this drive's _ADR info, if not already known */
663 if (!dev->obj_handle) {
664 dev_adr = SATA_ADR_RSVD;
665 err = get_sata_adr(gdev, handle, pcidevfn, dev->devno, ap, dev,
666 &dev_adr);
667 if (err < 0 || dev_adr == SATA_ADR_RSVD ||
668 !dev->obj_handle) {
669 if (ata_msg_probe(ap))
670 ata_dev_printk(dev, KERN_DEBUG,
671 "%s: get_sata_adr failed: "
672 "err=%d, dev_adr=%u, obj_handle=0x%p\n",
673 __FUNCTION__, err, dev_adr,
674 dev->obj_handle);
675 goto out;
676 }
677 }
678
679 /* Give the drive Identify data to the drive via the _SDD method */ 408 /* Give the drive Identify data to the drive via the _SDD method */
680 /* _SDD: set up input parameters */ 409 /* _SDD: set up input parameters */
681 input.count = 1; 410 input.count = 1;
@@ -687,7 +416,7 @@ int ata_acpi_push_id(struct ata_device *dev)
687 416
688 /* It's OK for _SDD to be missing too. */ 417 /* It's OK for _SDD to be missing too. */
689 swap_buf_le16(dev->id, ATA_ID_WORDS); 418 swap_buf_le16(dev->id, ATA_ID_WORDS);
690 status = acpi_evaluate_object(dev->obj_handle, "_SDD", &input, NULL); 419 status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL);
691 swap_buf_le16(dev->id, ATA_ID_WORDS); 420 swap_buf_le16(dev->id, ATA_ID_WORDS);
692 421
693 err = ACPI_FAILURE(status) ? -EIO : 0; 422 err = ACPI_FAILURE(status) ? -EIO : 0;
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 981b397cb46b..5a46cdebc588 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6293,6 +6293,9 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
6293 if (rc) 6293 if (rc)
6294 return rc; 6294 return rc;
6295 6295
6296 /* associate with ACPI nodes */
6297 ata_acpi_associate(host);
6298
6296 /* set cable, sata_spd_limit and report */ 6299 /* set cable, sata_spd_limit and report */
6297 for (i = 0; i < host->n_ports; i++) { 6300 for (i = 0; i < host->n_ports; i++) {
6298 struct ata_port *ap = host->ports[i]; 6301 struct ata_port *ap = host->ports[i];
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 5e2466658420..29037cd7c651 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -98,9 +98,11 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host);
98 98
99/* libata-acpi.c */ 99/* libata-acpi.c */
100#ifdef CONFIG_ATA_ACPI 100#ifdef CONFIG_ATA_ACPI
101extern void ata_acpi_associate(struct ata_host *host);
101extern int ata_acpi_exec_tfs(struct ata_port *ap); 102extern int ata_acpi_exec_tfs(struct ata_port *ap);
102extern int ata_acpi_push_id(struct ata_device *dev); 103extern int ata_acpi_push_id(struct ata_device *dev);
103#else 104#else
105static inline void ata_acpi_associate(struct ata_host *host) { }
104static inline int ata_acpi_exec_tfs(struct ata_port *ap) 106static inline int ata_acpi_exec_tfs(struct ata_port *ap)
105{ 107{
106 return 0; 108 return 0;