Skip to contentSkip to conversation

fixes for 2.6.0-test9

PATCH New Greg KH 1 participant 4 messages Oct 30, 2003

Subsystems (4)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

PATCH 1/1 fixes for 2.6.0-test9

Hi,

Here are 3 small fixes for 2.6.0-test9. They fix a problem on Alphas on boot time, remove some compiler warnings in some I2C drivers, and disable a USB driver when building for SMP as the locking in it is all messed up right now.

Please pull from:

	bk://kernel.bkbits.net/gregkh/linux/pci-2.6

thanks,

greg k-h

p.s. I'll send these as patches in response to this email to lkml for those who want to see them.

 drivers/media/video/bt832.c      |    2 --
 drivers/media/video/saa5249.c    |    2 --
 drivers/media/video/tuner-3036.c |    2 --
 drivers/pci/setup-bus.c          |   30 +++++++++++++++++++++---------
 drivers/usb/serial/Kconfig       |    2 +-
 5 files changed, 22 insertions(+), 16 deletions(-)

-----

Greg Kroah-Hartman:
o USB: don't build the whiteheat driver if on SMP as the locking is all messed up
o I2C: remove some MOD_INC and MOD_DEC usages that are not needed anymore

Ivan Kokshaysky:
o PCI: fix bug in pci_setup_bridge()

author
#1 lore raw

PATCH 1/1 fixes for 2.6.0-test9

ChangeSet 1.1384, 2003/10/29 15:20:38-08:00, [email protected]

[PATCH] PCI: fix bug in pci_setup_bridge()

This bug prevents Alphas with older firmware from booting if there is a card with PCI-PCI bridge that supports 32-bit IO. This has happened on AS2100 with a quad-tulip card, for example:
- initially, the I/O window of 21152 bridge was 0x10000-0x10fff, as set up by firmware;
- pci_setup_bridge() is going to change this, say, to 0xa000-0xafff:
first, it updates PCI_IO_BASE_UPPER16 and PCI_IO_LIMIT_UPPER16 registers, so that IO window temporarily is at 0x0000-0x0fff, which effectively blocks up all legacy IO ports in the lower 4K range, such as serial, floppy, RTC an so on;
does debugging printk - machine dies here with recursive machine checks as the serial console has gone.

Moving (or disabling) the debugging printk is not a solution - there is possibility that timer interrupt (which might access RTC ports) occurs between writes to lower and upper parts of the base/limit registers.

The patch temporarily disables the IO window of the bridge by setting PCI_IO_BASE_UPPER16 > PCI_IO_LIMIT_UPPER16 before doing an update. It's safe, as we don't have any active IO behind the bridge at this point. Also, it's a NOP for bridges with 16-bit-only IO.
Similar (but simpler, as we always clear upper 32 bits) fix for 64-bit prefetchable MMIO range.

 drivers/pci/setup-bus.c |   30 +++++++++++++++++++++---------
 1 files changed, 21 insertions(+), 9 deletions(-)
drivers/pci/setup-bus.c +21 -9
diff -Nru a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
@@ -132,13 +132,19 @@
    PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
    requires that if there is no I/O ports or memory behind the
    bridge, corresponding range must be turned off by writing base
-   value greater than limit to the bridge's base/limit registers.  */
+   value greater than limit to the bridge's base/limit registers.
+
+   Note: care must be taken when updating I/O base/limit registers
+   of bridges which support 32-bit I/O. This update requires two
+   config space writes, so it's quite possible that an I/O window of
+   the bridge will have some undesirable address (e.g. 0) after the
+   first write. Ditto 64-bit prefetchable MMIO.  */
 static void __devinit
 pci_setup_bridge(struct pci_bus *bus)
 {
 	struct pci_dev *bridge = bus->self;
 	struct pci_bus_region region;
-	u32 l;
+	u32 l, io_upper16;
 
 	DBGC((KERN_INFO "PCI: Bus %d, bridge: %s\n",
 			bus->number, pci_name(bridge)));
@@ -151,20 +157,22 @@
 		l |= (region.start >> 8) & 0x00f0;
 		l |= region.end & 0xf000;
 		/* Set up upper 16 bits of I/O base/limit. */
-		pci_write_config_word(bridge, PCI_IO_BASE_UPPER16,
-				      region.start >> 16);
-		pci_write_config_word(bridge, PCI_IO_LIMIT_UPPER16,
-				      region.end >> 16);
+		io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
 		DBGC((KERN_INFO "  IO window: %04lx-%04lx\n",
 				region.start, region.end));
 	}
 	else {
 		/* Clear upper 16 bits of I/O base/limit. */
-		pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0);
+		io_upper16 = 0;
 		l = 0x00f0;
 		DBGC((KERN_INFO "  IO window: disabled.\n"));
 	}
