aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2007-08-22 18:31:43 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-12 14:55:37 -0400
commitc7293870a93a99e9ce0f4d98f3a271539c7c6ad6 (patch)
tree837cb89920034e7983b483f1d8db5fb96c454414
parent614fe29bd91f99cc1c1fbf3274fa918691044f47 (diff)
libata: Strict checking for identify reporting
The ATA specifications require checks on certain flags before assuming the validity of other data. Go through the methods and correct those needing extra checks. Also note limits on ata_id_major_version with respect to ATA-1 and ATA-2. Correct the 32bit PIO check. Wants to sit in -mm for a bit in case of a screwup on my part that I didn't hit on the test drives and also in case someone, somewhere has a drive that gets it wrong. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--include/linux/ata.h96
1 files changed, 85 insertions, 11 deletions
diff --git a/include/linux/ata.h b/include/linux/ata.h
index fba8e1459832..a749f006387f 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -347,22 +347,12 @@ struct ata_taskfile {
347}; 347};
348 348
349#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0) 349#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0)
350#define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
351#define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
352#define ata_id_hpa_enabled(id) ((id)[85] & (1 << 10))
353#define ata_id_has_fua(id) ((id)[84] & (1 << 6))
354#define ata_id_has_flush(id) ((id)[83] & (1 << 12))
355#define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13))
356#define ata_id_has_lba48(id) ((id)[83] & (1 << 10))
357#define ata_id_has_hpa(id) ((id)[82] & (1 << 10))
358#define ata_id_has_wcache(id) ((id)[82] & (1 << 5))
359#define ata_id_has_pm(id) ((id)[82] & (1 << 3))
360#define ata_id_has_lba(id) ((id)[49] & (1 << 9)) 350#define ata_id_has_lba(id) ((id)[49] & (1 << 9))
361#define ata_id_has_dma(id) ((id)[49] & (1 << 8)) 351#define ata_id_has_dma(id) ((id)[49] & (1 << 8))
362#define ata_id_has_ncq(id) ((id)[76] & (1 << 8)) 352#define ata_id_has_ncq(id) ((id)[76] & (1 << 8))
363#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1) 353#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1)
364#define ata_id_removeable(id) ((id)[0] & (1 << 7)) 354#define ata_id_removeable(id) ((id)[0] & (1 << 7))
365#define ata_id_has_dword_io(id) ((id)[50] & (1 << 0)) 355#define ata_id_has_dword_io(id) ((id)[48] & (1 << 0))
366#define ata_id_has_AN(id) \ 356#define ata_id_has_AN(id) \
367 ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \ 357 ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
368 ((id)[78] & (1 << 5)) ) 358 ((id)[78] & (1 << 5)) )
@@ -378,6 +368,90 @@ struct ata_taskfile {
378 368
379#define ata_id_cdb_intr(id) (((id)[0] & 0x60) == 0x20) 369#define ata_id_cdb_intr(id) (((id)[0] & 0x60) == 0x20)
380 370
371static inline int ata_id_has_fua(const u16 *id)
372{
373 if ((id[84] & 0xC000) != 0x4000)
374 return 0;
375 return id[84] & (1 << 6);
376}
377
378static inline int ata_id_has_flush(const u16 *id)
379{
380 if ((id[83] & 0xC000) != 0x4000)
381 return 0;
382 return id[83] & (1 << 12);
383}
384
385static inline int ata_id_has_flush_ext(const u16 *id)
386{
387 if ((id[83] & 0xC000) != 0x4000)
388 return 0;
389 return id[83] & (1 << 13);
390}
391
392static inline int ata_id_has_lba48(const u16 *id)
393{
394 if ((id[83] & 0xC000) != 0x4000)
395 return 0;
396 return id[83] & (1 << 10);
397}
398
399static inline int ata_id_hpa_enabled(const u16 *id)
400{
401 /* Yes children, word 83 valid bits cover word 82 data */
402 if ((id[83] & 0xC000) != 0x4000)
403 return 0;
404 /* And 87 covers 85-87 */
405 if ((id[87] & 0xC000) != 0x4000)
406 return 0;
407 /* Check command sets enabled as well as supported */
408 if ((id[85] & ( 1 << 10)) == 0)
409 return 0;
410 return id[82] & (1 << 10);
411}
412
413static inline int ata_id_has_wcache(const u16 *id)
414{
415 /* Yes children, word 83 valid bits cover word 82 data */
416 if ((id[83] & 0xC000) != 0x4000)
417 return 0;
418 return id[82] & (1 << 5);
419}
420
421static inline int ata_id_has_pm(const u16 *id)
422{
423 if ((id[83] & 0xC000) != 0x4000)
424 return 0;
425 return id[82] & (1 << 3);
426}
427
428static inline int ata_id_rahead_enabled(const u16 *id)
429{
430 if ((id[87] & 0xC000) != 0x4000)
431 return 0;
432 return id[85] & (1 << 6);
433}
434
435static inline int ata_id_wcache_enabled(const u16 *id)
436{
437 if ((id[87] & 0xC000) != 0x4000)
438 return 0;
439 return id[85] & (1 << 5);
440}
441
442/**
443 * ata_id_major_version - get ATA level of drive
444 * @id: Identify data
445 *
446 * Caveats:
447 * ATA-1 considers identify optional
448 * ATA-2 introduces mandatory identify
449 * ATA-3 introduces word 80 and accurate reporting
450 *
451 * The practical impact of this is that ata_id_major_version cannot
452 * reliably report on drives below ATA3.
453 */
454
381static inline unsigned int ata_id_major_version(const u16 *id) 455static inline unsigned int ata_id_major_version(const u16 *id)
382{ 456{
383 unsigned int mver; 457 unsigned int mver;