diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-acpi.c | 204 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 16 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 3 | ||||
-rw-r--r-- | drivers/ata/libata.h | 14 |
4 files changed, 138 insertions, 99 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index ae2077e1e78f..e09df442a52f 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -273,91 +273,47 @@ static int taskfile_load_raw(struct ata_device *dev, | |||
273 | } | 273 | } |
274 | 274 | ||
275 | /** | 275 | /** |
276 | * ata_dev_set_taskfiles - write the drive taskfile settings from _GTF | ||
277 | * @dev: target ATA device | ||
278 | * @gtf: pointer to array of _GTF taskfiles to execute | ||
279 | * @gtf_count: number of taskfiles | ||
280 | * | ||
281 | * This applies to both PATA and SATA drives. | ||
282 | * | ||
283 | * Execute taskfiles in @gtf. | ||
284 | * | ||
285 | * LOCKING: | ||
286 | * EH context. | ||
287 | * | ||
288 | * RETURNS: | ||
289 | * 0 on success, -errno on failure. | ||
290 | */ | ||
291 | static int ata_dev_set_taskfiles(struct ata_device *dev, | ||
292 | struct ata_acpi_gtf *gtf, int gtf_count) | ||
293 | { | ||
294 | struct ata_port *ap = dev->ap; | ||
295 | int ix; | ||
296 | |||
297 | if (ata_msg_probe(ap)) | ||
298 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", | ||
299 | __FUNCTION__, ap->port_no); | ||
300 | |||
301 | if (!(ap->flags & ATA_FLAG_ACPI_SATA)) | ||
302 | return 0; | ||
303 | |||
304 | if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) | ||
305 | return -ENODEV; | ||
306 | |||
307 | /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ | ||
308 | for (ix = 0; ix < gtf_count; ix++) | ||
309 | taskfile_load_raw(dev, gtf++); | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | /** | ||
315 | * ata_acpi_exec_tfs - get then write drive taskfile settings | 276 | * ata_acpi_exec_tfs - get then write drive taskfile settings |
316 | * @ap: the ata_port for the drive | 277 | * @dev: target ATA device |
317 | * | 278 | * |
318 | * This applies to both PATA and SATA drives. | 279 | * Evaluate _GTF and excute returned taskfiles. |
319 | * | 280 | * |
320 | * LOCKING: | 281 | * LOCKING: |
321 | * EH context. | 282 | * EH context. |
322 | * | 283 | * |
323 | * RETURNS: | 284 | * RETURNS: |
324 | * 0 on success, -errno on failure. | 285 | * Number of executed taskfiles on success, 0 if _GTF doesn't exist or |
286 | * doesn't contain valid data. -errno on other errors. | ||
325 | */ | 287 | */ |
326 | int ata_acpi_exec_tfs(struct ata_port *ap) | 288 | static int ata_acpi_exec_tfs(struct ata_device *dev) |
327 | { | 289 | { |
328 | int ix, ret = 0; | 290 | struct ata_acpi_gtf *gtf = NULL; |
329 | 291 | void *ptr_to_free = NULL; | |
330 | /* | 292 | int gtf_count, i, rc; |
331 | * TBD - implement PATA support. For now, | 293 | |
332 | * we should not run GTF on PATA devices since some | 294 | /* get taskfiles */ |
333 | * PATA require execution of GTM/STM before GTF. | 295 | rc = ata_dev_get_GTF(dev, >f, &ptr_to_free); |
334 | */ | 296 | if (rc < 0) |
335 | if (!(ap->flags & ATA_FLAG_ACPI_SATA)) | 297 | return rc; |
336 | return 0; | 298 | gtf_count = rc; |
337 | 299 | ||
338 | for (ix = 0; ix < ATA_MAX_DEVICES; ix++) { | 300 | /* execute them */ |
339 | struct ata_device *dev = &ap->device[ix]; | 301 | for (i = 0, rc = 0; i < gtf_count; i++) { |
340 | struct ata_acpi_gtf *gtf = NULL; | 302 | int tmp; |
341 | int gtf_count; | 303 | |
342 | void *ptr_to_free = NULL; | 304 | /* ACPI errors are eventually ignored. Run till the |
343 | 305 | * end even after errors. | |
344 | if (!ata_dev_enabled(dev)) | 306 | */ |
345 | continue; | 307 | tmp = taskfile_load_raw(dev, gtf++); |
346 | 308 | if (!rc) | |
347 | ret = ata_dev_get_GTF(dev, >f, &ptr_to_free); | 309 | rc = tmp; |
348 | if (ret == 0) | ||
349 | continue; | ||
350 | if (ret < 0) | ||
351 | break; | ||
352 | gtf_count = ret; | ||
353 | |||
354 | ret = ata_dev_set_taskfiles(dev, gtf, gtf_count); | ||
355 | kfree(ptr_to_free); | ||
356 | if (ret < 0) | ||
357 | break; | ||
358 | } | 310 | } |
359 | 311 | ||
360 | return ret; | 312 | kfree(ptr_to_free); |
313 | |||
314 | if (rc == 0) | ||
315 | return gtf_count; | ||
316 | return rc; | ||
361 | } | 317 | } |
362 | 318 | ||
363 | /** | 319 | /** |
@@ -376,7 +332,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap) | |||
376 | * RETURNS: | 332 | * RETURNS: |
377 | * 0 on success, -errno on failure. | 333 | * 0 on success, -errno on failure. |
378 | */ | 334 | */ |
379 | int ata_acpi_push_id(struct ata_device *dev) | 335 | static int ata_acpi_push_id(struct ata_device *dev) |
380 | { | 336 | { |
381 | struct ata_port *ap = dev->ap; | 337 | struct ata_port *ap = dev->ap; |
382 | int err; | 338 | int err; |
@@ -396,7 +352,7 @@ int ata_acpi_push_id(struct ata_device *dev) | |||
396 | if (ata_msg_probe(ap)) | 352 | if (ata_msg_probe(ap)) |
397 | ata_dev_printk(dev, KERN_DEBUG, | 353 | ata_dev_printk(dev, KERN_DEBUG, |
398 | "%s: Not a SATA device\n", __FUNCTION__); | 354 | "%s: Not a SATA device\n", __FUNCTION__); |
399 | goto out; | 355 | return 0; |
400 | } | 356 | } |
401 | 357 | ||
402 | /* Give the drive Identify data to the drive via the _SDD method */ | 358 | /* Give the drive Identify data to the drive via the _SDD method */ |
@@ -418,9 +374,99 @@ int ata_acpi_push_id(struct ata_device *dev) | |||
418 | ata_dev_printk(dev, KERN_WARNING, | 374 | ata_dev_printk(dev, KERN_WARNING, |
419 | "ACPI _SDD failed (AE 0x%x)\n", status); | 375 | "ACPI _SDD failed (AE 0x%x)\n", status); |
420 | 376 | ||
421 | /* always return success */ | 377 | return err; |
422 | out: | 378 | } |
423 | return 0; | 379 | |
380 | /** | ||
381 | * ata_acpi_on_resume - ATA ACPI hook called on resume | ||
382 | * @ap: target ATA port | ||
383 | * | ||
384 | * This function is called when @ap is resumed - right after port | ||
385 | * itself is resumed but before any EH action is taken. | ||
386 | * | ||
387 | * LOCKING: | ||
388 | * EH context. | ||
389 | */ | ||
390 | void ata_acpi_on_resume(struct ata_port *ap) | ||
391 | { | ||
392 | int i; | ||
393 | |||
394 | /* schedule _GTF */ | ||
395 | for (i = 0; i < ATA_MAX_DEVICES; i++) | ||
396 | ap->device[i].flags |= ATA_DFLAG_ACPI_PENDING; | ||
424 | } | 397 | } |
425 | 398 | ||
399 | /** | ||
400 | * ata_acpi_on_devcfg - ATA ACPI hook called on device donfiguration | ||
401 | * @dev: target ATA device | ||
402 | * | ||
403 | * This function is called when @dev is about to be configured. | ||
404 | * IDENTIFY data might have been modified after this hook is run. | ||
405 | * | ||
406 | * LOCKING: | ||
407 | * EH context. | ||
408 | * | ||
409 | * RETURNS: | ||
410 | * Positive number if IDENTIFY data needs to be refreshed, 0 if not, | ||
411 | * -errno on failure. | ||
412 | */ | ||
413 | int ata_acpi_on_devcfg(struct ata_device *dev) | ||
414 | { | ||
415 | struct ata_port *ap = dev->ap; | ||
416 | struct ata_eh_context *ehc = &ap->eh_context; | ||
417 | int acpi_sata = ap->flags & ATA_FLAG_ACPI_SATA; | ||
418 | int rc; | ||
419 | |||
420 | /* XXX: _STM isn't implemented yet, skip if IDE for now */ | ||
421 | if (!acpi_sata) | ||
422 | return 0; | ||
426 | 423 | ||
424 | if (!dev->acpi_handle) | ||
425 | return 0; | ||
426 | |||
427 | /* do we need to do _GTF? */ | ||
428 | if (!(dev->flags & ATA_DFLAG_ACPI_PENDING) && | ||
429 | !(acpi_sata && (ehc->i.flags & ATA_EHI_DID_HARDRESET))) | ||
430 | return 0; | ||
431 | |||
432 | /* do _SDD if SATA */ | ||
433 | if (acpi_sata) { | ||
434 | rc = ata_acpi_push_id(dev); | ||
435 | if (rc) | ||
436 | goto acpi_err; | ||
437 | } | ||
438 | |||
439 | /* do _GTF */ | ||
440 | rc = ata_acpi_exec_tfs(dev); | ||
441 | if (rc < 0) | ||
442 | goto acpi_err; | ||
443 | |||
444 | dev->flags &= ~ATA_DFLAG_ACPI_PENDING; | ||
445 | |||
446 | /* refresh IDENTIFY page if any _GTF command has been executed */ | ||
447 | if (rc > 0) { | ||
448 | rc = ata_dev_reread_id(dev, 0); | ||
449 | if (rc < 0) { | ||
450 | ata_dev_printk(dev, KERN_ERR, "failed to IDENTIFY " | ||
451 | "after ACPI commands\n"); | ||
452 | return rc; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | return 0; | ||
457 | |||
458 | acpi_err: | ||
459 | /* let EH retry on the first failure, disable ACPI on the second */ | ||
460 | if (dev->flags & ATA_DFLAG_ACPI_FAILED) { | ||
461 | ata_dev_printk(dev, KERN_WARNING, "ACPI on devcfg failed the " | ||
462 | "second time, disabling (errno=%d)\n", rc); | ||
463 | |||
464 | dev->acpi_handle = NULL; | ||
465 | |||
466 | /* if port is working, request IDENTIFY reload and continue */ | ||
467 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | ||
468 | rc = 1; | ||
469 | } | ||
470 | dev->flags |= ATA_DFLAG_ACPI_FAILED; | ||
471 | return rc; | ||
472 | } | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5a46cdebc588..90ed2b9a34de 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1845,7 +1845,8 @@ static void ata_dev_config_ncq(struct ata_device *dev, | |||
1845 | int ata_dev_configure(struct ata_device *dev) | 1845 | int ata_dev_configure(struct ata_device *dev) |
1846 | { | 1846 | { |
1847 | struct ata_port *ap = dev->ap; | 1847 | struct ata_port *ap = dev->ap; |
1848 | int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO; | 1848 | struct ata_eh_context *ehc = &ap->eh_context; |
1849 | int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; | ||
1849 | const u16 *id = dev->id; | 1850 | const u16 *id = dev->id; |
1850 | unsigned int xfer_mask; | 1851 | unsigned int xfer_mask; |
1851 | char revbuf[7]; /* XYZ-99\0 */ | 1852 | char revbuf[7]; /* XYZ-99\0 */ |
@@ -1862,15 +1863,10 @@ int ata_dev_configure(struct ata_device *dev) | |||
1862 | if (ata_msg_probe(ap)) | 1863 | if (ata_msg_probe(ap)) |
1863 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); | 1864 | ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); |
1864 | 1865 | ||
1865 | /* set _SDD */ | 1866 | /* let ACPI work its magic */ |
1866 | rc = ata_acpi_push_id(dev); | 1867 | rc = ata_acpi_on_devcfg(dev); |
1867 | if (rc) { | 1868 | if (rc) |
1868 | ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n", | 1869 | return rc; |
1869 | rc); | ||
1870 | } | ||
1871 | |||
1872 | /* retrieve and execute the ATA task file of _GTF */ | ||
1873 | ata_acpi_exec_tfs(ap); | ||
1874 | 1870 | ||
1875 | /* print device capabilities */ | 1871 | /* print device capabilities */ |
1876 | if (ata_msg_probe(ap)) | 1872 | if (ata_msg_probe(ap)) |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f7582c9c320e..fed217db82d2 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -2207,6 +2207,9 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) | |||
2207 | if (ap->ops->port_resume) | 2207 | if (ap->ops->port_resume) |
2208 | rc = ap->ops->port_resume(ap); | 2208 | rc = ap->ops->port_resume(ap); |
2209 | 2209 | ||
2210 | /* tell ACPI that we're resuming */ | ||
2211 | ata_acpi_on_resume(ap); | ||
2212 | |||
2210 | /* report result */ | 2213 | /* report result */ |
2211 | spin_lock_irqsave(ap->lock, flags); | 2214 | spin_lock_irqsave(ap->lock, flags); |
2212 | ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); | 2215 | ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 29037cd7c651..bee7cbc4c97c 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -99,18 +99,12 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host); | |||
99 | /* libata-acpi.c */ | 99 | /* libata-acpi.c */ |
100 | #ifdef CONFIG_ATA_ACPI | 100 | #ifdef CONFIG_ATA_ACPI |
101 | extern void ata_acpi_associate(struct ata_host *host); | 101 | extern void ata_acpi_associate(struct ata_host *host); |
102 | extern int ata_acpi_exec_tfs(struct ata_port *ap); | 102 | extern void ata_acpi_on_resume(struct ata_port *ap); |
103 | extern int ata_acpi_push_id(struct ata_device *dev); | 103 | extern int ata_acpi_on_devcfg(struct ata_device *adev); |
104 | #else | 104 | #else |
105 | static inline void ata_acpi_associate(struct ata_host *host) { } | 105 | static inline void ata_acpi_associate(struct ata_host *host) { } |
106 | static inline int ata_acpi_exec_tfs(struct ata_port *ap) | 106 | static inline void ata_acpi_on_resume(struct ata_port *ap) { } |
107 | { | 107 | static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } |
108 | return 0; | ||
109 | } | ||
110 | static inline int ata_acpi_push_id(struct ata_device *dev) | ||
111 | { | ||
112 | return 0; | ||
113 | } | ||
114 | #endif | 108 | #endif |
115 | 109 | ||
116 | /* libata-scsi.c */ | 110 | /* libata-scsi.c */ |