diff options
author | Tejun Heo <htejun@gmail.com> | 2007-09-02 23:32:30 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-12 14:55:39 -0400 |
commit | c728a9149f519cbb9f610962873f4e22ed4a6efd (patch) | |
tree | f739bd40345252ab7885ac6af63ca176d7f36000 /drivers/ata/libata-core.c | |
parent | db6f8759d05d2082f09a45b5674edc0fb5e92b1b (diff) |
libata: clean up read/set native_max address functions
Merge ata_read_native_max_addres_ext() into ata_read_native_max_address()
and combine ata_set_native_max_address_ext() and
ata_set_native_max_address() into ata_set_max_sectors().
* reduce duplicate code
* return 0 or -errno depending on error conditions
* report if command fails
* use ATA_LBA instead of 0x40
This is in preparation of ata_hpa_resize() update.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 174 |
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 | |||
873 | static 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 | 877 | static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors) | |
900 | static 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 | |||
928 | static 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 | 927 | static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors, | |
966 | static 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); |