aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2007-04-10 19:23:13 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 14:16:06 -0400
commit1e999736cafdffc374f22eed37b291129ef82e4e (patch)
treed71e0907827841de66f172dec0cc4d550bd2cec8 /drivers/ata
parent6bfff31e77cfa1b13490337e5a4dbaa3407e83ac (diff)
libata: HPA support
Signed-off-by: Alan Cox <alan@redhat.com> Add support for ignoring the BIOS HPA result (off by default) and setting the disk to the full available size unless already frozen. Tested with various platforms/disks and confirmed to work with the Macintosh (which broke earlier) and ata_piix (breakage due to the LBA48 readback that Tejun fixed). For normal users this brings us, I believe, to feature parity with old IDE (and of course more featured in some areas too). Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b5839f84b384..6d0a946afe84 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -89,6 +89,10 @@ int libata_fua = 0;
89module_param_named(fua, libata_fua, int, 0444); 89module_param_named(fua, libata_fua, int, 0444);
90MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); 90MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)");
91 91
92static int ata_ignore_hpa = 0;
93module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644);
94MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)");
95
92static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ; 96static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ;
93module_param(ata_probe_timeout, int, 0444); 97module_param(ata_probe_timeout, int, 0444);
94MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)"); 98MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
@@ -808,6 +812,202 @@ void ata_id_c_string(const u16 *id, unsigned char *s,
808 *p = '\0'; 812 *p = '\0';
809} 813}
810 814
815static u64 ata_tf_to_lba48(struct ata_taskfile *tf)
816{
817 u64 sectors = 0;
818
819 sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40;
820 sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32;
821 sectors |= (tf->hob_lbal & 0xff) << 24;
822 sectors |= (tf->lbah & 0xff) << 16;
823 sectors |= (tf->lbam & 0xff) << 8;
824 sectors |= (tf->lbal & 0xff);
825
826 return ++sectors;
827}
828
829static u64 ata_tf_to_lba(struct ata_taskfile *tf)
830{
831 u64 sectors = 0;
832
833 sectors |= (tf->device & 0x0f) << 24;
834 sectors |= (tf->lbah & 0xff) << 16;
835 sectors |= (tf->lbam & 0xff) << 8;
836 sectors |= (tf->lbal & 0xff);
837
838 return ++sectors;
839}
840
841/**
842 * ata_read_native_max_address_ext - LBA48 native max query
843 * @dev: Device to query
844 *
845 * Perform an LBA48 size query upon the device in question. Return the
846 * actual LBA48 size or zero if the command fails.
847 */
848
849static u64 ata_read_native_max_address_ext(struct ata_device *dev)
850{
851 unsigned int err;
852 struct ata_taskfile tf;
853
854 ata_tf_init(dev, &tf);
855
856 tf.command = ATA_CMD_READ_NATIVE_MAX_EXT;
857 tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
858 tf.protocol |= ATA_PROT_NODATA;
859 tf.device |= 0x40;
860
861 err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
862 if (err)
863 return 0;
864
865 return ata_tf_to_lba48(&tf);
866}
867
868/**
869 * ata_read_native_max_address - LBA28 native max query
870 * @dev: Device to query
871 *
872 * Performa an LBA28 size query upon the device in question. Return the
873 * actual LBA28 size or zero if the command fails.
874 */
875
876static u64 ata_read_native_max_address(struct ata_device *dev)
877{
878 unsigned int err;
879 struct ata_taskfile tf;
880
881 ata_tf_init(dev, &tf);
882
883 tf.command = ATA_CMD_READ_NATIVE_MAX;
884 tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
885 tf.protocol |= ATA_PROT_NODATA;
886 tf.device |= 0x40;
887
888 err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
889 if (err)
890 return 0;
891
892 return ata_tf_to_lba(&tf);
893}
894
895/**
896 * ata_set_native_max_address_ext - LBA48 native max set
897 * @dev: Device to query
898 *
899 * Perform an LBA48 size set max upon the device in question. Return the
900 * actual LBA48 size or zero if the command fails.
901 */
902
903static u64 ata_set_native_max_address_ext(struct ata_device *dev, u64 new_sectors)
904{
905 unsigned int err;
906 struct ata_taskfile tf;
907
908 new_sectors--;
909
910 ata_tf_init(dev, &tf);
911
912 tf.command = ATA_CMD_SET_MAX_EXT;
913 tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
914 tf.protocol |= ATA_PROT_NODATA;
915 tf.device |= 0x40;
916
917 tf.lbal = (new_sectors >> 0) & 0xff;
918 tf.lbam = (new_sectors >> 8) & 0xff;
919 tf.lbah = (new_sectors >> 16) & 0xff;
920
921 tf.hob_lbal = (new_sectors >> 24) & 0xff;
922 tf.hob_lbam = (new_sectors >> 32) & 0xff;
923 tf.hob_lbah = (new_sectors >> 40) & 0xff;
924
925 err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
926 if (err)
927 return 0;
928
929 return ata_tf_to_lba48(&tf);
930}
931
932/**
933 * ata_set_native_max_address - LBA28 native max set
934 * @dev: Device to query
935 *
936 * Perform an LBA28 size set max upon the device in question. Return the
937 * actual LBA28 size or zero if the command fails.
938 */
939
940static u64 ata_set_native_max_address(struct ata_device *dev, u64 new_sectors)
941{
942 unsigned int err;
943 struct ata_taskfile tf;
944
945 new_sectors--;
946
947 ata_tf_init(dev, &tf);
948
949 tf.command = ATA_CMD_SET_MAX;
950 tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
951 tf.protocol |= ATA_PROT_NODATA;
952
953 tf.lbal = (new_sectors >> 0) & 0xff;
954 tf.lbam = (new_sectors >> 8) & 0xff;
955 tf.lbah = (new_sectors >> 16) & 0xff;
956 tf.device |= ((new_sectors >> 24) & 0x0f) | 0x40;
957
958 err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
959 if (err)
960 return 0;
961
962 return ata_tf_to_lba(&tf);
963}
964
965/**
966 * ata_hpa_resize - Resize a device with an HPA set
967 * @dev: Device to resize
968 *
969 * Read the size of an LBA28 or LBA48 disk with HPA features and resize
970 * it if required to the full size of the media. The caller must check
971 * the drive has the HPA feature set enabled.
972 */
973
974static u64 ata_hpa_resize(struct ata_device *dev)
975{
976 u64 sectors = dev->n_sectors;
977 u64 hpa_sectors;
978
979 if (ata_id_has_lba48(dev->id))
980 hpa_sectors = ata_read_native_max_address_ext(dev);
981 else
982 hpa_sectors = ata_read_native_max_address(dev);
983
984 /* if no hpa, both should be equal */
985 ata_dev_printk(dev, KERN_INFO, "%s 1: sectors = %lld, hpa_sectors = %lld\n",
986 __FUNCTION__, sectors, hpa_sectors);
987
988 if (hpa_sectors > sectors) {
989 ata_dev_printk(dev, KERN_INFO,
990 "Host Protected Area detected:\n"
991 "\tcurrent size: %lld sectors\n"
992 "\tnative size: %lld sectors\n",
993 sectors, hpa_sectors);
994
995 if (ata_ignore_hpa) {
996 if (ata_id_has_lba48(dev->id))
997 hpa_sectors = ata_set_native_max_address_ext(dev, hpa_sectors);
998 else
999 hpa_sectors = ata_set_native_max_address(dev, hpa_sectors);
1000
1001 if (hpa_sectors) {
1002 ata_dev_printk(dev, KERN_INFO,
1003 "native size increased to %lld sectors\n", hpa_sectors);
1004 return hpa_sectors;
1005 }
1006 }
1007 }
1008 return sectors;
1009}
1010
811static u64 ata_id_n_sectors(const u16 *id) 1011static u64 ata_id_n_sectors(const u16 *id)
812{ 1012{
813 if (ata_id_has_lba(id)) { 1013 if (ata_id_has_lba(id)) {
@@ -1662,6 +1862,7 @@ int ata_dev_configure(struct ata_device *dev)
1662 snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); 1862 snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id));
1663 1863
1664 dev->n_sectors = ata_id_n_sectors(id); 1864 dev->n_sectors = ata_id_n_sectors(id);
1865 dev->n_sectors_boot = dev->n_sectors;
1665 1866
1666 /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */ 1867 /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
1667 ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV, 1868 ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
@@ -1688,6 +1889,9 @@ int ata_dev_configure(struct ata_device *dev)
1688 dev->flags |= ATA_DFLAG_FLUSH_EXT; 1889 dev->flags |= ATA_DFLAG_FLUSH_EXT;
1689 } 1890 }
1690 1891
1892 if (ata_id_hpa_enabled(dev->id))
1893 dev->n_sectors = ata_hpa_resize(dev);
1894
1691 /* config NCQ */ 1895 /* config NCQ */
1692 ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc)); 1896 ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
1693 1897
@@ -3346,6 +3550,11 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
3346 "%llu != %llu\n", 3550 "%llu != %llu\n",
3347 (unsigned long long)dev->n_sectors, 3551 (unsigned long long)dev->n_sectors,
3348 (unsigned long long)new_n_sectors); 3552 (unsigned long long)new_n_sectors);
3553 /* Are we the boot time size - if so we appear to be the
3554 same disk at this point and our HPA got reapplied */
3555 if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors
3556 && ata_id_hpa_enabled(new_id))
3557 return 1;
3349 return 0; 3558 return 0;
3350 } 3559 }
3351 3560