patch-2.1.79 linux/arch/alpha/kernel/bios32.c
Next file: linux/arch/alpha/kernel/cia.c
Previous file: linux/arch/alpha/kernel/apecs.c
Back to the patch index
Back to the overall index
- Lines: 1670
- Date:
Mon Jan 12 14:51:14 1998
- Orig file:
v2.1.78/linux/arch/alpha/kernel/bios32.c
- Orig date:
Tue Sep 23 16:48:46 1997
diff -u --recursive --new-file v2.1.78/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
@@ -40,13 +40,15 @@
{
return 0;
}
+
asmlinkage int sys_pciconfig_read()
{
- return 0;
+ return -ENOSYS;
}
+
asmlinkage int sys_pciconfig_write()
{
- return 0;
+ return -ENOSYS;
}
#else /* CONFIG_PCI */
@@ -95,31 +97,73 @@
extern struct hwrpb_struct *hwrpb;
+/* Forward declarations for some extra fixup routines for specific hardware. */
+#ifdef CONFIG_ALPHA_PC164
+static int SMCInit(void);
+#endif
+#ifdef CONFIG_ALPHA_MIATA
+static int es1888_init(void);
+#endif
#if PCI_MODIFY
-/* NOTE: we can't just blindly use 64K for machines with EISA busses; they
- may also have PCI-PCI bridges present, and then we'd configure the bridge
- incorrectly */
-#if 0
-static unsigned int io_base = 64*KB; /* <64KB are (E)ISA ports */
+/*
+ * NOTE: we can't just blindly use 64K for machines with EISA busses; they
+ * may also have PCI-PCI bridges present, and then we'd configure the bridge
+ * incorrectly
+ *
+ * Also, we start at 0x8000 or 0x9000, in hopes to get all devices'
+ * IO space areas allocated *before* 0xC000; this is because certain
+ * BIOSes (Millennium for one) use PCI Config space "mechanism #2"
+ * accesses to probe the bus. If a device's registers appear at 0xC000,
+ * it may see an INx/OUTx at that address during BIOS emulation of the
+ * VGA BIOS, and some cards, notably Adaptec 2940UW, take mortal offense.
+ */
+#if defined(CONFIG_ALPHA_EISA)
+static unsigned int io_base = 0x9000; /* start above 8th slot */
#else
-static unsigned int io_base = 0xb000;
+static unsigned int io_base = 0x8000;
#endif
#if defined(CONFIG_ALPHA_XL)
/*
- an AVANTI *might* be an XL, and an XL has only 27 bits of ISA address
- that get passed through the PCI<->ISA bridge chip. Because this causes
- us to set the PCI->Mem window bases lower than normal, we've gotta allocate
- PCI bus devices' memory addresses *above* the PCI<->memory mapping windows,
- so that CPU memory DMA addresses issued by a bus device don't conflict
- with bus memory addresses, like frame buffer memory for graphics cards.
-*/
-static unsigned int mem_base = 1024*MB;
-#else /* CONFIG_ALPHA_XL */
-static unsigned int mem_base = 16*MB; /* <16MB is ISA memory */
-#endif /* CONFIG_ALPHA_XL */
+ * An XL is AVANTI (APECS) family, *but* it has only 27 bits of ISA address
+ * that get passed through the PCI<->ISA bridge chip. Although this causes
+ * us to set the PCI->Mem window bases lower than normal, we still allocate
+ * PCI bus devices' memory addresses *below* the low DMA mapping window,
+ * and hope they fit below 64Mb (to avoid conflicts), and so that they can
+ * be accessed via SPARSE space.
+ *
+ * We accept the risk that a broken Myrinet card will be put into a true XL
+ * and thus can more easily run into the problem described below.
+ */
+static unsigned int mem_base = 16*MB + 2*MB; /* 16M to 64M-1 is avail */
+
+#elif defined(CONFIG_ALPHA_LCA) || defined(CONFIG_ALPHA_APECS)
+/*
+ * We try to make this address *always* have more than 1 bit set.
+ * this is so that devices like the broken Myrinet card will always have
+ * a PCI memory address that will never match a IDSEL address in
+ * PCI Config space, which can cause problems with early rev cards.
+ *
+ * However, APECS and LCA have only 34 bits for physical addresses, thus
+ * limiting PCI bus memory addresses for SPARSE access to be less than 128Mb.
+ */
+static unsigned int mem_base = 64*MB + 2*MB;
+
+#else
+/*
+ * We try to make this address *always* have more than 1 bit set.
+ * this is so that devices like the broken Myrinet card will always have
+ * a PCI memory address that will never match a IDSEL address in
+ * PCI Config space, which can cause problems with early rev cards.
+ *
+ * Because CIA and PYXIS and T2 have more bits for physical addresses,
+ * they support an expanded range of SPARSE memory addresses.
+ */
+static unsigned int mem_base = 128*MB + 16*MB;
+
+#endif
/*
* Disable PCI device DEV so that it does not respond to I/O or memory
@@ -130,14 +174,14 @@
struct pci_bus *bus;
unsigned short cmd;
-#if defined(CONFIG_ALPHA_MIKASA) || defined(CONFIG_ALPHA_ALCOR)
+#if defined(CONFIG_ALPHA_EISA)
/*
* HACK: the PCI-to-EISA bridge does not seem to identify
* itself as a bridge... :-(
*/
if (dev->vendor == 0x8086 && dev->device == 0x0482) {
- DBG_DEVS(("disable_dev: ignoring PCEB...\n"));
- return;
+ DBG_DEVS(("disable_dev: ignoring PCEB...\n"));
+ return;
}
#endif
@@ -153,7 +197,7 @@
/*
* Layout memory and I/O for a device:
*/
-#define MAX(val1, val2) ( ((val1) > (val2)) ? val1 : val2)
+#define MAX(val1, val2) ((val1) > (val2) ? val1 : val2)
static void layout_dev(struct pci_dev *dev)
{
@@ -162,16 +206,15 @@
unsigned int base, mask, size, reg;
unsigned int alignto;
-#if defined(CONFIG_ALPHA_MIKASA) || defined(CONFIG_ALPHA_ALCOR)
/*
* HACK: the PCI-to-EISA bridge does not seem to identify
* itself as a bridge... :-(
*/
- if (dev->vendor == 0x8086 && dev->device == 0x0482) {
- DBG_DEVS(("layout_dev: ignoring PCEB...\n"));
- return;
+ if (dev->vendor == PCI_VENDOR_ID_INTEL &&
+ dev->device == PCI_DEVICE_ID_INTEL_82375) {
+ DBG_DEVS(("layout_dev: ignoring PCEB...\n"));
+ return;
}
-#endif
bus = dev->bus;
pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
@@ -203,12 +246,23 @@
base &= PCI_BASE_ADDRESS_IO_MASK;
mask = (~base << 1) | 0x1;
size = (mask & base) & 0xffffffff;
- /* align to multiple of size of minimum base */
- alignto = MAX(0x400, size) ;
- base = ALIGN(io_base, alignto );
+ /*
+ * Aligning to 0x800 rather than the minimum base of
+ * 0x400 is an attempt to avoid having devices in
+ * any 0x?C?? range, which is where the de4x5 driver
+ * probes for EISA cards.
+ *
+ * Adaptecs, especially, resent such intrusions.
+ */
+ alignto = MAX(0x800, size);
+ base = ALIGN(io_base, alignto);
io_base = base + size;
pcibios_write_config_dword(bus->number, dev->devfn,
reg, base | 0x1);
+ dev->base_address[(reg - PCI_BASE_ADDRESS_0)>>2]
+ = base | 0x1;
+ DBG_DEVS(("layout_dev: dev 0x%x IO @ 0x%x (0x%x)\n",
+ dev->device, base, size));
} else {
unsigned int type;
/*
@@ -220,10 +274,10 @@
mask = (~base << 1) | 0x1;
size = (mask & base) & 0xffffffff;
switch (type) {
- case PCI_BASE_ADDRESS_MEM_TYPE_32:
+ case PCI_BASE_ADDRESS_MEM_TYPE_32:
break;
- case PCI_BASE_ADDRESS_MEM_TYPE_64:
+ case PCI_BASE_ADDRESS_MEM_TYPE_64:
printk("bios32 WARNING: "
"ignoring 64-bit device in "
"slot %d, function %d: \n",
@@ -232,7 +286,7 @@
reg += 4; /* skip extra 4 bytes */
continue;
- case PCI_BASE_ADDRESS_MEM_TYPE_1M:
+ case PCI_BASE_ADDRESS_MEM_TYPE_1M:
/*
* Allocating memory below 1MB is *very*
* tricky, as there may be all kinds of
@@ -242,9 +296,9 @@
* Alpha (or that the console has set it
* up properly).
*/
- printk("bios32 WARNING: slot %d, function %d "
- "requests memory below 1MB---don't "
- "know how to do that.\n",
+ printk("bios32 WARNING: slot %d, function %d"
+ " requests memory below 1MB---don't"
+ " know how to do that.\n",
PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
continue;
@@ -265,13 +319,13 @@
* dense memory space only!
*/
/* align to multiple of size of minimum base */
- alignto = MAX(0x1000, size) ;
+ alignto = MAX(0x1000, size);
base = ALIGN(mem_base, alignto);
if (size > 7 * 16*MB) {
- printk("bios32 WARNING: slot %d, function %d "
- "requests %dB of contiguous address "
- " space---don't use sparse memory "
- " accesses on this device!!\n",
+ printk("bios32 WARNING: slot %d, function %d"
+ " requests 0x%x bytes of contiguous"
+ " address space---don't use sparse"
+ " memory accesses on this device!!\n",
PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), size);
} else {
@@ -280,7 +334,7 @@
base += 16*MB;
base = ALIGN(base, alignto);
}
- if (base / (128*MB) != (base + size) / (128*MB)) {
+ if (base/(128*MB) != (base + size)/(128*MB)) {
base &= ~(128*MB - 1);
base += (128 + 16)*MB;
base = ALIGN(base, alignto);
@@ -289,13 +343,17 @@
mem_base = base + size;
pcibios_write_config_dword(bus->number, dev->devfn,
reg, base);
+ dev->base_address[(reg-PCI_BASE_ADDRESS_0)>>2] = base;
+ DBG_DEVS(("layout_dev: dev 0x%x MEM @ 0x%x (0x%x)\n",
+ dev->device, base, size));
}
}
- /* enable device: */
+
+ /* Enable device: */
if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED ||
dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA ||
- dev->class >> 8 == PCI_CLASS_DISPLAY_VGA ||
- dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)
+ dev->class >> 8 == PCI_CLASS_STORAGE_IDE ||
+ dev->class >> 16 == PCI_BASE_CLASS_DISPLAY)
{
/*
* All of these (may) have I/O scattered all around
@@ -308,8 +366,11 @@
pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND,
cmd | PCI_COMMAND_MASTER);
- DBG_DEVS(("layout_dev: bus %d slot 0x%x VID 0x%x DID 0x%x class 0x%x\n",
- bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class));
+
+ DBG_DEVS(("layout_dev: bus %d slot %d VID 0x%x DID 0x%x"
+ " class 0x%x cmd 0 x%x\n",
+ bus->number, PCI_SLOT(dev->devfn), dev->vendor,
+ dev->device, dev->class, cmd|PCI_COMMAND_MASTER));
}
@@ -322,7 +383,7 @@
DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
if (!bus->devices && !bus->children)
- return;
+ return;
/*
* Align the current bases on appropriate boundaries (4K for
@@ -341,8 +402,9 @@
* decoders are programmed consistently.
*/
for (dev = bus->devices; dev; dev = dev->sibling) {
- if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) {
- disable_dev(dev) ;
+ if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
+ (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) {
+ disable_dev(dev);
}
}
@@ -352,7 +414,8 @@
DBG_DEVS(("layout_bus: starting bus %d devices\n", bus->number));
for (dev = bus->devices; dev; dev = dev->sibling) {
- if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) {
+ if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
+ (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) {
layout_dev(dev);
}
}
@@ -378,7 +441,8 @@
*/
pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
0x1c, &l);
- l = (l & 0xffff0000) | ((bio >> 8) & 0x00f0) | ((tio - 1) & 0xf000);
+ l &= 0xffff0000;
+ l |= ((bio >> 8) & 0x00f0) | ((tio - 1) & 0xf000);
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x1c, l);
/*
@@ -504,9 +568,10 @@
}
/*
- * A small note about bridges and interrupts. The DECchip 21050 (and later chips)
- * adheres to the PCI-PCI bridge specification. This says that the interrupts on
- * the other side of a bridge are swizzled in the following manner:
+ * A small note about bridges and interrupts. The DECchip 21050 (and later)
+ * adheres to the PCI-PCI bridge specification. This says that the
+ * interrupts on the other side of a bridge are swizzled in the following
+ * manner:
*
* Dev Interrupt Interrupt
* Pin on Pin on
@@ -538,64 +603,89 @@
* The following code is somewhat simplistic as it assumes only one bridge.
* I will fix it later (david.rusling@reo.mts.dec.com).
*/
-static inline unsigned char bridge_swizzle(unsigned char pin, unsigned int slot)
+static inline unsigned char
+bridge_swizzle(unsigned char pin, unsigned int slot)
{
/* swizzle */
- return (((pin-1) + slot) % 4) + 1 ;
+ return (((pin-1) + slot) % 4) + 1;
}
/*
- * Most evaluation boards share most of the fixup code, which is isolated here.
- * This function is declared "inline" as only one platform will ever be selected
- * in any given kernel. If that platform doesn't need this code, we don't want
- * it around as dead code.
+ * Most evaluation boards share most of the fixup code, which is isolated
+ * here. This function is declared "inline" as only one platform will ever
+ * be selected in any given kernel. If that platform doesn't need this code,
+ * we don't want it around as dead code.
*/
-static inline void common_fixup(long min_idsel, long max_idsel, long irqs_per_slot,
- char irq_tab[max_idsel - min_idsel + 1][irqs_per_slot],
- long ide_base)
+static inline void
+common_fixup(long min_idsel, long max_idsel, long irqs_per_slot,
+ char irq_tab[max_idsel - min_idsel + 1][irqs_per_slot],
+ long ide_base)
{
struct pci_dev *dev;
unsigned char pin;
- unsigned char slot ;
+ unsigned char slot;
/*
* Go through all devices, fixing up irqs as we see fit:
*/
for (dev = pci_devices; dev; dev = dev->next) {
- if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE
-#if defined(CONFIG_ALPHA_MIKASA) || defined(CONFIG_ALPHA_ALCOR)
- /* PCEB (PCI to EISA bridge) does not identify
- itself as a bridge... :-( */
- && !((dev->vendor==0x8086) && (dev->device==0x482))
-#endif
- ) {
- dev->irq = 0;
+ if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE
+ /* PCEB (PCI to EISA bridge) does not identify
+ itself as a bridge... :-P */
+ && !(dev->vendor == PCI_VENDOR_ID_INTEL &&
+ dev->device == PCI_DEVICE_ID_INTEL_82375))
+ || dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA) {
/*
- * This device is not on the primary bus, we need to figure out which
- * interrupt pin it will come in on. We know which slot it will come
- * in on 'cos that slot is where the bridge is. Each time the interrupt
- * line passes through a PCI-PCI bridge we must apply the swizzle function
- * (see the inline static routine above).
+ * This device is not on the primary bus, we need
+ * to figure out which interrupt pin it will come
+ * in on. We know which slot it will come in on
+ * 'cos that slot is where the bridge is. Each
+ * time the interrupt line passes through a PCI-PCI
+ * bridge we must apply the swizzle function (see
+ * the inline static routine above).
*/
+ dev->irq = 0;
if (dev->bus->number != 0) {
- struct pci_dev *curr = dev ;
- /* read the pin and do the PCI-PCI bridge interrupt pin swizzle */
- pcibios_read_config_byte(dev->bus->number, dev->devfn,
- PCI_INTERRUPT_PIN, &pin);
+ struct pci_dev *curr = dev;
+ /* read the pin and do the PCI-PCI bridge
+ interrupt pin swizzle */
+ pcibios_read_config_byte(dev->bus->number,
+ dev->devfn,
+ PCI_INTERRUPT_PIN,
+ &pin);
/* cope with 0 */
- if (pin == 0) pin = 1 ;
- /* follow the chain of bridges, swizzling as we go */
+ if (pin == 0)
+ pin = 1;
+ /* follow the chain of bridges, swizzling
+ as we go */
+#if defined(CONFIG_ALPHA_MIATA)
+ slot = PCI_SLOT(dev->devfn) + 5;
+ DBG_DEVS(("MIATA: bus 1 slot %d pin %d"
+ " irq %d min_idsel %d\n",
+ PCI_SLOT(dev->devfn), pin,
+ irq_tab[slot - min_idsel][pin],
+ min_idsel));
+#elif defined(CONFIG_ALPHA_NORITAKE)
+ /* WAG Alert! */
+ slot = PCI_SLOT(dev->devfn) + 14;
+ DBG_DEVS(("NORITAKE: bus 1 slot %d pin %d"
+ " irq %d min_idsel %d\n",
+ PCI_SLOT(dev->devfn), pin,
+ irq_tab[slot - min_idsel][pin],
+ min_idsel));
+#else
do {
/* swizzle */
- pin = bridge_swizzle(pin, PCI_SLOT(curr->devfn)) ;
+ pin = bridge_swizzle(pin, PCI_SLOT(curr->devfn));
/* move up the chain of bridges */
- curr = curr->bus->self ;
- } while (curr->bus->self) ;
+ curr = curr->bus->self;
+ } while (curr->bus->self);
/* The slot is the slot of the last bridge. */
- slot = PCI_SLOT(curr->devfn) ;
+ slot = PCI_SLOT(curr->devfn);
+#endif /* MIATA */
} else {
/* work out the slot */
- slot = PCI_SLOT(dev->devfn) ;
+ slot = PCI_SLOT(dev->devfn);
/* read the pin */
pcibios_read_config_byte(dev->bus->number,
dev->devfn,
@@ -606,20 +696,39 @@
dev->irq = irq_tab[slot - min_idsel][pin];
#if PCI_MODIFY
/* tell the device: */
- pcibios_write_config_byte(dev->bus->number, dev->devfn,
- PCI_INTERRUPT_LINE, dev->irq);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn,
+ PCI_INTERRUPT_LINE,
+ dev->irq);
#endif
+
+ DBG_DEVS(("common_fixup: bus %d slot 0x%x"
+ " VID 0x%x DID 0x%x\n"
+ " int_slot 0x%x pin 0x%x"
+ " pirq 0x%x\n",
+ dev->bus->number, PCI_SLOT(dev->devfn),
+ dev->vendor, dev->device,
+ slot, pin, dev->irq));
+
/*
* if it's a VGA, enable its BIOS ROM at C0000
*/
if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
- pcibios_write_config_dword(dev->bus->number,
- dev->devfn,
- PCI_ROM_ADDRESS,
- 0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
+ pcibios_write_config_dword(dev->bus->number,
+ dev->devfn,
+ PCI_ROM_ADDRESS,
+ 0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
+ }
+ /*
+ * if it's a SCSI, disable its BIOS ROM
+ */
+ if ((dev->class >> 8) == PCI_CLASS_STORAGE_SCSI) {
+ pcibios_write_config_dword(dev->bus->number,
+ dev->devfn,
+ PCI_ROM_ADDRESS,
+ 0x0000000);
}
}
-
}
if (ide_base) {
enable_ide(ide_base);
@@ -641,12 +750,12 @@
*/
static inline void eb66p_fixup(void)
{
- char irq_tab[5][5] = {
- {16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J25 */
- {16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J26 */
- { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
- {16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 9, slot 2, J27 */
- {16+3, 16+3, 16+8, 16+12, 16+6} /* IdSel 10, slot 3, J28 */
+ static char irq_tab[5][5] = {
+ {16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J25 */
+ {16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J26 */
+ { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
+ {16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 9, slot 2, J27 */
+ {16+3, 16+3, 16+8, 16+12, 16+6} /* IdSel 10, slot 3, J28 */
};
common_fixup(6, 10, 5, irq_tab, 0x398);
}
@@ -694,27 +803,24 @@
*
*/
+#ifdef CONFIG_ALPHA_PC164
static inline void alphapc164_fixup(void)
{
- extern int SMCInit(void);
- char irq_tab[7][5] = {
- /*
- * int intA intB intC intD
- * ---- ---- ---- ---- ----
- */
- { 16+2, 16+2, 16+9, 16+13, 16+17}, /* IdSel 5, slot 2, J20 */
- { 16+0, 16+0, 16+7, 16+11, 16+15}, /* IdSel 6, slot 0, J29 */
- { 16+1, 16+1, 16+8, 16+12, 16+16}, /* IdSel 7, slot 1, J26 */
- { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
- { 16+3, 16+3, 16+10, 16+14, 16+18}, /* IdSel 9, slot 3, J19 */
- { 16+6, 16+6, 16+6, 16+6, 16+6}, /* IdSel 10, USB */
- { 16+5, 16+5, 16+5, 16+5, 16+5} /* IdSel 11, IDE */
+ static char irq_tab[7][5] = {
+ /*INT INTA INTB INTC INTD */
+ { 16+2, 16+2, 16+9, 16+13, 16+17}, /* IdSel 5, slot 2, J20 */
+ { 16+0, 16+0, 16+7, 16+11, 16+15}, /* IdSel 6, slot 0, J29 */
+ { 16+1, 16+1, 16+8, 16+12, 16+16}, /* IdSel 7, slot 1, J26 */
+ { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
+ { 16+3, 16+3, 16+10, 16+14, 16+18}, /* IdSel 9, slot 3, J19 */
+ { 16+6, 16+6, 16+6, 16+6, 16+6}, /* IdSel 10, USB */
+ { 16+5, 16+5, 16+5, 16+5, 16+5} /* IdSel 11, IDE */
};
common_fixup(5, 11, 5, irq_tab, 0);
-
SMCInit();
}
+#endif
/*
* The AlphaPC64 is very similar to the EB66+ except that its slots
@@ -731,12 +837,12 @@
*/
static inline void cabriolet_fixup(void)
{
- char irq_tab[5][5] = {
- { 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5, slot 2, J21 */
- { 16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J19 */
- { 16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J20 */
- { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
- { 16+3, 16+3, 16+8, 16+12, 16+16} /* IdSel 9, slot 3, J22 */
+ static char irq_tab[5][5] = {
+ { 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5, slot 2, J21 */
+ { 16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J19 */
+ { 16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J20 */
+ { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
+ { 16+3, 16+3, 16+8, 16+12, 16+16} /* IdSel 9, slot 3, J22 */
};
common_fixup(5, 9, 5, irq_tab, 0x398);
@@ -787,12 +893,12 @@
*/
static inline void eb66_and_eb64p_fixup(void)
{
- char irq_tab[5][5] = {
- {16+7, 16+7, 16+7, 16+7, 16+7}, /* IdSel 5, slot ?, ?? */
- {16+0, 16+0, 16+2, 16+4, 16+9}, /* IdSel 6, slot ?, ?? */
- {16+1, 16+1, 16+3, 16+8, 16+10}, /* IdSel 7, slot ?, ?? */
- { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
- {16+6, 16+6, 16+6, 16+6, 16+6}, /* IdSel 9, TULIP */
+ static char irq_tab[5][5] = {
+ {16+7, 16+7, 16+7, 16+7, 16+7}, /* IdSel 5, slot ?, ?? */
+ {16+0, 16+0, 16+2, 16+4, 16+9}, /* IdSel 6, slot ?, ?? */
+ {16+1, 16+1, 16+3, 16+8, 16+10}, /* IdSel 7, slot ?, ?? */
+ { -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
+ {16+6, 16+6, 16+6, 16+6, 16+6}, /* IdSel 9, TULIP */
};
common_fixup(5, 9, 5, irq_tab, 0);
}
@@ -836,21 +942,97 @@
*/
static inline void mikasa_fixup(void)
{
- char irq_tab[8][5] = {
- /*INT INTA INTB INTC INTD */
- {16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 17, SCSI */
- { -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */
- { -1, -1, -1, -1, -1}, /* IdSel 19, ???? */
- { -1, -1, -1, -1, -1}, /* IdSel 20, ???? */
- { -1, -1, -1, -1, -1}, /* IdSel 21, ???? */
- { 16+0, 16+0, 16+1, 16+2, 16+3}, /* IdSel 22, slot 0 */
- { 16+4, 16+4, 16+5, 16+6, 16+7}, /* IdSel 23, slot 1 */
- { 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 24, slot 2 */
+ static char irq_tab[8][5] = {
+ /*INT INTA INTB INTC INTD */
+ {16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 17, SCSI */
+ { -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */
+ { -1, -1, -1, -1, -1}, /* IdSel 19, ???? */
+ { -1, -1, -1, -1, -1}, /* IdSel 20, ???? */
+ { -1, -1, -1, -1, -1}, /* IdSel 21, ???? */
+ { 16+0, 16+0, 16+1, 16+2, 16+3}, /* IdSel 22, slot 0 */
+ { 16+4, 16+4, 16+5, 16+6, 16+7}, /* IdSel 23, slot 1 */
+ { 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 24, slot 2 */
};
common_fixup(6, 13, 5, irq_tab, 0);
}
/*
+ * Fixup configuration for NORITAKE (MIKASA is different)
+ *
+ * Summary @ 0x542, summary register #1:
+ * Bit Meaning
+ * 0 All valid ints from summary regs 2 & 3
+ * 1 QLOGIC ISP1020A SCSI
+ * 2 Interrupt Line A from slot 0
+ * 3 Interrupt Line B from slot 0
+ * 4 Interrupt Line A from slot 1
+ * 5 Interrupt line B from slot 1
+ * 6 Interrupt Line A from slot 2
+ * 7 Interrupt Line B from slot 2
+ * 8 Interrupt Line A from slot 3
+ * 9 Interrupt Line B from slot 3
+ *10 Interrupt Line A from slot 4
+ *11 Interrupt Line B from slot 4
+ *12 Interrupt Line A from slot 5
+ *13 Interrupt Line B from slot 5
+ *14 Interrupt Line A from slot 6
+ *15 Interrupt Line B from slot 6
+ *
+ * Summary @ 0x544, summary register #2:
+ * Bit Meaning
+ * 0 OR of all unmasked ints in SR #2
+ * 1 OR of secondary bus ints
+ * 2 Interrupt Line C from slot 0
+ * 3 Interrupt Line D from slot 0
+ * 4 Interrupt Line C from slot 1
+ * 5 Interrupt line D from slot 1
+ * 6 Interrupt Line C from slot 2
+ * 7 Interrupt Line D from slot 2
+ * 8 Interrupt Line C from slot 3
+ * 9 Interrupt Line D from slot 3
+ *10 Interrupt Line C from slot 4
+ *11 Interrupt Line D from slot 4
+ *12 Interrupt Line C from slot 5
+ *13 Interrupt Line D from slot 5
+ *14 Interrupt Line C from slot 6
+ *15 Interrupt Line D from slot 6
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot Device
+ * 7 Intel PCI-EISA bridge chip
+ * 8 DEC PCI-PCI bridge chip
+ * 11 PCI on board slot 0
+ * 12 PCI on board slot 1
+ * 13 PCI on board slot 2
+ *
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and
+ * above for PCI interrupts. The IRQ relates to which bit the interrupt
+ * comes in on. This makes interrupt processing much easier.
+ */
+static inline void noritake_fixup(void)
+{
+ static char irq_tab[13][5] = {
+ /*INT INTA INTB INTC INTD */
+ { -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */
+ { -1, -1, -1, -1, -1}, /* IdSel 19, PPB */
+ { -1, -1, -1, -1, -1}, /* IdSel 20, ???? */
+ { -1, -1, -1, -1, -1}, /* IdSel 21, ???? */
+ { 16+2, 16+2, 16+3, 32+2, 32+3}, /* IdSel 22, slot 0 */
+ { 16+4, 16+4, 16+5, 32+4, 32+5}, /* IdSel 23, slot 1 */
+ { 16+6, 16+6, 16+7, 32+6, 32+7}, /* IdSel 24, slot 2 */
+ /* The following are actually on bus 1, across the bridge */
+ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */
+ { 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 17, slot 3 */
+ {16+10, 16+10, 16+11, 32+10, 32+11}, /* IdSel 18, slot 4 */
+ {16+12, 16+12, 16+13, 32+12, 32+13}, /* IdSel 19, slot 5 */
+ {16+14, 16+14, 16+15, 32+14, 32+15}, /* IdSel 20, slot 6 */
+ };
+ common_fixup(7, 18, 5, irq_tab, 0);
+}
+
+/*
* Fixup configuration for ALCOR
*
* Summary @ GRU_INT_REQ:
@@ -895,14 +1077,14 @@
*/
static inline void alcor_fixup(void)
{
- char irq_tab[6][5] = {
- /*INT INTA INTB INTC INTD */
- { 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 18, slot 0 */
- {16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 19, slot 3 */
- {16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 20, slot 4 */
- { -1, -1, -1, -1, -1}, /* IdSel 21, PCEB */
- { 16+0, 16+0, 16+1, 16+2, 16+3}, /* IdSel 22, slot 2 */
- { 16+4, 16+4, 16+5, 16+6, 16+7}, /* IdSel 23, slot 1 */
+ static char irq_tab[6][5] = {
+ /*INT INTA INTB INTC INTD */
+ { 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 18, slot 0 */
+ {16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 19, slot 3 */
+ {16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 20, slot 4 */
+ { -1, -1, -1, -1, -1}, /* IdSel 21, PCEB */
+ { 16+0, 16+0, 16+1, 16+2, 16+3}, /* IdSel 22, slot 2 */
+ { 16+4, 16+4, 16+5, 16+6, 16+7}, /* IdSel 23, slot 1 */
};
common_fixup(7, 12, 5, irq_tab, 0);
}
@@ -950,19 +1132,183 @@
*/
static inline void xlt_fixup(void)
{
- char irq_tab[7][5] = {
- /*INT INTA INTB INTC INTD */
- {16+13, 16+13, 16+13, 16+13, 16+13}, /* IdSel 17, TULIP */
- { 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 18, slot 0 */
- { -1, -1, -1, -1, -1}, /* IdSel 19, none */
- {16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 20, SCSI */
- { -1, -1, -1, -1, -1}, /* IdSel 21, SIO */
- { 16+0, 16+0, 16+1, 16+2, 16+3}, /* IdSel 22, slot 2 */
- { 16+4, 16+4, 16+5, 16+6, 16+7}, /* IdSel 23, slot 1 */
+ static char irq_tab[7][5] = {
+ /*INT INTA INTB INTC INTD */
+ {16+13, 16+13, 16+13, 16+13, 16+13}, /* IdSel 17, TULIP */
+ { 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 18, slot 0 */
+ { -1, -1, -1, -1, -1}, /* IdSel 19, none */
+ {16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 20, SCSI */
+ { -1, -1, -1, -1, -1}, /* IdSel 21, SIO */
+ { 16+0, 16+0, 16+1, 16+2, 16+3}, /* IdSel 22, slot 2 */
+ { 16+4, 16+4, 16+5, 16+6, 16+7}, /* IdSel 23, slot 1 */
};
common_fixup(6, 12, 5, irq_tab, 0);
}
+/*
+ * Fixup configuration for ALPHA SABLE (2100) - 2100A is different ??
+ *
+ * Summary Registers (536/53a/53c):
+ * Bit Meaning
+ *-----------------
+ * 0 PCI slot 0
+ * 1 NCR810 (builtin)
+ * 2 TULIP (builtin)
+ * 3 mouse
+ * 4 PCI slot 1
+ * 5 PCI slot 2
+ * 6 keyboard
+ * 7 floppy
+ * 8 COM2
+ * 9 parallel port
+ *10 EISA irq 3
+ *11 EISA irq 4
+ *12 EISA irq 5
+ *13 EISA irq 6
+ *14 EISA irq 7
+ *15 COM1
+ *16 EISA irq 9
+ *17 EISA irq 10
+ *18 EISA irq 11
+ *19 EISA irq 12
+ *20 EISA irq 13
+ *21 EISA irq 14
+ *22 NC
+ *23 IIC
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot Device
+ * 0 TULIP
+ * 1 SCSI
+ * 2 PCI-EISA bridge
+ * 3 none
+ * 4 none
+ * 5 none
+ * 6 PCI on board slot 0
+ * 7 PCI on board slot 1
+ * 8 PCI on board slot 2
+ *
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and
+ * above for PCI interrupts. The IRQ relates to which bit the interrupt
+ * comes in on. This makes interrupt processing much easier.
+ */
+/* NOTE: the IRQ assignments below are arbitrary, but need to be consistent
+ with the values in the sable_irq_to_mask[] and sable_mask_to_irq[] tables
+ in irq.c
+ */
+static inline void sable_fixup(void)
+{
+ static char irq_tab[9][5] = {
+ /*INT INTA INTB INTC INTD */
+ { 32+0, 32+0, 32+0, 32+0, 32+0}, /* IdSel 0, TULIP */
+ { 32+1, 32+1, 32+1, 32+1, 32+1}, /* IdSel 1, SCSI */
+ { -1, -1, -1, -1, -1}, /* IdSel 2, SIO */
+ { -1, -1, -1, -1, -1}, /* IdSel 3, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 4, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 5, none */
+ { 32+2, 32+2, 32+2, 32+2, 32+2}, /* IdSel 6, slot 0 */
+ { 32+3, 32+3, 32+3, 32+3, 32+3}, /* IdSel 7, slot 1 */
+ { 32+4, 32+4, 32+4, 32+4, 32+4}, /* IdSel 8, slot 2 */
+ };
+ common_fixup(0, 8, 5, irq_tab, 0);
+}
+
+/*
+ * Fixup configuration for MIATA (EV56+PYXIS)
+ *
+ * Summary @ PYXIS_INT_REQ:
+ * Bit Meaning
+ * 0 Fan Fault
+ * 1 NMI
+ * 2 Halt/Reset switch
+ * 3 none
+ * 4 CID0 (Riser ID)
+ * 5 CID1 (Riser ID)
+ * 6 Interval timer
+ * 7 PCI-ISA Bridge
+ * 8 Ethernet
+ * 9 EIDE (deprecated, ISA 14/15 used)
+ *10 none
+ *11 USB
+ *12 Interrupt Line A from slot 4
+ *13 Interrupt Line B from slot 4
+ *14 Interrupt Line C from slot 4
+ *15 Interrupt Line D from slot 4
+ *16 Interrupt Line A from slot 5
+ *17 Interrupt line B from slot 5
+ *18 Interrupt Line C from slot 5
+ *19 Interrupt Line D from slot 5
+ *20 Interrupt Line A from slot 1
+ *21 Interrupt Line B from slot 1
+ *22 Interrupt Line C from slot 1
+ *23 Interrupt Line D from slot 1
+ *24 Interrupt Line A from slot 2
+ *25 Interrupt Line B from slot 2
+ *26 Interrupt Line C from slot 2
+ *27 Interrupt Line D from slot 2
+ *27 Interrupt Line A from slot 3
+ *29 Interrupt Line B from slot 3
+ *30 Interrupt Line C from slot 3
+ *31 Interrupt Line D from slot 3
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot Device
+ * 3 DC21142 Ethernet
+ * 4 EIDE CMD646
+ * 5 none
+ * 6 USB
+ * 7 PCI-ISA bridge
+ * 8 PCI-PCI Bridge (SBU Riser)
+ * 9 none
+ * 10 none
+ * 11 PCI on board slot 4 (SBU Riser)
+ * 12 PCI on board slot 5 (SBU Riser)
+ *
+ * These are behind the bridge, so I'm not sure what to do...
+ *
+ * 13 PCI on board slot 1 (SBU Riser)
+ * 14 PCI on board slot 2 (SBU Riser)
+ * 15 PCI on board slot 3 (SBU Riser)
+ *
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and
+ * above for PCI interrupts. The IRQ relates to which bit the interrupt
+ * comes in on. This makes interrupt processing much easier.
+ */
+
+#ifdef CONFIG_ALPHA_MIATA
+static inline void miata_fixup(void)
+{
+ static char irq_tab[18][5] = {
+ /*INT INTA INTB INTC INTD */
+ {16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8}, /* IdSel 14, DC21142 */
+ { -1, -1, -1, -1, -1}, /* IdSel 15, EIDE */
+ { -1, -1, -1, -1, -1}, /* IdSel 16, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 17, none */
+/* {16+11, 16+11, 16+11, 16+11, 16+11},*//* IdSel 17, USB ?? */
+ { -1, -1, -1, -1, -1}, /* IdSel 18, PCI-ISA */
+ { -1, -1, -1, -1, -1}, /* IdSel 19, PCI-PCI */
+ { -1, -1, -1, -1, -1}, /* IdSel 20, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 21, none */
+ {16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 22, slot 4 */
+ {16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 23, slot 5 */
+ /* The following are actually on bus 1, across the bridge */
+ {16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 24, slot 1 */
+ {16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 25, slot 2 */
+ {16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 26, slot 3 */
+ { -1, -1, -1, -1, -1}, /* IdSel 27, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 28, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 29, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 30, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 31, PCI-PCI */
+ };
+ common_fixup(3, 20, 5, irq_tab, 0);
+ es1888_init();
+}
+#endif
/*
* Fixup configuration for all boards that route the PCI interrupts
@@ -1011,6 +1357,8 @@
{ 0, 0, 0, 0, 0}, /* idsel 14 AS255 TULIP */
#endif
};
+ const size_t pirq_tab_len = sizeof(pirq_tab)/sizeof(pirq_tab[0]);
+
/*
* route_tab selects irq routing in PCI/ISA bridge so that:
* PIRQ0 -> irq 15
@@ -1021,7 +1369,12 @@
* This probably ought to be configurable via MILO. For
* example, sound boards seem to like using IRQ 9.
*/
-#ifdef CONFIG_ALPHA_NONAME
+
+#if defined(CONFIG_ALPHA_BOOK1)
+ /* for the AlphaBook1, NCR810 SCSI is 14, PCMCIA controller is 15 */
+ const unsigned int route_tab = 0x0e0f0a0a;
+
+#elif defined(CONFIG_ALPHA_NONAME)
/*
* For UDB, the only available PCI slot must not map to IRQ 9,
* since that's the builtin MSS sound chip. That PCI slot
@@ -1033,9 +1386,10 @@
* selected... :-(
*/
const unsigned int route_tab = 0x0b0a0f09;
-#else /* CONFIG_ALPHA_NONAME */
+#else
const unsigned int route_tab = 0x0b0a090f;
-#endif /* CONFIG_ALPHA_NONAME */
+#endif
+
unsigned int level_bits;
unsigned char pin, slot;
int pirq;
@@ -1047,11 +1401,13 @@
*/
level_bits = 0;
for (dev = pci_devices; dev; dev = dev->next) {
- if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE)
+ if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
+ (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
continue;
+
dev->irq = 0;
if (dev->bus->number != 0) {
- struct pci_dev *curr = dev ;
+ struct pci_dev *curr = dev;
/*
* read the pin and do the PCI-PCI bridge
* interrupt pin swizzle
@@ -1059,41 +1415,44 @@
pcibios_read_config_byte(dev->bus->number, dev->devfn,
PCI_INTERRUPT_PIN, &pin);
/* cope with 0 */
- if (pin == 0) pin = 1 ;
+ if (pin == 0)
+ pin = 1;
/* follow the chain of bridges, swizzling as we go */
do {
/* swizzle */
- pin = bridge_swizzle(pin, PCI_SLOT(curr->devfn)) ;
+ pin = bridge_swizzle(pin, PCI_SLOT(curr->devfn));
/* move up the chain of bridges */
- curr = curr->bus->self ;
- } while (curr->bus->self) ;
+ curr = curr->bus->self;
+ } while (curr->bus->self);
/* The slot is the slot of the last bridge. */
- slot = PCI_SLOT(curr->devfn) ;
+ slot = PCI_SLOT(curr->devfn);
} else {
/* work out the slot */
- slot = PCI_SLOT(dev->devfn) ;
+ slot = PCI_SLOT(dev->devfn);
/* read the pin */
pcibios_read_config_byte(dev->bus->number, dev->devfn,
PCI_INTERRUPT_PIN, &pin);
}
- if (slot < 6 || slot >= 6 + sizeof(pirq_tab)/sizeof(pirq_tab[0])) {
+ if (slot < 6 || slot >= 6 + pirq_tab_len) {
printk("bios32.sio_fixup: "
- "weird, found device %04x:%04x in non-existent slot %d!!\n",
+ "weird, found device %04x:%04x in"
+ " non-existent slot %d!!\n",
dev->vendor, dev->device, slot);
continue;
}
pirq = pirq_tab[slot - 6][pin];
DBG_DEVS(("sio_fixup: bus %d slot 0x%x VID 0x%x DID 0x%x\n"
- " int_slot 0x%x int_pin 0x%x, pirq 0x%x\n",
- dev->bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device,
- slot, pin, pirq));
+ " int_slot 0x%x pin 0x%x pirq 0x%x\n",
+ dev->bus->number, PCI_SLOT(dev->devfn), dev->vendor,
+ dev->device, slot, pin, pirq));
/*
* if it's a VGA, enable its BIOS ROM at C0000
*/
if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
- pcibios_write_config_dword(dev->bus->number, dev->devfn,
+ pcibios_write_config_dword(dev->bus->number,
+ dev->devfn,
PCI_ROM_ADDRESS,
0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
}
@@ -1103,22 +1462,60 @@
if (pirq < 0) {
printk("bios32.sio_fixup: "
- "weird, device %04x:%04x coming in on slot %d has no irq line!!\n",
+ "weird, device %04x:%04x coming in on"
+ " slot %d has no irq line!!\n",
dev->vendor, dev->device, slot);
continue;
}
dev->irq = (route_tab >> (8 * pirq)) & 0xff;
- /* must set the PCI IRQs to level triggered */
- level_bits |= (1 << dev->irq);
+#ifndef CONFIG_ALPHA_BOOK1
+ /* do not set *ANY* level triggers for AlphaBook1 */
+ /* must set the PCI IRQs to level triggered */
+ level_bits |= (1 << dev->irq);
+#endif /* !CONFIG_ALPHA_BOOK1 */
#if PCI_MODIFY
/* tell the device: */
pcibios_write_config_byte(dev->bus->number, dev->devfn,
PCI_INTERRUPT_LINE, dev->irq);
#endif
- }
+
+#ifdef CONFIG_ALPHA_BOOK1
+ /*
+ * On the AlphaBook1, the PCMCIA chip (Cirrus 6729)
+ * is sensitive to PCI bus bursts, so we must DISABLE
+ * burst mode for the NCR 8xx SCSI... :-(
+ *
+ * Note that the NCR810 SCSI driver must preserve the
+ * setting of the bit in order for this to work. At the
+ * moment (2.0.29), ncr53c8xx.c does NOT do this, but
+ * 53c7,8xx.c DOES.
+ */
+ if (dev->vendor == PCI_VENDOR_ID_NCR &&
+ (dev->device == PCI_DEVICE_ID_NCR_53C810 ||
+ dev->device == PCI_DEVICE_ID_NCR_53C815 ||
+ dev->device == PCI_DEVICE_ID_NCR_53C820 ||
+ dev->device == PCI_DEVICE_ID_NCR_53C825)) {
+ unsigned int io_port;
+ unsigned char ctest4;
+
+ pcibios_read_config_dword(dev->bus->number,
+ dev->devfn,
+ PCI_BASE_ADDRESS_0,
+ &io_port);
+ io_port &= PCI_BASE_ADDRESS_IO_MASK;
+ ctest4 = inb(io_port+0x21);
+ if (!(ctest4 & 0x80)) {
+ printk("AlphaBook1 NCR init: setting"
+ " burst disable\n");
+ outb(ctest4 | 0x80, io_port+0x21);
+ }
+ }
+#endif /* CONFIG_ALPHA_BOOK1 */
+ } /* end for-devs */
+
/*
* Now, make all PCI interrupts level sensitive. Notice:
* these registers must be accessed byte-wise. inw()/outw()
@@ -1128,11 +1525,34 @@
* so that the only bits getting set are for devices actually found.
* Note that we do preserve the remainder of the bits, which we hope
* will be set correctly by ARC/SRM.
+ *
+ * Note: we at least preserve any level-set bits on AlphaBook1
*/
level_bits |= ((inb(0x4d0) | (inb(0x4d1) << 8)) & 0x71ff);
outb((level_bits >> 0) & 0xff, 0x4d0);
outb((level_bits >> 8) & 0xff, 0x4d1);
- enable_ide(0x26e);
+
+#ifdef CONFIG_ALPHA_BOOK1
+ {
+ unsigned char orig, config;
+ /* On the AlphaBook1, make sure that register PR1
+ indicates 1Mb mem */
+ outb(0x0f, 0x3ce); orig = inb(0x3cf); /* read PR5 */
+ outb(0x0f, 0x3ce); outb(0x05, 0x3cf); /* unlock PR0-4 */
+ outb(0x0b, 0x3ce); config = inb(0x3cf); /* read PR1 */
+ if ((config & 0xc0) != 0xc0) {
+ printk("AlphaBook1 VGA init: setting 1Mb memory\n");
+ config |= 0xc0;
+ outb(0x0b, 0x3ce); outb(config, 0x3cf); /* write PR1 */
+ }
+ outb(0x0f, 0x3ce); outb(orig, 0x3cf); /* (re)lock PR0-4 */
+ }
+#endif /* CONFIG_ALPHA_BOOK1 */
+
+#ifndef CONFIG_ALPHA_BOOK1
+ /* Do not do IDE init for AlphaBook1 */
+ enable_ide(0x26e);
+#endif
}
@@ -1152,7 +1572,8 @@
/*
* Now is the time to do all those dirty little deeds...
*/
-#if defined(CONFIG_ALPHA_NONAME) || defined(CONFIG_ALPHA_AVANTI) || defined(CONFIG_ALPHA_P2K)
+#if defined(CONFIG_ALPHA_NONAME) || defined(CONFIG_ALPHA_AVANTI) || \
+ defined(CONFIG_ALPHA_P2K)
sio_fixup();
#elif defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB164)
cabriolet_fixup();
@@ -1170,72 +1591,82 @@
alcor_fixup();
#elif defined(CONFIG_ALPHA_XLT)
xlt_fixup();
+#elif defined(CONFIG_ALPHA_SABLE)
+ sable_fixup();
+#elif defined(CONFIG_ALPHA_MIATA)
+ miata_fixup();
+#elif defined(CONFIG_ALPHA_NORITAKE)
+ noritake_fixup();
#else
-# error You must tell me what kind of platform you want.
+# error "You must tell me what kind of platform you want."
#endif
+#ifndef CONFIG_ABSTRACT_CONSOLE
#ifdef CONFIG_TGA_CONSOLE
tga_console_init();
-#endif /* CONFIG_TGA_CONSOLE */
+#endif
+#endif
return mem_start;
}
-asmlinkage int sys_pciconfig_read(
- unsigned long bus,
- unsigned long dfn,
- unsigned long off,
- unsigned long len,
- unsigned char *buf)
+asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn,
+ unsigned long off, unsigned long len,
+ unsigned char *buf)
{
unsigned char ubyte;
unsigned short ushort;
unsigned int uint;
long err = 0;
+ if (!suser())
+ return -EPERM;
+
lock_kernel();
switch (len) {
- case 1:
+ case 1:
err = pcibios_read_config_byte(bus, dfn, off, &ubyte);
if (err != PCIBIOS_SUCCESSFUL)
- ubyte = 0xff;
+ ubyte = 0xff;
put_user(ubyte, buf);
break;
- case 2:
+ case 2:
err = pcibios_read_config_word(bus, dfn, off, &ushort);
if (err != PCIBIOS_SUCCESSFUL)
- ushort = 0xffff;
+ ushort = 0xffff;
put_user(ushort, (unsigned short *)buf);
break;
- case 4:
+ case 4:
err = pcibios_read_config_dword(bus, dfn, off, &uint);
if (err != PCIBIOS_SUCCESSFUL)
- uint = 0xffffffff;
+ uint = 0xffffffff;
put_user(uint, (unsigned int *)buf);
break;
- default:
+ default:
err = -EINVAL;
break;
}
unlock_kernel();
return err;
}
-asmlinkage int sys_pciconfig_write(
- unsigned long bus,
- unsigned long dfn,
- unsigned long off,
- unsigned long len,
- unsigned char *buf)
+
+
+asmlinkage int sys_pciconfig_write(unsigned long bus, unsigned long dfn,
+ unsigned long off, unsigned long len,
+ unsigned char *buf)
{
unsigned char ubyte;
unsigned short ushort;
unsigned int uint;
long err = 0;
+ if (!suser())
+ return -EPERM;
+
lock_kernel();
switch (len) {
- case 1:
+ case 1:
err = get_user(ubyte, buf);
if (err)
break;
@@ -1244,7 +1675,7 @@
err = -EFAULT;
}
break;
- case 2:
+ case 2:
err = get_user(ushort, (unsigned short *)buf);
if (err)
break;
@@ -1253,7 +1684,7 @@
err = -EFAULT;
}
break;
- case 4:
+ case 4:
err = get_user(uint, (unsigned int *)buf);
if (err)
break;
@@ -1262,7 +1693,7 @@
err = -EFAULT;
}
break;
- default:
+ default:
err = -EINVAL;
break;
}
@@ -1270,8 +1701,8 @@
return err;
}
-#ifdef CONFIG_ALPHA_PC164
+#ifdef CONFIG_ALPHA_PC164
/* device "activate" register contents */
#define DEVICE_ON 1
#define DEVICE_OFF 0
@@ -1326,206 +1757,233 @@
#define SMC_DEBUG 0
-unsigned long SMCConfigState( unsigned long baseAddr )
+static unsigned long SMCConfigState(unsigned long baseAddr)
{
- unsigned char devId;
- unsigned char devRev;
-
- unsigned long configPort;
- unsigned long indexPort;
- unsigned long dataPort;
+ unsigned char devId;
+ unsigned char devRev;
- configPort = indexPort = baseAddr;
- dataPort = ( unsigned long )( ( char * )configPort + 1 );
-
- outb(CONFIG_ON_KEY, configPort);
- outb(CONFIG_ON_KEY, configPort);
- outb(DEVICE_ID, indexPort);
- devId = inb(dataPort);
- if ( devId == VALID_DEVICE_ID ) {
- outb(DEVICE_REV, indexPort);
- devRev = inb(dataPort);
- }
- else {
- baseAddr = 0;
- }
- return( baseAddr );
+ unsigned long configPort;
+ unsigned long indexPort;
+ unsigned long dataPort;
+
+ configPort = indexPort = baseAddr;
+ dataPort = configPort + 1;
+
+ outb(CONFIG_ON_KEY, configPort);
+ outb(CONFIG_ON_KEY, configPort);
+ outb(DEVICE_ID, indexPort);
+ devId = inb(dataPort);
+ if ( devId == VALID_DEVICE_ID ) {
+ outb(DEVICE_REV, indexPort);
+ devRev = inb(dataPort);
+ }
+ else {
+ baseAddr = 0;
+ }
+ return baseAddr;
}
-void SMCRunState( unsigned long baseAddr )
+static void SMCRunState(unsigned long baseAddr)
{
- outb(CONFIG_OFF_KEY, baseAddr);
+ outb(CONFIG_OFF_KEY, baseAddr);
}
-unsigned long SMCDetectUltraIO(void)
+static unsigned long SMCDetectUltraIO(void)
{
- unsigned long baseAddr;
+ unsigned long baseAddr;
- baseAddr = 0x3F0;
- if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x3F0 ) {
- return( baseAddr );
- }
- baseAddr = 0x370;
- if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x370 ) {
- return( baseAddr );
- }
- return( ( unsigned long )0 );
+ baseAddr = 0x3F0;
+ if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x3F0 ) {
+ return( baseAddr );
+ }
+ baseAddr = 0x370;
+ if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x370 ) {
+ return( baseAddr );
+ }
+ return( ( unsigned long )0 );
}
-void SMCEnableDevice( unsigned long baseAddr,
- unsigned long device,
- unsigned long portaddr,
- unsigned long interrupt)
+static void SMCEnableDevice(unsigned long baseAddr,
+ unsigned long device,
+ unsigned long portaddr,
+ unsigned long interrupt)
{
- unsigned long indexPort;
- unsigned long dataPort;
+ unsigned long indexPort;
+ unsigned long dataPort;
- indexPort = baseAddr;
- dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
+ indexPort = baseAddr;
+ dataPort = baseAddr + 1;
- outb(LOGICAL_DEVICE_NUMBER, indexPort);
- outb(device, dataPort);
+ outb(LOGICAL_DEVICE_NUMBER, indexPort);
+ outb(device, dataPort);
- outb(ADDR_LO, indexPort);
- outb(( portaddr & 0xFF ), dataPort);
+ outb(ADDR_LO, indexPort);
+ outb(( portaddr & 0xFF ), dataPort);
- outb(ADDR_HI, indexPort);
- outb(( ( portaddr >> 8 ) & 0xFF ), dataPort);
+ outb(ADDR_HI, indexPort);
+ outb((portaddr >> 8) & 0xFF, dataPort);
- outb(INTERRUPT_SEL, indexPort);
- outb(interrupt, dataPort);
+ outb(INTERRUPT_SEL, indexPort);
+ outb(interrupt, dataPort);
- outb(ACTIVATE, indexPort);
- outb(DEVICE_ON, dataPort);
+ outb(ACTIVATE, indexPort);
+ outb(DEVICE_ON, dataPort);
}
-void SMCEnableKYBD( unsigned long baseAddr )
+static void SMCEnableKYBD(unsigned long baseAddr)
{
- unsigned long indexPort;
- unsigned long dataPort;
+ unsigned long indexPort;
+ unsigned long dataPort;
- indexPort = baseAddr;
- dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
+ indexPort = baseAddr;
+ dataPort = baseAddr + 1;
- outb(LOGICAL_DEVICE_NUMBER, indexPort);
- outb(KYBD, dataPort);
+ outb(LOGICAL_DEVICE_NUMBER, indexPort);
+ outb(KYBD, dataPort);
- outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
- outb(KYBD_INTERRUPT, dataPort);
+ outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
+ outb(KYBD_INTERRUPT, dataPort);
- outb(INTERRUPT_SEL_2, indexPort);/* Secondary interrupt select */
- outb(MOUS_INTERRUPT, dataPort);
+ outb(INTERRUPT_SEL_2, indexPort); /* Secondary interrupt select */
+ outb(MOUS_INTERRUPT, dataPort);
- outb(ACTIVATE, indexPort);
- outb(DEVICE_ON, dataPort);
+ outb(ACTIVATE, indexPort);
+ outb(DEVICE_ON, dataPort);
}
-void SMCEnableFDC( unsigned long baseAddr )
+static void SMCEnableFDC(unsigned long baseAddr)
{
- unsigned long indexPort;
- unsigned long dataPort;
+ unsigned long indexPort;
+ unsigned long dataPort;
- unsigned char oldValue;
+ unsigned char oldValue;
- indexPort = baseAddr;
- dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
+ indexPort = baseAddr;
+ dataPort = baseAddr + 1;
- outb(LOGICAL_DEVICE_NUMBER, indexPort);
- outb(FDC, dataPort);
+ outb(LOGICAL_DEVICE_NUMBER, indexPort);
+ outb(FDC, dataPort);
- outb(FDD_MODE_REGISTER, indexPort);
- oldValue = inb(dataPort);
+ outb(FDD_MODE_REGISTER, indexPort);
+ oldValue = inb(dataPort);
- oldValue |= 0x0E; /* Enable burst mode */
- outb(oldValue, dataPort);
+ oldValue |= 0x0E; /* Enable burst mode */
+ outb(oldValue, dataPort);
- outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
- outb(0x06, dataPort );
+ outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
+ outb(0x06, dataPort );
- outb(DMA_CHANNEL_SEL, indexPort); /* DMA channel select */
- outb(0x02, dataPort);
+ outb(DMA_CHANNEL_SEL, indexPort); /* DMA channel select */
+ outb(0x02, dataPort);
- outb(ACTIVATE, indexPort);
- outb(DEVICE_ON, dataPort);
+ outb(ACTIVATE, indexPort);
+ outb(DEVICE_ON, dataPort);
}
#if SMC_DEBUG
-void SMCReportDeviceStatus( unsigned long baseAddr )
+static void SMCReportDeviceStatus(unsigned long baseAddr)
{
- unsigned long indexPort;
- unsigned long dataPort;
- unsigned char currentControl;
-
- indexPort = baseAddr;
- dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
-
- outb(POWER_CONTROL, indexPort);
- currentControl = inb(dataPort);
-
- if ( currentControl & ( 1 << FDC ) )
- printk( "\t+FDC Enabled\n" );
- else
- printk( "\t-FDC Disabled\n" );
-
- if ( currentControl & ( 1 << IDE1 ) )
- printk( "\t+IDE1 Enabled\n" );
- else
- printk( "\t-IDE1 Disabled\n" );
-
- if ( currentControl & ( 1 << IDE2 ) )
- printk( "\t+IDE2 Enabled\n" );
- else
- printk( "\t-IDE2 Disabled\n" );
-
- if ( currentControl & ( 1 << PARP ) )
- printk( "\t+PARP Enabled\n" );
- else
- printk( "\t-PARP Disabled\n" );
-
- if ( currentControl & ( 1 << SER1 ) )
- printk( "\t+SER1 Enabled\n" );
- else
- printk( "\t-SER1 Disabled\n" );
+ unsigned long indexPort;
+ unsigned long dataPort;
+ unsigned char currentControl;
+
+ indexPort = baseAddr;
+ dataPort = baseAddr + 1;
+
+ outb(POWER_CONTROL, indexPort);
+ currentControl = inb(dataPort);
+
+ printk(currentControl & (1 << FDC)
+ ? "\t+FDC Enabled\n" : "\t-FDC Disabled\n");
+ printk(currentControl & (1 << IDE1)
+ ? "\t+IDE1 Enabled\n" : "\t-IDE1 Disabled\n");
+ printk(currentControl & (1 << IDE2)
+ ? "\t+IDE2 Enabled\n" : "\t-IDE2 Disabled\n");
+ printk(currentControl & (1 << PARP)
+ ? "\t+PARP Enabled\n" : "\t-PARP Disabled\n");
+ printk(currentControl & (1 << SER1)
+ ? "\t+SER1 Enabled\n" : "\t-SER1 Disabled\n");
+ printk(currentControl & (1 << SER2)
+ ? "\t+SER2 Enabled\n" : "\t-SER2 Disabled\n");
- if ( currentControl & ( 1 << SER2 ) )
- printk( "\t+SER2 Enabled\n" );
- else
- printk( "\t-SER2 Disabled\n" );
-
- printk( "\n" );
+ printk( "\n" );
}
#endif
-int SMCInit(void)
+static int SMCInit(void)
{
- unsigned long SMCUltraBase;
+ unsigned long SMCUltraBase;
- if ( ( SMCUltraBase = SMCDetectUltraIO( ) ) != ( unsigned long )0 ) {
- printk( "SMC FDC37C93X Ultra I/O Controller found @ 0x%lx\n",
- SMCUltraBase );
+ if ((SMCUltraBase = SMCDetectUltraIO()) != 0UL) {
+ printk("SMC FDC37C93X Ultra I/O Controller found @ 0x%lx\n",
+ SMCUltraBase);
#if SMC_DEBUG
- SMCReportDeviceStatus( SMCUltraBase );
+ SMCReportDeviceStatus(SMCUltraBase);
#endif
- SMCEnableDevice( SMCUltraBase, SER1, COM1_BASE, COM1_INTERRUPT );
- SMCEnableDevice( SMCUltraBase, SER2, COM2_BASE, COM2_INTERRUPT );
- SMCEnableDevice( SMCUltraBase, PARP, PARP_BASE, PARP_INTERRUPT );
- /* on PC164, IDE on the SMC is not enabled; CMD646 (PCI) on MB */
- SMCEnableKYBD( SMCUltraBase );
- SMCEnableFDC( SMCUltraBase );
+ SMCEnableDevice(SMCUltraBase, SER1, COM1_BASE, COM1_INTERRUPT);
+ SMCEnableDevice(SMCUltraBase, SER2, COM2_BASE, COM2_INTERRUPT);
+ SMCEnableDevice(SMCUltraBase, PARP, PARP_BASE, PARP_INTERRUPT);
+ /* On PC164, IDE on the SMC is not enabled;
+ CMD646 (PCI) on MB */
+ SMCEnableKYBD(SMCUltraBase);
+ SMCEnableFDC(SMCUltraBase);
#if SMC_DEBUG
- SMCReportDeviceStatus( SMCUltraBase );
+ SMCReportDeviceStatus(SMCUltraBase);
#endif
- SMCRunState( SMCUltraBase );
- return( 1 );
- }
- else {
+ SMCRunState(SMCUltraBase);
+ return 1;
+ }
+ else {
#if SMC_DEBUG
- printk( "No SMC FDC37C93X Ultra I/O Controller found\n" );
+ printk("No SMC FDC37C93X Ultra I/O Controller found\n");
#endif
- return( 0 );
- }
+ return 0;
+ }
}
-
#endif /* CONFIG_ALPHA_PC164 */
+
+#ifdef CONFIG_ALPHA_MIATA
+/*
+ * Init the built-in ES1888 sound chip (SB16 compatible)
+ */
+static int es1888_init(void)
+{
+ /* Sequence of IO reads to init the audio controller */
+ inb(0x0229);
+ inb(0x0229);
+ inb(0x0229);
+ inb(0x022b);
+ inb(0x0229);
+ inb(0x022b);
+ inb(0x0229);
+ inb(0x0229);
+ inb(0x022b);
+ inb(0x0229);
+ inb(0x0220); /* This sets the base address to 0x220 */
+
+ /* Sequence to set DMA channels */
+ outb(0x01, 0x0226); /* reset */
+ inb(0x0226); /* pause */
+ outb(0x00, 0x0226); /* release reset */
+ while (!(inb(0x022e) & 0x80)) /* wait for bit 7 to assert*/
+ continue;
+ inb(0x022a); /* pause */
+ outb(0xc6, 0x022c); /* enable extended mode */
+ while (inb(0x022c) & 0x80) /* wait for bit 7 to deassert */
+ continue;
+ outb(0xb1, 0x022c); /* setup for write to Interrupt CR */
+ while (inb(0x022c) & 0x80) /* wait for bit 7 to deassert */
+ continue;
+ outb(0x14, 0x022c); /* set IRQ 5 */
+ while (inb(0x022c) & 0x80) /* wait for bit 7 to deassert */
+ continue;
+ outb(0xb2, 0x022c); /* setup for write to DMA CR */
+ while (inb(0x022c) & 0x80) /* wait for bit 7 to deassert */
+ continue;
+ outb(0x18, 0x022c); /* set DMA channel 1 */
+
+ return 0;
+}
+#endif /* CONFIG_ALPHA_MIATA */
#endif /* CONFIG_PCI */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov