diff options
Diffstat (limited to 'drivers/ata/libata-acpi.c')
| -rw-r--r-- | drivers/ata/libata-acpi.c | 387 |
1 files changed, 270 insertions, 117 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 545ea865ceb5..7bf4befd96bc 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * Copyright (C) 2006 Randy Dunlap | 6 | * Copyright (C) 2006 Randy Dunlap |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/module.h> | ||
| 9 | #include <linux/ata.h> | 10 | #include <linux/ata.h> |
| 10 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
| 11 | #include <linux/device.h> | 12 | #include <linux/device.h> |
| @@ -25,6 +26,18 @@ | |||
| 25 | #include <acpi/acmacros.h> | 26 | #include <acpi/acmacros.h> |
| 26 | #include <acpi/actypes.h> | 27 | #include <acpi/actypes.h> |
| 27 | 28 | ||
| 29 | enum { | ||
| 30 | ATA_ACPI_FILTER_SETXFER = 1 << 0, | ||
| 31 | ATA_ACPI_FILTER_LOCK = 1 << 1, | ||
| 32 | |||
| 33 | ATA_ACPI_FILTER_DEFAULT = ATA_ACPI_FILTER_SETXFER | | ||
| 34 | ATA_ACPI_FILTER_LOCK, | ||
| 35 | }; | ||
| 36 | |||
| 37 | static unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT; | ||
| 38 | module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644); | ||
| 39 | MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock)"); | ||
| 40 | |||
| 28 | #define NO_PORT_MULT 0xffff | 41 | #define NO_PORT_MULT 0xffff |
| 29 | #define SATA_ADR(root, pmp) (((root) << 16) | (pmp)) | 42 | #define SATA_ADR(root, pmp) (((root) << 16) | (pmp)) |
| 30 | 43 | ||
| @@ -41,6 +54,12 @@ static int is_pci_dev(struct device *dev) | |||
| 41 | return (dev->bus == &pci_bus_type); | 54 | return (dev->bus == &pci_bus_type); |
| 42 | } | 55 | } |
| 43 | 56 | ||
| 57 | static void ata_acpi_clear_gtf(struct ata_device *dev) | ||
| 58 | { | ||
| 59 | kfree(dev->gtf_cache); | ||
| 60 | dev->gtf_cache = NULL; | ||
| 61 | } | ||
| 62 | |||
| 44 | /** | 63 | /** |
| 45 | * ata_acpi_associate_sata_port - associate SATA port with ACPI objects | 64 | * ata_acpi_associate_sata_port - associate SATA port with ACPI objects |
| 46 | * @ap: target SATA port | 65 | * @ap: target SATA port |
| @@ -94,6 +113,9 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) | |||
| 94 | 113 | ||
| 95 | dev->acpi_handle = acpi_get_child(ap->acpi_handle, i); | 114 | dev->acpi_handle = acpi_get_child(ap->acpi_handle, i); |
| 96 | } | 115 | } |
| 116 | |||
| 117 | if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) | ||
| 118 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; | ||
| 97 | } | 119 | } |
| 98 | 120 | ||
| 99 | static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj, | 121 | static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj, |
| @@ -188,6 +210,32 @@ void ata_acpi_associate(struct ata_host *host) | |||
| 188 | } | 210 | } |
| 189 | 211 | ||
| 190 | /** | 212 | /** |
| 213 | * ata_acpi_dissociate - dissociate ATA host from ACPI objects | ||
| 214 | * @host: target ATA host | ||
| 215 | * | ||
| 216 | * This function is called during driver detach after the whole host | ||
| 217 | * is shut down. | ||
| 218 | * | ||
| 219 | * LOCKING: | ||
| 220 | * EH context. | ||
| 221 | */ | ||
| 222 | void ata_acpi_dissociate(struct ata_host *host) | ||
| 223 | { | ||
| 224 | int i; | ||
| 225 | |||
| 226 | /* Restore initial _GTM values so that driver which attaches | ||
| 227 | * afterward can use them too. | ||
| 228 | */ | ||
| 229 | for (i = 0; i < host->n_ports; i++) { | ||
| 230 | struct ata_port *ap = host->ports[i]; | ||
| 231 | const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); | ||
| 232 | |||
| 233 | if (ap->acpi_handle && gtm) | ||
| 234 | ata_acpi_stm(ap, gtm); | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 238 | /** | ||
| 191 | * ata_acpi_gtm - execute _GTM | 239 | * ata_acpi_gtm - execute _GTM |
| 192 | * @ap: target ATA port | 240 | * @ap: target ATA port |
| 193 | * @gtm: out parameter for _GTM result | 241 | * @gtm: out parameter for _GTM result |
| @@ -200,7 +248,7 @@ void ata_acpi_associate(struct ata_host *host) | |||
| 200 | * RETURNS: | 248 | * RETURNS: |
| 201 | * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure. | 249 | * 0 on success, -ENOENT if _GTM doesn't exist, -errno on failure. |
| 202 | */ | 250 | */ |
| 203 | int ata_acpi_gtm(const struct ata_port *ap, struct ata_acpi_gtm *gtm) | 251 | int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm) |
| 204 | { | 252 | { |
| 205 | struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER }; | 253 | struct acpi_buffer output = { .length = ACPI_ALLOCATE_BUFFER }; |
| 206 | union acpi_object *out_obj; | 254 | union acpi_object *out_obj; |
| @@ -259,15 +307,16 @@ EXPORT_SYMBOL_GPL(ata_acpi_gtm); | |||
| 259 | * RETURNS: | 307 | * RETURNS: |
| 260 | * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure. | 308 | * 0 on success, -ENOENT if _STM doesn't exist, -errno on failure. |
| 261 | */ | 309 | */ |
| 262 | int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm) | 310 | int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm) |
| 263 | { | 311 | { |
| 264 | acpi_status status; | 312 | acpi_status status; |
| 313 | struct ata_acpi_gtm stm_buf = *stm; | ||
| 265 | struct acpi_object_list input; | 314 | struct acpi_object_list input; |
| 266 | union acpi_object in_params[3]; | 315 | union acpi_object in_params[3]; |
| 267 | 316 | ||
| 268 | in_params[0].type = ACPI_TYPE_BUFFER; | 317 | in_params[0].type = ACPI_TYPE_BUFFER; |
| 269 | in_params[0].buffer.length = sizeof(struct ata_acpi_gtm); | 318 | in_params[0].buffer.length = sizeof(struct ata_acpi_gtm); |
| 270 | in_params[0].buffer.pointer = (u8 *)stm; | 319 | in_params[0].buffer.pointer = (u8 *)&stm_buf; |
| 271 | /* Buffers for id may need byteswapping ? */ | 320 | /* Buffers for id may need byteswapping ? */ |
| 272 | in_params[1].type = ACPI_TYPE_BUFFER; | 321 | in_params[1].type = ACPI_TYPE_BUFFER; |
| 273 | in_params[1].buffer.length = 512; | 322 | in_params[1].buffer.length = 512; |
| @@ -297,7 +346,6 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm); | |||
| 297 | * ata_dev_get_GTF - get the drive bootup default taskfile settings | 346 | * ata_dev_get_GTF - get the drive bootup default taskfile settings |
| 298 | * @dev: target ATA device | 347 | * @dev: target ATA device |
| 299 | * @gtf: output parameter for buffer containing _GTF taskfile arrays | 348 | * @gtf: output parameter for buffer containing _GTF taskfile arrays |
| 300 | * @ptr_to_free: pointer which should be freed | ||
| 301 | * | 349 | * |
| 302 | * This applies to both PATA and SATA drives. | 350 | * This applies to both PATA and SATA drives. |
| 303 | * | 351 | * |
| @@ -311,11 +359,10 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm); | |||
| 311 | * EH context. | 359 | * EH context. |
| 312 | * | 360 | * |
| 313 | * RETURNS: | 361 | * RETURNS: |
| 314 | * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't | 362 | * Number of taskfiles on success, 0 if _GTF doesn't exist. -EINVAL |
| 315 | * contain valid data. | 363 | * if _GTF is invalid. |
| 316 | */ | 364 | */ |
| 317 | static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, | 365 | static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) |
| 318 | void **ptr_to_free) | ||
| 319 | { | 366 | { |
| 320 | struct ata_port *ap = dev->link->ap; | 367 | struct ata_port *ap = dev->link->ap; |
| 321 | acpi_status status; | 368 | acpi_status status; |
| @@ -323,6 +370,12 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, | |||
| 323 | union acpi_object *out_obj; | 370 | union acpi_object *out_obj; |
| 324 | int rc = 0; | 371 | int rc = 0; |
| 325 | 372 | ||
| 373 | /* if _GTF is cached, use the cached value */ | ||
| 374 | if (dev->gtf_cache) { | ||
| 375 | out_obj = dev->gtf_cache; | ||
| 376 | goto done; | ||
| 377 | } | ||
| 378 | |||
| 326 | /* set up output buffer */ | 379 | /* set up output buffer */ |
| 327 | output.length = ACPI_ALLOCATE_BUFFER; | 380 | output.length = ACPI_ALLOCATE_BUFFER; |
| 328 | output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ | 381 | output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ |
| @@ -333,12 +386,14 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, | |||
| 333 | 386 | ||
| 334 | /* _GTF has no input parameters */ | 387 | /* _GTF has no input parameters */ |
| 335 | status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); | 388 | status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); |
| 389 | out_obj = dev->gtf_cache = output.pointer; | ||
| 336 | 390 | ||
| 337 | if (ACPI_FAILURE(status)) { | 391 | if (ACPI_FAILURE(status)) { |
| 338 | if (status != AE_NOT_FOUND) { | 392 | if (status != AE_NOT_FOUND) { |
| 339 | ata_dev_printk(dev, KERN_WARNING, | 393 | ata_dev_printk(dev, KERN_WARNING, |
| 340 | "_GTF evaluation failed (AE 0x%x)\n", | 394 | "_GTF evaluation failed (AE 0x%x)\n", |
| 341 | status); | 395 | status); |
| 396 | rc = -EINVAL; | ||
| 342 | } | 397 | } |
| 343 | goto out_free; | 398 | goto out_free; |
| 344 | } | 399 | } |
| @@ -350,14 +405,15 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, | |||
| 350 | __FUNCTION__, | 405 | __FUNCTION__, |
| 351 | (unsigned long long)output.length, | 406 | (unsigned long long)output.length, |
| 352 | output.pointer); | 407 | output.pointer); |
| 408 | rc = -EINVAL; | ||
| 353 | goto out_free; | 409 | goto out_free; |
| 354 | } | 410 | } |
| 355 | 411 | ||
| 356 | out_obj = output.pointer; | ||
| 357 | if (out_obj->type != ACPI_TYPE_BUFFER) { | 412 | if (out_obj->type != ACPI_TYPE_BUFFER) { |
| 358 | ata_dev_printk(dev, KERN_WARNING, | 413 | ata_dev_printk(dev, KERN_WARNING, |
| 359 | "_GTF unexpected object type 0x%x\n", | 414 | "_GTF unexpected object type 0x%x\n", |
| 360 | out_obj->type); | 415 | out_obj->type); |
| 416 | rc = -EINVAL; | ||
| 361 | goto out_free; | 417 | goto out_free; |
| 362 | } | 418 | } |
| 363 | 419 | ||
| @@ -365,21 +421,23 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, | |||
| 365 | ata_dev_printk(dev, KERN_WARNING, | 421 | ata_dev_printk(dev, KERN_WARNING, |
| 366 | "unexpected _GTF length (%d)\n", | 422 | "unexpected _GTF length (%d)\n", |
| 367 | out_obj->buffer.length); | 423 | out_obj->buffer.length); |
| 424 | rc = -EINVAL; | ||
| 368 | goto out_free; | 425 | goto out_free; |
| 369 | } | 426 | } |
| 370 | 427 | ||
| 371 | *ptr_to_free = out_obj; | 428 | done: |
| 372 | *gtf = (void *)out_obj->buffer.pointer; | ||
| 373 | rc = out_obj->buffer.length / REGS_PER_GTF; | 429 | rc = out_obj->buffer.length / REGS_PER_GTF; |
| 374 | 430 | if (gtf) { | |
| 375 | if (ata_msg_probe(ap)) | 431 | *gtf = (void *)out_obj->buffer.pointer; |
| 376 | ata_dev_printk(dev, KERN_DEBUG, "%s: returning " | 432 | if (ata_msg_probe(ap)) |
| 377 | "gtf=%p, gtf_count=%d, ptr_to_free=%p\n", | 433 | ata_dev_printk(dev, KERN_DEBUG, |
| 378 | __FUNCTION__, *gtf, rc, *ptr_to_free); | 434 | "%s: returning gtf=%p, gtf_count=%d\n", |
| 435 | __FUNCTION__, *gtf, rc); | ||
| 436 | } | ||
| 379 | return rc; | 437 | return rc; |
| 380 | 438 | ||
| 381 | out_free: | 439 | out_free: |
| 382 | kfree(output.pointer); | 440 | ata_acpi_clear_gtf(dev); |
| 383 | return rc; | 441 | return rc; |
| 384 | } | 442 | } |
| 385 | 443 | ||
| @@ -393,22 +451,21 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, | |||
| 393 | 451 | ||
| 394 | int ata_acpi_cbl_80wire(struct ata_port *ap) | 452 | int ata_acpi_cbl_80wire(struct ata_port *ap) |
| 395 | { | 453 | { |
| 396 | struct ata_acpi_gtm gtm; | 454 | const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); |
| 397 | int valid = 0; | 455 | int valid = 0; |
| 398 | 456 | ||
| 399 | /* No _GTM data, no information */ | 457 | if (!gtm) |
| 400 | if (ata_acpi_gtm(ap, >m) < 0) | ||
| 401 | return 0; | 458 | return 0; |
| 402 | 459 | ||
| 403 | /* Split timing, DMA enabled */ | 460 | /* Split timing, DMA enabled */ |
| 404 | if ((gtm.flags & 0x11) == 0x11 && gtm.drive[0].dma < 55) | 461 | if ((gtm->flags & 0x11) == 0x11 && gtm->drive[0].dma < 55) |
| 405 | valid |= 1; | 462 | valid |= 1; |
| 406 | if ((gtm.flags & 0x14) == 0x14 && gtm.drive[1].dma < 55) | 463 | if ((gtm->flags & 0x14) == 0x14 && gtm->drive[1].dma < 55) |
| 407 | valid |= 2; | 464 | valid |= 2; |
| 408 | /* Shared timing, DMA enabled */ | 465 | /* Shared timing, DMA enabled */ |
| 409 | if ((gtm.flags & 0x11) == 0x01 && gtm.drive[0].dma < 55) | 466 | if ((gtm->flags & 0x11) == 0x01 && gtm->drive[0].dma < 55) |
| 410 | valid |= 1; | 467 | valid |= 1; |
| 411 | if ((gtm.flags & 0x14) == 0x04 && gtm.drive[0].dma < 55) | 468 | if ((gtm->flags & 0x14) == 0x04 && gtm->drive[0].dma < 55) |
| 412 | valid |= 2; | 469 | valid |= 2; |
| 413 | 470 | ||
| 414 | /* Drive check */ | 471 | /* Drive check */ |
| @@ -421,8 +478,62 @@ int ata_acpi_cbl_80wire(struct ata_port *ap) | |||
| 421 | 478 | ||
| 422 | EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); | 479 | EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); |
| 423 | 480 | ||
| 481 | static void ata_acpi_gtf_to_tf(struct ata_device *dev, | ||
| 482 | const struct ata_acpi_gtf *gtf, | ||
| 483 | struct ata_taskfile *tf) | ||
| 484 | { | ||
| 485 | ata_tf_init(dev, tf); | ||
| 486 | |||
| 487 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
| 488 | tf->protocol = ATA_PROT_NODATA; | ||
| 489 | tf->feature = gtf->tf[0]; /* 0x1f1 */ | ||
| 490 | tf->nsect = gtf->tf[1]; /* 0x1f2 */ | ||
| 491 | tf->lbal = gtf->tf[2]; /* 0x1f3 */ | ||
| 492 | tf->lbam = gtf->tf[3]; /* 0x1f4 */ | ||
| 493 | tf->lbah = gtf->tf[4]; /* 0x1f5 */ | ||
| 494 | tf->device = gtf->tf[5]; /* 0x1f6 */ | ||
| 495 | tf->command = gtf->tf[6]; /* 0x1f7 */ | ||
| 496 | } | ||
| 497 | |||
| 498 | static int ata_acpi_filter_tf(const struct ata_taskfile *tf, | ||
| 499 | const struct ata_taskfile *ptf) | ||
| 500 | { | ||
| 501 | if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_SETXFER) { | ||
| 502 | /* libata doesn't use ACPI to configure transfer mode. | ||
| 503 | * It will only confuse device configuration. Skip. | ||
| 504 | */ | ||
| 505 | if (tf->command == ATA_CMD_SET_FEATURES && | ||
| 506 | tf->feature == SETFEATURES_XFER) | ||
| 507 | return 1; | ||
| 508 | } | ||
| 509 | |||
| 510 | if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_LOCK) { | ||
| 511 | /* BIOS writers, sorry but we don't wanna lock | ||
| 512 | * features unless the user explicitly said so. | ||
| 513 | */ | ||
| 514 | |||
| 515 | /* DEVICE CONFIGURATION FREEZE LOCK */ | ||
| 516 | if (tf->command == ATA_CMD_CONF_OVERLAY && | ||
| 517 | tf->feature == ATA_DCO_FREEZE_LOCK) | ||
| 518 | return 1; | ||
| 519 | |||
| 520 | /* SECURITY FREEZE LOCK */ | ||
| 521 | if (tf->command == ATA_CMD_SEC_FREEZE_LOCK) | ||
| 522 | return 1; | ||
| 523 | |||
| 524 | /* SET MAX LOCK and SET MAX FREEZE LOCK */ | ||
| 525 | if ((!ptf || ptf->command != ATA_CMD_READ_NATIVE_MAX) && | ||
| 526 | tf->command == ATA_CMD_SET_MAX && | ||
| 527 | (tf->feature == ATA_SET_MAX_LOCK || | ||
| 528 | tf->feature == ATA_SET_MAX_FREEZE_LOCK)) | ||
| 529 | return 1; | ||
| 530 | } | ||
| 531 | |||
| 532 | return 0; | ||
| 533 | } | ||
| 534 | |||
| 424 | /** | 535 | /** |
| 425 | * taskfile_load_raw - send taskfile registers to host controller | 536 | * ata_acpi_run_tf - send taskfile registers to host controller |
| 426 | * @dev: target ATA device | 537 | * @dev: target ATA device |
| 427 | * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) | 538 | * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) |
| 428 | * | 539 | * |
| @@ -441,56 +552,77 @@ EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); | |||
| 441 | * EH context. | 552 | * EH context. |
| 442 | * | 553 | * |
| 443 | * RETURNS: | 554 | * RETURNS: |
| 444 | * 0 on success, -errno on failure. | 555 | * 1 if command is executed successfully. 0 if ignored, rejected or |
| 556 | * filtered out, -errno on other errors. | ||
| 445 | */ | 557 | */ |
| 446 | static int taskfile_load_raw(struct ata_device *dev, | 558 | static int ata_acpi_run_tf(struct ata_device *dev, |
| 447 | const struct ata_acpi_gtf *gtf) | 559 | const struct ata_acpi_gtf *gtf, |
| 560 | const struct ata_acpi_gtf *prev_gtf) | ||
| 448 | { | 561 | { |
| 449 | struct ata_port *ap = dev->link->ap; | 562 | struct ata_taskfile *pptf = NULL; |
| 450 | struct ata_taskfile tf, rtf; | 563 | struct ata_taskfile tf, ptf, rtf; |
| 451 | unsigned int err_mask; | 564 | unsigned int err_mask; |
| 565 | const char *level; | ||
| 566 | char msg[60]; | ||
| 567 | int rc; | ||
| 452 | 568 | ||
| 453 | if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0) | 569 | if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0) |
| 454 | && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0) | 570 | && (gtf->tf[3] == 0) && (gtf->tf[4] == 0) && (gtf->tf[5] == 0) |
| 455 | && (gtf->tf[6] == 0)) | 571 | && (gtf->tf[6] == 0)) |
| 456 | return 0; | 572 | return 0; |
| 457 | 573 | ||
| 458 | ata_tf_init(dev, &tf); | 574 | ata_acpi_gtf_to_tf(dev, gtf, &tf); |
| 575 | if (prev_gtf) { | ||
| 576 | ata_acpi_gtf_to_tf(dev, prev_gtf, &ptf); | ||
| 577 | pptf = &ptf; | ||
| 578 | } | ||
| 459 | 579 | ||
| 460 | /* convert gtf to tf */ | 580 | if (!ata_acpi_filter_tf(&tf, pptf)) { |
| 461 | tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */ | 581 | rtf = tf; |
| 462 | tf.protocol = ATA_PROT_NODATA; | 582 | err_mask = ata_exec_internal(dev, &rtf, NULL, |
| 463 | tf.feature = gtf->tf[0]; /* 0x1f1 */ | 583 | DMA_NONE, NULL, 0, 0); |
| 464 | tf.nsect = gtf->tf[1]; /* 0x1f2 */ | ||
| 465 | tf.lbal = gtf->tf[2]; /* 0x1f3 */ | ||
| 466 | tf.lbam = gtf->tf[3]; /* 0x1f4 */ | ||
| 467 | tf.lbah = gtf->tf[4]; /* 0x1f5 */ | ||
| 468 | tf.device = gtf->tf[5]; /* 0x1f6 */ | ||
| 469 | tf.command = gtf->tf[6]; /* 0x1f7 */ | ||
| 470 | 584 | ||
| 471 | if (ata_msg_probe(ap)) | 585 | switch (err_mask) { |
| 472 | ata_dev_printk(dev, KERN_DEBUG, "executing ACPI cmd " | 586 | case 0: |
| 473 | "%02x/%02x:%02x:%02x:%02x:%02x:%02x\n", | 587 | level = KERN_DEBUG; |
| 474 | tf.command, tf.feature, tf.nsect, | 588 | snprintf(msg, sizeof(msg), "succeeded"); |
| 475 | tf.lbal, tf.lbam, tf.lbah, tf.device); | 589 | rc = 1; |
| 476 | 590 | break; | |
| 477 | rtf = tf; | 591 | |
| 478 | err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0, 0); | 592 | case AC_ERR_DEV: |
| 479 | if (err_mask) { | 593 | level = KERN_INFO; |
| 480 | ata_dev_printk(dev, KERN_ERR, | 594 | snprintf(msg, sizeof(msg), |
| 481 | "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x failed " | 595 | "rejected by device (Stat=0x%02x Err=0x%02x)", |
| 482 | "(Emask=0x%x Stat=0x%02x Err=0x%02x)\n", | 596 | rtf.command, rtf.feature); |
| 483 | tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam, | 597 | rc = 0; |
| 484 | tf.lbah, tf.device, err_mask, rtf.command, rtf.feature); | 598 | break; |
| 485 | return -EIO; | 599 | |
| 600 | default: | ||
| 601 | level = KERN_ERR; | ||
| 602 | snprintf(msg, sizeof(msg), | ||
| 603 | "failed (Emask=0x%x Stat=0x%02x Err=0x%02x)", | ||
| 604 | err_mask, rtf.command, rtf.feature); | ||
| 605 | rc = -EIO; | ||
| 606 | break; | ||
| 607 | } | ||
| 608 | } else { | ||
| 609 | level = KERN_INFO; | ||
| 610 | snprintf(msg, sizeof(msg), "filtered out"); | ||
| 611 | rc = 0; | ||
| 486 | } | 612 | } |
| 487 | 613 | ||
| 488 | return 0; | 614 | ata_dev_printk(dev, level, |
| 615 | "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x %s\n", | ||
| 616 | tf.command, tf.feature, tf.nsect, tf.lbal, | ||
| 617 | tf.lbam, tf.lbah, tf.device, msg); | ||
| 618 | |||
| 619 | return rc; | ||
| 489 | } | 620 | } |
| 490 | 621 | ||
| 491 | /** | 622 | /** |
| 492 | * ata_acpi_exec_tfs - get then write drive taskfile settings | 623 | * ata_acpi_exec_tfs - get then write drive taskfile settings |
| 493 | * @dev: target ATA device | 624 | * @dev: target ATA device |
| 625 | * @nr_executed: out paramter for the number of executed commands | ||
| 494 | * | 626 | * |
| 495 | * Evaluate _GTF and excute returned taskfiles. | 627 | * Evaluate _GTF and excute returned taskfiles. |
| 496 | * | 628 | * |
| @@ -498,35 +630,36 @@ static int taskfile_load_raw(struct ata_device *dev, | |||
| 498 | * EH context. | 630 | * EH context. |
| 499 | * | 631 | * |
| 500 | * RETURNS: | 632 | * RETURNS: |
| 501 | * Number of executed taskfiles on success, 0 if _GTF doesn't exist or | 633 | * Number of executed taskfiles on success, 0 if _GTF doesn't exist. |
| 502 | * doesn't contain valid data. -errno on other errors. | 634 | * -errno on other errors. |
| 503 | */ | 635 | */ |
| 504 | static int ata_acpi_exec_tfs(struct ata_device *dev) | 636 | static int ata_acpi_exec_tfs(struct ata_device *dev, int *nr_executed) |
| 505 | { | 637 | { |
| 506 | struct ata_acpi_gtf *gtf = NULL; | 638 | struct ata_acpi_gtf *gtf = NULL, *pgtf = NULL; |
| 507 | void *ptr_to_free = NULL; | ||
| 508 | int gtf_count, i, rc; | 639 | int gtf_count, i, rc; |
| 509 | 640 | ||
| 510 | /* get taskfiles */ | 641 | /* get taskfiles */ |
| 511 | gtf_count = ata_dev_get_GTF(dev, >f, &ptr_to_free); | 642 | rc = ata_dev_get_GTF(dev, >f); |
| 643 | if (rc < 0) | ||
| 644 | return rc; | ||
| 645 | gtf_count = rc; | ||
| 512 | 646 | ||
| 513 | /* execute them */ | 647 | /* execute them */ |
| 514 | for (i = 0, rc = 0; i < gtf_count; i++) { | 648 | for (i = 0; i < gtf_count; i++, gtf++) { |
| 515 | int tmp; | 649 | rc = ata_acpi_run_tf(dev, gtf, pgtf); |
| 516 | 650 | if (rc < 0) | |
| 517 | /* ACPI errors are eventually ignored. Run till the | 651 | break; |
| 518 | * end even after errors. | 652 | if (rc) { |
| 519 | */ | 653 | (*nr_executed)++; |
| 520 | tmp = taskfile_load_raw(dev, gtf++); | 654 | pgtf = gtf; |
| 521 | if (!rc) | 655 | } |
| 522 | rc = tmp; | ||
| 523 | } | 656 | } |
| 524 | 657 | ||
| 525 | kfree(ptr_to_free); | 658 | ata_acpi_clear_gtf(dev); |
| 526 | 659 | ||
| 527 | if (rc == 0) | 660 | if (rc < 0) |
| 528 | return gtf_count; | 661 | return rc; |
| 529 | return rc; | 662 | return 0; |
| 530 | } | 663 | } |
| 531 | 664 | ||
| 532 | /** | 665 | /** |
| @@ -596,27 +729,8 @@ static int ata_acpi_push_id(struct ata_device *dev) | |||
| 596 | */ | 729 | */ |
| 597 | int ata_acpi_on_suspend(struct ata_port *ap) | 730 | int ata_acpi_on_suspend(struct ata_port *ap) |
| 598 | { | 731 | { |
| 599 | unsigned long flags; | 732 | /* nada */ |
| 600 | int rc; | 733 | return 0; |
| 601 | |||
| 602 | /* proceed iff per-port acpi_handle is valid */ | ||
| 603 | if (!ap->acpi_handle) | ||
| 604 | return 0; | ||
| 605 | BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); | ||
| 606 | |||
| 607 | /* store timing parameters */ | ||
| 608 | rc = ata_acpi_gtm(ap, &ap->acpi_gtm); | ||
| 609 | |||
| 610 | spin_lock_irqsave(ap->lock, flags); | ||
| 611 | if (rc == 0) | ||
| 612 | ap->pflags |= ATA_PFLAG_GTM_VALID; | ||
| 613 | else | ||
| 614 | ap->pflags &= ~ATA_PFLAG_GTM_VALID; | ||
| 615 | spin_unlock_irqrestore(ap->lock, flags); | ||
| 616 | |||
| 617 | if (rc == -ENOENT) | ||
| 618 | rc = 0; | ||
| 619 | return rc; | ||
| 620 | } | 734 | } |
| 621 | 735 | ||
| 622 | /** | 736 | /** |
| @@ -631,18 +745,34 @@ int ata_acpi_on_suspend(struct ata_port *ap) | |||
| 631 | */ | 745 | */ |
| 632 | void ata_acpi_on_resume(struct ata_port *ap) | 746 | void ata_acpi_on_resume(struct ata_port *ap) |
| 633 | { | 747 | { |
| 748 | const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap); | ||
| 634 | struct ata_device *dev; | 749 | struct ata_device *dev; |
| 635 | 750 | ||
| 636 | if (ap->acpi_handle && (ap->pflags & ATA_PFLAG_GTM_VALID)) { | 751 | if (ap->acpi_handle && gtm) { |
| 637 | BUG_ON(ap->flags & ATA_FLAG_ACPI_SATA); | 752 | /* _GTM valid */ |
| 638 | 753 | ||
| 639 | /* restore timing parameters */ | 754 | /* restore timing parameters */ |
| 640 | ata_acpi_stm(ap, &ap->acpi_gtm); | 755 | ata_acpi_stm(ap, gtm); |
| 641 | } | ||
| 642 | 756 | ||
| 643 | /* schedule _GTF */ | 757 | /* _GTF should immediately follow _STM so that it can |
| 644 | ata_link_for_each_dev(dev, &ap->link) | 758 | * use values set by _STM. Cache _GTF result and |
| 645 | dev->flags |= ATA_DFLAG_ACPI_PENDING; | 759 | * schedule _GTF. |
| 760 | */ | ||
| 761 | ata_link_for_each_dev(dev, &ap->link) { | ||
| 762 | ata_acpi_clear_gtf(dev); | ||
| 763 | if (ata_dev_get_GTF(dev, NULL) >= 0) | ||
| 764 | dev->flags |= ATA_DFLAG_ACPI_PENDING; | ||
| 765 | } | ||
| 766 | } else { | ||
| 767 | /* SATA _GTF needs to be evaulated after _SDD and | ||
| 768 | * there's no reason to evaluate IDE _GTF early | ||
| 769 | * without _STM. Clear cache and schedule _GTF. | ||
| 770 | */ | ||
| 771 | ata_link_for_each_dev(dev, &ap->link) { | ||
| 772 | ata_acpi_clear_gtf(dev); | ||
| 773 | dev->flags |= ATA_DFLAG_ACPI_PENDING; | ||
| 774 | } | ||
| 775 | } | ||
| 646 | } | 776 | } |
| 647 | 777 | ||
| 648 | /** | 778 | /** |
| @@ -664,6 +794,7 @@ int ata_acpi_on_devcfg(struct ata_device *dev) | |||
| 664 | struct ata_port *ap = dev->link->ap; | 794 | struct ata_port *ap = dev->link->ap; |
| 665 | struct ata_eh_context *ehc = &ap->link.eh_context; | 795 | struct ata_eh_context *ehc = &ap->link.eh_context; |
| 666 | int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA; | 796 | int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA; |
| 797 | int nr_executed = 0; | ||
| 667 | int rc; | 798 | int rc; |
| 668 | 799 | ||
| 669 | if (!dev->acpi_handle) | 800 | if (!dev->acpi_handle) |
| @@ -682,14 +813,14 @@ int ata_acpi_on_devcfg(struct ata_device *dev) | |||
| 682 | } | 813 | } |
| 683 | 814 | ||
| 684 | /* do _GTF */ | 815 | /* do _GTF */ |
| 685 | rc = ata_acpi_exec_tfs(dev); | 816 | rc = ata_acpi_exec_tfs(dev, &nr_executed); |
| 686 | if (rc < 0) | 817 | if (rc) |
| 687 | goto acpi_err; | 818 | goto acpi_err; |
| 688 | 819 | ||
| 689 | dev->flags &= ~ATA_DFLAG_ACPI_PENDING; | 820 | dev->flags &= ~ATA_DFLAG_ACPI_PENDING; |
| 690 | 821 | ||
| 691 | /* refresh IDENTIFY page if any _GTF command has been executed */ | 822 | /* refresh IDENTIFY page if any _GTF command has been executed */ |
| 692 | if (rc > 0) { | 823 | if (nr_executed) { |
| 693 | rc = ata_dev_reread_id(dev, 0); | 824 | rc = ata_dev_reread_id(dev, 0); |
| 694 | if (rc < 0) { | 825 | if (rc < 0) { |
| 695 | ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY " | 826 | ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY " |
| @@ -701,17 +832,39 @@ int ata_acpi_on_devcfg(struct ata_device *dev) | |||
| 701 | return 0; | 832 | return 0; |
| 702 | 833 | ||
| 703 | acpi_err: | 834 | acpi_err: |
| 704 | /* let EH retry on the first failure, disable ACPI on the second */ | 835 | /* ignore evaluation failure if we can continue safely */ |
| 705 | if (dev->flags & ATA_DFLAG_ACPI_FAILED) { | 836 | if (rc == -EINVAL && !nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN)) |
| 706 | ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the " | 837 | return 0; |
| 707 | "second time, disabling (errno=%d)\n", rc); | ||
| 708 | |||
| 709 | dev->acpi_handle = NULL; | ||
| 710 | 838 | ||
| 711 | /* if port is working, request IDENTIFY reload and continue */ | 839 | /* fail and let EH retry once more for unknown IO errors */ |
| 712 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | 840 | if (!(dev->flags & ATA_DFLAG_ACPI_FAILED)) { |
| 713 | rc = 1; | 841 | dev->flags |= ATA_DFLAG_ACPI_FAILED; |
| 842 | return rc; | ||
| 714 | } | 843 | } |
| 715 | dev->flags |= ATA_DFLAG_ACPI_FAILED; | 844 | |
| 845 | ata_dev_printk(dev, KERN_WARNING, | ||
| 846 | "ACPI: failed the second time, disabled\n"); | ||
| 847 | dev->acpi_handle = NULL; | ||
| 848 | |||
| 849 | /* We can safely continue if no _GTF command has been executed | ||
| 850 | * and port is not frozen. | ||
| 851 | */ | ||
| 852 | if (!nr_executed && !(ap->pflags & ATA_PFLAG_FROZEN)) | ||
| 853 | return 0; | ||
| 854 | |||
| 716 | return rc; | 855 | return rc; |
| 717 | } | 856 | } |
| 857 | |||
| 858 | /** | ||
| 859 | * ata_acpi_on_disable - ATA ACPI hook called when a device is disabled | ||
| 860 | * @dev: target ATA device | ||
| 861 | * | ||
| 862 | * This function is called when @dev is about to be disabled. | ||
| 863 | * | ||
| 864 | * LOCKING: | ||
| 865 | * EH context. | ||
| 866 | */ | ||
| 867 | void ata_acpi_on_disable(struct ata_device *dev) | ||
| 868 | { | ||
| 869 | ata_acpi_clear_gtf(dev); | ||
| 870 | } | ||
