diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-28 12:11:15 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-28 12:11:15 -0400 |
commit | 64f09c98d7fce21dcb8da9f248e4159eb1ec245e (patch) | |
tree | e03ed75665d536438fcb79b468a439caacd3d7dc /drivers/scsi/libata-core.c | |
parent | 14be71f4c5c5ad1e222c5202ee6d234e9c8828b7 (diff) | |
parent | 98ed72deebfd2b55b7e1bb94c8175b1169999212 (diff) |
/spare/repo/libata-dev branch 'chs-support'
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 c4fcdc30f18c..03d422e99e58 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -62,6 +62,7 @@ | |||
62 | static unsigned int ata_busy_sleep (struct ata_port *ap, | 62 | static unsigned int ata_busy_sleep (struct ata_port *ap, |
63 | unsigned long tmout_pat, | 63 | unsigned long tmout_pat, |
64 | unsigned long tmout); | 64 | unsigned long tmout); |
65 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); | ||
65 | static void ata_set_mode(struct ata_port *ap); | 66 | static void ata_set_mode(struct ata_port *ap); |
66 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); | 67 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); |
67 | static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift); | 68 | static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift); |
@@ -1131,7 +1132,7 @@ static inline void ata_dump_id(struct ata_device *dev) | |||
1131 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) | 1132 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) |
1132 | { | 1133 | { |
1133 | struct ata_device *dev = &ap->device[device]; | 1134 | struct ata_device *dev = &ap->device[device]; |
1134 | unsigned int i; | 1135 | unsigned int major_version; |
1135 | u16 tmp; | 1136 | u16 tmp; |
1136 | unsigned long xfer_modes; | 1137 | unsigned long xfer_modes; |
1137 | u8 status; | 1138 | u8 status; |
@@ -1229,9 +1230,9 @@ retry: | |||
1229 | * common ATA, ATAPI feature tests | 1230 | * common ATA, ATAPI feature tests |
1230 | */ | 1231 | */ |
1231 | 1232 | ||
1232 | /* we require LBA and DMA support (bits 8 & 9 of word 49) */ | 1233 | /* we require DMA support (bits 8 of word 49) */ |
1233 | if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) { | 1234 | if (!ata_id_has_dma(dev->id)) { |
1234 | printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id); | 1235 | printk(KERN_DEBUG "ata%u: no dma\n", ap->id); |
1235 | goto err_out_nosup; | 1236 | goto err_out_nosup; |
1236 | } | 1237 | } |
1237 | 1238 | ||
@@ -1251,32 +1252,69 @@ retry: | |||
1251 | if (!ata_id_is_ata(dev->id)) /* sanity check */ | 1252 | if (!ata_id_is_ata(dev->id)) /* sanity check */ |
1252 | goto err_out_nosup; | 1253 | goto err_out_nosup; |
1253 | 1254 | ||
1255 | /* get major version */ | ||
1254 | tmp = dev->id[ATA_ID_MAJOR_VER]; | 1256 | tmp = dev->id[ATA_ID_MAJOR_VER]; |
1255 | for (i = 14; i >= 1; i--) | 1257 | for (major_version = 14; major_version >= 1; major_version--) |
1256 | if (tmp & (1 << i)) | 1258 | if (tmp & (1 << major_version)) |
1257 | break; | 1259 | break; |
1258 | 1260 | ||
1259 | /* we require at least ATA-3 */ | 1261 | /* |
1260 | if (i < 3) { | 1262 | * The exact sequence expected by certain pre-ATA4 drives is: |
1261 | printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id); | 1263 | * SRST RESET |
1262 | goto err_out_nosup; | 1264 | * IDENTIFY |
1263 | } | 1265 | * INITIALIZE DEVICE PARAMETERS |
1266 | * anything else.. | ||
1267 | * Some drives were very specific about that exact sequence. | ||
1268 | */ | ||
1269 | if (major_version < 4 || (!ata_id_has_lba(dev->id))) | ||
1270 | ata_dev_init_params(ap, dev); | ||
1271 | |||
1272 | if (ata_id_has_lba(dev->id)) { | ||
1273 | dev->flags |= ATA_DFLAG_LBA; | ||
1274 | |||
1275 | if (ata_id_has_lba48(dev->id)) { | ||
1276 | dev->flags |= ATA_DFLAG_LBA48; | ||
1277 | dev->n_sectors = ata_id_u64(dev->id, 100); | ||
1278 | } else { | ||
1279 | dev->n_sectors = ata_id_u32(dev->id, 60); | ||
1280 | } | ||
1281 | |||
1282 | /* print device info to dmesg */ | ||
1283 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n", | ||
1284 | ap->id, device, | ||
1285 | major_version, | ||
1286 | ata_mode_string(xfer_modes), | ||
1287 | (unsigned long long)dev->n_sectors, | ||
1288 | dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA"); | ||
1289 | } else { | ||
1290 | /* CHS */ | ||
1291 | |||
1292 | /* Default translation */ | ||
1293 | dev->cylinders = dev->id[1]; | ||
1294 | dev->heads = dev->id[3]; | ||
1295 | dev->sectors = dev->id[6]; | ||
1296 | dev->n_sectors = dev->cylinders * dev->heads * dev->sectors; | ||
1297 | |||
1298 | if (ata_id_current_chs_valid(dev->id)) { | ||
1299 | /* Current CHS translation is valid. */ | ||
1300 | dev->cylinders = dev->id[54]; | ||
1301 | dev->heads = dev->id[55]; | ||
1302 | dev->sectors = dev->id[56]; | ||
1303 | |||
1304 | dev->n_sectors = ata_id_u32(dev->id, 57); | ||
1305 | } | ||
1306 | |||
1307 | /* print device info to dmesg */ | ||
1308 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n", | ||
1309 | ap->id, device, | ||
1310 | major_version, | ||
1311 | ata_mode_string(xfer_modes), | ||
1312 | (unsigned long long)dev->n_sectors, | ||
1313 | (int)dev->cylinders, (int)dev->heads, (int)dev->sectors); | ||
1264 | 1314 | ||
1265 | if (ata_id_has_lba48(dev->id)) { | ||
1266 | dev->flags |= ATA_DFLAG_LBA48; | ||
1267 | dev->n_sectors = ata_id_u64(dev->id, 100); | ||
1268 | } else { | ||
1269 | dev->n_sectors = ata_id_u32(dev->id, 60); | ||
1270 | } | 1315 | } |
1271 | 1316 | ||
1272 | ap->host->max_cmd_len = 16; | 1317 | ap->host->max_cmd_len = 16; |
1273 | |||
1274 | /* print device info to dmesg */ | ||
1275 | printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n", | ||
1276 | ap->id, device, | ||
1277 | ata_mode_string(xfer_modes), | ||
1278 | (unsigned long long)dev->n_sectors, | ||
1279 | dev->flags & ATA_DFLAG_LBA48 ? " lba48" : ""); | ||
1280 | } | 1318 | } |
1281 | 1319 | ||
1282 | /* ATAPI-specific feature tests */ | 1320 | /* ATAPI-specific feature tests */ |
@@ -2144,6 +2182,54 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | |||
2144 | } | 2182 | } |
2145 | 2183 | ||
2146 | /** | 2184 | /** |
2185 | * ata_dev_init_params - Issue INIT DEV PARAMS command | ||
2186 | * @ap: Port associated with device @dev | ||
2187 | * @dev: Device to which command will be sent | ||
2188 | * | ||
2189 | * LOCKING: | ||
2190 | */ | ||
2191 | |||
2192 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev) | ||
2193 | { | ||
2194 | DECLARE_COMPLETION(wait); | ||
2195 | struct ata_queued_cmd *qc; | ||
2196 | int rc; | ||
2197 | unsigned long flags; | ||
2198 | u16 sectors = dev->id[6]; | ||
2199 | u16 heads = dev->id[3]; | ||
2200 | |||
2201 | /* Number of sectors per track 1-255. Number of heads 1-16 */ | ||
2202 | if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) | ||
2203 | return; | ||
2204 | |||
2205 | /* set up init dev params taskfile */ | ||
2206 | DPRINTK("init dev params \n"); | ||
2207 | |||
2208 | qc = ata_qc_new_init(ap, dev); | ||
2209 | BUG_ON(qc == NULL); | ||
2210 | |||
2211 | qc->tf.command = ATA_CMD_INIT_DEV_PARAMS; | ||
2212 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
2213 | qc->tf.protocol = ATA_PROT_NODATA; | ||
2214 | qc->tf.nsect = sectors; | ||
2215 | qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */ | ||
2216 | |||
2217 | qc->waiting = &wait; | ||
2218 | qc->complete_fn = ata_qc_complete_noop; | ||
2219 | |||
2220 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
2221 | rc = ata_qc_issue(qc); | ||
2222 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
2223 | |||
2224 | if (rc) | ||
2225 | ata_port_disable(ap); | ||
2226 | else | ||
2227 | wait_for_completion(&wait); | ||
2228 | |||
2229 | DPRINTK("EXIT\n"); | ||
2230 | } | ||
2231 | |||
2232 | /** | ||
2147 | * ata_sg_clean - Unmap DMA memory associated with command | 2233 | * ata_sg_clean - Unmap DMA memory associated with command |
2148 | * @qc: Command containing DMA memory to be released | 2234 | * @qc: Command containing DMA memory to be released |
2149 | * | 2235 | * |
@@ -3156,8 +3242,12 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | |||
3156 | 3242 | ||
3157 | ata_tf_init(ap, &qc->tf, dev->devno); | 3243 | ata_tf_init(ap, &qc->tf, dev->devno); |
3158 | 3244 | ||
3159 | if (dev->flags & ATA_DFLAG_LBA48) | 3245 | if (dev->flags & ATA_DFLAG_LBA) { |
3160 | qc->tf.flags |= ATA_TFLAG_LBA48; | 3246 | qc->tf.flags |= ATA_TFLAG_LBA; |
3247 | |||
3248 | if (dev->flags & ATA_DFLAG_LBA48) | ||
3249 | qc->tf.flags |= ATA_TFLAG_LBA48; | ||
3250 | } | ||
3161 | } | 3251 | } |
3162 | 3252 | ||
3163 | return qc; | 3253 | return qc; |