aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-core.c174
1 files changed, 77 insertions, 97 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b33aea3638d..c7614bdc0cb 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -863,129 +863,113 @@ static u64 ata_tf_to_lba(struct ata_taskfile *tf)
863} 863}
864 864
865/** 865/**
866 * ata_read_native_max_address_ext - LBA48 native max query 866 * ata_read_native_max_address - Read native max address
867 * @dev: Device to query 867 * @dev: target device
868 * @max_sectors: out parameter for the result native max address
868 * 869 *
869 * Perform an LBA48 size query upon the device in question. Return the 870 * Perform an LBA48 or LBA28 native size query upon the device in
870 * actual LBA48 size or zero if the command fails. 871 * question.
871 */
872
873static u64 ata_read_native_max_address_ext(struct ata_device *dev)
874{
875 unsigned int err;
876 struct ata_taskfile tf;
877
878 ata_tf_init(dev, &tf);
879
880 tf.command = ATA_CMD_READ_NATIVE_MAX_EXT;
881 tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
882 tf.protocol |= ATA_PROT_NODATA;
883 tf.device |= 0x40;
884
885 err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
886 if (err)
887 return 0;
888
889 return ata_tf_to_lba48(&tf);
890}
891
892/**
893 * ata_read_native_max_address - LBA28 native max query
894 * @dev: Device to query
895 * 872 *
896 * Performa an LBA28 size query upon the device in question. Return the 873 * RETURNS:
897 * actual LBA28 size or zero if the command fails. 874 * 0 on success, -EACCES if command is aborted by the drive.
875 * -EIO on other errors.
898 */ 876 */
899 877static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors)
900static u64 ata_read_native_max_address(struct ata_device *dev)
901{ 878{
902 unsigned int err; 879 unsigned int err_mask;
903 struct ata_taskfile tf; 880 struct ata_taskfile tf;
881 int lba48 = ata_id_has_lba48(dev->id);
904 882
905 ata_tf_init(dev, &tf); 883 ata_tf_init(dev, &tf);
906 884
907 tf.command = ATA_CMD_READ_NATIVE_MAX; 885 /* always clear all address registers */
908 tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; 886 tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
909 tf.protocol |= ATA_PROT_NODATA;
910 tf.device |= 0x40;
911 887
912 err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); 888 if (lba48) {
913 if (err) 889 tf.command = ATA_CMD_READ_NATIVE_MAX_EXT;
914 return 0; 890 tf.flags |= ATA_TFLAG_LBA48;
915 891 } else
916 return ata_tf_to_lba(&tf); 892 tf.command = ATA_CMD_READ_NATIVE_MAX;
917}
918
919/**
920 * ata_set_native_max_address_ext - LBA48 native max set
921 * @dev: Device to query
922 * @new_sectors: new max sectors value to set for the device
923 *
924 * Perform an LBA48 size set max upon the device in question. Return the
925 * actual LBA48 size or zero if the command fails.
926 */
927
928static u64 ata_set_native_max_address_ext(struct ata_device *dev, u64 new_sectors)
929{
930 unsigned int err;
931 struct ata_taskfile tf;
932
933 new_sectors--;
934
935 ata_tf_init(dev, &tf);
936 893
937 tf.command = ATA_CMD_SET_MAX_EXT;
938 tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
939 tf.protocol |= ATA_PROT_NODATA; 894 tf.protocol |= ATA_PROT_NODATA;
940 tf.device |= 0x40; 895 tf.device |= ATA_LBA;
941
942 tf.lbal = (new_sectors >> 0) & 0xff;
943 tf.lbam = (new_sectors >> 8) & 0xff;
944 tf.lbah = (new_sectors >> 16) & 0xff;
945 896
946 tf.hob_lbal = (new_sectors >> 24) & 0xff; 897 err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
947 tf.hob_lbam = (new_sectors >> 32) & 0xff; 898 if (err_mask) {
948 tf.hob_lbah = (new_sectors >> 40) & 0xff; 899 ata_dev_printk(dev, KERN_WARNING, "failed to read native "
900 "max address (err_mask=0x%x)\n", err_mask);
901 if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED))
902 return -EACCES;
903 return -EIO;
904 }
949 905
950 err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); 906 if (lba48)
951 if (err) 907 *max_sectors = ata_tf_to_lba48(&tf);
952 return 0; 908 else
909 *max_sectors = ata_tf_to_lba(&tf);
953 910
954 return ata_tf_to_lba48(&tf); 911 return 0;
955} 912}
956 913
957/** 914/**
958 * ata_set_native_max_address - LBA28 native max set 915 * ata_set_max_sectors - Set max sectors
959 * @dev: Device to query 916 * @dev: target device
960 * @new_sectors: new max sectors value to set for the device 917 * @new_sectors: new max sectors value to set for the device
918 * @res_sectors: result max sectors
961 * 919 *
962 * Perform an LBA28 size set max upon the device in question. Return the 920 * Set max sectors of @dev to @new_sectors.
963 * actual LBA28 size or zero if the command fails. 921 *
922 * RETURNS:
923 * 0 on success, -EACCES if command is aborted or denied (due to
924 * previous non-volatile SET_MAX) by the drive. -EIO on other
925 * errors.
964 */ 926 */
965 927static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors,
966static u64 ata_set_native_max_address(struct ata_device *dev, u64 new_sectors) 928 u64 *res_sectors)
967{ 929{
968 unsigned int err; 930 unsigned int err_mask;
969 struct ata_taskfile tf; 931 struct ata_taskfile tf;
932 int lba48 = ata_id_has_lba48(dev->id);
970 933
971 new_sectors--; 934 new_sectors--;
972 935
973 ata_tf_init(dev, &tf); 936 ata_tf_init(dev, &tf);
974 937
975 tf.command = ATA_CMD_SET_MAX;
976 tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; 938 tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
939
940 if (lba48) {
941 tf.command = ATA_CMD_SET_MAX_EXT;
942 tf.flags |= ATA_TFLAG_LBA48;
943
944 tf.hob_lbal = (new_sectors >> 24) & 0xff;
945 tf.hob_lbam = (new_sectors >> 32) & 0xff;
946 tf.hob_lbah = (new_sectors >> 40) & 0xff;
947 } else
948 tf.command = ATA_CMD_SET_MAX;
949
977 tf.protocol |= ATA_PROT_NODATA; 950 tf.protocol |= ATA_PROT_NODATA;
951 tf.device |= ATA_LBA;
978 952
979 tf.lbal = (new_sectors >> 0) & 0xff; 953 tf.lbal = (new_sectors >> 0) & 0xff;
980 tf.lbam = (new_sectors >> 8) & 0xff; 954 tf.lbam = (new_sectors >> 8) & 0xff;
981 tf.lbah = (new_sectors >> 16) & 0xff; 955 tf.lbah = (new_sectors >> 16) & 0xff;
982 tf.device |= ((new_sectors >> 24) & 0x0f) | 0x40;
983 956
984 err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); 957 err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
985 if (err) 958 if (err_mask) {
986 return 0; 959 ata_dev_printk(dev, KERN_WARNING, "failed to set "
960 "max address (err_mask=0x%x)\n", err_mask);
961 if (err_mask == AC_ERR_DEV &&
962 (tf.feature & (ATA_ABORTED | ATA_IDNF)))
963 return -EACCES;
964 return -EIO;
965 }
987 966
988 return ata_tf_to_lba(&tf); 967 if (lba48)
968 *res_sectors = ata_tf_to_lba48(&tf);
969 else
970 *res_sectors = ata_tf_to_lba(&tf);
971
972 return 0;
989} 973}
990 974
991/** 975/**
@@ -1001,11 +985,11 @@ static u64 ata_hpa_resize(struct ata_device *dev)
1001{ 985{
1002 u64 sectors = dev->n_sectors; 986 u64 sectors = dev->n_sectors;
1003 u64 hpa_sectors; 987 u64 hpa_sectors;
988 int rc;
1004 989
1005 if (ata_id_has_lba48(dev->id)) 990 rc = ata_read_native_max_address(dev, &hpa_sectors);
1006 hpa_sectors = ata_read_native_max_address_ext(dev); 991 if (rc)
1007 else 992 return 0;
1008 hpa_sectors = ata_read_native_max_address(dev);
1009 993
1010 if (hpa_sectors > sectors) { 994 if (hpa_sectors > sectors) {
1011 ata_dev_printk(dev, KERN_INFO, 995 ata_dev_printk(dev, KERN_INFO,
@@ -1015,13 +999,9 @@ static u64 ata_hpa_resize(struct ata_device *dev)
1015 (long long)sectors, (long long)hpa_sectors); 999 (long long)sectors, (long long)hpa_sectors);
1016 1000
1017 if (ata_ignore_hpa) { 1001 if (ata_ignore_hpa) {
1018 if (ata_id_has_lba48(dev->id)) 1002 rc = ata_set_max_sectors(dev, hpa_sectors, &hpa_sectors);
1019 hpa_sectors = ata_set_native_max_address_ext(dev, hpa_sectors);
1020 else
1021 hpa_sectors = ata_set_native_max_address(dev,
1022 hpa_sectors);
1023 1003
1024 if (hpa_sectors) { 1004 if (rc == 0) {
1025 ata_dev_printk(dev, KERN_INFO, "native size " 1005 ata_dev_printk(dev, KERN_INFO, "native size "
1026 "increased to %lld sectors\n", 1006 "increased to %lld sectors\n",
1027 (long long)hpa_sectors); 1007 (long long)hpa_sectors);