diff options
Diffstat (limited to 'drivers/ata/pata_amd.c')
-rw-r--r-- | drivers/ata/pata_amd.c | 89 |
1 files changed, 42 insertions, 47 deletions
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 18381762908b..536ee892ab72 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/libata.h> | 25 | #include <linux/libata.h> |
26 | 26 | ||
27 | #define DRV_NAME "pata_amd" | 27 | #define DRV_NAME "pata_amd" |
28 | #define DRV_VERSION "0.2.8" | 28 | #define DRV_VERSION "0.3.8" |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * timing_setup - shared timing computation and load | 31 | * timing_setup - shared timing computation and load |
@@ -119,32 +119,25 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse | |||
119 | } | 119 | } |
120 | 120 | ||
121 | /** | 121 | /** |
122 | * amd_probe_init - cable detection | 122 | * amd_probe_init - perform reset handling |
123 | * @ap: ATA port | 123 | * @ap: ATA port |
124 | * | 124 | * |
125 | * Perform cable detection. The BIOS stores this in PCI config | 125 | * Reset sequence checking enable bits to see which ports are |
126 | * space for us. | 126 | * active. |
127 | */ | 127 | */ |
128 | 128 | ||
129 | static int amd_pre_reset(struct ata_port *ap) | 129 | static int amd_pre_reset(struct ata_port *ap) |
130 | { | 130 | { |
131 | static const u32 bitmask[2] = {0x03, 0x0C}; | ||
132 | static const struct pci_bits amd_enable_bits[] = { | 131 | static const struct pci_bits amd_enable_bits[] = { |
133 | { 0x40, 1, 0x02, 0x02 }, | 132 | { 0x40, 1, 0x02, 0x02 }, |
134 | { 0x40, 1, 0x01, 0x01 } | 133 | { 0x40, 1, 0x01, 0x01 } |
135 | }; | 134 | }; |
136 | 135 | ||
137 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 136 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
138 | u8 ata66; | ||
139 | 137 | ||
140 | if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) | 138 | if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) |
141 | return -ENOENT; | 139 | return -ENOENT; |
142 | 140 | ||
143 | pci_read_config_byte(pdev, 0x42, &ata66); | ||
144 | if (ata66 & bitmask[ap->port_no]) | ||
145 | ap->cbl = ATA_CBL_PATA80; | ||
146 | else | ||
147 | ap->cbl = ATA_CBL_PATA40; | ||
148 | return ata_std_prereset(ap); | 141 | return ata_std_prereset(ap); |
149 | 142 | ||
150 | } | 143 | } |
@@ -156,28 +149,16 @@ static void amd_error_handler(struct ata_port *ap) | |||
156 | ata_std_postreset); | 149 | ata_std_postreset); |
157 | } | 150 | } |
158 | 151 | ||
159 | static int amd_early_pre_reset(struct ata_port *ap) | 152 | static int amd_cable_detect(struct ata_port *ap) |
160 | { | 153 | { |
154 | static const u32 bitmask[2] = {0x03, 0x0C}; | ||
161 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 155 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
162 | static struct pci_bits amd_enable_bits[] = { | 156 | u8 ata66; |
163 | { 0x40, 1, 0x02, 0x02 }, | ||
164 | { 0x40, 1, 0x01, 0x01 } | ||
165 | }; | ||
166 | |||
167 | if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) | ||
168 | return -ENOENT; | ||
169 | |||
170 | /* No host side cable detection */ | ||
171 | ap->cbl = ATA_CBL_PATA80; | ||
172 | return ata_std_prereset(ap); | ||
173 | |||
174 | } | ||
175 | 157 | ||
176 | static void amd_early_error_handler(struct ata_port *ap) | 158 | pci_read_config_byte(pdev, 0x42, &ata66); |
177 | { | 159 | if (ata66 & bitmask[ap->port_no]) |
178 | ata_bmdma_drive_eh(ap, amd_early_pre_reset, | 160 | return ATA_CBL_PATA80; |
179 | ata_std_softreset, NULL, | 161 | return ATA_CBL_PATA40; |
180 | ata_std_postreset); | ||
181 | } | 162 | } |
182 | 163 | ||
183 | /** | 164 | /** |
@@ -247,31 +228,16 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
247 | */ | 228 | */ |
248 | 229 | ||
249 | static int nv_pre_reset(struct ata_port *ap) { | 230 | static int nv_pre_reset(struct ata_port *ap) { |
250 | static const u8 bitmask[2] = {0x03, 0x0C}; | ||
251 | static const struct pci_bits nv_enable_bits[] = { | 231 | static const struct pci_bits nv_enable_bits[] = { |
252 | { 0x50, 1, 0x02, 0x02 }, | 232 | { 0x50, 1, 0x02, 0x02 }, |
253 | { 0x50, 1, 0x01, 0x01 } | 233 | { 0x50, 1, 0x01, 0x01 } |
254 | }; | 234 | }; |
255 | 235 | ||
256 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 236 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
257 | u8 ata66; | ||
258 | u16 udma; | ||
259 | 237 | ||
260 | if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no])) | 238 | if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no])) |
261 | return -ENOENT; | 239 | return -ENOENT; |
262 | 240 | ||
263 | pci_read_config_byte(pdev, 0x52, &ata66); | ||
264 | if (ata66 & bitmask[ap->port_no]) | ||
265 | ap->cbl = ATA_CBL_PATA80; | ||
266 | else | ||
267 | ap->cbl = ATA_CBL_PATA40; | ||
268 | |||
269 | /* We now have to double check because the Nvidia boxes BIOS | ||
270 | doesn't always set the cable bits but does set mode bits */ | ||
271 | |||
272 | pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma); | ||
273 | if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400) | ||
274 | ap->cbl = ATA_CBL_PATA80; | ||
275 | return ata_std_prereset(ap); | 241 | return ata_std_prereset(ap); |
276 | } | 242 | } |
277 | 243 | ||
@@ -281,6 +247,29 @@ static void nv_error_handler(struct ata_port *ap) | |||
281 | ata_std_softreset, NULL, | 247 | ata_std_softreset, NULL, |
282 | ata_std_postreset); | 248 | ata_std_postreset); |
283 | } | 249 | } |
250 | |||
251 | static int nv_cable_detect(struct ata_port *ap) | ||
252 | { | ||
253 | static const u8 bitmask[2] = {0x03, 0x0C}; | ||
254 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
255 | u8 ata66; | ||
256 | u16 udma; | ||
257 | int cbl; | ||
258 | |||
259 | pci_read_config_byte(pdev, 0x52, &ata66); | ||
260 | if (ata66 & bitmask[ap->port_no]) | ||
261 | cbl = ATA_CBL_PATA80; | ||
262 | else | ||
263 | cbl = ATA_CBL_PATA40; | ||
264 | |||
265 | /* We now have to double check because the Nvidia boxes BIOS | ||
266 | doesn't always set the cable bits but does set mode bits */ | ||
267 | pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma); | ||
268 | if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400) | ||
269 | cbl = ATA_CBL_PATA80; | ||
270 | return cbl; | ||
271 | } | ||
272 | |||
284 | /** | 273 | /** |
285 | * nv100_set_piomode - set initial PIO mode data | 274 | * nv100_set_piomode - set initial PIO mode data |
286 | * @ap: ATA interface | 275 | * @ap: ATA interface |
@@ -353,8 +342,9 @@ static struct ata_port_operations amd33_port_ops = { | |||
353 | 342 | ||
354 | .freeze = ata_bmdma_freeze, | 343 | .freeze = ata_bmdma_freeze, |
355 | .thaw = ata_bmdma_thaw, | 344 | .thaw = ata_bmdma_thaw, |
356 | .error_handler = amd_early_error_handler, | 345 | .error_handler = amd_error_handler, |
357 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 346 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
347 | .cable_detect = ata_cable_40wire, | ||
358 | 348 | ||
359 | .bmdma_setup = ata_bmdma_setup, | 349 | .bmdma_setup = ata_bmdma_setup, |
360 | .bmdma_start = ata_bmdma_start, | 350 | .bmdma_start = ata_bmdma_start, |
@@ -387,8 +377,9 @@ static struct ata_port_operations amd66_port_ops = { | |||
387 | 377 | ||
388 | .freeze = ata_bmdma_freeze, | 378 | .freeze = ata_bmdma_freeze, |
389 | .thaw = ata_bmdma_thaw, | 379 | .thaw = ata_bmdma_thaw, |
390 | .error_handler = amd_early_error_handler, | 380 | .error_handler = amd_error_handler, |
391 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 381 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
382 | .cable_detect = ata_cable_unknown, | ||
392 | 383 | ||
393 | .bmdma_setup = ata_bmdma_setup, | 384 | .bmdma_setup = ata_bmdma_setup, |
394 | .bmdma_start = ata_bmdma_start, | 385 | .bmdma_start = ata_bmdma_start, |
@@ -423,6 +414,7 @@ static struct ata_port_operations amd100_port_ops = { | |||
423 | .thaw = ata_bmdma_thaw, | 414 | .thaw = ata_bmdma_thaw, |
424 | .error_handler = amd_error_handler, | 415 | .error_handler = amd_error_handler, |
425 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 416 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
417 | .cable_detect = ata_cable_unknown, | ||
426 | 418 | ||
427 | .bmdma_setup = ata_bmdma_setup, | 419 | .bmdma_setup = ata_bmdma_setup, |
428 | .bmdma_start = ata_bmdma_start, | 420 | .bmdma_start = ata_bmdma_start, |
@@ -457,6 +449,7 @@ static struct ata_port_operations amd133_port_ops = { | |||
457 | .thaw = ata_bmdma_thaw, | 449 | .thaw = ata_bmdma_thaw, |
458 | .error_handler = amd_error_handler, | 450 | .error_handler = amd_error_handler, |
459 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 451 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
452 | .cable_detect = amd_cable_detect, | ||
460 | 453 | ||
461 | .bmdma_setup = ata_bmdma_setup, | 454 | .bmdma_setup = ata_bmdma_setup, |
462 | .bmdma_start = ata_bmdma_start, | 455 | .bmdma_start = ata_bmdma_start, |
@@ -491,6 +484,7 @@ static struct ata_port_operations nv100_port_ops = { | |||
491 | .thaw = ata_bmdma_thaw, | 484 | .thaw = ata_bmdma_thaw, |
492 | .error_handler = nv_error_handler, | 485 | .error_handler = nv_error_handler, |
493 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 486 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
487 | .cable_detect = nv_cable_detect, | ||
494 | 488 | ||
495 | .bmdma_setup = ata_bmdma_setup, | 489 | .bmdma_setup = ata_bmdma_setup, |
496 | .bmdma_start = ata_bmdma_start, | 490 | .bmdma_start = ata_bmdma_start, |
@@ -525,6 +519,7 @@ static struct ata_port_operations nv133_port_ops = { | |||
525 | .thaw = ata_bmdma_thaw, | 519 | .thaw = ata_bmdma_thaw, |
526 | .error_handler = nv_error_handler, | 520 | .error_handler = nv_error_handler, |
527 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 521 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
522 | .cable_detect = nv_cable_detect, | ||
528 | 523 | ||
529 | .bmdma_setup = ata_bmdma_setup, | 524 | .bmdma_setup = ata_bmdma_setup, |
530 | .bmdma_start = ata_bmdma_start, | 525 | .bmdma_start = ata_bmdma_start, |