Resent-Date: Thu, 26 Aug 1999 20:19:09 +0200 (MET DST) From: Wout Klaren To: Jes Sorensen Subject: Patches for 2.3.14 Date: Thu, 26 Aug 1999 19:08:36 +0200 Cc: Linux/m68k Resent-From: linux-m68k@phil.uni-sb.de Hello, Here are some patches for 2.3.14: - Fix PPP configuration - Fix Hades PCI support Wout Klaren diff -ur linux-2.3.14.orig/arch/m68k/config.in linux-2.3.14/arch/m68k/config.in --- linux-2.3.14.orig/arch/m68k/config.in Thu Aug 26 18:16:56 1999 +++ linux-2.3.14/arch/m68k/config.in Thu Aug 26 18:57:59 1999 @@ -246,7 +246,9 @@ fi tristate 'PPP (point-to-point) support' CONFIG_PPP if [ ! "$CONFIG_PPP" = "n" ]; then - comment 'CCP compressors for PPP are only built as modules.' + dep_tristate 'PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP + dep_tristate 'PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP + dep_tristate 'PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m fi tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER if [ "$CONFIG_ZORRO" = "y" ]; then diff -ruN -x *.o -x *.a -x .*depend -x .config* -x .menuconfig* -x System.map -x .version -x autoconf.h -x compile.h -x vmlinux -x *_MODULES -x *.ver -x *.flags -x Entries -x Root -x Repository linux-2.3.14.orig/arch/m68k/atari/Makefile linux-2.3.14/arch/m68k/atari/Makefile --- linux-2.3.14.orig/arch/m68k/atari/Makefile Sat Jan 31 14:01:28 1998 +++ linux-2.3.14/arch/m68k/atari/Makefile Wed Aug 25 18:51:44 1999 @@ -12,4 +12,10 @@ joystick.o stram.o OX_OBJS := atari_ksyms.o +ifdef CONFIG_PCI +ifdef CONFIG_HADES +O_OBJS += hades-pci.o +endif +endif + include $(TOPDIR)/Rules.make diff -ruN -x *.o -x *.a -x .*depend -x .config* -x .menuconfig* -x System.map -x .version -x autoconf.h -x compile.h -x vmlinux -x *_MODULES -x *.ver -x *.flags -x Entries -x Root -x Repository linux-2.3.14.orig/arch/m68k/atari/config.c linux-2.3.14/arch/m68k/atari/config.c --- linux-2.3.14.orig/arch/m68k/atari/config.c Sat Jan 16 10:16:11 1999 +++ linux-2.3.14/arch/m68k/atari/config.c Thu Aug 26 18:26:59 1999 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -245,6 +246,9 @@ memset(&atari_hw_present, 0, sizeof(atari_hw_present)); atari_debug_init(); + + ioport_resource.end = 0xFFFFFFFF; /* Change size of I/O space from 64KB + to 4GB. */ mach_sched_init = atari_sched_init; mach_keyb_init = atari_keyb_init; diff -ruN -x *.o -x *.a -x .*depend -x .config* -x .menuconfig* -x System.map -x .version -x autoconf.h -x compile.h -x vmlinux -x *_MODULES -x *.ver -x *.flags -x Entries -x Root -x Repository linux-2.3.14.orig/arch/m68k/atari/hades-pci.c linux-2.3.14/arch/m68k/atari/hades-pci.c --- linux-2.3.14.orig/arch/m68k/atari/hades-pci.c Thu Jan 1 01:00:00 1970 +++ linux-2.3.14/arch/m68k/atari/hades-pci.c Wed Aug 25 18:53:41 1999 @@ -0,0 +1,361 @@ +/* + * hades-pci.c - Hardware specific PCI BIOS functions the Hades Atari clone. + * + * Written by Wout Klaren. + */ + +#include +#include +#include + +#if 0 +# define DBG_DEVS(args) printk args +#else +# define DBG_DEVS(args) +#endif + +#if defined(CONFIG_PCI) && defined(CONFIG_HADES) + +#include +#include +#include + +#include +#include +#include +#include + +#define HADES_MEM_BASE 0x80000000 +#define HADES_MEM_SIZE 0x20000000 +#define HADES_IO_BASE 0xB0000000 +#define HADES_IO_SIZE 0x10000000 + +/* + * static void *mk_conf_addr(unsigned char bus, unsigned char device_fn, + * unsigned char where) + * + * Calculate the address of the PCI configuration area of the given + * device. + * + * BUG: boards with multiple functions are probably not correctly + * supported. + */ + +static void *mk_conf_addr(unsigned char bus, unsigned char device_fn, + unsigned char where) +{ + static const unsigned long pci_conf_base[] = { 0xA0080000, 0xA0040000, + 0xA0020000, 0xA0010000 }; + int device = device_fn >> 3, function = device_fn & 7; + void *result; + + DBG_DEVS(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p)\n", + bus, device_fn, where, pci_addr)); + + if (device > 3) + { + DBG_DEVS(("mk_conf_addr: device (%d) > 3, returning NULL\n", device)); + return NULL; + } + + if (bus != 0) + { + DBG_DEVS(("mk_conf_addr: bus (%d) > 0, returning NULL\n", device)); + return NULL; + } + + result = (void *) (pci_conf_base[device] | (function << 8) | (where)); + DBG_DEVS(("mk_conf_addr: returning pci_addr 0x%lx\n", (unsigned long) result)); + return result; +} + +static int hades_read_config_byte(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned char *value) +{ + volatile unsigned char *pci_addr; + + *value = 0xff; + + if ((pci_addr = (unsigned char *) mk_conf_addr(bus, device_fn, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *value = *pci_addr; + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_read_config_word(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned short *value) +{ + volatile unsigned short *pci_addr; + + *value = 0xffff; + + if (where & 0x1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if ((pci_addr = (unsigned short *) mk_conf_addr(bus, device_fn, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *value = le16_to_cpu(*pci_addr); + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_read_config_dword(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned int *value) +{ + volatile unsigned int *pci_addr; + unsigned char header_type; + int result; + + *value = 0xffffffff; + + if (where & 0x3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if ((pci_addr = (unsigned int *) mk_conf_addr(bus, device_fn, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *value = le32_to_cpu(*pci_addr); + + /* + * Check if the value is an address on the bus. If true, add the + * base address of the PCI memory or PCI I/O area on the Hades. + */ + + if ((result = hades_read_config_byte(bus, device_fn, PCI_HEADER_TYPE, + &header_type)) != PCIBIOS_SUCCESSFUL) + return result; + + if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) || + ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) && + (where <= PCI_BASE_ADDRESS_5)))) + { + if ((*value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) + { + /* + * Base address register that contains an I/O address. If the + * address is valid on the Hades (0 <= *value < HADES_IO_SIZE), + * add HADES_IO_BASE to the value. + */ + + if (*value < HADES_IO_SIZE) + *value += HADES_IO_BASE; + } + else + { + /* + * Base address register that contains an memory address. If the + * address is valid on the Hades (0 <= *value < HADES_MEM_SIZE), + * add HADES_MEM_BASE to the value. + */ + + if (*value == 0) + { + /* + * Base address is 0. Test if this base + * address register is used. + */ + + *pci_addr = 0xffffffff; + if (*pci_addr != 0) + { + *pci_addr = *value; + if (*value < HADES_MEM_SIZE) + *value += HADES_MEM_BASE; + } + } + else + { + if (*value < HADES_MEM_SIZE) + *value += HADES_MEM_BASE; + } + } + } + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_write_config_byte(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned char value) +{ + volatile unsigned char *pci_addr; + + if ((pci_addr = (unsigned char *) mk_conf_addr(bus, device_fn, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *pci_addr = value; + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_write_config_word(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned short value) +{ + volatile unsigned short *pci_addr; + + if ((pci_addr = (unsigned short *) mk_conf_addr(bus, device_fn, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + *pci_addr = cpu_to_le16(value); + + return PCIBIOS_SUCCESSFUL; +} + +static int hades_write_config_dword(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned int value) +{ + volatile unsigned int *pci_addr; + unsigned char header_type; + int result; + + if ((pci_addr = (unsigned int *) mk_conf_addr(bus, device_fn, where)) == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* + * Check if the value is an address on the bus. If true, subtract the + * base address of the PCI memory or PCI I/O area on the Hades. + */ + + if ((result = hades_read_config_byte(bus, device_fn, PCI_HEADER_TYPE, + &header_type)) != PCIBIOS_SUCCESSFUL) + return result; + + if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) || + ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) && + (where <= PCI_BASE_ADDRESS_5)))) + { + if ((value & PCI_BASE_ADDRESS_SPACE) == + PCI_BASE_ADDRESS_SPACE_IO) + { + /* + * I/O address. Check if the address is valid address on + * the Hades (HADES_IO_BASE <= value < HADES_IO_BASE + HADES_IO_SIZE) or + * if the value is 0xffffffff. If not true do not write + * the base address register. If it is a valid base address + * subtract HADES_IO_BASE from the value. + */ + + if ((value >= HADES_IO_BASE) && (value < (HADES_IO_BASE + HADES_IO_SIZE))) + value -= HADES_IO_BASE; + else + { + if (value != 0xffffffff) + return PCIBIOS_SET_FAILED; + } + } + else + { + /* + * Memory address. Check if the address is valid address on + * the Hades (HADES_MEM_BASE <= value < HADES_MEM_BASE + HADES_MEM_SIZE) or + * if the value is 0xffffffff. If not true do not write + * the base address register. If it is a valid base address + * subtract HADES_MEM_BASE from the value. + */ + + if ((value >= HADES_MEM_BASE) && (value < (HADES_MEM_BASE + HADES_MEM_SIZE))) + value -= HADES_MEM_BASE; + else + { + if (value != 0xffffffff) + return PCIBIOS_SET_FAILED; + } + } + } + + *pci_addr = cpu_to_le32(value); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * static inline void hades_fixup(void) + * + * Assign IRQ numbers as used by Linux to the interrupt pins + * of the PCI cards. + */ + +__initfunc(static void hades_fixup(int pci_modify)) +{ + char irq_tab[4] = { + IRQ_TT_MFP_IO0, /* Slot 0. */ + IRQ_TT_MFP_IO1, /* Slot 1. */ + IRQ_TT_MFP_SCC, /* Slot 2. */ + IRQ_TT_MFP_SCSIDMA /* Slot 3. */ + }; + struct pci_dev *dev; + 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) + { + slot = PCI_SLOT(dev->devfn); /* Determine slot number. */ + dev->irq = irq_tab[slot]; + if (pci_modify) + pcibios_write_config_byte(dev->bus->number, dev->devfn, + PCI_INTERRUPT_LINE, dev->irq); + } + } +} + +/* + * static void hades_conf_device(unsigned char bus, unsigned char device_fn) + * + * Machine dependent Configure the given device. + * + * Parameters: + * + * bus - bus number of the device. + * device_fn - device and function number of the device. + */ + +__initfunc(static void hades_conf_device(unsigned char bus, unsigned char device_fn)) +{ + pcibios_write_config_byte(bus, device_fn, PCI_CACHE_LINE_SIZE, 0); +} + +/* + * struct pci_bus_info *init_hades_pci(void) + * + * Machine specific initialisation: + * + * - Allocate and initialise a 'pci_bus_info' structure + * - Initialise hardware + * + * Result: pointer to 'pci_bus_info' structure. + */ + +__initfunc(struct pci_bus_info *init_hades_pci(void)) +{ + struct pci_bus_info *bus; + + bus = kmalloc(sizeof(struct pci_bus_info), GFP_ATOMIC); + + bus->mem_base = HADES_MEM_BASE; + bus->mem_size = HADES_MEM_SIZE; + bus->io_base = HADES_IO_BASE; + bus->io_size = HADES_IO_SIZE; + + bus->read_config_byte = hades_read_config_byte; + bus->read_config_word = hades_read_config_word; + bus->read_config_dword = hades_read_config_dword; + + bus->write_config_byte = hades_write_config_byte; + bus->write_config_word = hades_write_config_word; + bus->write_config_dword = hades_write_config_dword; + + bus->fixup = hades_fixup; + bus->conf_device = hades_conf_device; + + tt_mfp.active_edge &= ~0x27; /* Select high to low edge for PCI interrupts. */ + + return bus; +} +#endif diff -ruN -x *.o -x *.a -x .*depend -x .config* -x .menuconfig* -x System.map -x .version -x autoconf.h -x compile.h -x vmlinux -x *_MODULES -x *.ver -x *.flags -x Entries -x Root -x Repository linux-2.3.14.orig/arch/m68k/kernel/bios32.c linux-2.3.14/arch/m68k/kernel/bios32.c --- linux-2.3.14.orig/arch/m68k/kernel/bios32.c Sun Aug 9 11:34:19 1998 +++ linux-2.3.14/arch/m68k/kernel/bios32.c Wed Aug 25 18:56:24 1999 @@ -1,6 +1,5 @@ /* - * bios32.c - PCI BIOS functions for Alpha systems not using BIOS - * emulation code. + * bios32.c - PCI BIOS functions for m68k systems. * * Written by Wout Klaren. * @@ -22,25 +21,16 @@ /* * PCI support for Linux/m68k. Currently only the Hades is supported. * - * Notes: - * - * 1. The PCI memory area starts at address 0x80000000 and the - * I/O area starts at 0xB0000000. Therefore these offsets - * are added to the base addresses when they are read and - * substracted when they are written. - * - * 2. The support for PCI bridges in the DEC Alpha version has - * been removed in this version. + * The support for PCI bridges in the DEC Alpha version has + * been removed in this version. */ #include #include #include -#include -#include -#include #include +#include #include #define KB 1024 @@ -48,14 +38,7 @@ #define GB (1024*MB) #define MAJOR_REV 0 -#define MINOR_REV 1 - -/* - * Base addresses of the PCI memory and I/O areas on the Hades. - */ - -static unsigned long pci_mem_base = 0; -static unsigned long pci_io_base = 0; +#define MINOR_REV 4 /* * Align VAL to ALIGN, which must be a power of two. @@ -63,181 +46,88 @@ #define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) +#define MAX(val1, val2) (((val1) > (val2)) ? val1 : val2) + +extern struct pci_bus_info *init_hades_pci(void); + /* - * Calculate the address of the PCI configuration area of the given - * device. - * - * BUG: boards with multiple functions are probably not correctly - * supported. + * Bus info structure of the PCI bus. A pointer to this structure is + * put in the sysdata member of the pci_bus structure. */ -static int mk_conf_addr(unsigned char bus, unsigned char device_fn, - unsigned char where, unsigned long *pci_addr) -{ - static const unsigned long pci_conf_base[] = { 0xA0080000, 0xA0040000, - 0xA0020000, 0xA0010000 }; - int device = device_fn >> 3; - - DBG_DEVS(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p)\n", - bus, device_fn, where, pci_addr)); - - if (device > 3) { - DBG_DEVS(("mk_conf_addr: device (%d) > 3, returning -1\n", device)); - return -1; - } +static struct pci_bus_info *bus_info; - *pci_addr = pci_conf_base[device] | (where); - DBG_DEVS(("mk_conf_addr: returning pci_addr 0x%lx\n", *pci_addr)); - return 0; -} +static int pci_modify = 1; /* If set, layout the PCI bus ourself. */ +static int skip_vga = 0; /* If set do not modify base addresses + of vga cards.*/ +static int disable_pci_burst = 0; /* If set do not allow PCI bursts. */ + +static unsigned int io_base; +static unsigned int mem_base; int pcibios_read_config_byte(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned char *value) { - unsigned long pci_addr; - - *value = 0xff; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; - - *value = *((unsigned char *)pci_addr); - - return PCIBIOS_SUCCESSFUL; + if (bus_info != NULL) + return bus_info->read_config_byte(bus, device_fn, where, value); + else + return PCIBIOS_FUNC_NOT_SUPPORTED; } int pcibios_read_config_word(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short *value) { - unsigned long pci_addr; - - *value = 0xffff; - - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr)) - return PCIBIOS_DEVICE_NOT_FOUND; - - *value = le16_to_cpu(*((unsigned short *)pci_addr)); - - return PCIBIOS_SUCCESSFUL; + if (bus_info != NULL) + return bus_info->read_config_word(bus, device_fn, where, value); + else + return PCIBIOS_FUNC_NOT_SUPPORTED; } int pcibios_read_config_dword(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned int *value) { - unsigned long pci_addr; - - *value = 0xffffffff; - - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr)) - return PCIBIOS_DEVICE_NOT_FOUND; - - *value = le32_to_cpu(*((unsigned int *)pci_addr)); - - if ((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_5)) - { - if ((*value & PCI_BASE_ADDRESS_SPACE) == - PCI_BASE_ADDRESS_SPACE_IO) - *value += pci_io_base; - else - { - if (*value == 0) - { - /* - * Base address is 0. Test if this base - * address register is used. - */ - - *((unsigned long *)pci_addr) = 0xffffffff; - if (*((unsigned long *)pci_addr) != 0) - *value += pci_mem_base; - } - else - *value += pci_mem_base; - } - } - - return PCIBIOS_SUCCESSFUL; + if (bus_info != NULL) + return bus_info->read_config_dword(bus, device_fn, where, value); + else + return PCIBIOS_FUNC_NOT_SUPPORTED; } int pcibios_write_config_byte(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned char value) { - unsigned long pci_addr; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; - - *((unsigned char *)pci_addr) = value; - - return PCIBIOS_SUCCESSFUL; + if (bus_info != NULL) + return bus_info->write_config_byte(bus, device_fn, where, value); + else + return PCIBIOS_FUNC_NOT_SUPPORTED; } int pcibios_write_config_word(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned short value) { - unsigned long pci_addr; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; - - *((unsigned short *)pci_addr) = cpu_to_le16(value); - - return PCIBIOS_SUCCESSFUL; + if (bus_info != NULL) + return bus_info->write_config_word(bus, device_fn, where, value); + else + return PCIBIOS_FUNC_NOT_SUPPORTED; } int pcibios_write_config_dword(unsigned char bus, unsigned char device_fn, unsigned char where, unsigned int value) { - unsigned long pci_addr; - - if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) - return PCIBIOS_DEVICE_NOT_FOUND; - - if ((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_5)) - { - if ((value & PCI_BASE_ADDRESS_SPACE) == - PCI_BASE_ADDRESS_SPACE_IO) - value -= pci_io_base; - else - value -= pci_mem_base; - } - - *((unsigned int *)pci_addr) = cpu_to_le32(value); - - return PCIBIOS_SUCCESSFUL; + if (bus_info != NULL) + return bus_info->write_config_dword(bus, device_fn, where, value); + else + return PCIBIOS_FUNC_NOT_SUPPORTED; } /* - * Macro to enable programming of the PCI devices. On the Hades this - * define should be true, because the Hades has no PCI BIOS. - */ - -#define PCI_MODIFY 1 - -#if PCI_MODIFY - -/* - * Leave some room for a VGA card. We assume that the VGA card is - * always in the first 32M of PCI memory. For the time being we do - * not program the VGA card, because to make this work we also - * need to change the frame buffer device. - */ - -#define FIRST_IO_ADDR 0x10000 -#define FIRST_MEM_ADDR 0x02000000 - -static unsigned int io_base = FIRST_IO_ADDR; /* Skip first 64K. */ -static unsigned int mem_base = FIRST_MEM_ADDR; /* Skip first 32M. */ - -/* + * static void disable_dev(struct pci_dev *dev) + * * Disable PCI device DEV so that it does not respond to I/O or memory * accesses. + * + * Parameters: + * + * dev - device to disable. */ __initfunc(static void disable_dev(struct pci_dev *dev)) @@ -245,9 +135,9 @@ struct pci_bus *bus; unsigned short cmd; - if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA || - dev->class >> 8 == PCI_CLASS_DISPLAY_VGA || - dev->class >> 8 == PCI_CLASS_DISPLAY_XGA) + if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga) return; bus = dev->bus; @@ -261,10 +151,7 @@ * Layout memory and I/O for a device: */ -#define MAX(val1, val2) ( ((val1) > (val2)) ? val1 : val2) - -__initfunc(static void layout_dev(struct pci_dev *dev, unsigned long pci_mem_base, - unsigned long pci_io_base)) +__initfunc(static void layout_dev(struct pci_dev *dev)) { struct pci_bus *bus; unsigned short cmd; @@ -273,12 +160,12 @@ int i; /* - * Skip video cards for the time being. + * Skip video cards if requested. */ - if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA || - dev->class >> 8 == PCI_CLASS_DISPLAY_VGA || - dev->class >> 8 == PCI_CLASS_DISPLAY_XGA) + if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) || + (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga) return; bus = dev->bus; @@ -298,7 +185,9 @@ if (!base) { /* this base-address register is unused */ - dev->base_address[i] = 0; + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; continue; } @@ -318,13 +207,21 @@ base &= PCI_BASE_ADDRESS_IO_MASK; mask = (~base << 1) | 0x1; size = (mask & base) & 0xffffffff; - /* align to multiple of size of minimum base */ + + /* + * Align to multiple of size of minimum base. + */ + alignto = MAX(0x400, size) ; base = ALIGN(io_base, alignto); io_base = base + size; pcibios_write_config_dword(bus->number, dev->devfn, - reg, base | 0x1); - dev->base_address[i] = (pci_io_base + base) | 1; + reg, base | PCI_BASE_ADDRESS_SPACE_IO); + + dev->resource[i].start = base; + dev->resource[i].end = dev->resource[i].start + size - 1; + dev->resource[i].flags = PCI_BASE_ADDRESS_SPACE_IO; + DBG_DEVS(("layout_dev: IO address: %lX\n", base)); } else @@ -343,16 +240,8 @@ switch (type) { case PCI_BASE_ADDRESS_MEM_TYPE_32: - break; - case PCI_BASE_ADDRESS_MEM_TYPE_64: - printk("bios32 WARNING: " - "ignoring 64-bit device in " - "slot %d, function %d: \n", - PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn)); - reg += 4; /* skip extra 4 bytes */ - continue; + break; case PCI_BASE_ADDRESS_MEM_TYPE_1M: printk("bios32 WARNING: slot %d, function %d " @@ -364,7 +253,7 @@ } /* - * Align to multiple of size of minimum base + * Align to multiple of size of minimum base. */ alignto = MAX(0x1000, size) ; @@ -372,7 +261,27 @@ mem_base = base + size; pcibios_write_config_dword(bus->number, dev->devfn, reg, base); - dev->base_address[i] = pci_mem_base + base; + + dev->resource[i].start = base; + dev->resource[i].end = dev->resource[i].start + size - 1; + dev->resource[i].flags = 0; + + if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) + { + /* + * 64-bit address, set the highest 32 bits + * to zero. + */ + + reg += 4; + pcibios_write_config_dword(bus->number, dev->devfn, + reg, 0); + + i++; + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } } } @@ -396,13 +305,20 @@ pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND, cmd | PCI_COMMAND_MASTER); + + pcibios_write_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER, + (disable_pci_burst) ? 0 : 32); + + if (bus_info != NULL) + bus_info->conf_device(bus->number, dev->devfn); /* Machine dependent configuration. */ + 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)); } -__initfunc(static void layout_bus(struct pci_bus *bus, unsigned long pci_mem_base, - unsigned long pci_io_base)) +__initfunc(static void layout_bus(struct pci_bus *bus)) { + unsigned int bio, bmem; struct pci_dev *dev; DBG_DEVS(("layout_bus: starting bus %d\n", bus->number)); @@ -415,22 +331,25 @@ * IO and 1MB for memory). */ - io_base = ALIGN(io_base, 4*KB); - mem_base = ALIGN(mem_base, 1*MB); + bio = io_base = ALIGN(io_base, 4*KB); + bmem = mem_base = ALIGN(mem_base, 1*MB); /* * PCI devices might have been setup by a PCI BIOS emulation * running under TOS. In these cases there is a * window during which two devices may have an overlapping - * address range. To avoid this causing trouble, we first + * address range. To avoid this causing trouble, we first * turn off the I/O and memory address decoders for all PCI * devices. They'll be re-enabled only once all address * decoders are programmed consistently. */ + DBG_DEVS(("layout_bus: disable_dev for bus %d\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)) disable_dev(dev); } @@ -442,66 +361,12 @@ for (dev = bus->devices; dev; dev = dev->sibling) { - if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) - layout_dev(dev, pci_mem_base, pci_io_base); + if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) || + (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)) + layout_dev(dev); } -} - -#endif /* !PCI_MODIFY */ - -/* - * Given the vendor and device ids, find the n'th instance of that device - * in the system. - */ -int pcibios_find_device(unsigned short vendor, unsigned short device_id, - unsigned short index, unsigned char *bus, - unsigned char *devfn) -{ - unsigned int curr = 0; - struct pci_dev *dev; - - for (dev = pci_devices; dev; dev = dev->next) - { - if (dev->vendor == vendor && dev->device == device_id) - { - if (curr == index) - { - *devfn = dev->devfn; - *bus = dev->bus->number; - return PCIBIOS_SUCCESSFUL; - } - ++curr; - } - } - return PCIBIOS_DEVICE_NOT_FOUND; -} - -/* - * Given the class, find the n'th instance of that device - * in the system. - */ - -int pcibios_find_class(unsigned int class_code, unsigned short index, - unsigned char *bus, unsigned char *devfn) -{ - unsigned int curr = 0; - struct pci_dev *dev; - - for (dev = pci_devices; dev; dev = dev->next) - { - if (dev->class == class_code) - { - if (curr == index) - { - *devfn = dev->devfn; - *bus = dev->bus->number; - return PCIBIOS_SUCCESSFUL; - } - ++curr; - } - } - return PCIBIOS_DEVICE_NOT_FOUND; + DBG_DEVS(("layout_bus: bus %d finished\n", bus->number)); } int pcibios_present(void) @@ -516,75 +381,69 @@ { printk("Linux/m68k PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV); -#if !PCI_MODIFY - printk("...NOT modifying existing PCI configuration\n"); + bus_info = NULL; +#ifdef CONFIG_HADES + if (MACH_IS_HADES) + bus_info = init_hades_pci(); #endif - - pci_mem_base = 0x80000000; - pci_io_base = 0xB0000000; } -/* - * static inline void hades_fixup(void) - * - * Assign IRQ numbers as used by Linux to the interrupt pins - * of the PCI cards. - */ - -__initfunc(static inline void hades_fixup(void)) +__initfunc(static void pcibios_set_sysdata(struct pci_bus *bus)) { - char irq_tab[4] = { - IRQ_TT_MFP_IO0, /* Slot 0. */ - IRQ_TT_MFP_IO1, /* Slot 1. */ - IRQ_TT_MFP_SCC, /* Slot 2. */ - IRQ_TT_MFP_SCSIDMA /* Slot 3. */ - }; - struct pci_dev *dev; - unsigned char slot; + struct pci_bus *p; - /* - * Go through all devices, fixing up irqs as we see fit: - */ + bus->sysdata = (void *) bus_info; - for (dev = pci_devices; dev; dev = dev->next) - { - if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) - { - slot = PCI_SLOT(dev->devfn); /* Determine slot number. */ - dev->irq = irq_tab[slot]; -#if PCI_MODIFY - pcibios_write_config_byte(dev->bus->number, dev->devfn, - PCI_INTERRUPT_LINE, dev->irq); -#endif - } - } + for (p = bus->children; p != NULL; p = p->next) + pcibios_set_sysdata(p); } __initfunc(void pcibios_fixup(void)) { -#if PCI_MODIFY - unsigned long orig_mem_base, orig_io_base; + if (bus_info == NULL) + return; /* No bus. Return. */ + + if (pci_modify) + { + /* + * Layout the bus. First determine the start addresses to use. The + * first 64K I/O addresses is always skipped. VGA cards might have + * I/O registers in this area. + */ + + io_base = bus_info->io_base + 0x10000; + + /* + * If 'skip_vga' is true, skip the first 64 MB when allocating + * devices. The memory area of most video cards on the PCI bus + * of the Hades are in the first 64 MB. Otherwise start + * allocating devices from address 0. + */ + + mem_base = bus_info->mem_base; + if (skip_vga) + mem_base += 0x04000000; /* Skip the first 64 MB. */ + else + mem_base += 0x01000000; /* Start allocation at PCI address 0x1000000. */ + + /* + * Scan the tree, allocating PCI memory and I/O space. + */ - orig_mem_base = pci_mem_base; - orig_io_base = pci_io_base; - pci_mem_base = 0; - pci_io_base = 0; + layout_bus(&pci_root); + } /* - * Scan the tree, allocating PCI memory and I/O space. + * Fix interrupt assignments, etc. */ - layout_bus(&pci_root, orig_mem_base, orig_io_base); - - pci_mem_base = orig_mem_base; - pci_io_base = orig_io_base; -#endif + bus_info->fixup(pci_modify); /* - * Now is the time to do all those dirty little deeds... + * Set the 'sysdata' member of the PCI buses. */ - hades_fixup(); + pcibios_set_sysdata(&pci_root); } __initfunc(void pcibios_fixup_bus(struct pci_bus *bus)) @@ -593,6 +452,22 @@ __initfunc(char *pcibios_setup(char *str)) { + if (!strcmp(str, "nomodify")) + { + pci_modify = 0; + return NULL; + } + else if (!strcmp(str, "skipvga")) + { + skip_vga = 1; + return NULL; + } + else if (!strcmp(str, "noburst")) + { + disable_pci_burst = 1; + return NULL; + } + return str; } #endif /* CONFIG_PCI */ diff -ruN -x *.o -x *.a -x .*depend -x .config* -x .menuconfig* -x System.map -x .version -x autoconf.h -x compile.h -x vmlinux -x *_MODULES -x *.ver -x *.flags -x Entries -x Root -x Repository linux-2.3.14.orig/include/asm-m68k/pci.h linux-2.3.14/include/asm-m68k/pci.h --- linux-2.3.14.orig/include/asm-m68k/pci.h Thu Jan 1 01:00:00 1970 +++ linux-2.3.14/include/asm-m68k/pci.h Sun Dec 6 15:33:12 1998 @@ -0,0 +1,43 @@ +/* + * asm-m68k/pci.h - m68k specific PCI declarations. + * + * Written by Wout Klaren. + */ + +/* + * Structure with hardware dependent information and functions of the + * PCI bus. + */ + +struct pci_bus_info +{ + /* + * Information about memory areas. + */ + + unsigned long mem_base; /* Base address of memory area of the PCI bus. */ + unsigned long mem_size; /* Size of memory area. */ + unsigned long io_base; /* Base address of I/O area. */ + unsigned long io_size; /* Size of I/O area. */ + + /* + * System dependent functions. + */ + + int (*read_config_byte)(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned char *value); + int (*read_config_word)(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned short *value); + int (*read_config_dword)(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned int *value); + + int (*write_config_byte)(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned char value); + int (*write_config_word)(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned short value); + int (*write_config_dword)(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned int value); + + void (*fixup)(int pci_modify); + void (*conf_device)(unsigned char bus, unsigned char device_fn); +};