aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ata_piix.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ata_piix.c')
-rw-r--r--drivers/scsi/ata_piix.c165
1 files changed, 111 insertions, 54 deletions
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 94b1261a259d..19745a31072b 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
142struct piix_map_db { 140struct 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
147struct piix_host_priv {
148 const int *map;
149 const struct piix_map_db *map_db;
150};
151
147static int piix_init_one (struct pci_dev *pdev, 152static int piix_init_one (struct pci_dev *pdev,
148 const struct pci_device_id *ent); 153 const struct pci_device_id *ent);
154static void piix_host_stop(struct ata_host_set *host_set);
149static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev); 155static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
150static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); 156static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
151static void piix_pata_error_handler(struct ata_port *ap); 157static 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
260static const struct ata_port_operations piix_sata_ops = { 266static 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
290static struct piix_map_db ich5_map_db = { 296static 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
305static struct piix_map_db ich6_map_db = { 313static 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
316static struct piix_map_db ich6m_map_db = { 326static 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
339static 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
352static 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
327static struct ata_port_info piix_port_info[] = { 361static struct ata_port_info piix_port_info[] = {
328 /* piix4_pata */ 362 /* piix4_pata */
329 { 363 {
@@ -356,63 +390,69 @@ 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,
361 .pio_mask = 0x1f, /* pio0-4 */ 394 .pio_mask = 0x1f, /* pio0-4 */
362 .mwdma_mask = 0x07, /* mwdma0-2 */ 395 .mwdma_mask = 0x07, /* mwdma0-2 */
363 .udma_mask = 0x7f, /* udma0-6 */ 396 .udma_mask = 0x7f, /* udma0-6 */
364 .port_ops = &piix_sata_ops, 397 .port_ops = &piix_sata_ops,
365 .private_data = &ich5_map_db,
366 }, 398 },
367 399
368 /* i6300esb_sata */ 400 /* i6300esb_sata */
369 { 401 {
370 .sht = &piix_sht, 402 .sht = &piix_sht,
371 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED | 403 .host_flags = ATA_FLAG_SATA |
372 PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS, 404 PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS,
373 .pio_mask = 0x1f, /* pio0-4 */ 405 .pio_mask = 0x1f, /* pio0-4 */
374 .mwdma_mask = 0x07, /* mwdma0-2 */ 406 .mwdma_mask = 0x07, /* mwdma0-2 */
375 .udma_mask = 0x7f, /* udma0-6 */ 407 .udma_mask = 0x7f, /* udma0-6 */
376 .port_ops = &piix_sata_ops, 408 .port_ops = &piix_sata_ops,
377 .private_data = &ich5_map_db,
378 }, 409 },
379 410
380 /* ich6_sata */ 411 /* ich6_sata */
381 { 412 {
382 .sht = &piix_sht, 413 .sht = &piix_sht,
383 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | 414 .host_flags = ATA_FLAG_SATA |
384 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR, 415 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR,
385 .pio_mask = 0x1f, /* pio0-4 */ 416 .pio_mask = 0x1f, /* pio0-4 */
386 .mwdma_mask = 0x07, /* mwdma0-2 */ 417 .mwdma_mask = 0x07, /* mwdma0-2 */
387 .udma_mask = 0x7f, /* udma0-6 */ 418 .udma_mask = 0x7f, /* udma0-6 */
388 .port_ops = &piix_sata_ops, 419 .port_ops = &piix_sata_ops,
389 .private_data = &ich6_map_db,
390 }, 420 },
391 421
392 /* ich6_sata_ahci */ 422 /* ich6_sata_ahci */
393 { 423 {
394 .sht = &piix_sht, 424 .sht = &piix_sht,
395 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | 425 .host_flags = ATA_FLAG_SATA |
396 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | 426 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
397 PIIX_FLAG_AHCI, 427 PIIX_FLAG_AHCI,
398 .pio_mask = 0x1f, /* pio0-4 */ 428 .pio_mask = 0x1f, /* pio0-4 */
399 .mwdma_mask = 0x07, /* mwdma0-2 */ 429 .mwdma_mask = 0x07, /* mwdma0-2 */
400 .udma_mask = 0x7f, /* udma0-6 */ 430 .udma_mask = 0x7f, /* udma0-6 */
401 .port_ops = &piix_sata_ops, 431 .port_ops = &piix_sata_ops,
402 .private_data = &ich6_map_db,
403 }, 432 },
404 433
405 /* ich6m_sata_ahci */ 434 /* ich6m_sata_ahci */
406 { 435 {
407 .sht = &piix_sht, 436 .sht = &piix_sht,
408 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_COMBINED_ICH6 | 437 .host_flags = ATA_FLAG_SATA |
438 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
439 PIIX_FLAG_AHCI,
440 .pio_mask = 0x1f, /* pio0-4 */
441 .mwdma_mask = 0x07, /* mwdma0-2 */
442 .udma_mask = 0x7f, /* udma0-6 */
443 .port_ops = &piix_sata_ops,
444 },
445
446 /* ich8_sata_ahci */
447 {
448 .sht = &piix_sht,
449 .host_flags = ATA_FLAG_SATA |
409 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR | 450 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
410 PIIX_FLAG_AHCI, 451 PIIX_FLAG_AHCI,
411 .pio_mask = 0x1f, /* pio0-4 */ 452 .pio_mask = 0x1f, /* pio0-4 */
412 .mwdma_mask = 0x07, /* mwdma0-2 */ 453 .mwdma_mask = 0x07, /* mwdma0-2 */
413 .udma_mask = 0x7f, /* udma0-6 */ 454 .udma_mask = 0x7f, /* udma0-6 */
414 .port_ops = &piix_sata_ops, 455 .port_ops = &piix_sata_ops,
415 .private_data = &ich6m_map_db,
416 }, 456 },
417}; 457};
418 458
@@ -508,46 +548,29 @@ static void piix_pata_error_handler(struct ata_port *ap)
508static int piix_sata_prereset(struct ata_port *ap) 548static int piix_sata_prereset(struct ata_port *ap)
509{ 549{
510 struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); 550 struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
511 const unsigned int *map = ap->host_set->private_data; 551 struct piix_host_priv *hpriv = ap->host_set->private_data;
552 const unsigned int *map = hpriv->map;
512 int base = 2 * ap->hard_port_no; 553 int base = 2 * ap->hard_port_no;
513 unsigned int present_mask = 0; 554 unsigned int present = 0;
514 int port, i; 555 int port, i;
515 u8 pcs; 556 u16 pcs;
516 557
517 pci_read_config_byte(pdev, ICH5_PCS, &pcs); 558 pci_read_config_word(pdev, ICH5_PCS, &pcs);
518 DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base); 559 DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
519 560
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++) { 561 for (i = 0; i < 2; i++) {
534 port = map[base + i]; 562 port = map[base + i];
535 if (port < 0) 563 if (port < 0)
536 continue; 564 continue;
537 if (ap->flags & PIIX_FLAG_IGNORE_PCS || pcs & 1 << (4 + port)) 565 if ((ap->flags & PIIX_FLAG_IGNORE_PCS) ||
538 present_mask |= 1 << i; 566 (pcs & 1 << (hpriv->map_db->present_shift + port)))
539 else 567 present = 1;
540 pcs &= ~(1 << port);
541 } 568 }
542 569
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", 570 DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
548 ap->id, pcs, present_mask); 571 ap->id, pcs, present_mask);
549 572
550 if (!present_mask) { 573 if (!present) {
551 ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n"); 574 ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n");
552 ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; 575 ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
553 return 0; 576 return 0;
@@ -761,10 +784,27 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
761 return no_piix_dma; 784 return no_piix_dma;
762} 785}
763 786
787static void __devinit piix_init_pcs(struct pci_dev *pdev,
788 const struct piix_map_db *map_db)
789{
790 u16 pcs, new_pcs;
791
792 pci_read_config_word(pdev, ICH5_PCS, &pcs);
793
794 new_pcs = pcs | map_db->port_enable;
795
796 if (new_pcs != pcs) {
797 DPRINTK("updating PCS from 0x%x to 0x%x\n", pcs, new_pcs);
798 pci_write_config_word(pdev, ICH5_PCS, new_pcs);
799 msleep(150);
800 }
801}
802
764static void __devinit piix_init_sata_map(struct pci_dev *pdev, 803static void __devinit piix_init_sata_map(struct pci_dev *pdev,
765 struct ata_port_info *pinfo) 804 struct ata_port_info *pinfo,
805 const struct piix_map_db *map_db)
766{ 806{
767 struct piix_map_db *map_db = pinfo[0].private_data; 807 struct piix_host_priv *hpriv = pinfo[0].private_data;
768 const unsigned int *map; 808 const unsigned int *map;
769 int i, invalid_map = 0; 809 int i, invalid_map = 0;
770 u8 map_value; 810 u8 map_value;
@@ -805,8 +845,8 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
805 dev_printk(KERN_ERR, &pdev->dev, 845 dev_printk(KERN_ERR, &pdev->dev,
806 "invalid MAP value %u\n", map_value); 846 "invalid MAP value %u\n", map_value);
807 847
808 pinfo[0].private_data = (void *)map; 848 hpriv->map = map;
809 pinfo[1].private_data = (void *)map; 849 hpriv->map_db = map_db;
810} 850}
811 851
812/** 852/**
@@ -829,6 +869,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
829 static int printed_version; 869 static int printed_version;
830 struct ata_port_info port_info[2]; 870 struct ata_port_info port_info[2];
831 struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] }; 871 struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] };
872 struct piix_host_priv *hpriv;
832 unsigned long host_flags; 873 unsigned long host_flags;
833 874
834 if (!printed_version++) 875 if (!printed_version++)
@@ -839,8 +880,14 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
839 if (!in_module_init) 880 if (!in_module_init)
840 return -ENODEV; 881 return -ENODEV;
841 882
883 hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
884 if (!hpriv)
885 return -ENOMEM;
886
842 port_info[0] = piix_port_info[ent->driver_data]; 887 port_info[0] = piix_port_info[ent->driver_data];
843 port_info[1] = piix_port_info[ent->driver_data]; 888 port_info[1] = piix_port_info[ent->driver_data];
889 port_info[0].private_data = hpriv;
890 port_info[1].private_data = hpriv;
844 891
845 host_flags = port_info[0].host_flags; 892 host_flags = port_info[0].host_flags;
846 893
@@ -855,8 +902,11 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
855 } 902 }
856 903
857 /* Initialize SATA map */ 904 /* Initialize SATA map */
858 if (host_flags & ATA_FLAG_SATA) 905 if (host_flags & ATA_FLAG_SATA) {
859 piix_init_sata_map(pdev, port_info); 906 piix_init_sata_map(pdev, port_info,
907 piix_map_db_table[ent->driver_data]);
908 piix_init_pcs(pdev, piix_map_db_table[ent->driver_data]);
909 }
860 910
861 /* On ICH5, some BIOSen disable the interrupt using the 911 /* On ICH5, some BIOSen disable the interrupt using the
862 * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3. 912 * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
@@ -879,6 +929,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); 929 return ata_pci_init_one(pdev, ppinfo, 2);
880} 930}
881 931
932static void piix_host_stop(struct ata_host_set *host_set)
933{
934 if (host_set->next == NULL)
935 kfree(host_set->private_data);
936 ata_host_stop(host_set);
937}
938
882static int __init piix_init(void) 939static int __init piix_init(void)
883{ 940{
884 int rc; 941 int rc;