diff options
Diffstat (limited to 'drivers/scsi/ata_piix.c')
-rw-r--r-- | drivers/scsi/ata_piix.c | 232 |
1 files changed, 168 insertions, 64 deletions
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 94b1261a259d..2d20caf377f5 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
@@ -105,9 +105,6 @@ enum { | |||
105 | PIIX_FLAG_SCR = (1 << 26), /* SCR available */ | 105 | PIIX_FLAG_SCR = (1 << 26), /* SCR available */ |
106 | PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ | 106 | PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ |
107 | PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ | 107 | PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ |
108 | PIIX_FLAG_COMBINED = (1 << 29), /* combined mode possible */ | ||
109 | /* ICH6/7 use different scheme for map value */ | ||
110 | PIIX_FLAG_COMBINED_ICH6 = PIIX_FLAG_COMBINED | (1 << 30), | ||
111 | 108 | ||
112 | /* combined mode. if set, PATA is channel 0. | 109 | /* combined mode. if set, PATA is channel 0. |
113 | * if clear, PATA is channel 1. | 110 | * if clear, PATA is channel 1. |
@@ -126,6 +123,7 @@ enum { | |||
126 | ich6_sata = 4, | 123 | ich6_sata = 4, |
127 | ich6_sata_ahci = 5, | 124 | ich6_sata_ahci = 5, |
128 | ich6m_sata_ahci = 6, | 125 | ich6m_sata_ahci = 6, |
126 | ich8_sata_ahci = 7, | ||
129 | 127 | ||
130 | /* constants for mapping table */ | 128 | /* constants for mapping table */ |
131 | P0 = 0, /* port 0 */ | 129 | P0 = 0, /* port 0 */ |
@@ -141,11 +139,19 @@ enum { | |||
141 | 139 | ||
142 | struct piix_map_db { | 140 | struct piix_map_db { |
143 | const u32 mask; | 141 | const u32 mask; |
142 | const u16 port_enable; | ||
143 | const int present_shift; | ||
144 | const int map[][4]; | 144 | const int map[][4]; |
145 | }; | 145 | }; |
146 | 146 | ||
147 | struct piix_host_priv { | ||
148 | const int *map; | ||
149 | const struct piix_map_db *map_db; | ||
150 | }; | ||
151 | |||
147 | static int piix_init_one (struct pci_dev *pdev, | 152 | static int piix_init_one (struct pci_dev *pdev, |
148 | const struct pci_device_id *ent); | 153 | const struct pci_device_id *ent); |
154 | static void piix_host_stop(struct ata_host_set *host_set); | ||
149 | static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev); | 155 | static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev); |
150 | static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); | 156 | static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); |
151 | static void piix_pata_error_handler(struct ata_port *ap); | 157 | static void piix_pata_error_handler(struct ata_port *ap); |
@@ -186,11 +192,11 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
186 | /* Enterprise Southbridge 2 (where's the datasheet?) */ | 192 | /* Enterprise Southbridge 2 (where's the datasheet?) */ |
187 | { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, | 193 | { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, |
188 | /* SATA Controller 1 IDE (ICH8, no datasheet yet) */ | 194 | /* SATA Controller 1 IDE (ICH8, no datasheet yet) */ |
189 | { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, | 195 | { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, |
190 | /* SATA Controller 2 IDE (ICH8, ditto) */ | 196 | /* SATA Controller 2 IDE (ICH8, ditto) */ |
191 | { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, | 197 | { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, |
192 | /* Mobile SATA Controller IDE (ICH8M, ditto) */ | 198 | /* Mobile SATA Controller IDE (ICH8M, ditto) */ |
193 | { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci }, | 199 | { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, |
194 | 200 | ||
195 | { } /* terminate list */ | 201 | { } /* terminate list */ |
196 | }; | 202 | }; |
@@ -254,7 +260,7 @@ static const struct ata_port_operations piix_pata_ops = { | |||
254 | 260 | ||
255 | .port_start = ata_port_start, | 261 | .port_start = ata_port_start, |
256 | .port_stop = ata_port_stop, | 262 | .port_stop = ata_port_stop, |
257 | .host_stop = ata_host_stop, | 263 | .host_stop = piix_host_stop, |
258 | }; | 264 | }; |
259 | 265 | ||
260 | static const struct ata_port_operations piix_sata_ops = { | 266 | static const struct ata_port_operations piix_sata_ops = { |
@@ -284,11 +290,13 @@ static const struct ata_port_operations piix_sata_ops = { | |||
284 | 290 | ||
285 | .port_start = ata_port_start, | 291 | .port_start = ata_port_start, |
286 | .port_stop = ata_port_stop, | 292 | .port_stop = ata_port_stop, |
287 | .host_stop = ata_host_stop, | 293 | .host_stop = piix_host_stop, |
288 | }; | 294 | }; |
289 | 295 | ||
290 | static struct piix_map_db ich5_map_db = { | 296 | static const struct piix_map_db ich5_map_db = { |
291 | .mask = 0x7, | 297 | .mask = 0x7, |
298 | .port_enable = 0x3, | ||
299 | .present_shift = 4, | ||
292 | .map = { | 300 | .map = { |
293 | /* PM PS SM SS MAP */ | 301 | /* PM PS SM SS MAP */ |
294 | { P0, NA, P1, NA }, /* 000b */ | 302 | { P0, NA, P1, NA }, /* 000b */ |
@@ -302,8 +310,10 @@ static struct piix_map_db ich5_map_db = { | |||
302 | }, | 310 | }, |
303 | }; | 311 | }; |
304 | 312 | ||
305 | static struct piix_map_db ich6_map_db = { | 313 | static const struct piix_map_db ich6_map_db = { |
306 | .mask = 0x3, | 314 | .mask = 0x3, |
315 | .port_enable = 0xf, | ||
316 | .present_shift = 4, | ||
307 | .map = { | 317 | .map = { |
308 | /* PM PS SM SS MAP */ | 318 | /* PM PS SM SS MAP */ |
309 | { P0, P2, P1, P3 }, /* 00b */ | 319 | { P0, P2, P1, P3 }, /* 00b */ |
@@ -313,8 +323,10 @@ static struct piix_map_db ich6_map_db = { | |||
313 | }, | 323 | }, |
314 | }; | 324 | }; |
315 | 325 | ||
316 | static struct piix_map_db ich6m_map_db = { | 326 | static const struct piix_map_db ich6m_map_db = { |
317 | .mask = 0x3, | 327 | .mask = 0x3, |
328 | .port_enable = 0x5, | ||
329 | .present_shift = 4, | ||
318 | .map = { | 330 | .map = { |
319 | /* PM PS SM SS MAP */ | 331 | /* PM PS SM SS MAP */ |
320 | { P0, P2, RV, RV }, /* 00b */ | 332 | { P0, P2, RV, RV }, /* 00b */ |
@@ -324,6 +336,28 @@ static struct piix_map_db ich6m_map_db = { | |||
324 | }, | 336 | }, |
325 | }; | 337 | }; |
326 | 338 | ||
339 | static const struct piix_map_db ich8_map_db = { | ||
340 | .mask = 0x3, | ||
341 | .port_enable = 0x3, | ||
342 | .present_shift = 8, | ||
343 | .map = { | ||
344 | /* PM PS SM SS MAP */ | ||
345 | { P0, NA, P1, NA }, /* 00b (hardwired) */ | ||
346 | { RV, RV, RV, RV }, | ||
347 | { RV, RV, RV, RV }, /* 10b (never) */ | ||
348 | { RV, RV, RV, RV }, | ||
349 | }, | ||
350 | }; | ||
351 | |||
352 | static const struct piix_map_db *piix_map_db_table[] = { | ||
353 | [ich5_sata] = &ich5_map_db, | ||
354 | [esb_sata] = &ich5_map_db, | ||
355 | [ich6_sata] = &ich6_map_db, | ||
356 | [ich6_sata_ahci] = &ich6_map_db, | ||
357 | [ich6m_sata_ahci] = &ich6m_map_db, | ||
358 | [ich8_sata_ahci] = &ich8_map_db, | ||
359 | }; | ||
360 | |||
327 | static struct ata_port_info piix_port_info[] = { | 361 | static struct ata_port_info piix_port_info[] = { |
328 | /* piix4_pata */ | 362 | /* piix4_pata */ |
329 | { | 363 | { |
@@ -356,63 +390,70 @@ static struct ata_port_info piix_port_info[] = { | |||
356 | /* ich5_sata */ | 390 | /* ich5_sata */ |
357 | { | 391 | { |
358 | .sht = &piix_sht, | 392 | .sht = &piix_sht, |
359 | .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED | | 393 | .host_flags = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR | |
360 | PIIX_FLAG_CHECKINTR, | 394 | PIIX_FLAG_IGNORE_PCS, |
361 | .pio_mask = 0x1f, /* pio0-4 */ | 395 | .pio_mask = 0x1f, /* pio0-4 */ |
362 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 396 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
363 | .udma_mask = 0x7f, /* udma0-6 */ | 397 | .udma_mask = 0x7f, /* udma0-6 */ |
364 | .port_ops = &piix_sata_ops, | 398 | .port_ops = &piix_sata_ops, |
365 | .private_data = &ich5_map_db, | ||
366 | }, | 399 | }, |
367 | 400 | ||
368 | /* i6300esb_sata */ | 401 | /* i6300esb_sata */ |
369 | { | 402 | { |
370 | .sht = &piix_sht, | 403 | .sht = &piix_sht, |
371 | .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED | | 404 | .host_flags = ATA_FLAG_SATA | |
372 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS, | 405 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS, |
373 | .pio_mask = 0x1f, /* pio0-4 */ | 406 | .pio_mask = 0x1f, /* pio0-4 */ |
374 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 407 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
375 | .udma_mask = 0x7f, /* udma0-6 */ | 408 | .udma_mask = 0x7f, /* udma0-6 */ |
376 | .port_ops = &piix_sata_ops, | 409 | .port_ops = &piix_sata_ops, |
377 | .private_data = &ich5_map_db, | ||
378 | }, | 410 | }, |
379 | 411 | ||
380 | /* ich6_sata */ | 412 | /* ich6_sata */ |
381 | { | 413 | { |
382 | .sht = &piix_sht, | 414 | .sht = &piix_sht, |
383 | .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | | 415 | .host_flags = ATA_FLAG_SATA | |
384 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR, | 416 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR, |
385 | .pio_mask = 0x1f, /* pio0-4 */ | 417 | .pio_mask = 0x1f, /* pio0-4 */ |
386 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 418 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
387 | .udma_mask = 0x7f, /* udma0-6 */ | 419 | .udma_mask = 0x7f, /* udma0-6 */ |
388 | .port_ops = &piix_sata_ops, | 420 | .port_ops = &piix_sata_ops, |
389 | .private_data = &ich6_map_db, | ||
390 | }, | 421 | }, |
391 | 422 | ||
392 | /* ich6_sata_ahci */ | 423 | /* ich6_sata_ahci */ |
393 | { | 424 | { |
394 | .sht = &piix_sht, | 425 | .sht = &piix_sht, |
395 | .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | | 426 | .host_flags = ATA_FLAG_SATA | |
396 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | | 427 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | |
397 | PIIX_FLAG_AHCI, | 428 | PIIX_FLAG_AHCI, |
398 | .pio_mask = 0x1f, /* pio0-4 */ | 429 | .pio_mask = 0x1f, /* pio0-4 */ |
399 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 430 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
400 | .udma_mask = 0x7f, /* udma0-6 */ | 431 | .udma_mask = 0x7f, /* udma0-6 */ |
401 | .port_ops = &piix_sata_ops, | 432 | .port_ops = &piix_sata_ops, |
402 | .private_data = &ich6_map_db, | ||
403 | }, | 433 | }, |
404 | 434 | ||
405 | /* ich6m_sata_ahci */ | 435 | /* ich6m_sata_ahci */ |
406 | { | 436 | { |
407 | .sht = &piix_sht, | 437 | .sht = &piix_sht, |
408 | .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | | 438 | .host_flags = ATA_FLAG_SATA | |
439 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | | ||
440 | PIIX_FLAG_AHCI, | ||
441 | .pio_mask = 0x1f, /* pio0-4 */ | ||
442 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
443 | .udma_mask = 0x7f, /* udma0-6 */ | ||
444 | .port_ops = &piix_sata_ops, | ||
445 | }, | ||
446 | |||
447 | /* ich8_sata_ahci */ | ||
448 | { | ||
449 | .sht = &piix_sht, | ||
450 | .host_flags = ATA_FLAG_SATA | | ||
409 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | | 451 | PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | |
410 | PIIX_FLAG_AHCI, | 452 | PIIX_FLAG_AHCI, |
411 | .pio_mask = 0x1f, /* pio0-4 */ | 453 | .pio_mask = 0x1f, /* pio0-4 */ |
412 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 454 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
413 | .udma_mask = 0x7f, /* udma0-6 */ | 455 | .udma_mask = 0x7f, /* udma0-6 */ |
414 | .port_ops = &piix_sata_ops, | 456 | .port_ops = &piix_sata_ops, |
415 | .private_data = &ich6m_map_db, | ||
416 | }, | 457 | }, |
417 | }; | 458 | }; |
418 | 459 | ||
@@ -427,6 +468,11 @@ MODULE_LICENSE("GPL"); | |||
427 | MODULE_DEVICE_TABLE(pci, piix_pci_tbl); | 468 | MODULE_DEVICE_TABLE(pci, piix_pci_tbl); |
428 | MODULE_VERSION(DRV_VERSION); | 469 | MODULE_VERSION(DRV_VERSION); |
429 | 470 | ||
471 | static int force_pcs = 0; | ||
472 | module_param(force_pcs, int, 0444); | ||
473 | MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around " | ||
474 | "device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)"); | ||
475 | |||
430 | /** | 476 | /** |
431 | * piix_pata_cbl_detect - Probe host controller cable detect info | 477 | * piix_pata_cbl_detect - Probe host controller cable detect info |
432 | * @ap: Port for which cable detect info is desired | 478 | * @ap: Port for which cable detect info is desired |
@@ -491,74 +537,83 @@ static void piix_pata_error_handler(struct ata_port *ap) | |||
491 | } | 537 | } |
492 | 538 | ||
493 | /** | 539 | /** |
494 | * piix_sata_prereset - prereset for SATA host controller | 540 | * piix_sata_present_mask - determine present mask for SATA host controller |
495 | * @ap: Target port | 541 | * @ap: Target port |
496 | * | 542 | * |
497 | * Reads and configures SATA PCI device's PCI config register | 543 | * Reads SATA PCI device's PCI config register Port Configuration |
498 | * Port Configuration and Status (PCS) to determine port and | 544 | * and Status (PCS) to determine port and device availability. |
499 | * device availability. Return -ENODEV to skip reset if no | ||
500 | * device is present. | ||
501 | * | 545 | * |
502 | * LOCKING: | 546 | * LOCKING: |
503 | * None (inherited from caller). | 547 | * None (inherited from caller). |
504 | * | 548 | * |
505 | * RETURNS: | 549 | * RETURNS: |
506 | * 0 if device is present, -ENODEV otherwise. | 550 | * determined present_mask |
507 | */ | 551 | */ |
508 | static int piix_sata_prereset(struct ata_port *ap) | 552 | static unsigned int piix_sata_present_mask(struct ata_port *ap) |
509 | { | 553 | { |
510 | struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); | 554 | struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); |
511 | const unsigned int *map = ap->host_set->private_data; | 555 | struct piix_host_priv *hpriv = ap->host_set->private_data; |
556 | const unsigned int *map = hpriv->map; | ||
512 | int base = 2 * ap->hard_port_no; | 557 | int base = 2 * ap->hard_port_no; |
513 | unsigned int present_mask = 0; | 558 | unsigned int present_mask = 0; |
514 | int port, i; | 559 | int port, i; |
515 | u8 pcs; | 560 | u16 pcs; |
516 | 561 | ||
517 | pci_read_config_byte(pdev, ICH5_PCS, &pcs); | 562 | pci_read_config_word(pdev, ICH5_PCS, &pcs); |
518 | DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base); | 563 | DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base); |
519 | 564 | ||
520 | /* enable all ports on this ap and wait for them to settle */ | ||
521 | for (i = 0; i < 2; i++) { | ||
522 | port = map[base + i]; | ||
523 | if (port >= 0) | ||
524 | pcs |= 1 << port; | ||
525 | } | ||
526 | |||
527 | pci_write_config_byte(pdev, ICH5_PCS, pcs); | ||
528 | msleep(100); | ||
529 | |||
530 | /* let's see which devices are present */ | ||
531 | pci_read_config_byte(pdev, ICH5_PCS, &pcs); | ||
532 | |||
533 | for (i = 0; i < 2; i++) { | 565 | for (i = 0; i < 2; i++) { |
534 | port = map[base + i]; | 566 | port = map[base + i]; |
535 | if (port < 0) | 567 | if (port < 0) |
536 | continue; | 568 | continue; |
537 | if (ap->flags & PIIX_FLAG_IGNORE_PCS || pcs & 1 << (4 + port)) | 569 | if ((ap->flags & PIIX_FLAG_IGNORE_PCS) || |
570 | (pcs & 1 << (hpriv->map_db->present_shift + port))) | ||
538 | present_mask |= 1 << i; | 571 | present_mask |= 1 << i; |
539 | else | ||
540 | pcs &= ~(1 << port); | ||
541 | } | 572 | } |
542 | 573 | ||
543 | /* disable offline ports on non-AHCI controllers */ | ||
544 | if (!(ap->flags & PIIX_FLAG_AHCI)) | ||
545 | pci_write_config_byte(pdev, ICH5_PCS, pcs); | ||
546 | |||
547 | DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", | 574 | DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", |
548 | ap->id, pcs, present_mask); | 575 | ap->id, pcs, present_mask); |
549 | 576 | ||
550 | if (!present_mask) { | 577 | return present_mask; |
551 | ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n"); | 578 | } |
552 | ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; | 579 | |
553 | return 0; | 580 | /** |
581 | * piix_sata_softreset - reset SATA host port via ATA SRST | ||
582 | * @ap: port to reset | ||
583 | * @classes: resulting classes of attached devices | ||
584 | * | ||
585 | * Reset SATA host port via ATA SRST. On controllers with | ||
586 | * reliable PCS present bits, the bits are used to determine | ||
587 | * device presence. | ||
588 | * | ||
589 | * LOCKING: | ||
590 | * Kernel thread context (may sleep) | ||
591 | * | ||
592 | * RETURNS: | ||
593 | * 0 on success, -errno otherwise. | ||
594 | */ | ||
595 | static int piix_sata_softreset(struct ata_port *ap, unsigned int *classes) | ||
596 | { | ||
597 | unsigned int present_mask; | ||
598 | int i, rc; | ||
599 | |||
600 | present_mask = piix_sata_present_mask(ap); | ||
601 | |||
602 | rc = ata_std_softreset(ap, classes); | ||
603 | if (rc) | ||
604 | return rc; | ||
605 | |||
606 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | ||
607 | if (!(present_mask & (1 << i))) | ||
608 | classes[i] = ATA_DEV_NONE; | ||
554 | } | 609 | } |
555 | 610 | ||
556 | return ata_std_prereset(ap); | 611 | return 0; |
557 | } | 612 | } |
558 | 613 | ||
559 | static void piix_sata_error_handler(struct ata_port *ap) | 614 | static void piix_sata_error_handler(struct ata_port *ap) |
560 | { | 615 | { |
561 | ata_bmdma_drive_eh(ap, piix_sata_prereset, ata_std_softreset, NULL, | 616 | ata_bmdma_drive_eh(ap, ata_std_prereset, piix_sata_softreset, NULL, |
562 | ata_std_postreset); | 617 | ata_std_postreset); |
563 | } | 618 | } |
564 | 619 | ||
@@ -761,10 +816,40 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev) | |||
761 | return no_piix_dma; | 816 | return no_piix_dma; |
762 | } | 817 | } |
763 | 818 | ||
819 | static void __devinit piix_init_pcs(struct pci_dev *pdev, | ||
820 | struct ata_port_info *pinfo, | ||
821 | const struct piix_map_db *map_db) | ||
822 | { | ||
823 | u16 pcs, new_pcs; | ||
824 | |||
825 | pci_read_config_word(pdev, ICH5_PCS, &pcs); | ||
826 | |||
827 | new_pcs = pcs | map_db->port_enable; | ||
828 | |||
829 | if (new_pcs != pcs) { | ||
830 | DPRINTK("updating PCS from 0x%x to 0x%x\n", pcs, new_pcs); | ||
831 | pci_write_config_word(pdev, ICH5_PCS, new_pcs); | ||
832 | msleep(150); | ||
833 | } | ||
834 | |||
835 | if (force_pcs == 1) { | ||
836 | dev_printk(KERN_INFO, &pdev->dev, | ||
837 | "force ignoring PCS (0x%x)\n", new_pcs); | ||
838 | pinfo[0].host_flags |= PIIX_FLAG_IGNORE_PCS; | ||
839 | pinfo[1].host_flags |= PIIX_FLAG_IGNORE_PCS; | ||
840 | } else if (force_pcs == 2) { | ||
841 | dev_printk(KERN_INFO, &pdev->dev, | ||
842 | "force honoring PCS (0x%x)\n", new_pcs); | ||
843 | pinfo[0].host_flags &= ~PIIX_FLAG_IGNORE_PCS; | ||
844 | pinfo[1].host_flags &= ~PIIX_FLAG_IGNORE_PCS; | ||
845 | } | ||
846 | } | ||
847 | |||
764 | static void __devinit piix_init_sata_map(struct pci_dev *pdev, | 848 | static void __devinit piix_init_sata_map(struct pci_dev *pdev, |
765 | struct ata_port_info *pinfo) | 849 | struct ata_port_info *pinfo, |
850 | const struct piix_map_db *map_db) | ||
766 | { | 851 | { |
767 | struct piix_map_db *map_db = pinfo[0].private_data; | 852 | struct piix_host_priv *hpriv = pinfo[0].private_data; |
768 | const unsigned int *map; | 853 | const unsigned int *map; |
769 | int i, invalid_map = 0; | 854 | int i, invalid_map = 0; |
770 | u8 map_value; | 855 | u8 map_value; |
@@ -788,6 +873,7 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev, | |||
788 | case IDE: | 873 | case IDE: |
789 | WARN_ON((i & 1) || map[i + 1] != IDE); | 874 | WARN_ON((i & 1) || map[i + 1] != IDE); |
790 | pinfo[i / 2] = piix_port_info[ich5_pata]; | 875 | pinfo[i / 2] = piix_port_info[ich5_pata]; |
876 | pinfo[i / 2].private_data = hpriv; | ||
791 | i++; | 877 | i++; |
792 | printk(" IDE IDE"); | 878 | printk(" IDE IDE"); |
793 | break; | 879 | break; |
@@ -805,8 +891,8 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev, | |||
805 | dev_printk(KERN_ERR, &pdev->dev, | 891 | dev_printk(KERN_ERR, &pdev->dev, |
806 | "invalid MAP value %u\n", map_value); | 892 | "invalid MAP value %u\n", map_value); |
807 | 893 | ||
808 | pinfo[0].private_data = (void *)map; | 894 | hpriv->map = map; |
809 | pinfo[1].private_data = (void *)map; | 895 | hpriv->map_db = map_db; |
810 | } | 896 | } |
811 | 897 | ||
812 | /** | 898 | /** |
@@ -829,6 +915,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
829 | static int printed_version; | 915 | static int printed_version; |
830 | struct ata_port_info port_info[2]; | 916 | struct ata_port_info port_info[2]; |
831 | struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] }; | 917 | struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] }; |
918 | struct piix_host_priv *hpriv; | ||
832 | unsigned long host_flags; | 919 | unsigned long host_flags; |
833 | 920 | ||
834 | if (!printed_version++) | 921 | if (!printed_version++) |
@@ -839,8 +926,14 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
839 | if (!in_module_init) | 926 | if (!in_module_init) |
840 | return -ENODEV; | 927 | return -ENODEV; |
841 | 928 | ||
929 | hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL); | ||
930 | if (!hpriv) | ||
931 | return -ENOMEM; | ||
932 | |||
842 | port_info[0] = piix_port_info[ent->driver_data]; | 933 | port_info[0] = piix_port_info[ent->driver_data]; |
843 | port_info[1] = piix_port_info[ent->driver_data]; | 934 | port_info[1] = piix_port_info[ent->driver_data]; |
935 | port_info[0].private_data = hpriv; | ||
936 | port_info[1].private_data = hpriv; | ||
844 | 937 | ||
845 | host_flags = port_info[0].host_flags; | 938 | host_flags = port_info[0].host_flags; |
846 | 939 | ||
@@ -855,8 +948,12 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
855 | } | 948 | } |
856 | 949 | ||
857 | /* Initialize SATA map */ | 950 | /* Initialize SATA map */ |
858 | if (host_flags & ATA_FLAG_SATA) | 951 | if (host_flags & ATA_FLAG_SATA) { |
859 | piix_init_sata_map(pdev, port_info); | 952 | piix_init_sata_map(pdev, port_info, |
953 | piix_map_db_table[ent->driver_data]); | ||
954 | piix_init_pcs(pdev, port_info, | ||
955 | piix_map_db_table[ent->driver_data]); | ||
956 | } | ||
860 | 957 | ||
861 | /* On ICH5, some BIOSen disable the interrupt using the | 958 | /* On ICH5, some BIOSen disable the interrupt using the |
862 | * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3. | 959 | * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3. |
@@ -879,6 +976,13 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
879 | return ata_pci_init_one(pdev, ppinfo, 2); | 976 | return ata_pci_init_one(pdev, ppinfo, 2); |
880 | } | 977 | } |
881 | 978 | ||
979 | static void piix_host_stop(struct ata_host_set *host_set) | ||
980 | { | ||
981 | if (host_set->next == NULL) | ||
982 | kfree(host_set->private_data); | ||
983 | ata_host_stop(host_set); | ||
984 | } | ||
985 | |||
882 | static int __init piix_init(void) | 986 | static int __init piix_init(void) |
883 | { | 987 | { |
884 | int rc; | 988 | int rc; |