diff options
author | Albert Lee <albertcc@tw.ibm.com> | 2005-05-12 15:29:42 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-05-12 15:29:42 -0400 |
commit | 8bf62ecee58360749c5f0e68bc97d5e02a6816b1 (patch) | |
tree | a3da6e695fc5a71ac7f3246707380a9ac22f6402 /drivers/scsi/libata-core.c | |
parent | 88d7bd8cb9eb8d64bf7997600b0d64f7834047c5 (diff) |
[libata] C/H/S support, for older devices
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r-- | drivers/scsi/libata-core.c | 140 |
1 files changed, 115 insertions, 25 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 0b5d3a5b7eda..96355b05fe5c 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -52,6 +52,7 @@ | |||
52 | static unsigned int ata_busy_sleep (struct ata_port *ap, | 52 | static unsigned int ata_busy_sleep (struct ata_port *ap, |
53 | unsigned long tmout_pat, | 53 | unsigned long tmout_pat, |
54 | unsigned long tmout); | 54 | unsigned long tmout); |
55 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); | ||
55 | static void ata_set_mode(struct ata_port *ap); | 56 | static void ata_set_mode(struct ata_port *ap); |
56 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); | 57 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); |
57 | static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift); | 58 | static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift); |
@@ -1008,7 +1009,7 @@ static inline void ata_dump_id(struct ata_device *dev) | |||
1008 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) | 1009 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) |
1009 | { | 1010 | { |
1010 | struct ata_device *dev = &ap->device[device]; | 1011 | struct ata_device *dev = &ap->device[device]; |
1011 | unsigned int i; | 1012 | unsigned int major_version; |
1012 | u16 tmp; | 1013 | u16 tmp; |
1013 | unsigned long xfer_modes; | 1014 | unsigned long xfer_modes; |
1014 | u8 status; | 1015 | u8 status; |
@@ -1106,9 +1107,9 @@ retry: | |||
1106 | * common ATA, ATAPI feature tests | 1107 | * common ATA, ATAPI feature tests |
1107 | */ | 1108 | */ |
1108 | 1109 | ||
1109 | /* we require LBA and DMA support (bits 8 & 9 of word 49) */ | 1110 | /* we require DMA support (bits 8 of word 49) */ |
1110 | if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) { | 1111 | if (!ata_id_has_dma(dev->id)) { |
1111 | printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id); | 1112 | printk(KERN_DEBUG "ata%u: no dma\n", ap->id); |
1112 | goto err_out_nosup; | 1113 | goto err_out_nosup; |
1113 | } | 1114 | } |
1114 | 1115 | ||
@@ -1128,32 +1129,69 @@ retry: | |||
1128 | if (!ata_id_is_ata(dev->id)) /* sanity check */ | 1129 | if (!ata_id_is_ata(dev->id)) /* sanity check */ |
1129 | goto err_out_nosup; | 1130 | goto err_out_nosup; |
1130 | 1131 | ||
1132 | /* get major version */ | ||
1131 | tmp = dev->id[ATA_ID_MAJOR_VER]; | 1133 | tmp = dev->id[ATA_ID_MAJOR_VER]; |
1132 | for (i = 14; i >= 1; i--) | 1134 | for (major_version = 14; major_version >= 1; major_version--) |
1133 | if (tmp & (1 << i)) | 1135 | if (tmp & (1 << major_version)) |
1134 | break; | 1136 | break; |
1135 | 1137 | ||
1136 | /* we require at least ATA-3 */ | 1138 | /* |
1137 | if (i < 3) { | 1139 | * The exact sequence expected by certain pre-ATA4 drives is: |
1138 | printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id); | 1140 | * SRST RESET |
1139 | goto err_out_nosup; | 1141 | * IDENTIFY |
1140 | } | 1142 | * INITIALIZE DEVICE PARAMETERS |
1143 | * anything else.. | ||
1144 | * Some drives were very specific about that exact sequence. | ||
1145 | */ | ||
1146 | if (major_version < 4 || (!ata_id_has_lba(dev->id))) | ||
1147 | ata_dev_init_params(ap, dev); | ||
1148 | |||
1149 | if (ata_id_has_lba(dev->id)) { | ||
1150 | dev->flags |= ATA_DFLAG_LBA; | ||
1151 | |||
1152 | if (ata_id_has_lba48(dev->id)) { | ||
1153 | dev->flags |= ATA_DFLAG_LBA48; | ||
1154 | dev->n_sectors = ata_id_u64(dev->id, 100); | ||
1155 | } else { | ||
1156 | dev->n_sectors = ata_id_u32(dev->id, 60); | ||
1157 | } | ||
1158 | |||
1159 | /* print device info to dmesg */ | ||
1160 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n", | ||
1161 | ap->id, device, | ||
1162 | major_version, | ||
1163 | ata_mode_string(xfer_modes), | ||
1164 | (unsigned long long)dev->n_sectors, | ||
1165 | dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA"); | ||
1166 | } else { | ||
1167 | /* CHS */ | ||
1168 | |||
1169 | /* Default translation */ | ||
1170 | dev->cylinders = dev->id[1]; | ||
1171 | dev->heads = dev->id[3]; | ||
1172 | dev->sectors = dev->id[6]; | ||
1173 | dev->n_sectors = dev->cylinders * dev->heads * dev->sectors; | ||
1174 | |||
1175 | if (ata_id_current_chs_valid(dev->id)) { | ||
1176 | /* Current CHS translation is valid. */ | ||
1177 | dev->cylinders = dev->id[54]; | ||
1178 | dev->heads = dev->id[55]; | ||
1179 | dev->sectors = dev->id[56]; | ||
1180 | |||
1181 | dev->n_sectors = ata_id_u32(dev->id, 57); | ||
1182 | } | ||
1183 | |||
1184 | /* print device info to dmesg */ | ||
1185 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n", | ||
1186 | ap->id, device, | ||
1187 | major_version, | ||
1188 | ata_mode_string(xfer_modes), | ||
1189 | (unsigned long long)dev->n_sectors, | ||
1190 | (int)dev->cylinders, (int)dev->heads, (int)dev->sectors); | ||
1141 | 1191 | ||
1142 | if (ata_id_has_lba48(dev->id)) { | ||
1143 | dev->flags |= ATA_DFLAG_LBA48; | ||
1144 | dev->n_sectors = ata_id_u64(dev->id, 100); | ||
1145 | } else { | ||
1146 | dev->n_sectors = ata_id_u32(dev->id, 60); | ||
1147 | } | 1192 | } |
1148 | 1193 | ||
1149 | ap->host->max_cmd_len = 16; | 1194 | ap->host->max_cmd_len = 16; |
1150 | |||
1151 | /* print device info to dmesg */ | ||
1152 | printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n", | ||
1153 | ap->id, device, | ||
1154 | ata_mode_string(xfer_modes), | ||
1155 | (unsigned long long)dev->n_sectors, | ||
1156 | dev->flags & ATA_DFLAG_LBA48 ? " lba48" : ""); | ||
1157 | } | 1195 | } |
1158 | 1196 | ||
1159 | /* ATAPI-specific feature tests */ | 1197 | /* ATAPI-specific feature tests */ |
@@ -1947,6 +1985,54 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | |||
1947 | } | 1985 | } |
1948 | 1986 | ||
1949 | /** | 1987 | /** |
1988 | * ata_dev_init_params - Issue INIT DEV PARAMS command | ||
1989 | * @ap: Port associated with device @dev | ||
1990 | * @dev: Device to which command will be sent | ||
1991 | * | ||
1992 | * LOCKING: | ||
1993 | */ | ||
1994 | |||
1995 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev) | ||
1996 | { | ||
1997 | DECLARE_COMPLETION(wait); | ||
1998 | struct ata_queued_cmd *qc; | ||
1999 | int rc; | ||
2000 | unsigned long flags; | ||
2001 | u16 sectors = dev->id[6]; | ||
2002 | u16 heads = dev->id[3]; | ||
2003 | |||
2004 | /* Number of sectors per track 1-255. Number of heads 1-16 */ | ||
2005 | if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) | ||
2006 | return; | ||
2007 | |||
2008 | /* set up init dev params taskfile */ | ||
2009 | DPRINTK("init dev params \n"); | ||
2010 | |||
2011 | qc = ata_qc_new_init(ap, dev); | ||
2012 | BUG_ON(qc == NULL); | ||
2013 | |||
2014 | qc->tf.command = ATA_CMD_INIT_DEV_PARAMS; | ||
2015 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
2016 | qc->tf.protocol = ATA_PROT_NODATA; | ||
2017 | qc->tf.nsect = sectors; | ||
2018 | qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */ | ||
2019 | |||
2020 | qc->waiting = &wait; | ||
2021 | qc->complete_fn = ata_qc_complete_noop; | ||
2022 | |||
2023 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
2024 | rc = ata_qc_issue(qc); | ||
2025 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
2026 | |||
2027 | if (rc) | ||
2028 | ata_port_disable(ap); | ||
2029 | else | ||
2030 | wait_for_completion(&wait); | ||
2031 | |||
2032 | DPRINTK("EXIT\n"); | ||
2033 | } | ||
2034 | |||
2035 | /** | ||
1950 | * ata_sg_clean - | 2036 | * ata_sg_clean - |
1951 | * @qc: | 2037 | * @qc: |
1952 | * | 2038 | * |
@@ -2736,8 +2822,12 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | |||
2736 | 2822 | ||
2737 | ata_tf_init(ap, &qc->tf, dev->devno); | 2823 | ata_tf_init(ap, &qc->tf, dev->devno); |
2738 | 2824 | ||
2739 | if (dev->flags & ATA_DFLAG_LBA48) | 2825 | if (dev->flags & ATA_DFLAG_LBA) { |
2740 | qc->tf.flags |= ATA_TFLAG_LBA48; | 2826 | qc->tf.flags |= ATA_TFLAG_LBA; |
2827 | |||
2828 | if (dev->flags & ATA_DFLAG_LBA48) | ||
2829 | qc->tf.flags |= ATA_TFLAG_LBA48; | ||
2830 | } | ||
2741 | } | 2831 | } |
2742 | 2832 | ||
2743 | return qc; | 2833 | return qc; |