diff options
author | Tejun Heo <htejun@gmail.com> | 2006-02-20 12:12:11 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-20 18:56:58 -0500 |
commit | 49016aca2e54c64f08c31d5512dfd8d35f934c58 (patch) | |
tree | f0b5c2843f74a9adb62761d0ec9d05284bc47a1c /drivers/scsi/libata-core.c | |
parent | f131883e73a8662dc92c3ea371ae9ded0c8f2c37 (diff) |
[PATCH] libata: separate out ata_dev_read_id()
Separate out ata_dev_read_id() from ata_dev_identify(). This is the
first half of splitting ata_dev_identify(). ata_dev_read_id() will
also be used for revalidation. This patch does not make any behavior
change.
ata_dev_read_id() doesn't modify any of libata-internal data
structures. It simply reads IDENTIFY page and returns error code on
failure. INIT_DEV_PARAMS and EDD wrong class code are also handled by
this function.
Re-reading IDENTIFY after INIT_DEV_PARAMS is performed by jumping to
retry: instead of calling ata_dev_reread_id(). This is done because
1. there's retry label anyway 2. ata_dev_reread_id() cannot be used
anywhere else so there's no reason to keep it.
This function is probably the place to set transfer mode to PIO0
before IDENTIFY. However, reset -> identify -> init_dev_params order
should be kept for pre-ATA4 devices so we cannot set transfer mode
before IDENTIFY for them. How do we know if a device is post-ATA4
before IDENTIFY?
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r-- | drivers/scsi/libata-core.c | 210 |
1 files changed, 128 insertions, 82 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 70efde99f652..d0a26e9553a1 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -903,42 +903,36 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) | |||
903 | } | 903 | } |
904 | 904 | ||
905 | /** | 905 | /** |
906 | * ata_dev_identify - obtain IDENTIFY x DEVICE page | 906 | * ata_dev_read_id - Read ID data from the specified device |
907 | * @ap: port on which device we wish to probe resides | 907 | * @ap: port on which target device resides |
908 | * @device: device bus address, starting at zero | 908 | * @dev: target device |
909 | * | 909 | * @p_class: pointer to class of the target device (may be changed) |
910 | * Following bus reset, we issue the IDENTIFY [PACKET] DEVICE | 910 | * @post_reset: is this read ID post-reset? |
911 | * command, and read back the 512-byte device information page. | 911 | * @id: buffer to fill IDENTIFY page into |
912 | * The device information page is fed to us via the standard | 912 | * |
913 | * PIO-IN protocol, but we hand-code it here. (TODO: investigate | 913 | * Read ID data from the specified device. ATA_CMD_ID_ATA is |
914 | * using standard PIO-IN paths) | 914 | * performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI |
915 | * | 915 | * devices. This function also takes care of EDD signature |
916 | * After reading the device information page, we use several | 916 | * misreporting (to be removed once EDD support is gone) and |
917 | * bits of information from it to initialize data structures | 917 | * issues ATA_CMD_INIT_DEV_PARAMS for pre-ATA4 drives. |
918 | * that will be used during the lifetime of the ata_device. | ||
919 | * Other data from the info page is used to disqualify certain | ||
920 | * older ATA devices we do not wish to support. | ||
921 | * | 918 | * |
922 | * LOCKING: | 919 | * LOCKING: |
923 | * Inherited from caller. Some functions called by this function | 920 | * Kernel thread context (may sleep) |
924 | * obtain the host_set lock. | 921 | * |
922 | * RETURNS: | ||
923 | * 0 on success, -errno otherwise. | ||
925 | */ | 924 | */ |
926 | 925 | static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, | |
927 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) | 926 | unsigned int *p_class, int post_reset, u16 *id) |
928 | { | 927 | { |
929 | struct ata_device *dev = &ap->device[device]; | 928 | unsigned int class = *p_class; |
930 | unsigned int major_version; | ||
931 | unsigned long xfer_modes; | ||
932 | unsigned int using_edd; | 929 | unsigned int using_edd; |
933 | struct ata_taskfile tf; | 930 | struct ata_taskfile tf; |
934 | unsigned int err_mask; | 931 | unsigned int err_mask = 0; |
935 | int i, rc; | 932 | const char *reason; |
933 | int rc; | ||
936 | 934 | ||
937 | if (!ata_dev_present(dev)) { | 935 | DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); |
938 | DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n", | ||
939 | ap->id, device); | ||
940 | return; | ||
941 | } | ||
942 | 936 | ||
943 | if (ap->ops->probe_reset || | 937 | if (ap->ops->probe_reset || |
944 | ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET)) | 938 | ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET)) |
@@ -946,30 +940,33 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device) | |||
946 | else | 940 | else |
947 | using_edd = 1; | 941 | using_edd = 1; |
948 | 942 | ||
949 | DPRINTK("ENTER, host %u, dev %u\n", ap->id, device); | 943 | ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ |
950 | |||
951 | WARN_ON(dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ATAPI && | ||
952 | dev->class != ATA_DEV_NONE); | ||
953 | |||
954 | ata_dev_select(ap, device, 1, 1); /* select device 0/1 */ | ||
955 | 944 | ||
956 | retry: | 945 | retry: |
957 | ata_tf_init(ap, &tf, device); | 946 | ata_tf_init(ap, &tf, dev->devno); |
958 | 947 | ||
959 | if (dev->class == ATA_DEV_ATA) { | 948 | switch (class) { |
949 | case ATA_DEV_ATA: | ||
960 | tf.command = ATA_CMD_ID_ATA; | 950 | tf.command = ATA_CMD_ID_ATA; |
961 | DPRINTK("do ATA identify\n"); | 951 | break; |
962 | } else { | 952 | case ATA_DEV_ATAPI: |
963 | tf.command = ATA_CMD_ID_ATAPI; | 953 | tf.command = ATA_CMD_ID_ATAPI; |
964 | DPRINTK("do ATAPI identify\n"); | 954 | break; |
955 | default: | ||
956 | rc = -ENODEV; | ||
957 | reason = "unsupported class"; | ||
958 | goto err_out; | ||
965 | } | 959 | } |
966 | 960 | ||
967 | tf.protocol = ATA_PROT_PIO; | 961 | tf.protocol = ATA_PROT_PIO; |
968 | 962 | ||
969 | err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE, | 963 | err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE, |
970 | dev->id, sizeof(dev->id)); | 964 | id, sizeof(id[0]) * ATA_ID_WORDS); |
971 | 965 | ||
972 | if (err_mask) { | 966 | if (err_mask) { |
967 | rc = -EIO; | ||
968 | reason = "I/O error"; | ||
969 | |||
973 | if (err_mask & ~AC_ERR_DEV) | 970 | if (err_mask & ~AC_ERR_DEV) |
974 | goto err_out; | 971 | goto err_out; |
975 | 972 | ||
@@ -984,25 +981,105 @@ retry: | |||
984 | * ATA software reset (SRST, the default) does not appear | 981 | * ATA software reset (SRST, the default) does not appear |
985 | * to have this problem. | 982 | * to have this problem. |
986 | */ | 983 | */ |
987 | if ((using_edd) && (dev->class == ATA_DEV_ATA)) { | 984 | if ((using_edd) && (class == ATA_DEV_ATA)) { |
988 | u8 err = tf.feature; | 985 | u8 err = tf.feature; |
989 | if (err & ATA_ABORTED) { | 986 | if (err & ATA_ABORTED) { |
990 | dev->class = ATA_DEV_ATAPI; | 987 | class = ATA_DEV_ATAPI; |
991 | goto retry; | 988 | goto retry; |
992 | } | 989 | } |
993 | } | 990 | } |
994 | goto err_out; | 991 | goto err_out; |
995 | } | 992 | } |
996 | 993 | ||
997 | swap_buf_le16(dev->id, ATA_ID_WORDS); | 994 | swap_buf_le16(id, ATA_ID_WORDS); |
998 | 995 | ||
999 | /* print device capabilities */ | 996 | /* print device capabilities */ |
1000 | printk(KERN_DEBUG "ata%u: dev %u cfg " | 997 | printk(KERN_DEBUG "ata%u: dev %u cfg " |
1001 | "49:%04x 82:%04x 83:%04x 84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", | 998 | "49:%04x 82:%04x 83:%04x 84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", |
1002 | ap->id, device, dev->id[49], | 999 | ap->id, dev->devno, |
1003 | dev->id[82], dev->id[83], dev->id[84], | 1000 | id[49], id[82], id[83], id[84], id[85], id[86], id[87], id[88]); |
1004 | dev->id[85], dev->id[86], dev->id[87], | 1001 | |
1005 | dev->id[88]); | 1002 | /* sanity check */ |
1003 | if ((class == ATA_DEV_ATA) != ata_id_is_ata(id)) { | ||
1004 | rc = -EINVAL; | ||
1005 | reason = "device reports illegal type"; | ||
1006 | goto err_out; | ||
1007 | } | ||
1008 | |||
1009 | if (post_reset && class == ATA_DEV_ATA) { | ||
1010 | /* | ||
1011 | * The exact sequence expected by certain pre-ATA4 drives is: | ||
1012 | * SRST RESET | ||
1013 | * IDENTIFY | ||
1014 | * INITIALIZE DEVICE PARAMETERS | ||
1015 | * anything else.. | ||
1016 | * Some drives were very specific about that exact sequence. | ||
1017 | */ | ||
1018 | if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) { | ||
1019 | err_mask = ata_dev_init_params(ap, dev); | ||
1020 | if (err_mask) { | ||
1021 | rc = -EIO; | ||
1022 | reason = "INIT_DEV_PARAMS failed"; | ||
1023 | goto err_out; | ||
1024 | } | ||
1025 | |||
1026 | /* current CHS translation info (id[53-58]) might be | ||
1027 | * changed. reread the identify device info. | ||
1028 | */ | ||
1029 | post_reset = 0; | ||
1030 | goto retry; | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | *p_class = class; | ||
1035 | return 0; | ||
1036 | |||
1037 | err_out: | ||
1038 | printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n", | ||
1039 | ap->id, dev->devno, reason); | ||
1040 | kfree(id); | ||
1041 | return rc; | ||
1042 | } | ||
1043 | |||
1044 | /** | ||
1045 | * ata_dev_identify - obtain IDENTIFY x DEVICE page | ||
1046 | * @ap: port on which device we wish to probe resides | ||
1047 | * @device: device bus address, starting at zero | ||
1048 | * | ||
1049 | * Following bus reset, we issue the IDENTIFY [PACKET] DEVICE | ||
1050 | * command, and read back the 512-byte device information page. | ||
1051 | * The device information page is fed to us via the standard | ||
1052 | * PIO-IN protocol, but we hand-code it here. (TODO: investigate | ||
1053 | * using standard PIO-IN paths) | ||
1054 | * | ||
1055 | * After reading the device information page, we use several | ||
1056 | * bits of information from it to initialize data structures | ||
1057 | * that will be used during the lifetime of the ata_device. | ||
1058 | * Other data from the info page is used to disqualify certain | ||
1059 | * older ATA devices we do not wish to support. | ||
1060 | * | ||
1061 | * LOCKING: | ||
1062 | * Inherited from caller. Some functions called by this function | ||
1063 | * obtain the host_set lock. | ||
1064 | */ | ||
1065 | |||
1066 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) | ||
1067 | { | ||
1068 | struct ata_device *dev = &ap->device[device]; | ||
1069 | unsigned long xfer_modes; | ||
1070 | int i, rc; | ||
1071 | |||
1072 | if (!ata_dev_present(dev)) { | ||
1073 | DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n", | ||
1074 | ap->id, device); | ||
1075 | return; | ||
1076 | } | ||
1077 | |||
1078 | DPRINTK("ENTER, host %u, dev %u\n", ap->id, device); | ||
1079 | |||
1080 | rc = ata_dev_read_id(ap, dev, &dev->class, 1, dev->id); | ||
1081 | if (rc) | ||
1082 | goto err_out; | ||
1006 | 1083 | ||
1007 | /* | 1084 | /* |
1008 | * common ATA, ATAPI feature tests | 1085 | * common ATA, ATAPI feature tests |
@@ -1027,34 +1104,6 @@ retry: | |||
1027 | if (dev->class == ATA_DEV_ATA) { | 1104 | if (dev->class == ATA_DEV_ATA) { |
1028 | dev->n_sectors = ata_id_n_sectors(dev->id); | 1105 | dev->n_sectors = ata_id_n_sectors(dev->id); |
1029 | 1106 | ||
1030 | if (!ata_id_is_ata(dev->id)) /* sanity check */ | ||
1031 | goto err_out_nosup; | ||
1032 | |||
1033 | /* get major version */ | ||
1034 | major_version = ata_id_major_version(dev->id); | ||
1035 | |||
1036 | /* | ||
1037 | * The exact sequence expected by certain pre-ATA4 drives is: | ||
1038 | * SRST RESET | ||
1039 | * IDENTIFY | ||
1040 | * INITIALIZE DEVICE PARAMETERS | ||
1041 | * anything else.. | ||
1042 | * Some drives were very specific about that exact sequence. | ||
1043 | */ | ||
1044 | if (major_version < 4 || (!ata_id_has_lba(dev->id))) { | ||
1045 | err_mask = ata_dev_init_params(ap, dev); | ||
1046 | if (err_mask) { | ||
1047 | printk(KERN_ERR "ata%u: failed to init " | ||
1048 | "parameters, disabled\n", ap->id); | ||
1049 | goto err_out; | ||
1050 | } | ||
1051 | |||
1052 | /* current CHS translation info (id[53-58]) might be | ||
1053 | * changed. reread the identify device info. | ||
1054 | */ | ||
1055 | ata_dev_reread_id(ap, dev); | ||
1056 | } | ||
1057 | |||
1058 | if (ata_id_has_lba(dev->id)) { | 1107 | if (ata_id_has_lba(dev->id)) { |
1059 | dev->flags |= ATA_DFLAG_LBA; | 1108 | dev->flags |= ATA_DFLAG_LBA; |
1060 | 1109 | ||
@@ -1064,7 +1113,7 @@ retry: | |||
1064 | /* print device info to dmesg */ | 1113 | /* print device info to dmesg */ |
1065 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n", | 1114 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n", |
1066 | ap->id, device, | 1115 | ap->id, device, |
1067 | major_version, | 1116 | ata_id_major_version(dev->id), |
1068 | ata_mode_string(xfer_modes), | 1117 | ata_mode_string(xfer_modes), |
1069 | (unsigned long long)dev->n_sectors, | 1118 | (unsigned long long)dev->n_sectors, |
1070 | dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA"); | 1119 | dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA"); |
@@ -1086,7 +1135,7 @@ retry: | |||
1086 | /* print device info to dmesg */ | 1135 | /* print device info to dmesg */ |
1087 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n", | 1136 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n", |
1088 | ap->id, device, | 1137 | ap->id, device, |
1089 | major_version, | 1138 | ata_id_major_version(dev->id), |
1090 | ata_mode_string(xfer_modes), | 1139 | ata_mode_string(xfer_modes), |
1091 | (unsigned long long)dev->n_sectors, | 1140 | (unsigned long long)dev->n_sectors, |
1092 | (int)dev->cylinders, (int)dev->heads, (int)dev->sectors); | 1141 | (int)dev->cylinders, (int)dev->heads, (int)dev->sectors); |
@@ -1098,9 +1147,6 @@ retry: | |||
1098 | 1147 | ||
1099 | /* ATAPI-specific feature tests */ | 1148 | /* ATAPI-specific feature tests */ |
1100 | else if (dev->class == ATA_DEV_ATAPI) { | 1149 | else if (dev->class == ATA_DEV_ATAPI) { |
1101 | if (ata_id_is_ata(dev->id)) /* sanity check */ | ||
1102 | goto err_out_nosup; | ||
1103 | |||
1104 | rc = atapi_cdb_len(dev->id); | 1150 | rc = atapi_cdb_len(dev->id); |
1105 | if ((rc < 12) || (rc > ATAPI_CDB_LEN)) { | 1151 | if ((rc < 12) || (rc > ATAPI_CDB_LEN)) { |
1106 | printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id); | 1152 | printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id); |