aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-15 01:05:03 -0500
committerJeff Garzik <jeff@garzik.org>2007-12-17 20:33:14 -0500
commit398e07826b24cbeb5ff2f0a178367fc9d24cd475 (patch)
tree78191583f2e1e5bb0aba9fbee8016e72285f4b31
parentc05e6ff035c1b25d17364a685432b33937d3dc23 (diff)
libata-acpi: implement dev->gtf_cache and evaluate _GTF right after _STM during resume
On certain implementations, _GTF evaluation depends on preceding _STM and both can be pretty picky about the configuration. Using _GTM result cached during controller initialization satisfies the most neurotic _STM implementation. However, libata evaluates _GTF after reset during device configuration and the hardware state can be different from what _GTF expects and can cause evaluation failure. This patch adds dev->gtf_cache and updates ata_dev_get_GTF() such that it uses the cached value if available. Cache is cleared with a call to ata_acpi_clear_gtf(). Because for SATA ACPI nodes _GTF must be evaluated after _SDD which can't be done till IDENTIFY is complete, _GTF caching from ata_acpi_on_resume() is used only for IDE ACPI nodes. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/libata-acpi.c69
-rw-r--r--include/linux/libata.h1
2 files changed, 50 insertions, 20 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index b3aeca368774..e0dd132fd490 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -41,6 +41,12 @@ static int is_pci_dev(struct device *dev)
41 return (dev->bus == &pci_bus_type); 41 return (dev->bus == &pci_bus_type);
42} 42}
43 43
44static void ata_acpi_clear_gtf(struct ata_device *dev)
45{
46 kfree(dev->gtf_cache);
47 dev->gtf_cache = NULL;
48}
49
44/** 50/**
45 * ata_acpi_associate_sata_port - associate SATA port with ACPI objects 51 * ata_acpi_associate_sata_port - associate SATA port with ACPI objects
46 * @ap: target SATA port 52 * @ap: target SATA port
@@ -327,7 +333,6 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm);
327 * ata_dev_get_GTF - get the drive bootup default taskfile settings 333 * ata_dev_get_GTF - get the drive bootup default taskfile settings
328 * @dev: target ATA device 334 * @dev: target ATA device
329 * @gtf: output parameter for buffer containing _GTF taskfile arrays 335 * @gtf: output parameter for buffer containing _GTF taskfile arrays
330 * @ptr_to_free: pointer which should be freed
331 * 336 *
332 * This applies to both PATA and SATA drives. 337 * This applies to both PATA and SATA drives.
333 * 338 *
@@ -344,8 +349,7 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm);
344 * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't 349 * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't
345 * contain valid data. 350 * contain valid data.
346 */ 351 */
347static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, 352static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf)
348 void **ptr_to_free)
349{ 353{
350 struct ata_port *ap = dev->link->ap; 354 struct ata_port *ap = dev->link->ap;
351 acpi_status status; 355 acpi_status status;
@@ -353,6 +357,12 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
353 union acpi_object *out_obj; 357 union acpi_object *out_obj;
354 int rc = 0; 358 int rc = 0;
355 359
360 /* if _GTF is cached, use the cached value */
361 if (dev->gtf_cache) {
362 out_obj = dev->gtf_cache;
363 goto done;
364 }
365
356 /* set up output buffer */ 366 /* set up output buffer */
357 output.length = ACPI_ALLOCATE_BUFFER; 367 output.length = ACPI_ALLOCATE_BUFFER;
358 output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ 368 output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
@@ -363,6 +373,7 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
363 373
364 /* _GTF has no input parameters */ 374 /* _GTF has no input parameters */
365 status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); 375 status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output);
376 out_obj = dev->gtf_cache = output.pointer;
366 377
367 if (ACPI_FAILURE(status)) { 378 if (ACPI_FAILURE(status)) {
368 if (status != AE_NOT_FOUND) { 379 if (status != AE_NOT_FOUND) {
@@ -383,7 +394,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
383 goto out_free; 394 goto out_free;
384 } 395 }
385 396
386 out_obj = output.pointer;
387 if (out_obj->type != ACPI_TYPE_BUFFER) { 397 if (out_obj->type != ACPI_TYPE_BUFFER) {
388 ata_dev_printk(dev, KERN_WARNING, 398 ata_dev_printk(dev, KERN_WARNING,
389 "_GTF unexpected object type 0x%x\n", 399 "_GTF unexpected object type 0x%x\n",
@@ -398,18 +408,19 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
398 goto out_free; 408 goto out_free;
399 } 409 }
400 410
401 *ptr_to_free = out_obj; 411 done:
402 *gtf = (void *)out_obj->buffer.pointer;
403 rc = out_obj->buffer.length / REGS_PER_GTF; 412 rc = out_obj->buffer.length / REGS_PER_GTF;
404 413 if (gtf) {
405 if (ata_msg_probe(ap)) 414 *gtf = (void *)out_obj->buffer.pointer;
406 ata_dev_printk(dev, KERN_DEBUG, "%s: returning " 415 if (ata_msg_probe(ap))
407 "gtf=%p, gtf_count=%d, ptr_to_free=%p\n", 416 ata_dev_printk(dev, KERN_DEBUG,
408 __FUNCTION__, *gtf, rc, *ptr_to_free); 417 "%s: returning gtf=%p, gtf_count=%d\n",
418 __FUNCTION__, *gtf, rc);
419 }
409 return rc; 420 return rc;
410 421
411 out_free: 422 out_free:
412 kfree(output.pointer); 423 ata_acpi_clear_gtf(dev);
413 return rc; 424 return rc;
414} 425}
415 426
@@ -533,11 +544,10 @@ static int taskfile_load_raw(struct ata_device *dev,
533static int ata_acpi_exec_tfs(struct ata_device *dev) 544static int ata_acpi_exec_tfs(struct ata_device *dev)
534{ 545{
535 struct ata_acpi_gtf *gtf = NULL; 546 struct ata_acpi_gtf *gtf = NULL;
536 void *ptr_to_free = NULL;
537 int gtf_count, i, rc; 547 int gtf_count, i, rc;
538 548
539 /* get taskfiles */ 549 /* get taskfiles */
540 gtf_count = ata_dev_get_GTF(dev, &gtf, &ptr_to_free); 550 gtf_count = ata_dev_get_GTF(dev, &gtf);
541 551
542 /* execute them */ 552 /* execute them */
543 for (i = 0, rc = 0; i < gtf_count; i++) { 553 for (i = 0, rc = 0; i < gtf_count; i++) {
@@ -551,7 +561,7 @@ static int ata_acpi_exec_tfs(struct ata_device *dev)
551 rc = tmp; 561 rc = tmp;
552 } 562 }
553 563
554 kfree(ptr_to_free); 564 ata_acpi_clear_gtf(dev);
555 565
556 if (rc == 0) 566 if (rc == 0)
557 return gtf_count; 567 return gtf_count;
@@ -644,13 +654,31 @@ void ata_acpi_on_resume(struct ata_port *ap)
644 const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); 654 const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
645 struct ata_device *dev; 655 struct ata_device *dev;
646 656
647 /* restore timing parameters */ 657 if (ap->acpi_handle && gtm) {
648 if (ap->acpi_handle && gtm) 658 /* _GTM valid */
659
660 /* restore timing parameters */
649 ata_acpi_stm(ap, gtm); 661 ata_acpi_stm(ap, gtm);
650 662
651 /* schedule _GTF */ 663 /* _GTF should immediately follow _STM so that it can
652 ata_link_for_each_dev(dev, &ap->link) 664 * use values set by _STM. Cache _GTF result and
653 dev->flags |= ATA_DFLAG_ACPI_PENDING; 665 * schedule _GTF.
666 */
667 ata_link_for_each_dev(dev, &ap->link) {
668 ata_acpi_clear_gtf(dev);
669 if (ata_dev_get_GTF(dev, NULL) >= 0)
670 dev->flags |= ATA_DFLAG_ACPI_PENDING;
671 }
672 } else {
673 /* SATA _GTF needs to be evaulated after _SDD and
674 * there's no reason to evaluate IDE _GTF early
675 * without _STM. Clear cache and schedule _GTF.
676 */
677 ata_link_for_each_dev(dev, &ap->link) {
678 ata_acpi_clear_gtf(dev);
679 dev->flags |= ATA_DFLAG_ACPI_PENDING;
680 }
681 }
654} 682}
655 683
656/** 684/**
@@ -735,4 +763,5 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
735 */ 763 */
736void ata_acpi_on_disable(struct ata_device *dev) 764void ata_acpi_on_disable(struct ata_device *dev)
737{ 765{
766 ata_acpi_clear_gtf(dev);
738} 767}
diff --git a/include/linux/libata.h b/include/linux/libata.h
index ba84d8a37545..cb91280be9bd 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -498,6 +498,7 @@ struct ata_device {
498 struct scsi_device *sdev; /* attached SCSI device */ 498 struct scsi_device *sdev; /* attached SCSI device */
499#ifdef CONFIG_ATA_ACPI 499#ifdef CONFIG_ATA_ACPI
500 acpi_handle acpi_handle; 500 acpi_handle acpi_handle;
501 union acpi_object *gtf_cache;
501#endif 502#endif
502 /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ 503 /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
503 u64 n_sectors; /* size of device, if ATA */ 504 u64 n_sectors; /* size of device, if ATA */