+	/* Temporarily disable the I/O range before updating PCI_IO_BASE. */
+	pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff);
+	/* Update lower 16 bits of I/O base/limit. */
 	pci_write_config_dword(bridge, PCI_IO_BASE, l);
+	/* Update upper 16 bits of I/O base/limit. */
+	pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16);
 
 	/* Set up the top and bottom of the PCI Memory segment
 	   for this bus. */
@@ -181,8 +189,9 @@
 	}
 	pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
 
-	/* Clear out the upper 32 bits of PREF base/limit. */
-	pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
+	/* Clear out the upper 32 bits of PREF limit.
+	   If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily
+	   disables PREF range, which is ok. */
 	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
 
 	/* Set up PREF base/limit. */
@@ -198,6 +207,9 @@
 		DBGC((KERN_INFO "  PREFETCH window: disabled.\n"));
 	}
 	pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
+
+	/* Clear out the upper 32 bits of PREF base. */
+	pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
 
 	/* Check if we have VGA behind the bridge.
 	   Enable ISA in either case (FIXME!). */
author
#2 lore raw

ChangeSet 1.1385, 2003/10/29 16:04:38-08:00, [email protected]

[PATCH] I2C: remove some MOD_INC and MOD_DEC usages that are not needed anymore.

 drivers/media/video/bt832.c      |    2 --
 drivers/media/video/saa5249.c    |    2 --
 drivers/media/video/tuner-3036.c |    2 --
 3 files changed, 6 deletions(-)
drivers/media/video/bt832.c +0 -2
diff -Nru a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
@@ -187,7 +187,6 @@
         t->client.data = t;
         i2c_attach_client(&t->client);
 
-	MOD_INC_USE_COUNT;
 	if(! bt832_init(&t->client)) {
 		bt832_detach(&t->client);
 		return -1;
@@ -210,7 +209,6 @@
 	printk("bt832: detach.\n");
 	i2c_detach_client(client);
 	kfree(t);
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
drivers/media/video/saa5249.c +0 -2
diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
@@ -214,7 +214,6 @@
 	}
 	t->client = client;
 	i2c_attach_client(client);
-	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -237,7 +236,6 @@
 	kfree(vd->priv);
 	kfree(vd);
 	kfree(client);
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
drivers/media/video/tuner-3036.c +0 -2
diff -Nru a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c
@@ -134,7 +134,6 @@
 	printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client));
 
         i2c_attach_client(client);
-	MOD_INC_USE_COUNT;
 
 	if (i2c_master_send(client, buffer, 2) != 2)
 		printk("tuner: i2c i/o error 1\n");
@@ -148,7 +147,6 @@
 static int 
 tuner_detach(struct i2c_client *c)
 {
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
author
#3 lore raw

ChangeSet 1.1386, 2003/10/29 16:04:55-08:00, [email protected]

[PATCH] USB: don't build the whiteheat driver if on SMP as the locking is all messed up.

 drivers/usb/serial/Kconfig |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)
drivers/usb/serial/Kconfig +1 -1
diff -Nru a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
@@ -73,7 +73,7 @@
 
 config USB_SERIAL_WHITEHEAT
 	tristate "USB ConnectTech WhiteHEAT Serial Driver"
-	depends on USB_SERIAL
+	depends on USB_SERIAL && BROKEN_ON_SMP
 	help
 	  Say Y here if you want to use a ConnectTech WhiteHEAT 4 port
 	  USB to serial converter device.