aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/parport/parport_pc.c
diff options
context:
space:
mode:
authorJens Rottmann <JRottmann@LiPPERTEmbedded.de>2009-06-22 11:51:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-22 14:28:59 -0400
commite2434dc1c19412639dd047a4d4eff8ed0e5d0d50 (patch)
treeaa723d51dedc8c404205877c9885af09906e6d18 /drivers/parport/parport_pc.c
parent752a4787511bf7515f99609ff4ae52341b5bfcde (diff)
parport_pc: after superio probing restore original register values
CONFIG_PARPORT_PC_SUPERIO probes for various superio chips by writing byte sequences to a set of different potential I/O ranges. But the probed ranges are not exclusive to parallel ports. Some of our boards just happen to have a watchdog in one of them. Took us almost a week to figure out why some distros reboot without warning after running flawlessly for 3 hours. For exactly 170 = 0xAA minutes, that is ... Fixed by restoring original values after probing. Also fixed too small request_region() in detect_and_report_it87(). Signed-off-by: Jens Rottmann <JRottmann@LiPPERTEmbedded.de> Signed-off-by: Alan Cox <alan@linux.intel.com> Cc: <stable@kernel.org> Acked-by: Jeff Garzik <jgarzik@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/parport/parport_pc.c')
-rw-r--r--drivers/parport/parport_pc.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 151bf5bc8afe..7f1cca701c11 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -1471,11 +1471,13 @@ static void __devinit decode_smsc(int efer, int key, int devid, int devrev)
1471 1471
1472static void __devinit winbond_check(int io, int key) 1472static void __devinit winbond_check(int io, int key)
1473{ 1473{
1474 int devid, devrev, oldid, x_devid, x_devrev, x_oldid; 1474 int origval, devid, devrev, oldid, x_devid, x_devrev, x_oldid;
1475 1475
1476 if (!request_region(io, 3, __func__)) 1476 if (!request_region(io, 3, __func__))
1477 return; 1477 return;
1478 1478
1479 origval = inb(io); /* Save original value */
1480
1479 /* First probe without key */ 1481 /* First probe without key */
1480 outb(0x20, io); 1482 outb(0x20, io);
1481 x_devid = inb(io + 1); 1483 x_devid = inb(io + 1);
@@ -1495,6 +1497,8 @@ static void __devinit winbond_check(int io, int key)
1495 oldid = inb(io + 1); 1497 oldid = inb(io + 1);
1496 outb(0xaa, io); /* Magic Seal */ 1498 outb(0xaa, io); /* Magic Seal */
1497 1499
1500 outb(origval, io); /* in case we poked some entirely different hardware */
1501
1498 if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid)) 1502 if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))
1499 goto out; /* protection against false positives */ 1503 goto out; /* protection against false positives */
1500 1504
@@ -1505,11 +1509,15 @@ out:
1505 1509
1506static void __devinit winbond_check2(int io, int key) 1510static void __devinit winbond_check2(int io, int key)
1507{ 1511{
1508 int devid, devrev, oldid, x_devid, x_devrev, x_oldid; 1512 int origval[3], devid, devrev, oldid, x_devid, x_devrev, x_oldid;
1509 1513
1510 if (!request_region(io, 3, __func__)) 1514 if (!request_region(io, 3, __func__))
1511 return; 1515 return;
1512 1516
1517 origval[0] = inb(io); /* Save original values */
1518 origval[1] = inb(io + 1);
1519 origval[2] = inb(io + 2);
1520
1513 /* First probe without the key */ 1521 /* First probe without the key */
1514 outb(0x20, io + 2); 1522 outb(0x20, io + 2);
1515 x_devid = inb(io + 2); 1523 x_devid = inb(io + 2);
@@ -1528,6 +1536,10 @@ static void __devinit winbond_check2(int io, int key)
1528 oldid = inb(io + 2); 1536 oldid = inb(io + 2);
1529 outb(0xaa, io); /* Magic Seal */ 1537 outb(0xaa, io); /* Magic Seal */
1530 1538
1539 outb(origval[0], io); /* in case we poked some entirely different hardware */
1540 outb(origval[1], io + 1);
1541 outb(origval[2], io + 2);
1542
1531 if (x_devid == devid && x_devrev == devrev && x_oldid == oldid) 1543 if (x_devid == devid && x_devrev == devrev && x_oldid == oldid)
1532 goto out; /* protection against false positives */ 1544 goto out; /* protection against false positives */
1533 1545
@@ -1538,11 +1550,13 @@ out:
1538 1550
1539static void __devinit smsc_check(int io, int key) 1551static void __devinit smsc_check(int io, int key)
1540{ 1552{
1541 int id, rev, oldid, oldrev, x_id, x_rev, x_oldid, x_oldrev; 1553 int origval, id, rev, oldid, oldrev, x_id, x_rev, x_oldid, x_oldrev;
1542 1554
1543 if (!request_region(io, 3, __func__)) 1555 if (!request_region(io, 3, __func__))
1544 return; 1556 return;
1545 1557
1558 origval = inb(io); /* Save original value */
1559
1546 /* First probe without the key */ 1560 /* First probe without the key */
1547 outb(0x0d, io); 1561 outb(0x0d, io);
1548 x_oldid = inb(io + 1); 1562 x_oldid = inb(io + 1);
@@ -1566,6 +1580,8 @@ static void __devinit smsc_check(int io, int key)
1566 rev = inb(io + 1); 1580 rev = inb(io + 1);
1567 outb(0xaa, io); /* Magic Seal */ 1581 outb(0xaa, io); /* Magic Seal */
1568 1582
1583 outb(origval, io); /* in case we poked some entirely different hardware */
1584
1569 if (x_id == id && x_oldrev == oldrev && 1585 if (x_id == id && x_oldrev == oldrev &&
1570 x_oldid == oldid && x_rev == rev) 1586 x_oldid == oldid && x_rev == rev)
1571 goto out; /* protection against false positives */ 1587 goto out; /* protection against false positives */
@@ -1602,11 +1618,12 @@ static void __devinit detect_and_report_smsc(void)
1602static void __devinit detect_and_report_it87(void) 1618static void __devinit detect_and_report_it87(void)
1603{ 1619{
1604 u16 dev; 1620 u16 dev;
1605 u8 r; 1621 u8 origval, r;
1606 if (verbose_probing) 1622 if (verbose_probing)
1607 printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n"); 1623 printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
1608 if (!request_region(0x2e, 1, __func__)) 1624 if (!request_region(0x2e, 2, __func__))
1609 return; 1625 return;
1626 origval = inb(0x2e); /* Save original value */
1610 outb(0x87, 0x2e); 1627 outb(0x87, 0x2e);
1611 outb(0x01, 0x2e); 1628 outb(0x01, 0x2e);
1612 outb(0x55, 0x2e); 1629 outb(0x55, 0x2e);
@@ -1626,8 +1643,10 @@ static void __devinit detect_and_report_it87(void)
1626 outb(r | 8, 0x2F); 1643 outb(r | 8, 0x2F);
1627 outb(0x02, 0x2E); /* Lock */ 1644 outb(0x02, 0x2E); /* Lock */
1628 outb(0x02, 0x2F); 1645 outb(0x02, 0x2F);
1646 } else {
1647 outb(origval, 0x2e); /* Oops, sorry to disturb */
1629 } 1648 }
1630 release_region(0x2e, 1); 1649 release_region(0x2e, 2);
1631} 1650}
1632#endif /* CONFIG_PARPORT_PC_SUPERIO */ 1651#endif /* CONFIG_PARPORT_PC_SUPERIO */
1633 1652