diff options
author | Albert Lee <albertcc@tw.ibm.com> | 2005-10-12 03:09:42 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-18 17:16:14 -0400 |
commit | 59a10b172fccaea793352c00fd9065f0a5b4ef70 (patch) | |
tree | fc0acf367b9fca2ff2c5f8062288f8e271771862 | |
parent | 8cbd6df1f0ce977ab7b61feffa59879bb5e0ed8f (diff) |
[PATCH] libata CHS: reread device identify info (revise #6)
problem:
id[53-58] might be changed after initializing device CHS settings.
changes:
- call ata_dev_reread_id() to reread the identify device info,
after initializing device CHS settings.
Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
============
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r-- | drivers/scsi/libata-core.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 19d3d717faf6..175d4646333d 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -63,6 +63,7 @@ | |||
63 | static unsigned int ata_busy_sleep (struct ata_port *ap, | 63 | static unsigned int ata_busy_sleep (struct ata_port *ap, |
64 | unsigned long tmout_pat, | 64 | unsigned long tmout_pat, |
65 | unsigned long tmout); | 65 | unsigned long tmout); |
66 | static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev); | ||
66 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); | 67 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); |
67 | static void ata_set_mode(struct ata_port *ap); | 68 | static void ata_set_mode(struct ata_port *ap); |
68 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); | 69 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); |
@@ -1240,9 +1241,15 @@ retry: | |||
1240 | * anything else.. | 1241 | * anything else.. |
1241 | * Some drives were very specific about that exact sequence. | 1242 | * Some drives were very specific about that exact sequence. |
1242 | */ | 1243 | */ |
1243 | if (major_version < 4 || (!ata_id_has_lba(dev->id))) | 1244 | if (major_version < 4 || (!ata_id_has_lba(dev->id))) { |
1244 | ata_dev_init_params(ap, dev); | 1245 | ata_dev_init_params(ap, dev); |
1245 | 1246 | ||
1247 | /* current CHS translation info (id[53-58]) might be | ||
1248 | * changed. reread the identify device info. | ||
1249 | */ | ||
1250 | ata_dev_reread_id(ap, dev); | ||
1251 | } | ||
1252 | |||
1246 | if (ata_id_has_lba(dev->id)) { | 1253 | if (ata_id_has_lba(dev->id)) { |
1247 | dev->flags |= ATA_DFLAG_LBA; | 1254 | dev->flags |= ATA_DFLAG_LBA; |
1248 | 1255 | ||
@@ -2151,6 +2158,62 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | |||
2151 | } | 2158 | } |
2152 | 2159 | ||
2153 | /** | 2160 | /** |
2161 | * ata_dev_reread_id - Reread the device identify device info | ||
2162 | * @ap: port where the device is | ||
2163 | * @dev: device to reread the identify device info | ||
2164 | * | ||
2165 | * LOCKING: | ||
2166 | */ | ||
2167 | |||
2168 | static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev) | ||
2169 | { | ||
2170 | DECLARE_COMPLETION(wait); | ||
2171 | struct ata_queued_cmd *qc; | ||
2172 | unsigned long flags; | ||
2173 | int rc; | ||
2174 | |||
2175 | qc = ata_qc_new_init(ap, dev); | ||
2176 | BUG_ON(qc == NULL); | ||
2177 | |||
2178 | ata_sg_init_one(qc, dev->id, sizeof(dev->id)); | ||
2179 | qc->dma_dir = DMA_FROM_DEVICE; | ||
2180 | |||
2181 | if (dev->class == ATA_DEV_ATA) { | ||
2182 | qc->tf.command = ATA_CMD_ID_ATA; | ||
2183 | DPRINTK("do ATA identify\n"); | ||
2184 | } else { | ||
2185 | qc->tf.command = ATA_CMD_ID_ATAPI; | ||
2186 | DPRINTK("do ATAPI identify\n"); | ||
2187 | } | ||
2188 | |||
2189 | qc->tf.flags |= ATA_TFLAG_DEVICE; | ||
2190 | qc->tf.protocol = ATA_PROT_PIO; | ||
2191 | qc->nsect = 1; | ||
2192 | |||
2193 | qc->waiting = &wait; | ||
2194 | qc->complete_fn = ata_qc_complete_noop; | ||
2195 | |||
2196 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
2197 | rc = ata_qc_issue(qc); | ||
2198 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
2199 | |||
2200 | if (rc) | ||
2201 | goto err_out; | ||
2202 | |||
2203 | wait_for_completion(&wait); | ||
2204 | |||
2205 | swap_buf_le16(dev->id, ATA_ID_WORDS); | ||
2206 | |||
2207 | ata_dump_id(dev); | ||
2208 | |||
2209 | DPRINTK("EXIT\n"); | ||
2210 | |||
2211 | return; | ||
2212 | err_out: | ||
2213 | ata_port_disable(ap); | ||
2214 | } | ||
2215 | |||
2216 | /** | ||
2154 | * ata_dev_init_params - Issue INIT DEV PARAMS command | 2217 | * ata_dev_init_params - Issue INIT DEV PARAMS command |
2155 | * @ap: Port associated with device @dev | 2218 | * @ap: Port associated with device @dev |
2156 | * @dev: Device to which command will be sent | 2219 | * @dev: Device to which command will be sent |