aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-09-02 23:32:57 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-12 14:55:39 -0400
commit05027adccc09401a7e31d5ef51040dc75ab03c22 (patch)
tree83fbb8e65d26e10e1fd74377bc13fd358a61c13e /drivers
parentc728a9149f519cbb9f610962873f4e22ed4a6efd (diff)
libata: remiplement ata_hpa_resize()
This patch reimplement ata_hpa_resize() such that... * All HPA related decisions are made inside ata_hpa_resize() proper. ata_hpa_resize() returns 0 if configuration can proceed, -errno if device needs to be reset and reconfigured. * All errors are handled properly. If HPA unlocking isn't requested, HPA handling is disabled automatically to avoid unnecessary device detection failure. * Messages are trimmed. HPA detection message is printed only during initial configuration. HPA unlocked message is printed only during initial configuration or unlocking results in different size. * Instead of using sectors returned in TF of SET_MAX, re-read IDENTIFY data as that's the value the device is going to use. * It's called early during ata_dev_configure() as IDENTIFY data might change after resizing. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-core.c124
1 files changed, 85 insertions, 39 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index c7614bdc0cb9..b01b5a897dcf 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -915,7 +915,6 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors)
915 * ata_set_max_sectors - Set max sectors 915 * ata_set_max_sectors - Set max sectors
916 * @dev: target device 916 * @dev: target device
917 * @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
919 * 918 *
920 * Set max sectors of @dev to @new_sectors. 919 * Set max sectors of @dev to @new_sectors.
921 * 920 *
@@ -924,8 +923,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors)
924 * previous non-volatile SET_MAX) by the drive. -EIO on other 923 * previous non-volatile SET_MAX) by the drive. -EIO on other
925 * errors. 924 * errors.
926 */ 925 */
927static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors, 926static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors)
928 u64 *res_sectors)
929{ 927{
930 unsigned int err_mask; 928 unsigned int err_mask;
931 struct ata_taskfile tf; 929 struct ata_taskfile tf;
@@ -964,11 +962,6 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors,
964 return -EIO; 962 return -EIO;
965 } 963 }
966 964
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; 965 return 0;
973} 966}
974 967
@@ -979,41 +972,93 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors,
979 * Read the size of an LBA28 or LBA48 disk with HPA features and resize 972 * Read the size of an LBA28 or LBA48 disk with HPA features and resize
980 * it if required to the full size of the media. The caller must check 973 * it if required to the full size of the media. The caller must check
981 * the drive has the HPA feature set enabled. 974 * the drive has the HPA feature set enabled.
975 *
976 * RETURNS:
977 * 0 on success, -errno on failure.
982 */ 978 */
983 979static int ata_hpa_resize(struct ata_device *dev)
984static u64 ata_hpa_resize(struct ata_device *dev)
985{ 980{
986 u64 sectors = dev->n_sectors; 981 struct ata_eh_context *ehc = &dev->link->eh_context;
987 u64 hpa_sectors; 982 int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
983 u64 sectors = ata_id_n_sectors(dev->id);
984 u64 native_sectors;
988 int rc; 985 int rc;
989 986
990 rc = ata_read_native_max_address(dev, &hpa_sectors); 987 /* do we need to do it? */
991 if (rc) 988 if (dev->class != ATA_DEV_ATA ||
989 !ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) ||
990 (dev->horkage & ATA_HORKAGE_BROKEN_HPA))
992 return 0; 991 return 0;
993 992
994 if (hpa_sectors > sectors) { 993 /* read native max address */
995 ata_dev_printk(dev, KERN_INFO, 994 rc = ata_read_native_max_address(dev, &native_sectors);
996 "Host Protected Area detected:\n" 995 if (rc) {
997 "\tcurrent size: %lld sectors\n" 996 /* If HPA isn't going to be unlocked, skip HPA
998 "\tnative size: %lld sectors\n", 997 * resizing from the next try.
999 (long long)sectors, (long long)hpa_sectors); 998 */
1000 999 if (!ata_ignore_hpa) {
1001 if (ata_ignore_hpa) { 1000 ata_dev_printk(dev, KERN_WARNING, "HPA support seems "
1002 rc = ata_set_max_sectors(dev, hpa_sectors, &hpa_sectors); 1001 "broken, will skip HPA handling\n");
1003 1002 dev->horkage |= ATA_HORKAGE_BROKEN_HPA;
1004 if (rc == 0) { 1003
1005 ata_dev_printk(dev, KERN_INFO, "native size " 1004 /* we can continue if device aborted the command */
1006 "increased to %lld sectors\n", 1005 if (rc == -EACCES)
1007 (long long)hpa_sectors); 1006 rc = 0;
1008 return hpa_sectors;
1009 }
1010 } 1007 }
1011 } else if (hpa_sectors < sectors)
1012 ata_dev_printk(dev, KERN_WARNING, "%s 1: hpa sectors (%lld) "
1013 "is smaller than sectors (%lld)\n", __FUNCTION__,
1014 (long long)hpa_sectors, (long long)sectors);
1015 1008
1016 return sectors; 1009 return rc;
1010 }
1011
1012 /* nothing to do? */
1013 if (native_sectors <= sectors || !ata_ignore_hpa) {
1014 if (!print_info || native_sectors == sectors)
1015 return 0;
1016
1017 if (native_sectors > sectors)
1018 ata_dev_printk(dev, KERN_INFO,
1019 "HPA detected: current %llu, native %llu\n",
1020 (unsigned long long)sectors,
1021 (unsigned long long)native_sectors);
1022 else if (native_sectors < sectors)
1023 ata_dev_printk(dev, KERN_WARNING,
1024 "native sectors (%llu) is smaller than "
1025 "sectors (%llu)\n",
1026 (unsigned long long)native_sectors,
1027 (unsigned long long)sectors);
1028 return 0;
1029 }
1030
1031 /* let's unlock HPA */
1032 rc = ata_set_max_sectors(dev, native_sectors);
1033 if (rc == -EACCES) {
1034 /* if device aborted the command, skip HPA resizing */
1035 ata_dev_printk(dev, KERN_WARNING, "device aborted resize "
1036 "(%llu -> %llu), skipping HPA handling\n",
1037 (unsigned long long)sectors,
1038 (unsigned long long)native_sectors);
1039 dev->horkage |= ATA_HORKAGE_BROKEN_HPA;
1040 return 0;
1041 } else if (rc)
1042 return rc;
1043
1044 /* re-read IDENTIFY data */
1045 rc = ata_dev_reread_id(dev, 0);
1046 if (rc) {
1047 ata_dev_printk(dev, KERN_ERR, "failed to re-read IDENTIFY "
1048 "data after HPA resizing\n");
1049 return rc;
1050 }
1051
1052 if (print_info) {
1053 u64 new_sectors = ata_id_n_sectors(dev->id);
1054 ata_dev_printk(dev, KERN_INFO,
1055 "HPA unlocked: %llu -> %llu, native %llu\n",
1056 (unsigned long long)sectors,
1057 (unsigned long long)new_sectors,
1058 (unsigned long long)native_sectors);
1059 }
1060
1061 return 0;
1017} 1062}
1018 1063
1019/** 1064/**
@@ -1837,6 +1882,11 @@ int ata_dev_configure(struct ata_device *dev)
1837 if (rc) 1882 if (rc)
1838 return rc; 1883 return rc;
1839 1884
1885 /* massage HPA, do it early as it might change IDENTIFY data */
1886 rc = ata_hpa_resize(dev);
1887 if (rc)
1888 return rc;
1889
1840 /* print device capabilities */ 1890 /* print device capabilities */
1841 if (ata_msg_probe(ap)) 1891 if (ata_msg_probe(ap))
1842 ata_dev_printk(dev, KERN_DEBUG, 1892 ata_dev_printk(dev, KERN_DEBUG,
@@ -1904,10 +1954,6 @@ int ata_dev_configure(struct ata_device *dev)
1904 dev->flags |= ATA_DFLAG_FLUSH_EXT; 1954 dev->flags |= ATA_DFLAG_FLUSH_EXT;
1905 } 1955 }
1906 1956
1907 if (!(dev->horkage & ATA_HORKAGE_BROKEN_HPA) &&
1908 ata_id_hpa_enabled(dev->id))
1909 dev->n_sectors = ata_hpa_resize(dev);
1910
1911 /* config NCQ */ 1957 /* config NCQ */
1912 ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc)); 1958 ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
1913 1959