aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/ata.h
diff options
context:
space:
mode:
authorGrant Grundler <grundler@google.com>2010-08-17 13:56:53 -0400
committerJeff Garzik <jgarzik@redhat.com>2010-10-21 20:21:03 -0400
commit295124dce4ddfd40b1f12d3ffd2779673e87c701 (patch)
treecccdc9d6270fbc72b9147050232c627f7ddee23b /include/linux/ata.h
parent1aadf5c3bbbbb0db09dcb5aa26c61326e0d3e9e7 (diff)
[libata] support for > 512 byte sectors (e.g. 4K Native)
This change enables my x86 machine to recognize and talk to a "Native 4K" SATA device. When I started working on this, I didn't know Matthew Wilcox had posted a similar patch 2 years ago: http://git.kernel.org/?p=linux/kernel/git/willy/ata.git;a=shortlog;h=refs/heads/ata-large-sectors Gwendal Grignou pointed me at the the above code and small portions of this patch include Matthew's work. That's why Mathew is first on the "Signed-off-by:". I've NOT included his use of a bitmap to determine 512 vs Native for ATA command block size - just used a simple table. And bugs are almost certainly mine. Lastly, the patch has been tested with a native 4K 'Engineering Sample' drive provided by Hitachi GST. Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com> Signed-off-by: Grant Grundler <grundler@google.com> Reviewed-by: Gwendal Grignou <gwendal@google.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'include/linux/ata.h')
-rw-r--r--include/linux/ata.h46
1 files changed, 40 insertions, 6 deletions
diff --git a/include/linux/ata.h b/include/linux/ata.h
index fe6e681a9d74..0c4929fa34d3 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -89,6 +89,7 @@ enum {
89 ATA_ID_SPG = 98, 89 ATA_ID_SPG = 98,
90 ATA_ID_LBA_CAPACITY_2 = 100, 90 ATA_ID_LBA_CAPACITY_2 = 100,
91 ATA_ID_SECTOR_SIZE = 106, 91 ATA_ID_SECTOR_SIZE = 106,
92 ATA_ID_LOGICAL_SECTOR_SIZE = 117, /* and 118 */
92 ATA_ID_LAST_LUN = 126, 93 ATA_ID_LAST_LUN = 126,
93 ATA_ID_DLF = 128, 94 ATA_ID_DLF = 128,
94 ATA_ID_CSFO = 129, 95 ATA_ID_CSFO = 129,
@@ -640,16 +641,49 @@ static inline int ata_id_flush_ext_enabled(const u16 *id)
640 return (id[ATA_ID_CFS_ENABLE_2] & 0x2400) == 0x2400; 641 return (id[ATA_ID_CFS_ENABLE_2] & 0x2400) == 0x2400;
641} 642}
642 643
643static inline int ata_id_has_large_logical_sectors(const u16 *id) 644static inline u32 ata_id_logical_sector_size(const u16 *id)
644{ 645{
645 if ((id[ATA_ID_SECTOR_SIZE] & 0xc000) != 0x4000) 646 /* T13/1699-D Revision 6a, Sep 6, 2008. Page 128.
646 return 0; 647 * IDENTIFY DEVICE data, word 117-118.
647 return id[ATA_ID_SECTOR_SIZE] & (1 << 13); 648 * 0xd000 ignores bit 13 (logical:physical > 1)
649 */
650 if ((id[ATA_ID_SECTOR_SIZE] & 0xd000) == 0x5000)
651 return (((id[ATA_ID_LOGICAL_SECTOR_SIZE+1] << 16)
652 + id[ATA_ID_LOGICAL_SECTOR_SIZE]) * sizeof(u16)) ;
653 return ATA_SECT_SIZE;
654}
655
656static inline u8 ata_id_log2_per_physical_sector(const u16 *id)
657{
658 /* T13/1699-D Revision 6a, Sep 6, 2008. Page 128.
659 * IDENTIFY DEVICE data, word 106.
660 * 0xe000 ignores bit 12 (logical sector > 512 bytes)
661 */
662 if ((id[ATA_ID_SECTOR_SIZE] & 0xe000) == 0x6000)
663 return (id[ATA_ID_SECTOR_SIZE] & 0xf);
664 return 0;
648} 665}
649 666
650static inline u16 ata_id_logical_per_physical_sectors(const u16 *id) 667/* Offset of logical sectors relative to physical sectors.
668 *
669 * If device has more than one logical sector per physical sector
670 * (aka 512 byte emulation), vendors might offset the "sector 0" address
671 * so sector 63 is "naturally aligned" - e.g. FAT partition table.
672 * This avoids Read/Mod/Write penalties when using FAT partition table
673 * and updating "well aligned" (FS perspective) physical sectors on every
674 * transaction.
675 */
676static inline u16 ata_id_logical_sector_offset(const u16 *id,
677 u8 log2_per_phys)
651{ 678{
652 return 1 << (id[ATA_ID_SECTOR_SIZE] & 0xf); 679 u16 word_209 = id[209];
680
681 if ((log2_per_phys > 1) && (word_209 & 0xc000) == 0x4000) {
682 u16 first = word_209 & 0x3fff;
683 if (first > 0)
684 return (1 << log2_per_phys) - first;
685 }
686 return 0;
653} 687}
654 688
655static inline int ata_id_has_lba48(const u16 *id) 689static inline int ata_id_has_lba48(const u16 *id)