--- ./arch/mips/Makefile Wed Jan 10 20:41:53 2001 +++ ./arch/mips/Makefile Fri Apr 27 10:11:31 2001 @@ -138,9 +138,9 @@ endif ifdef CONFIG_COBALT_MICRO_SERVER -ARCHIVES += arch/mips/cobalt/cobalt.o SUBDIRS += arch/mips/cobalt -LOADADDR += 0x80000000 +CORE_FILES += arch/mips/cobalt/cobalt.o +LOADADDR += 0x80080000 endif ifdef CONFIG_SNI_RM200_PCI --- ./arch/mips/cobalt/Makefile Thu Jan 1 10:00:00 1970 +++ ./arch/mips/cobalt/Makefile Fri Apr 27 10:20:49 2001 @@ -0,0 +1,20 @@ +# +# Makefile for the Cobalt micro systems family specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET := cobalt.o + +obj-y := hw-access.o irq.o int-handler.o pci.o \ + reset.o setup.o via.o promcon.o ide.o + +include $(TOPDIR)/Rules.make --- ./arch/mips/cobalt/hw-access.c Thu Jan 1 10:00:00 1970 +++ ./arch/mips/cobalt/hw-access.c Fri Apr 27 10:21:32 2001 @@ -0,0 +1,49 @@ +/* + * Low-level hardware access stuff for Cobalt Microserver 27 board. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996, 1997 by Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +dummy(void) +{ +} + +static unsigned char cobalt_read_cmos(unsigned long reg) +{ + unsigned char retval; + + VIA_PORT_WRITE(0x70, reg); + retval = VIA_PORT_READ(0x71); + VIA_DELAY(); + + return retval; +} + +static void cobalt_write_cmos(unsigned char val, unsigned long reg) +{ + VIA_PORT_WRITE(0x70, reg); + VIA_PORT_WRITE(0x71, val); +} + +struct rtc_ops cobalt_rtc_ops = { + /* + * How to access the RTC functions + */ + &cobalt_read_cmos, + &cobalt_write_cmos, + (void *)dummy /* rtc_bcd_mode */ +}; --- ./arch/mips/cobalt/ide.c Thu Jan 1 10:00:00 1970 +++ ./arch/mips/cobalt/ide.c Thu Mar 8 11:16:59 2001 @@ -0,0 +1,97 @@ +/* + * IDE operations + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996, 1997 by Ralf Baechle + */ +#include +#include +#include +#include +#include +#include + + +static int cobalt_ide_default_irq(ide_ioreg_t base) +{ + switch (base & 0x0fffffff) { + case 0x1f0: return 14; + case 0x170: return 15; + default: + return 0; + } +} + +static ide_ioreg_t cobalt_ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x100001f0; + case 1: return 0x10000170; + default: + return 0; + } +} + +static void cobalt_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + +printk("init_hwif_ports: data_port=%08lx\n", data_port); + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; +} + +static int cobalt_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static void cobalt_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int cobalt_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void cobalt_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void cobalt_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + + +struct ide_ops cobalt_ide_ops = { + &cobalt_ide_default_irq, + &cobalt_ide_default_io_base, + &cobalt_ide_init_hwif_ports, + &cobalt_ide_request_irq, + &cobalt_ide_free_irq, + &cobalt_ide_check_region, + &cobalt_ide_request_region, + &cobalt_ide_release_region +}; --- ./arch/mips/cobalt/int-handler.S Thu Jan 1 10:00:00 1970 +++ ./arch/mips/cobalt/int-handler.S Wed Apr 4 17:08:54 2001 @@ -0,0 +1,131 @@ +/* + * arch/mips/cobalt/int-handler.S + */ +#include +#include +#include +#include +#include +#include + +/* + * cobalt_handle_int: Interrupt handler for the twenty-seven board. + */ + .text + .set noreorder + .set noat + .align 5 + NESTED(cobalt_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + /* + * Get pending Interrupts + */ + mfc0 t0,CP0_CAUSE # get irq mask + mfc0 t1,CP0_STATUS # get enabled interrupts + and t0,t1 + + /* Such a kind of cascade is optimal for R5000 */ + + andi t1,t0,STATUSF_IP2 /* Check for Galileo timer */ + bnez t1,ll_galileo_irq + + andi t1,t0,STATUSF_IP6 /* Check for Via chip */ + bnez t1,ll_via_irq + andi t1,t0,STATUSF_IP3 + bnez t1,ll_ethernet0_irq +/* + * This should be conditional, and not used for the cube-1, but + * there is not a config flag that is useful. + */ + + andi t1,t0,STATUSF_IP4 + bnez t1,ll_ethernet1_irq + andi t1,t0,STATUSF_IP5 + bnez t1,ll_serial_irq + andi t1,t0,STATUSF_IP7 + bnez t1,ll_pci_irq + nop + + /* wrong alarm ... */ + j spurious_interrupt + nop + END(cobalt_handle_int) + + + .align 5 + .set reorder +ll_galileo_irq: move a0,sp + jal galileo_irq + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_via_irq: move a0,sp + jal via_irq + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_ethernet0_irq: + mfc0 s0,CP0_STATUS # mask interrupt + ori t0,s0,(STATUSF_IP3 | STATUSF_IP4) + xori t0,(STATUSF_IP3 | STATUSF_IP4) + mtc0 t0,CP0_STATUS + li a0,4 + move a1,sp + jal cobalt_dispatch_irq + nop + mtc0 s0,CP0_STATUS + j ret_from_irq + nop + + .align 5 + .set reorder +ll_serial_irq: li a0,7 + move a1,sp + jal cobalt_dispatch_irq + nop + j ret_from_irq + nop + + + .align 5 + .set reorder +ll_ethernet1_irq: + mfc0 s0,CP0_STATUS # mask interrupt + + ori t0,s0, (STATUSF_IP3 | STATUSF_IP4) + xori t0,(STATUSF_IP3 | STATUSF_IP4) + + mtc0 t0,CP0_STATUS + li a0,13 + move a1,sp + jal cobalt_dispatch_irq + nop + mtc0 s0,CP0_STATUS + j ret_from_irq + nop + + # + # This is pretty weird. The "pci" interrupt on the hardware + # skematic is from the PCI side of the galileo, so we would + # only get interrupts here if WE write the control register + # that normally enables the cpu to send interrupts to the PCI. + # + # If you want to interrupt a PCI card, look elsewhere. + # + .align 5 + .set reorder +ll_pci_irq: li a0,7 + move a1,sp + jal cobalt_dispatch_irq + nop + j ret_from_irq + nop --- ./arch/mips/cobalt/irq.c Thu Jan 1 10:00:00 1970 +++ ./arch/mips/cobalt/irq.c Wed Apr 4 17:08:54 2001 @@ -0,0 +1,346 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +/* + * These are the routines that handle all the low level interrupt stuff. + * Actions handled here are: initialization of the interrupt map, + * requesting of interrupt lines by handlers, dispatching if interrupts + * to handlers, probing for interrupt lines */ + + +#undef DEBUG + +#ifdef CONFIG_REMOTE_DEBUG +extern void breakpoint(void); +#endif + + +extern void unmask_irq(unsigned int irq_nr); +extern void mask_irq(unsigned int irq_nr); + +unsigned char cache_21 = 0xfb; +unsigned char cache_A1 = 0xff; + +void enable_irq(unsigned int irq) +{ + unsigned long flags; + +#ifdef DEBUG +printk("Enabled IRQ %d\n", irq); +#endif + save_and_cli(flags); + unmask_irq(irq); + restore_flags(flags); +} + +void disable_irq(unsigned int irq) +{ + unsigned long flags; + +#ifdef DEBUG +printk("Disabled IRQ %d\n", irq); +#endif + save_and_cli(flags); + mask_irq(irq); + restore_flags(flags); +} + +static unsigned int startup_none(unsigned int irq) +{ + /* Do nothing */ + return 0; +} + +static void shutdown_none(unsigned int irq) +{ + /* Do nothing */ +} + +#define enable_none shutdown_none +#define disable_none shutdown_none +#define ack_none shutdown_none +#define end_none shutdown_none + +static void affinity_none(unsigned int irq, unsigned long mask) +{ + /* Do nothing */ +} + + + + + +static struct hw_interrupt_type no_irq_type = { + "none", + startup_none, + shutdown_none, + enable_none, + disable_none, + ack_none, + end_none, + affinity_none +}; + +/* + * irq_desc is the structure that keeps track of the state + * and handlers for each of the IRQ lines + */ +static irq_desc_t irq_desc[NR_IRQS] = +{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}}; + + +/* Defined in arch/mips/cobalt/int_handler.S */ +extern void cobalt_handle_int(void); +/* + * spurious_count is used in arch/mips/kernel/entry.S to record the + * number of spurious interrupts we see before the handler is installed. + * It doesn't provide any particularly relevant information for us, so + * we basically ignore it. + */ +unsigned long spurious_count = 0; + +/* + * The interrupt handler calls this once for every unmasked interrupt + * that is pending. vector is the IRQ number that was raised + */ + +void cobalt_dispatch_irq(unsigned int vector, struct pt_regs *regs) +{ + struct irqaction *action; + irq_desc_t *desc = irq_desc + vector; + spin_lock(&desc->lock); +#ifdef DEBUG + if (vector > 0) { + if (desc->action != NULL) + printk("dispatch handle for %d is %x\n", vector, desc->action->handler); + else + printk("dispatch for %d is NULL\n", vector); + } +#endif + + for (action = desc->action; action != NULL; action = action->next) { + if (action->handler != NULL) { + kstat.irqs[0][vector]++; + (*(action->handler))(vector, action->dev_id, regs); + } + } + spin_unlock(&desc->lock); +} + +/* + * Stolen, pretty much intact, from arch/i386/kernel/irq.c + */ + +int setup_irq(unsigned int irq, struct irqaction * new) +{ + int shared = 0; + unsigned long flags; + struct irqaction *old, **p; + irq_desc_t *desc = irq_desc + irq; + + /* + * The following block of code has to be executed atomically + */ + +#ifdef DEBUG +printk("(1)irq_desc_t %d: status=%x handler=%x action=%x depth=%d\n", + irq, desc->status, desc->handler, desc->action, desc->depth); +#endif + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + if ((old = *p) != NULL) { + /* Can't share interrupts unless both agree to */ + if (!(old->flags & new->flags & SA_SHIRQ)) { + spin_unlock_irqrestore(&desc->lock,flags); + return -EBUSY; + } + + /* add new interrupt at end of irq queue */ + do { + p = &old->next; + old = *p; + } while (old); + shared = 1; + } + + *p = new; + + if (!shared) { + desc->depth = 0; + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); + desc->handler->startup(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); +#ifdef DEBUG +printk("(2)irq_desc_t %d: status=%x handler=%x action=%x depth=%d\n", + irq, desc->status, desc->handler, desc->action, desc->depth); +#endif + return 0; +} + + + +/* + * request_irq() is called by drivers to request addition to the chain + * of handlers called for a given interrupt. + * + * arch/i386/kernel/irq.c says this is going to become generic code in 2.5 + * Makes sense, considering it's already architecture independent. As such, + * I've tried to match the i386 style as much as possible to make the + * transition simple + */ +int request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, const char * devname, void *dev_id) +{ + int retval; + struct irqaction * action; + /* + * Sanity-check: shared interrupts should REALLY pass in + * a real dev-ID, otherwise we'll have trouble later trying + * to figure out which interrupt is which (messes up the + * interrupt freeing logic etc). + */ + if (irqflags & SA_SHIRQ) { + if (!dev_id) + printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]); + } + + if (irq >= NR_IRQS) { + return -EINVAL; + } + if (!handler) { + return -EINVAL; + } + + action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL); + if (!action) { + return -ENOMEM; + } + + action->handler = handler; + action->flags = irqflags; + action->mask = 0; + action->name = devname; + action->next = NULL; + action->dev_id = dev_id; + + retval = setup_irq(irq, action); + if (retval) { + kfree(action); + } + enable_irq(irq); + return retval; +} + + +/* + * free_irq() releases a handler set up by request_irq() + */ +void free_irq(unsigned int irq, void *dev_id) +{ + irq_desc_t *desc; + struct irqaction **p; + unsigned long flags; + + if (irq >= NR_IRQS) + return; + + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + for (;;) { + struct irqaction * action = *p; + if (action) { + struct irqaction **pp = p; + p = &action->next; + if (action->dev_id != dev_id) + continue; + + /* Found it - now remove it from the list of entries */ + *pp = action->next; + if (!desc->action) { + desc->status |= IRQ_DISABLED; + desc->handler->shutdown(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); +#ifdef CONFIG_SMP + /* Wait to make sure it's not being used on another CPU */ + while (desc->status & IRQ_INPROGRESS) + barrier(); +#endif + kfree(action); + return; + } + spin_unlock_irqrestore(&desc->lock,flags); + return; + } +} + +/* + * get_irq_list() pretty prints a list of who has requested which + * irqs. This function is activated by a read of a file in /proc/ + * Returns the length of the string generated + * + */ +int get_irq_list(char *buf) +{ + int i, len = 0; + struct irqaction * action; + + for (i = 0 ; i < 16 ; i++) { + irq_desc_t *desc = irq_desc + i; + action = desc->action; + if (!action) + continue; + len += sprintf(buf+len, "%2d: %8d %c %s", + i, kstat_irqs(i), + (action->flags & SA_INTERRUPT) ? '+' : ' ', + action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + len += sprintf(buf+len, "\n"); + } + + return len; +} + + +unsigned long probe_irq_on (void) +{ + return 0; +} + +int probe_irq_off (unsigned long irqs) +{ + return 0; +} + +void __init init_IRQ(void) +{ + irq_setup(); + +#ifdef CONFIG_REMOTE_DEBUG + set_debug_traps(); + breakpoint(); +#endif +} + --- ./arch/mips/cobalt/pci.c Thu Jan 1 10:00:00 1970 +++ ./arch/mips/cobalt/pci.c Wed Apr 4 17:08:54 2001 @@ -0,0 +1,470 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Cobalt Qube specific PCI support. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_PCI + +#define SELF 0 + +static void qube_expansion_slot_bist(void) +{ + unsigned char ctrl; + int timeout = 100000; + + pcibios_read_config_byte(0, (0x0a<<3), PCI_BIST, &ctrl); + if(!(ctrl & PCI_BIST_CAPABLE)) + return; + + pcibios_write_config_byte(0, (0x0a<<3), PCI_BIST, ctrl|PCI_BIST_START); + do { + pcibios_read_config_byte(0, (0x0a<<3), PCI_BIST, &ctrl); + if(!(ctrl & PCI_BIST_START)) + break; + } while(--timeout > 0); + if((timeout <= 0) || (ctrl & PCI_BIST_CODE_MASK)) + printk("PCI: Expansion slot card failed BIST with code %x\n", + (ctrl & PCI_BIST_CODE_MASK)); +} + +static void qube_expansion_slot_fixup(void) +{ + unsigned short pci_cmd; + unsigned long ioaddr_base = 0x10108000; /* It's magic, ask Doug. */ + unsigned long memaddr_base = 0x12000000; + int i; + + /* Enable bits in COMMAND so driver can talk to it. */ + pcibios_read_config_word(0, (0x0a<<3), PCI_COMMAND, &pci_cmd); + pci_cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + pcibios_write_config_word(0, (0x0a<<3), PCI_COMMAND, pci_cmd); + + /* Give it a working IRQ. */ + pcibios_write_config_byte(0, (0x0a<<3), PCI_INTERRUPT_LINE, 9); + + /* Fixup base addresses, we only support I/O at the moment. */ + for(i = 0; i <= 5; i++) { + unsigned int regaddr = (PCI_BASE_ADDRESS_0 + (i * 4)); + unsigned int rval, mask, size, alignme, aspace; + unsigned long *basep = &ioaddr_base; + + /* Check type first, punt if non-IO. */ + pcibios_read_config_dword(0, (0x0a<<3), regaddr, &rval); + aspace = (rval & PCI_BASE_ADDRESS_SPACE); + if(aspace != PCI_BASE_ADDRESS_SPACE_IO) + basep = &memaddr_base; + + /* Figure out how much it wants, if anything. */ + pcibios_write_config_dword(0, (0x0a<<3), regaddr, 0xffffffff); + pcibios_read_config_dword(0, (0x0a<<3), regaddr, &rval); + + /* Unused? */ + if(rval == 0) + continue; + + rval &= PCI_BASE_ADDRESS_IO_MASK; + mask = (~rval << 1) | 0x1; + size = (mask & rval) & 0xffffffff; + alignme = size; + if(alignme < 0x400) + alignme = 0x400; + rval = ((*basep + (alignme - 1)) & ~(alignme - 1)); + *basep = (rval + size); + pcibios_write_config_dword(0, (0x0a<<3), regaddr, rval | aspace); + } + qube_expansion_slot_bist(); +} + +#define DEFAULT_BMIBA 0xcc00 /* in case ROM did not init it */ + + +static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) +{ + unsigned short cfgword; + unsigned char lt; + unsigned int bmiba; + int try_again = 1; + + /* Enable Bus Mastering and fast back to back. */ + pci_read_config_word(dev, PCI_COMMAND, &cfgword); + cfgword |= (PCI_COMMAND_FAST_BACK | PCI_COMMAND_MASTER); + pci_write_config_word(dev, PCI_COMMAND, cfgword); + + /* Enable interfaces. ROM only enables primary one. */ + { +#ifdef CONFIG_BLK_DEV_COBALT_SECONDARY + unsigned char iface_enable = 0xb; +#else + unsigned char iface_enable = 0xa; +#endif + pci_write_config_byte(dev, 0x40, iface_enable); + } + + /* Set latency timer to reasonable value. */ + pci_read_config_byte(dev, PCI_LATENCY_TIMER, <); + if(lt < 64) + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7); + + /* Get the bmiba base address. */ + do { + pci_read_config_dword(dev, 0x20, &bmiba); + bmiba &= 0xfff0; /* extract port base address */ + if (bmiba) { + break; + } else { + printk("ide: BM-DMA base register is invalid (0x%08x)\n", bmiba); + if (inb(DEFAULT_BMIBA) != 0xff || !try_again) + break; + printk("ide: setting BM-DMA base register to 0x%08x\n", + DEFAULT_BMIBA); + pci_write_config_dword(dev, 0x20, DEFAULT_BMIBA|1); + } + } while (try_again--); + + bmiba += 0x10000000; + + dev->resource[4].start = bmiba; +} + +static void qube_raq_tulip_fixup(struct pci_dev *dev) +{ + unsigned short pci_cmd; + extern int cobalt_is_raq; + unsigned int tmp; + + /* Fixup the first tulip located at device PCICONF_ETH0 */ + if (dev->devfn == PCI_DEVSHFT(COBALT_PCICONF_ETH0)) { + /* + * Now tell the Ethernet device that we expect an interrupt at + * IRQ 13 and not the default 189. + * + * The IRQ of the first Tulip is different on Qube and RaQ + * hardware except for the weird first RaQ bringup board, + */ + if (! cobalt_is_raq) { + /* All Qube's route this the same way. */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + COBALT_ETHERNET_IRQ); + } else { + /* Setup the first Tulip on the RAQ */ +#ifndef RAQ_BOARD_1_WITH_HWHACKS + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 4); +#else + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 13); +#endif + } + /* Fixup the second tulip located at device PCICONF_ETH1 */ + } else if (dev->devfn == PCI_DEVSHFT(COBALT_PCICONF_ETH1)) { + /* XXX Check for the second Tulip on the RAQ (Already got it!) */ + pci_read_config_dword(dev, PCI_VENDOR_ID, &tmp); + if(tmp == 0xffffffff || tmp == 0x00000000) + return; + + /* Enable the second Tulip device. */ + pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); + pci_cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MASTER); + pci_write_config_word(dev, PCI_COMMAND, pci_cmd); + + /* Give it it's IRQ. */ + /* NOTE: RaQ board #1 has a bunch of green wires which swapped the + * IRQ line values of Tulip 0 and Tulip 1. All other + * boards have eth0=4,eth1=13. -DaveM + */ +#ifndef RAQ_BOARD_1_WITH_HWHACKS + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 13); +#else + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 4); +#endif + + /* And finally, a usable I/O space allocation, right after what + * the first Tulip uses. + */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x10101001); + } +} + +static void qube_raq_scsi_fixup(struct pci_dev *dev) +{ + unsigned short pci_cmd; + extern int cobalt_is_raq; + unsigned int tmp; + + /* + * Tell the SCSI device that we expect an interrupt at + * IRQ 7 and not the default 0. + */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_SCSI_IRQ); + + if (cobalt_is_raq) { + /* Check for the SCSI on the RAQ */ + pci_read_config_dword(dev, PCI_VENDOR_ID, &tmp); + if(tmp == 0xffffffff || tmp == 0x00000000) + return; + + /* Enable the device. */ + pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); + + pci_cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY + | PCI_COMMAND_INVALIDATE); + pci_write_config_word(dev, PCI_COMMAND, pci_cmd); + + /* Give it it's IRQ. */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 4); + + /* And finally, a usable I/O space allocation, right after what + * the second Tulip uses. + */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x10102001); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0x00002000); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, 0x00100000); + } +} + +static void qube_raq_galileo_fixup(struct pci_dev *dev) +{ + unsigned short galileo_id; + + /* Fix PCI latency-timer and cache-line-size values in Galileo + * host bridge. + */ + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7); + + /* On all machines prior to Q2, we had the STOP line disconnected + * from Galileo to VIA on PCI. The new Galileo does not function + * correctly unless we have it connected. + * + * Therefore we must set the disconnect/retry cycle values to + * something sensible when using the new Galileo. + */ + pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id); + galileo_id &= 0xff; /* mask off class info */ + if (galileo_id == 0x10) { + /* New Galileo, assumes PCI stop line to VIA is connected. */ + *((volatile unsigned int *)0xb4000c04) = 0x00004020; + } else if (galileo_id == 0x1 || galileo_id == 0x2) { + unsigned int timeo; + /* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */ + timeo = *((volatile unsigned int *)0xb4000c04); + /* Old Galileo, assumes PCI STOP line to VIA is disconnected. */ + *((volatile unsigned int *)0xb4000c04) = 0x0000ffff; + } +} + +static void +qube_pcibios_fixup(struct pci_dev *dev) +{ + extern int cobalt_is_raq; + unsigned int tmp; + + + if (! cobalt_is_raq) { + /* See if there is a device in the expansion slot, if so + * fixup IRQ, fix base addresses, and enable master + + * I/O + memory accesses in config space. + */ + pcibios_read_config_dword(0, 0x0a<<3, PCI_VENDOR_ID, &tmp); + if(tmp != 0xffffffff && tmp != 0x00000000) + qube_expansion_slot_fixup(); + } else { + + /* And if we are a 2800 we have to setup the expansion slot + * too. + */ + pcibios_read_config_dword(0, 0x0a<<3, PCI_VENDOR_ID, &tmp); + if(tmp != 0xffffffff && tmp != 0x00000000) + qube_expansion_slot_fixup(); + } +} + +struct pci_fixup pcibios_fixups[] = { +/* TBD:: Add each device here and divvy up pcibios_fixup */ + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, qube_raq_via_bmIDE_fixup }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, qube_raq_tulip_fixup }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_GALILEO, PCI_ANY_ID, qube_raq_galileo_fixup }, +/* Not sure about what scsi chips are available on the RAQ, put an entry for all */ + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C860, qube_raq_scsi_fixup }, + { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, qube_pcibios_fixup } +}; + + +static __inline__ int pci_range_ck(struct pci_dev *dev) +{ + if ((dev->bus->number == 0) + && ((PCI_SLOT (dev->devfn) == 0) + || ((PCI_SLOT (dev->devfn) > 6) + && (PCI_SLOT (dev->devfn) <= 12)))) + return 0; /* OK device number */ + + return -1; /* NOT ok device number */ +} + +#define PCI_CFG_DATA ((volatile unsigned long *)0xb4000cfc) +#define PCI_CFG_CTRL ((volatile unsigned long *)0xb4000cf8) + +#define PCI_CFG_SET(dev,where) \ + ((*PCI_CFG_CTRL) = (0x80000000 | (PCI_SLOT ((dev)->devfn) << 11) | \ + (PCI_FUNC ((dev)->devfn) << 8) | (where))) + +static int qube_pci_read_config_dword (struct pci_dev *dev, + int where, + u32 *val) +{ + if (where & 0x3) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (pci_range_ck (dev)) { + *val = 0xFFFFFFFF; + return PCIBIOS_DEVICE_NOT_FOUND; + } + PCI_CFG_SET(dev, where); + *val = *PCI_CFG_DATA; + return PCIBIOS_SUCCESSFUL; +} + +static int qube_pci_read_config_word (struct pci_dev *dev, + int where, + u16 *val) +{ + if (where & 0x1) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (pci_range_ck (dev)) { + *val = 0xffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + PCI_CFG_SET(dev, (where & ~0x3)); + *val = *PCI_CFG_DATA >> ((where & 3) * 8); + return PCIBIOS_SUCCESSFUL; +} + +static int qube_pci_read_config_byte (struct pci_dev *dev, + int where, + u8 *val) +{ + if (pci_range_ck (dev)) { + *val = 0xff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + PCI_CFG_SET(dev, (where & ~0x3)); + *val = *PCI_CFG_DATA >> ((where & 3) * 8); + return PCIBIOS_SUCCESSFUL; +} + +static int qube_pci_write_config_dword (struct pci_dev *dev, + int where, + u32 val) +{ + if(where & 0x3) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (pci_range_ck (dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + PCI_CFG_SET(dev, where); + *PCI_CFG_DATA = val; + return PCIBIOS_SUCCESSFUL; +} + +static int +qube_pci_write_config_word (struct pci_dev *dev, + int where, + u16 val) +{ + unsigned long tmp; + + if (where & 0x1) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (pci_range_ck (dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + PCI_CFG_SET(dev, (where & ~0x3)); + tmp = *PCI_CFG_DATA; + tmp &= ~(0xffff << ((where & 0x3) * 8)); + tmp |= (val << ((where & 0x3) * 8)); + *PCI_CFG_DATA = tmp; + return PCIBIOS_SUCCESSFUL; +} + +static int +qube_pci_write_config_byte (struct pci_dev *dev, + int where, + u8 val) +{ + unsigned long tmp; + + if (pci_range_ck (dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + PCI_CFG_SET(dev, (where & ~0x3)); + tmp = *PCI_CFG_DATA; + tmp &= ~(0xff << ((where & 0x3) * 8)); + tmp |= (val << ((where & 0x3) * 8)); + *PCI_CFG_DATA = tmp; + return PCIBIOS_SUCCESSFUL; +} + + +struct pci_ops qube_pci_ops = { + qube_pci_read_config_byte, + qube_pci_read_config_word, + qube_pci_read_config_dword, + qube_pci_write_config_byte, + qube_pci_write_config_word, + qube_pci_write_config_dword +}; + +void __init pcibios_init(void) +{ + printk("PCI: Probing PCI hardware\n"); + + ioport_resource.start = 0x00000000; + ioport_resource.end = 0x1cffffff; + + pci_scan_bus(0, &qube_pci_ops, NULL); +} + +char *pcibios_setup(char *str) +{ + return str; +} + +int pcibios_enable_device(struct pci_dev *dev) +{ + u16 cmd, status; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + pci_read_config_word(dev, PCI_STATUS, &status); + printk("PCI: Enabling device %s (%04x %04x)\n", dev->slot_name, cmd, status); + /* We'll sort this out when we know it isn't enabled ;) */ + return 0; /* pcibios_enable_resources */ +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size) +{ + + panic("Uhhoh called pcibios_align_resource\n"); +} + +void pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + + panic("Uhhoh called pcibios_update_resource\n"); +} + +void __init pcibios_fixup_bus(struct pci_bus *bus) +{ + /* We don't appear to have sub-busses to fixup here */ +} + + +#endif /* CONFIG_PCI */ --- ./arch/mips/cobalt/promcon.c Thu Jan 1 10:00:00 1970 +++ ./arch/mips/cobalt/promcon.c Wed Mar 7 12:10:43 2001 @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include + +#include +#include +#include + +static unsigned long port = 0x1c800000; + +static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr) +{ + char lsr; + + do { lsr = inb(ioaddr + UART_LSR); + } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE)); + outb(ch, ioaddr + UART_TX); +} + +static __inline__ char ns16550_cons_get_char(unsigned long ioaddr) +{ + char lsr; + + while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0) + udelay(1); + return inb(ioaddr + UART_RX); +} + +void ns16550_console_write(struct console *co, const char *s, unsigned count) +{ + char lsr, ier; + unsigned i; + + ier = inb(port + UART_IER); + outb(0x00, port + UART_IER); + for (i=0; i < count; i++, s++) { + + if(*s == '\n') + ns16550_cons_put_char('\r', port); + ns16550_cons_put_char(*s, port); + } + + do { lsr = inb(port + UART_LSR); + } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE)); + outb(ier, port + UART_IER); +} + +char getDebugChar(void) +{ + return ns16550_cons_get_char(port); +} + +void putDebugChar(char kgdb_char) +{ + ns16550_cons_put_char(kgdb_char, port); +} + + + +static kdev_t +ns16550_console_dev(struct console *c) +{ + return MKDEV(TTY_MAJOR, 64 + c->index); +} + +static struct console ns16550_console = { + name: "prom", + setup: NULL, + write: ns16550_console_write, + device: ns16550_console_dev, + flags: CON_PRINTBUFFER, + index: -1, +}; + +void __init ns16550_setup_console(void) +{ + register_console(&ns16550_console); +} --- ./arch/mips/cobalt/reset.c Thu Jan 1 10:00:00 1970 +++ ./arch/mips/cobalt/reset.c Wed Apr 4 17:08:54 2001 @@ -0,0 +1,62 @@ +/* + * Reset a Cobalt Qube. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void cobalt_machine_restart(char *command) +{ + *(volatile char *)0xbc000000 = 0x0f; + + /* + * Ouch, we're still alive ... This time we take the silver bullet ... + * ... and find that we leave the hardware in a state in which the + * kernel in the flush locks up somewhen during of after the PCI + * detection stuff. + */ + set_cp0_status((ST0_BEV | ST0_ERL), (ST0_BEV | ST0_ERL)); + set_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_32bit_cp0_register(CP0_WIRED, 0); + __asm__ __volatile__( + "jr\t%0" + : + : "r" (0xbfc00000)); +} + +extern int led_state; +#define kLED 0xBC000000 +#define LEDSet(x) (*(volatile unsigned char *) kLED) = (( unsigned char)x) + +void cobalt_machine_halt(void) +{ + int mark; + + // Blink our cute little LED (number 3)... + while (1) { + led_state = led_state | ( 1 << 3 ); + LEDSet(led_state); + mark = jiffies; + while (jiffies<(mark+HZ)); + led_state = led_state & ~( 1 << 3 ); + LEDSet(led_state); + mark = jiffies; + while (jiffies<(mark+HZ)); + } +} + +/* + * This triggers the luser mode device driver for the power switch ;-) + */ +void cobalt_machine_power_off(void) +{ + printk("You can switch the machine off now.\n"); + cobalt_machine_halt(); +} --- ./arch/mips/cobalt/setup.c Thu Jan 1 10:00:00 1970 +++ ./arch/mips/cobalt/setup.c Wed Apr 4 17:08:54 2001 @@ -0,0 +1,169 @@ +/* + * Setup pointers to hardware dependand routines. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996, 1997 by Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern void cobalt_machine_restart(char *command); +extern void cobalt_machine_halt(void); +extern void cobalt_machine_power_off(void); + +extern struct rtc_ops cobalt_rtc_ops; +extern struct ide_ops cobalt_ide_ops; + +char arcs_cmdline[COMMAND_LINE_SIZE] = { "console=ttyS0,115200 root=/dev/hda1" }; + + + +/* + * Initial irq handlers. + */ +void no_action(int cpl, void *dev_id, struct pt_regs *regs) +{ +} + +/* + * IRQ2 is cascade interrupt to second interrupt controller + */ +static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; + +extern asmlinkage void cobalt_handle_int(void); + +static struct resource res_pic1 = + { "pic1", 0xb0000020, 0xb000003F, IORESOURCE_IO }; +static struct resource res_pic2 = + { "pic2", 0xb00000A0, 0xb00000BF, IORESOURCE_IO }; + + + +static void __init cobalt_irq_setup(void) +{ + /* + * Clear all of the interrupts while we change the table around a bit. + */ + set_cp0_status(ST0_IM, 0); + + /* Sets the exception_handler array. */ + set_except_vector(0, cobalt_handle_int); + + request_resource(&ioport_resource, &res_pic1); + request_resource(&ioport_resource, &res_pic2); + + set_cp0_status(ST0_IM, 0); + setup_irq(2, &irq2); + + cli(); + + set_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); + + /* Setup VIA irq mask */ + VIA_PORT_WRITE(0x20, 0x10); + VIA_PORT_WRITE(0x21, 0x00); + VIA_PORT_WRITE(0x21, 0x00); + + VIA_PORT_WRITE(0xa0, 0x10); + VIA_PORT_WRITE(0xa1, 0x00); + VIA_PORT_WRITE(0xa1, 0x00); + +} + +void (*board_time_init)(struct irqaction *irq); + +#define GALILEO_T0_VAL 0xb4000850 +#define GALILEO_TIMER_CTRL 0xb4000864 +#define GALILEO_CPU_MASK 0xb4000c1c + +#define GALILEO_ENTC0 0x01 +#define GALILEO_SELTC0 0x02 + +static void __init cobalt_calibrate_timer(void) +{ + volatile unsigned long *timer_reg = (volatile unsigned long *)GALILEO_T0_VAL; + + /* Default to 150MHZ, since this is what we are shipping. */ + *timer_reg = 500000; +} + +static void __init cobalt_time_init(struct irqaction *irq) +{ + /* Load timer value for 150 Hz */ + cobalt_calibrate_timer(); + + setup_irq(0, irq); + + set_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1 | IE_IRQ0); + + /* Enable timer ints */ + *((volatile unsigned long *) GALILEO_TIMER_CTRL) = + (unsigned long) (GALILEO_ENTC0 | GALILEO_SELTC0); + /* Unmask timer int */ + *((volatile unsigned long *) GALILEO_CPU_MASK) = (unsigned long) 0x00000100; +} + +int cobalt_serial_present; +int cobalt_serial_type; +int cobalt_is_raq; + +void __init cobalt_setup(void) +{ + + _machine_restart = cobalt_machine_restart; + _machine_halt = cobalt_machine_halt; + _machine_power_off = cobalt_machine_power_off; + + irq_setup = cobalt_irq_setup; + board_time_init = cobalt_time_init; + rtc_ops = &cobalt_rtc_ops; +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &cobalt_ide_ops; +#endif + mips_io_port_base = COBALT_LOCAL_IO_SPACE; + + /*ns16550_setup_console();*/ + + /* We have to do this early, here, before the value could + * possibly be overwritten by the bootup sequence. + */ + + cobalt_serial_present = *((unsigned long *) 0xa020001c); + cobalt_serial_type = *((unsigned long *) 0xa0200020); + cobalt_is_raq = (cobalt_serial_present != 0x0 + && cobalt_serial_type == 0x1); +} + +/* prom_init() is called just after the cpu type is determined, from + init_arch(). */ +void __init prom_init(int argc, char **arg) +{ + mips_machgroup = MACH_GROUP_COBALT; + + add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM); +} + +void __init prom_free_prom_memory(void) +{ + /* Something to do here?? */ +} + --- ./arch/mips/cobalt/via.c Thu Jan 1 10:00:00 1970 +++ ./arch/mips/cobalt/via.c Wed Mar 7 12:10:43 2001 @@ -0,0 +1,131 @@ +/* + * Interrupt handling for the VIA ISA bridge. + * + * Everything the same ... just different ... + */ +#include +#include +#include +#include +#include + +extern asmlinkage void do_IRQ(int irq, struct pt_regs * regs); + +extern unsigned char cache_21; +extern unsigned char cache_A1; + +/* + * (un)mask_irq, disable_irq() and enable_irq() only handle (E)ISA and + * PCI devices. Other onboard hardware needs specific routines. + */ +void mask_irq(unsigned int irq_nr) +{ + unsigned char mask; + + mask = 1 << (irq_nr & 7); + if (irq_nr < 8) { + cache_21 |= mask; +#ifdef DEBUG +printk("Masked IRQ %d Cache 21=%x\n", irq_nr, cache_21); +#endif + outb(cache_21, 0x10000021); + } else { + cache_A1 |= mask; +#ifdef DEBUG +printk("Masked IRQ %d Cache A1=%x\n", irq_nr, cache_A1); +#endif + outb(cache_A1, 0x100000a1); + } +} + +void unmask_irq(unsigned int irq_nr) +{ + unsigned char mask; + + mask = ~(1 << (irq_nr & 7)); + if (irq_nr < 8) { + cache_21 &= mask; +#ifdef DEBUG +printk("Unmasked IRQ %d Cache 21=%x\n", irq_nr, cache_21); +#endif + outb(cache_21, 0x10000021); + } else { + cache_A1 &= mask; +#ifdef DEBUG +printk("Unmasked IRQ %d Cache A1=%x\n", irq_nr, cache_A1); +#endif + outb(cache_A1, 0x100000a1); + } +} + +#ifdef DEBUG +asmlinkage void via_irq(struct pt_regs *regs, int cause, int status) +#else +asmlinkage void via_irq(struct pt_regs *regs) +#endif +{ + char mstat, sstat; + + /* Read Master Status */ + VIA_PORT_WRITE(0x20, 0x0C); + mstat = VIA_PORT_READ(0x20); + +#ifdef DEBUG +printk("Via: Cause=%x Status=%x mstat=%x ", cause, status, mstat); +printk("Cache 21=%x\n", cache_21); +#endif + + if (mstat < 0) { + mstat &= 0x7f; + if (mstat != 2) { + cobalt_dispatch_irq(mstat, regs); + VIA_PORT_WRITE(0x20, mstat | 0x20); + } else { + sstat = VIA_PORT_READ(0xA0); + + /* Slave interrupt */ + VIA_PORT_WRITE(0xA0, 0x0C); + sstat = VIA_PORT_READ(0xA0); + +#ifdef DEBUG +printk("Via: Cause=%x Status=%x sstat=%x ", cause, status, sstat); +printk("Cache A1=%x\n", cache_A1); +#endif + if (sstat < 0) { + cobalt_dispatch_irq((sstat + 8) & 0x7f, regs); + VIA_PORT_WRITE(0x20, 0x22); + VIA_PORT_WRITE(0xA0, (sstat & 0x7f) | 0x20); + } else { + printk("Spurious slave interrupt...\n"); + } + } + } else + printk("Spurious master interrupt..."); +} + +#define GALILEO_INTCAUSE 0xb4000c18 +#define GALILEO_T0EXP 0x00000100 + +#ifdef DEBUG +asmlinkage void galileo_irq(struct pt_regs *regs, int cause, int status) +#else +asmlinkage void galileo_irq(struct pt_regs *regs) +#endif +{ + unsigned long irq_src = *((unsigned long *) GALILEO_INTCAUSE); + +#ifdef DEBUG +printk("Galileo: Cause=%x Status=%x IRQsrc=%x\n", cause, status, irq_src); +#endif + + /* Check for timer irq ... */ + if (irq_src & GALILEO_T0EXP) { + cobalt_dispatch_irq(0, regs); + *((volatile unsigned long *) GALILEO_INTCAUSE) = 0; + } else { + long cause = read_32bit_cp0_register(CP0_CAUSE), + status = read_32bit_cp0_register(CP0_STATUS); + printk("Spurious Galileo interrupt..."); + printk("Galileo: Cause=%x Status=%x IRQsrc=%x\n", cause, status, irq_src); + } +} --- ./arch/mips/config.in Thu Jan 11 20:30:32 2001 +++ ./arch/mips/config.in Fri Apr 27 10:16:32 2001 @@ -17,6 +17,10 @@ bool 'Support for Acer PICA 1 chipset' CONFIG_ACER_PICA_61 bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032 bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS + bool 'Support for Cobalt Server (EXPERIMENTAL)' CONFIG_COBALT_MICRO_SERVER + if [ "${CONFIG_COBALT_MICRO_SERVER}" = "y" ]; then + bool ' Support for 2800 (note: only works on 2800)' CONFIG_COBALT_28 n + fi bool 'Support for DECstations (EXPERIMENTAL)' CONFIG_DECSTATION bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 bool 'Support for NEC DDB Vrc-5476 (EXPERIMENTAL)' CONFIG_DDB5476 @@ -141,6 +145,16 @@ define_bool CONFIG_I8259 n fi endmenu + +if [ "$CONFIG_COBALT_MICRO_SERVER" = "y" ]; then + define_bool COBALT_MICRO_SERVER y + define_bool CONFIG_NO_SWAPPER y + define_bool CONFIG_COBALT_27 y + define_bool CONFIG_NO_KEYBOARD y + define_bool CONFIG_NO_VIDEO_CONSOLE y + define_bool CONFIG_COBALT_LCD y + define_bool CONFIG_PCI y +fi mainmenu_option next_comment comment 'Loadable module support' --- ./arch/mips/kernel/setup.c Thu Jan 11 20:30:34 2001 +++ ./arch/mips/kernel/setup.c Wed Mar 14 17:03:33 2001 @@ -439,6 +437,7 @@ { void atlas_setup(void); void baget_setup(void); + void cobalt_setup(void); void ddb_setup(void); void decstation_setup(void); void deskstation_setup(void); @@ -476,6 +475,11 @@ case MACH_GROUP_BAGET: baget_setup(); break; +#endif +#ifdef CONFIG_COBALT_MICRO_SERVER + case MACH_GROUP_COBALT: + cobalt_setup(); + break; #endif #ifdef CONFIG_DECSTATION case MACH_GROUP_DEC: --- ./arch/mips/lib/ide-std.c Thu Jun 17 23:25:49 1999 +++ ./arch/mips/lib/ide-std.c Wed Mar 7 12:16:28 2001 @@ -17,7 +17,7 @@ static int std_ide_default_irq(ide_ioreg_t base) { - switch (base) { + switch (base & 0x0fffffff) { case 0x1f0: return 14; case 0x170: return 15; case 0x1e8: return 11; --- ./drivers/char/Makefile Thu Jan 11 20:30:53 2001 +++ ./drivers/char/Makefile Thu Mar 8 09:20:31 2001 @@ -159,6 +159,7 @@ obj-$(CONFIG_TOSHIBA) += toshiba.o obj-$(CONFIG_DS1620) += ds1620.o obj-$(CONFIG_INTEL_RNG) += i810_rng.o +obj-$(CONFIG_COBALT_LCD) += lcd.o obj-$(CONFIG_QIC02_TAPE) += tpqic02.o --- ./drivers/char/lcd.c Thu Jan 1 10:00:00 1970 +++ ./drivers/char/lcd.c Mon Mar 12 15:28:01 2001 @@ -0,0 +1,621 @@ +/* + * LCD, LED, and Button interface for Cobalt + * Andrew Bose + * + * + */ + +#define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "lcd.h" + +static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg); + +static int lcd_present = 1; + +int led_state = 0; + +#define MAX_INTERFACES 8 +static linkcheck_func_t linkcheck_callbacks[MAX_INTERFACES]; +static void *linkcheck_cookies[MAX_INTERFACES]; + +int lcd_register_linkcheck_func(int iface_num, void *func, void *cookie) +{ + if (iface_num < 0 || + iface_num >= MAX_INTERFACES || + linkcheck_callbacks[iface_num] != NULL) + return -1; + linkcheck_callbacks[iface_num] = (linkcheck_func_t) func; + linkcheck_cookies[iface_num] = cookie; + return 0; +} + +static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct lcd_display button_display; + unsigned long address, a; + int index; + + switch (cmd) { + case LCD_On: + udelay(150); + BusyCheck(); + LCDWriteInst(0x0F); + break; + + case LCD_Off: + udelay(150); + BusyCheck(); + LCDWriteInst(0x08); + break; + + case LCD_Reset: + udelay(150); + LCDWriteInst(0x3F); + udelay(150); + LCDWriteInst(0x3F); + udelay(150); + LCDWriteInst(0x3F); + udelay(150); + LCDWriteInst(0x3F); + udelay(150); + LCDWriteInst(0x01); + udelay(150); + LCDWriteInst(0x06); + break; + + case LCD_Clear: + udelay(150); + BusyCheck(); + LCDWriteInst(0x01); + break; + + case LCD_Cursor_Left: + udelay(150); + BusyCheck(); + LCDWriteInst(0x10); + break; + + case LCD_Cursor_Right: + udelay(150); + BusyCheck(); + LCDWriteInst(0x14); + break; + + case LCD_Cursor_Off: + udelay(150); + BusyCheck(); + LCDWriteInst(0x0C); + break; + + case LCD_Cursor_On: + udelay(150); + BusyCheck(); + LCDWriteInst(0x0F); + break; + + case LCD_Blink_Off: + udelay(150); + BusyCheck(); + LCDWriteInst(0x0E); + break; + + case LCD_Get_Cursor_Pos:{ + struct lcd_display display; + + udelay(150); + BusyCheck(); + display.cursor_address = ( LCDReadInst ); + display.cursor_address = ( display.cursor_address & 0x07F ); + if(copy_to_user((struct lcd_display*)arg, &display, sizeof(struct lcd_display))) + return -EFAULT; + + break; + } + + + case LCD_Set_Cursor_Pos: { + struct lcd_display display; + + if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) + return -EFAULT; + + a = (display.cursor_address | kLCD_Addr ); + + udelay(150); + BusyCheck(); + LCDWriteInst( a ); + + break; + } + + case LCD_Get_Cursor: { + struct lcd_display display; + + udelay(150); + BusyCheck(); + display.character = LCDReadData; + + if(copy_to_user((struct lcd_display*)arg, &display, sizeof(struct lcd_display))) + return -EFAULT; + udelay(150); + BusyCheck(); + LCDWriteInst(0x10); + + break; + } + + case LCD_Set_Cursor:{ + struct lcd_display display; + + if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) + return -EFAULT; + + udelay(150); + BusyCheck(); + LCDWriteData( display.character ); + udelay(150); + BusyCheck(); + LCDWriteInst(0x10); + + break; + } + + + case LCD_Disp_Left: + udelay(150); + BusyCheck(); + LCDWriteInst(0x18); + break; + + case LCD_Disp_Right: + udelay(150); + BusyCheck(); + LCDWriteInst(0x1C); + break; + + case LCD_Home: + udelay(150); + BusyCheck(); + LCDWriteInst(0x02); + break; + + case LCD_Write: { + struct lcd_display display; + + + if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) + return -EFAULT; + + udelay(150); + BusyCheck(); + LCDWriteInst(0x80); + udelay(150); + BusyCheck(); + + for (index = 0; index < (display.size1); index++) { + udelay(150); + BusyCheck(); + LCDWriteData( display.line1[index]); + BusyCheck(); + } + + udelay(150); + BusyCheck(); + LCDWriteInst(0xC0); + udelay(150); + BusyCheck(); + for (index = 0; index < (display.size2); index++) { + udelay(150); + BusyCheck(); + LCDWriteData( display.line2[index]); + } + + break; + } + + case LCD_Read: { + struct lcd_display display; + + BusyCheck(); + for (address = kDD_R00; address <= kDD_R01; address++) { + a = (address | kLCD_Addr ); + + udelay(150); + BusyCheck(); + LCDWriteInst( a ); + udelay(150); + BusyCheck(); + display.line1[address] = LCDReadData; + } + + display.line1[ 0x27 ] = '\0'; + + for (address = kDD_R10; address <= kDD_R11; address++) { + a = (address | kLCD_Addr ); + + udelay(150); + BusyCheck(); + LCDWriteInst( a ); + + udelay(150); + BusyCheck(); + display.line2[address - 0x40 ] = LCDReadData; + } + + display.line2[ 0x27 ] = '\0'; + + if(copy_to_user((struct lcd_display*)arg, &display, + sizeof(struct lcd_display))) + return -EFAULT; + break; + } + +// set all GPIO leds to led_display.leds + + case LED_Set: { + struct lcd_display led_display; + + + if(copy_from_user(&led_display, (struct lcd_display*)arg, + sizeof(struct lcd_display))) + return -EFAULT; + + led_state = led_display.leds; + LEDSet(led_state); + + break; + } + + +// set only bit led_display.leds + + case LED_Bit_Set: { + int i; + int bit=1; + struct lcd_display led_display; + + + if(copy_from_user(&led_display, (struct lcd_display*)arg, + sizeof(struct lcd_display))) + return -EFAULT; + + for (i=0;i<(int)led_display.leds;i++) + { + bit = 2*bit; + } + + led_state = led_state | bit; + LEDSet(led_state); + break; + } + +// clear only bit led_display.leds + + case LED_Bit_Clear: { + int i; + int bit=1; + struct lcd_display led_display; + + + if(copy_from_user(&led_display, (struct lcd_display*)arg, + sizeof(struct lcd_display))) + return -EFAULT; + + for (i=0;i<(int)led_display.leds;i++) + { + bit = 2*bit; + } + + led_state = led_state & ~bit; + LEDSet(led_state); + break; + } + + + case BUTTON_Read: { + button_display.buttons = GPIRead; + if(copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) + return -EFAULT; + break; + } + + case LINK_Check: { + button_display.buttons = *((volatile unsigned long *) (0xB0100060) ); + if(copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) + return -EFAULT; + break; + } + + case LINK_Check_2: { + int iface_num; + + /* panel-utils should pass in the desired interface status is wanted for + * in "buttons" of the structure. We will set this to non-zero if the + * link is in fact up for the requested interface. --DaveM + */ + if(copy_from_user(&button_display, (struct lcd_display *)arg, sizeof(button_display))) + return -EFAULT; + iface_num = button_display.buttons; + if (iface_num >= 0 && + iface_num < MAX_INTERFACES && + linkcheck_callbacks[iface_num] != NULL) { + button_display.buttons = + linkcheck_callbacks[iface_num](linkcheck_cookies[iface_num]); + } else { + button_display.buttons = 0; + } + + if(__copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) + return -EFAULT; + break; + } + +// Erase the flash + + case FLASH_Erase: { + + int ctr=0; + + // Chip Erase Sequence + WRITE_FLASH( kFlash_Addr1, kFlash_Data1 ); + WRITE_FLASH( kFlash_Addr2, kFlash_Data2 ); + WRITE_FLASH( kFlash_Addr1, kFlash_Erase3 ); + WRITE_FLASH( kFlash_Addr1, kFlash_Data1 ); + WRITE_FLASH( kFlash_Addr2, kFlash_Data2 ); + WRITE_FLASH( kFlash_Addr1, kFlash_Erase6 ); + + printk( "Erasing Flash.\n"); + + while ( (!dqpoll(0x00000000,0xFF)) && (!timeout(0x00000000)) ) { + ctr++; + } + + printk("\n"); + printk("\n"); + printk("\n"); + + if (READ_FLASH(0x07FFF0)==0xFF) { printk("Erase Successful\r\n"); } + else if (timeout) { printk("Erase Timed Out\r\n"); } + + break; + } + +// burn the flash + + case FLASH_Burn: { + + volatile unsigned long burn_addr; + unsigned long flags; + int i; + unsigned char *rom; + + + struct lcd_display display; + + if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) + return -EFAULT; + rom = (unsigned char *) kmalloc((128),GFP_ATOMIC); + if ( rom == NULL ) { + printk ("broken\n"); + return 1; + } + + printk("Churning and Burning -"); + save_flags(flags); + for (i=0; iRomImage[0]); + + if(!access_ok(VERIFY_WRITE, user_bytes, FLASH_SIZE)) + return -EFAULT; + + printk("Reading Flash"); + for (i=0; i 0) + return -EINVAL; + + lcd_waiters++; + while(((buttons_now = (long)button_pressed()) == 0) && + !(signal_pending(current))) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(2 * HZ); + } + lcd_waiters--; + + if(signal_pending(current)) + return -ERESTARTSYS; + return buttons_now; +} + +/* + * The various file operations we support. + */ + +static struct file_operations lcd_fops = { + read: lcd_read, + ioctl: lcd_ioctl, + open: lcd_open, +}; + +static struct miscdevice lcd_dev= +{ + LCD_MINOR, + "lcd", + &lcd_fops +}; + +int lcd_init(void) +{ +unsigned long data; + + printk("%s\n", LCD_DRIVER); + misc_register(&lcd_dev); + + /* Check region? Naaah! Just snarf it up. */ +/* request_region(RTC_PORT(0), RTC_IO_EXTENT, "lcd");*/ + + udelay(150); + data = LCDReadData; + if ( (data & 0x000000FF) == (0x00) ) { + lcd_present = 0; + printk("LCD Not Present\n"); + } + else { + lcd_present = 1; + WRITE_GAL( kGal_DevBank2PReg, kGal_DevBank2Cfg ); + WRITE_GAL( kGal_DevBank3PReg, kGal_DevBank3Cfg ); + } + + return 0; +} + + +// +// Function: dqpoll +// +// Description: Polls the data lines to see if the flash is busy +// +// In: address, byte data +// +// Out: 0 = busy, 1 = write or erase complete +// +// + +int dqpoll( volatile unsigned long address, volatile unsigned char data ) { + +volatile unsigned char dq7; + +dq7 = data & 0x80; + +return ( (READ_FLASH(address) & 0x80) == dq7 ); + +} + + +// +// Function: timeout +// +// Description: Checks to see if erase or write has timed out +// By polling dq5 +// +// In: address +// +// +// Out: 0 = not timed out, 1 = timed out + +int timeout( volatile unsigned long address ) { + + +return ( (READ_FLASH(address) & 0x20) == 0x20 ); + +} + + + --- ./drivers/char/lcd.h Thu Jan 1 10:00:00 1970 +++ ./drivers/char/lcd.h Thu Mar 8 09:20:32 2001 @@ -0,0 +1,179 @@ +/* +* +* +* File: lcd.h +* Andrew Bose +* +*/ + + +// function headers + +int dqpoll( volatile unsigned long, volatile unsigned char ); +int timeout( volatile unsigned long ); + +#define LCD_CHARS_PER_LINE 40 +#define FLASH_SIZE 524288 +#define MAX_IDLE_TIME 120 + +struct lcd_display { + unsigned long buttons; + int size1; + int size2; + unsigned char line1[LCD_CHARS_PER_LINE]; + unsigned char line2[LCD_CHARS_PER_LINE]; + unsigned char cursor_address; + unsigned char character; + unsigned char leds; + unsigned char *RomImage; +}; + + + +#define LCD_DRIVER "Cobalt LCD Driver v2.10" + +#define kLCD_IR 0xBF000000 +#define kLCD_DR 0xBF000010 +#define kGPI 0xBD000000 +#define kLED 0xBC000000 + +#define kDD_R00 0x00 +#define kDD_R01 0x27 +#define kDD_R10 0x40 +#define kDD_R11 0x67 + +#define kLCD_Addr 0x00000080 + +#define LCDTimeoutValue 0xfff + + +// Flash definitions AMD 29F040 +#define kFlashBase 0xBFC00000 + +#define kFlash_Addr1 0x5555 +#define kFlash_Addr2 0x2AAA +#define kFlash_Data1 0xAA +#define kFlash_Data2 0x55 +#define kFlash_Prog 0xA0 +#define kFlash_Erase3 0x80 +#define kFlash_Erase6 0x10 +#define kFlash_Read 0xF0 + +#define kFlash_ID 0x90 +#define kFlash_VenAddr 0x00 +#define kFlash_DevAddr 0x01 +#define kFlash_VenID 0x01 +#define kFlash_DevID 0xA4 // 29F040 +//#define kFlash_DevID 0xAD // 29F016 + + +// Macros + +#define LCDWriteData(x) (*(volatile unsigned long *) kLCD_DR) = (x << 24) +#define LCDWriteInst(x) (*(volatile unsigned long *) kLCD_IR) = (x << 24) + +#define LCDReadData (((*(volatile unsigned long *) kLCD_DR) >> 24)) +#define LCDReadInst (((*(volatile unsigned long *) kLCD_IR) >> 24)) + +#define GPIRead (( (*(volatile unsigned long *) kGPI) >> 24)) + +#define LEDSet(x) (*(volatile unsigned char *) kLED) = ((char)x) + +#define WRITE_GAL(x,y) (*((volatile unsigned long *) (0xB4000000 | (x)) ) =y) +#define BusyCheck() while ((LCDReadInst & 0x80) == 0x80) + +#define WRITE_FLASH(x,y) (*((volatile unsigned char *) (kFlashBase | (x)) ) = y) +#define READ_FLASH(x) *((volatile unsigned char *) (kFlashBase | (x)) ) + + + +/* + * Function command codes for io_ctl. + */ +#define LCD_On 1 +#define LCD_Off 2 +#define LCD_Clear 3 +#define LCD_Reset 4 +#define LCD_Cursor_Left 5 +#define LCD_Cursor_Right 6 +#define LCD_Disp_Left 7 +#define LCD_Disp_Right 8 +#define LCD_Get_Cursor 9 +#define LCD_Set_Cursor 10 +#define LCD_Home 11 +#define LCD_Read 12 +#define LCD_Write 13 +#define LCD_Cursor_Off 14 +#define LCD_Cursor_On 15 +#define LCD_Get_Cursor_Pos 16 +#define LCD_Set_Cursor_Pos 17 +#define LCD_Blink_Off 18 + +#define LED_Set 40 +#define LED_Bit_Set 41 +#define LED_Bit_Clear 42 + + +// Button defs +#define BUTTON_Read 50 + +// Flash command codes +#define FLASH_Erase 60 +#define FLASH_Burn 61 +#define FLASH_Read 62 + + +// Ethernet LINK check hackaroo +#define LINK_Check 90 +#define LINK_Check_2 91 + +// Button patterns _B - single layer lcd boards + +#define BUTTON_NONE 0x3F +#define BUTTON_NONE_B 0xFE + +#define BUTTON_Left 0x3B +#define BUTTON_Left_B 0xFA + +#define BUTTON_Right 0x37 +#define BUTTON_Right_B 0xDE + +#define BUTTON_Up 0x2F +#define BUTTON_Up_B 0xF6 + +#define BUTTON_Down 0x1F +#define BUTTON_Down_B 0xEE + +#define BUTTON_Next 0x3D +#define BUTTON_Next_B 0x7E + +#define BUTTON_Enter 0x3E +#define BUTTON_Enter_B 0xBE + +#define BUTTON_Reset_B 0xFC + + +// debounce constants + +#define BUTTON_SENSE 160000 +#define BUTTON_DEBOUNCE 5000 + + +// Galileo register stuff + +#define kGal_DevBank2Cfg 0x1466DB33 +#define kGal_DevBank2PReg 0x464 +#define kGal_DevBank3Cfg 0x146FDFFB +#define kGal_DevBank3PReg 0x468 + +// Network + +#define kIPADDR 1 +#define kNETMASK 2 +#define kGATEWAY 3 +#define kDNS 4 + +#define kClassA 5 +#define kClassB 6 +#define kClassC 7 + --- ./drivers/char/misc.c Wed Jan 10 20:42:23 2001 +++ ./drivers/char/misc.c Thu Mar 8 09:20:32 2001 @@ -80,6 +80,7 @@ extern int pmu_device_init(void); extern int qpmouse_init(void); extern int tosh_init(void); +extern int lcd_init(void); static int misc_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *private) @@ -285,6 +286,9 @@ #endif #ifdef CONFIG_TOSHIBA tosh_init(); +#endif +#ifdef CONFIG_COBALT_LCD + lcd_init(); #endif if (devfs_register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { printk("unable to get major %d for misc devices\n", --- ./drivers/char/serial.c Wed Jan 10 20:42:25 2001 +++ ./drivers/char/serial.c Wed Mar 7 12:16:28 2001 @@ -3719,6 +3719,7 @@ state->type = PORT_16550A; break; } +#ifndef CONFIG_COBALT_MICRO_SERVER if (state->type == PORT_16550A) { /* Check for Startech UART's */ serial_outp(info, UART_LCR, UART_LCR_DLAB); @@ -3753,6 +3754,7 @@ } serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); } +#endif #if defined(CONFIG_SERIAL_RSA) && defined(MODULE) if (state->type == PORT_16550A) { int i; --- ./drivers/ide/ide-dma.c Thu Jan 11 20:31:00 2001 +++ ./drivers/ide/ide-dma.c Fri Apr 27 09:58:19 2001 @@ -267,6 +267,14 @@ cur_addr = sg_dma_address(sg); cur_len = sg_dma_len(sg); +#ifdef CONFIG_COBALT_MICRO_SERVER + if (func == ide_dma_write) { + dma_cache_wback_inv(bus_to_virt(cur_addr), cur_len); + } else { + dma_cache_inv(bus_to_virt(cur_addr), cur_len); + } +#endif + /* * Fill in the dma table, without crossing any 64kB boundaries. * Most hardware requires 16-bit alignment of all blocks, --- ./drivers/ide/ide-pci.c Thu Jan 11 20:31:01 2001 +++ ./drivers/ide/ide-pci.c Wed Apr 4 17:08:54 2001 @@ -634,6 +634,14 @@ memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; } +#ifdef CONFIG_COBALT_MICRO_SERVER + /* This is an unglorified hack.. bad, bad, bad */ + { + int i; + for (i=0; i < IDE_NR_PORTS; i++) + hwif->io_ports[i] += 0x10000000; + } +#endif hwif->chipset = ide_pci; hwif->pci_dev = dev; hwif->pci_devid = d->devid; --- ./drivers/net/tulip/eeprom.c Thu Jan 11 20:31:14 2001 +++ ./drivers/net/tulip/eeprom.c Thu Mar 8 09:20:32 2001 @@ -28,6 +28,24 @@ /* Known cards that have old-style EEPROMs. */ static struct eeprom_fixup eeprom_fixups[] __devinitdata = { + // Super big hack... we don't have a registered MAC address yet. TJS + // Add 100Mbps here too... + {"Cobalt 27", 0, 0x10, 0xE0, {0x1e00, /* 0 == controller #, 1e == offset */ + 0x0000, /* 0 == high offset, 0 == gap */ + 0x0800, /* Default Autoselect */ + 0x8001, /* 1 leaf, extended type, bogus len */ + 0x0003, /* Type 3 (MII), PHY #0 */ + 0x0400, /* 0 init instr, 4 reset instr */ + 0x0801, /* Set control mode, GP0 output */ + 0x0000, /* Drive GP0 Low (RST is active low) */ + 0x0800, /* control mode, GP0 input (undriven) */ + 0x0000, /* clear control mode */ + 0x7800, /* 100TX FDX + HDX, 10bT FDX + HDX */ + 0x01e0, /* Advertise all above */ + 0x5000, /* FDX all above */ + 0x1800, /* Set fast TTM in 100bt modes */ + 0x0, /* PHY cannot be unplugged */ + }}, {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c, 0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }}, {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f, @@ -81,10 +99,25 @@ static unsigned char *last_ee_data = NULL; static int controller_index = 0; struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; unsigned char *ee_data = tp->eeprom; int i; tp->mtable = 0; +#if defined(__mips__) + /* + * Cobalt: + * Our EEPROMs are specification challenged, so we check + * to see if the current device is not in the PCI slot. + * PCI cards fend for themselves, otherwise we kludge. + */ + if(ioaddr != 0x10108000) { /* not PCI slot */ + ee_data[19] = 1; /* set One controller... TJS */ + i = 8; /* make us fall into the right code */ + } + else +#endif + /* Detect an old-style (SA only) EEPROM layout: memcmp(eedata, eedata+16, 8). */ for (i = 0; i < 8; i ++) --- ./drivers/net/tulip/interrupt.c Tue Nov 28 22:05:31 2000 +++ ./drivers/net/tulip/interrupt.c Thu Mar 8 09:20:32 2001 @@ -36,7 +36,8 @@ struct sk_buff *skb; dma_addr_t mapping; - skb = tp->rx_buffers[entry].skb = dev_alloc_skb(PKT_BUF_SZ); + skb = tp->rx_buffers[entry].skb = + dev_alloc_skb(PKT_BUF_SZ + PKT_BUF_FUDGE); if (skb == NULL) break; @@ -125,6 +126,18 @@ tp->rx_buffers[entry].skb->tail, pkt_len); #endif + +#ifdef CONFIG_COBALT_27 + /* + * Scrub the cache to avoid stale data in + * the next packet delivered in this slot. + * (This should be #ifdef NON_COHERENT_DMA) + */ + dma_cache_inv((unsigned long) + bus_to_virt(tp->rx_ring[entry].buffer1), + pkt_len); +#endif + } else { /* Pass up the skb already on the Rx ring. */ char *temp = skb_put(skb = tp->rx_buffers[entry].skb, pkt_len); --- ./drivers/net/tulip/tulip.h Thu Jan 11 20:31:14 2001 +++ ./drivers/net/tulip/tulip.h Thu Mar 8 11:45:16 2001 @@ -20,7 +20,6 @@ #include - /* undefine, or define to various debugging levels (>4 == obscene levels) */ #undef TULIP_DEBUG @@ -230,6 +229,12 @@ #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */ + +#ifdef __mips__ +#define PKT_BUF_FUDGE 4 +#else +#define PKT_BUF_FUDGE 0 +#endif /* Ring-wrap flag in length field, use for last ring entry. --- ./drivers/net/tulip/tulip_core.c Thu Jan 11 20:31:14 2001 +++ ./drivers/net/tulip/tulip_core.c Thu Mar 8 11:45:17 2001 @@ -19,6 +19,7 @@ */ +#include /* for CONFIG_COBALT_27 */ #include #include "tulip.h" #include @@ -30,6 +31,15 @@ static char version[] __devinitdata = "Linux Tulip driver version 0.9.13 (January 2, 2001)\n"; +#ifdef CONFIG_COBALT_27 +#include +#endif + +#ifdef CONFIG_COBALT_27 +/* COBALT LOCAL: Needed because our mips is not DMA coherent. -DaveM */ +#define CACHED_TO_UNCACHED(x) (((unsigned long)(x) & (unsigned long)0x1fffffff) + KSEG1) +#endif + /* A few user-configurable values. */ @@ -54,6 +64,8 @@ #if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \ || defined(__sparc_) || defined(__ia64__) static int rx_copybreak = 1518; +#elif defined(__mips__) +static int rx_copybreak = 1536; #else static int rx_copybreak = 100; #endif @@ -83,6 +95,8 @@ static int csr0 = 0x01A00000 | 0x9000; #elif defined(__arm__) static int csr0 = 0x01A00000 | 0x4800; +#elif defined(__mips__) +static int csr0 = 0x00200000 | 0x4000; #else #warning Processor architecture undefined! static int csr0 = 0x00A00000 | 0x4800; @@ -210,6 +224,9 @@ static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void set_rx_mode(struct net_device *dev); +#ifdef CONFIG_COBALT_27 +static int tulip_linkcheck(void *cookie); +#endif static void tulip_up(struct net_device *dev) @@ -275,6 +292,10 @@ tp->tx_buffers[0].skb = NULL; tp->tx_buffers[0].mapping = mapping; +#ifdef CONFIG_COBALT_27 + dma_cache_wback_inv((unsigned long)tp->setup_frame, + sizeof(tp->setup_frame)); +#endif /* Put the setup frame on the Tx list. */ tp->tx_ring[0].length = cpu_to_le32(0x08000000 | 192); tp->tx_ring[0].buffer1 = cpu_to_le32(mapping); @@ -568,7 +589,7 @@ /* Note the receive buffer must be longword aligned. dev_alloc_skb() provides 16 byte alignment. But do *not* use skb_reserve() to align the IP header! */ - struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ); + struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ + PKT_BUF_FUDGE); tp->rx_buffers[i].skb = skb; if (skb == NULL) break; @@ -576,6 +597,10 @@ PKT_BUF_SZ, PCI_DMA_FROMDEVICE); tp->rx_buffers[i].mapping = mapping; skb->dev = dev; /* Mark as being used by this device. */ +#ifdef CONFIG_COBALT_27 + /* COBALT LOCAL: Kick out any matching lines in the cache. -DaveM */ + dma_cache_inv((unsigned long)skb->tail, PKT_BUF_SZ); +#endif tp->rx_ring[i].status = cpu_to_le32(DescOwned); /* Owned by Tulip chip */ tp->rx_ring[i].buffer1 = cpu_to_le32(mapping); } @@ -592,6 +617,36 @@ tp->tx_ring[i-1].buffer2 = cpu_to_le32(tp->tx_ring_dma); } +#ifdef CONFIG_COBALT_27 +static int +tulip_linkcheck(void *cookie) +{ + struct net_device *dev = cookie; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + int ioaddr = dev->base_addr; + unsigned int link_status; + + /* + * If we have a MII, check the PHY + */ + if (tp->mtable && tp->mtable->has_mii == 1) { + + link_status = tulip_mdio_read(dev, 1, 1); + + return (link_status & (1 << 2)) != 0; + } + + /* + * Check the chip 10 and 100 Mbit/s link + * (not obvious how 100 Mbit can blink if there is no MII) + */ + link_status = inl(ioaddr + CSR12); + + return (link_status & 6) != 0; +} +#endif /* CONFIG_COBALT_27 */ + + static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -627,6 +682,9 @@ tp->tx_ring[entry].length = cpu_to_le32(skb->len | flag); /* if we were using Transmit Automatic Polling, we would need a * wmb() here. */ +#ifdef CONFIG_COBALT_27 + dma_cache_wback_inv((unsigned long)skb->data, skb->len); +#endif tp->tx_ring[entry].status = cpu_to_le32(DescOwned); wmb(); @@ -1149,6 +1207,7 @@ if (!tp->rx_ring) goto err_out_free_mmio_res; tp->tx_ring = (struct tulip_tx_desc *)(tp->rx_ring + RX_RING_SIZE); + tp->tx_ring_dma = tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * RX_RING_SIZE; tp->chip_id = chip_idx; @@ -1239,17 +1298,21 @@ for (i = 0; i < sizeof(ee_data)/2; i++) ((u16 *)ee_data)[i] = le16_to_cpu(tulip_read_eeprom(ioaddr, i, ee_addr_size)); - /* DEC now has a specification (see Notes) but early board makers just put the address in the first EEPROM locations. */ /* This does memcmp(eedata, eedata+16, 8) */ - for (i = 0; i < 8; i ++) - if (ee_data[i] != ee_data[16+i]) - sa_offset = 20; +#ifdef __mips__ + if (ioaddr == 0x10108000) /* PCI board does it right */ +#endif + for (i = 0; i < 8; i ++) + if (ee_data[i] != ee_data[16+i]) + sa_offset = 20; + if (ee_data[0] == 0xff && ee_data[1] == 0xff && ee_data[2] == 0) { sa_offset = 2; /* Grrr, damn Matrox boards. */ multiport_cnt = 4; } + for (i = 0; i < 6; i ++) { dev->dev_addr[i] = ee_data[i + sa_offset]; sum += ee_data[i + sa_offset]; @@ -1384,6 +1447,10 @@ tp->link_change = t21142_lnk_change; else if (tp->flags & HAS_PNICNWAY) tp->link_change = pnic_lnk_change; + +#ifdef CONFIG_COBALT_27 + lcd_register_linkcheck_func(dev->name[3] - '0', tulip_linkcheck, dev); +#endif /* Reset the xcvr interface and turn on heartbeat. */ switch (chip_idx) { --- ./drivers/scsi/ncr53c8xx.c Thu Oct 5 11:18:57 2000 +++ ./drivers/scsi/ncr53c8xx.c Wed Apr 4 17:08:54 2001 @@ -168,6 +168,11 @@ #include +#ifdef CONFIG_COBALT_27 +/* COBALT LOCAL: Needed because our mips is not DMA coherent. -DaveM */ +#define CACHED_TO_UNCACHED(x) (((unsigned long)(x) & (unsigned long)0x1fffffff) + KSEG1) +#endif + /* ** Define BITS_PER_LONG for earlier linux versions. */ @@ -3684,6 +3689,11 @@ np = __m_calloc_dma(device->pdev, sizeof(struct ncb), "NCB"); if (!np) goto attach_error; +#ifdef CONFIG_COBALT_27 + /* COBALT LOCAL: We're not DMA coherent, so reference in uncached space. -DaveM */ + dma_cache_wback_inv((unsigned long)np, sizeof(*np)); + np = (ncb_p) CACHED_TO_UNCACHED(np); +#endif NCR_INIT_LOCK_NCB(np); np->pdev = device->pdev; np->p_ncb = vtobus(np); @@ -3695,6 +3705,13 @@ np->ccb = (ccb_p) m_calloc_dma(sizeof(struct ccb), "CCB"); if (!np->ccb) goto attach_error; +#ifdef CONFIG_COBALT_27 + /* COBALT LOCAL: We're not DMA coherent, so reference in uncached space. -DaveM */ + dma_cache_wback_inv((unsigned long)np->ccb, sizeof(*np->ccb)); + np->ccb = (ccb_p) CACHED_TO_UNCACHED(np->ccb); +#endif + + /* ** Store input informations in the host data structure. @@ -3724,6 +3741,13 @@ m_calloc_dma(sizeof(struct scripth), "SCRIPTH"); if (!np->scripth0) goto attach_error; +#ifdef CONFIG_COBALT_27 + /* COBALT LOCAL: We're not DMA coherent, so reference in uncached space. -DaveM */ + dma_cache_wback_inv((unsigned long)np->script0, sizeof(*np->script0)); + np->script0 = (struct script *) CACHED_TO_UNCACHED(np->script0); + dma_cache_wback_inv((unsigned long)np->scripth0, sizeof(*np->scripth0)); + np->scripth0 = (struct scripth *) CACHED_TO_UNCACHED(np->scripth0); +#endif /* ** Initialize timer structure @@ -4685,6 +4709,10 @@ memcpy(cp->cdb_buf, cmd->cmnd, MIN(cmd->cmd_len, sizeof(cp->cdb_buf))); cp->phys.cmd.addr = cpu_to_scr(CCB_PHYS (cp, cdb_buf[0])); cp->phys.cmd.size = cpu_to_scr(cmd->cmd_len); +#ifdef CONFIG_COBALT_27 + dma_cache_wback_inv((unsigned long)&cmd->cmnd[0], + sizeof(cmd->cmnd)); +#endif /* ** status @@ -7171,6 +7199,10 @@ bzero(cp->sense_buf, sizeof(cp->sense_buf)); cp->phys.sense.addr = cpu_to_scr(CCB_PHYS(cp,sense_buf[0])); cp->phys.sense.size = cpu_to_scr(sizeof(cp->sense_buf)); +#ifdef CONFIG_COBALT_27 + dma_cache_wback_inv((unsigned long)&cp->sense_buf[0], + sizeof(cp->sense_buf)); +#endif /* ** requeue the command. @@ -7954,6 +7986,11 @@ lp->actccbs++; np->actccbs++; bzero (cp, sizeof (*cp)); +#ifdef CONFIG_COBALT_27 + /* COBALT LOCAL: We're not DMA coherent, so reference in uncached space. -DaveM */ + dma_cache_wback_inv((unsigned long)cp, sizeof(*cp)); + cp = (ccb_p) CACHED_TO_UNCACHED(cp); +#endif ncr_init_ccb(np, cp); /* @@ -8283,6 +8320,10 @@ data = &data[MAX_SCATTER - 1]; data[0].addr = cpu_to_scr(baddr); data[0].size = cpu_to_scr(cmd->request_bufflen); +#ifdef CONFIG_COBALT_27 + dma_cache_wback_inv((unsigned long)cmd->request_buffer, + cmd->request_bufflen); +#endif cp->data_len = cmd->request_bufflen; segment = 1; } @@ -8300,6 +8341,10 @@ data[segment].addr = cpu_to_scr(baddr); data[segment].size = cpu_to_scr(len); cp->data_len += len; +#ifdef CONFIG_COBALT_27 + dma_cache_wback_inv((unsigned long)scatter[segment].address, + scatter[segment].length); +#endif ++segment; } } --- ./include/asm-mips/cobalt/cobalt.h Thu Jan 1 10:00:00 1970 +++ ./include/asm-mips/cobalt/cobalt.h Wed Apr 4 17:08:54 2001 @@ -0,0 +1,188 @@ +/* + * Lowlevel hardware stuff for the MIPS based Cobalt microservers. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1997 Cobalt Microserver + * Copyright (C) 1997 Ralf Baechle + * + * $Id: cobalt.h,v 1.1 1997/10/27 23:26:47 davem Exp $ + */ +#ifndef __ASM_MIPS_COBALT_H +#define __ASM_MIPS_COBALT_H + +/* + * Base address of I/O ports + */ +#define COBALT_LOCAL_IO_SPACE 0xa0000000 + +/* + * COBALT interrupt enable bits + */ +#define COBALT_IE_PCI (1 << 0) +#define COBALT_IE_FLOPPY (1 << 1) +#define COBALT_IE_KEYBOARD (1 << 2) +#define COBALT_IE_SERIAL1 (1 << 3) +#define COBALT_IE_SERIAL2 (1 << 4) +#define COBALT_IE_PARALLEL (1 << 5) +#define COBALT_IE_GPIO (1 << 6) +#define COBALT_IE_RTC (1 << 7) + +/* + * PCI defines + */ +#define COBALT_IE_ETHERNET (1 << 7) +#define COBALT_IE_SCSI (1 << 7) + +/* + * COBALT Interrupt Level definitions. + * These should match the request IRQ id's. + */ +#define COBALT_TIMER_IRQ 0 +#define COBALT_KEYBOARD_IRQ 1 +#define COBALT_ETHERNET_IRQ 13 +#define COBALT_SCC_IRQ 4 +#define COBALT_SERIAL2_IRQ 4 +#define COBALT_PARALLEL_IRQ 5 +#define COBALT_FLOPPY_IRQ 6 /* needs to be consistent with floppy driver! */ +#define COBALT_SCSI_IRQ 7 + +/* + * PCI configuration space manifest constants. These are wired into + * the board layout according to the PCI spec to enable the software + * to probe the hardware configuration space in a well defined manner. + * + * The PCI_DEVSHFT() macro transforms these values into numbers + * suitable for passing as the dev parameter to the various + * pcibios_read/write_config routines. + */ +#define COBALT_PCICONF_CPU 0x06 +#define COBALT_PCICONF_ETH0 0x07 +#define COBALT_PCICONF_RAQSCSI 0x08 +#define COBALT_PCICONF_VIA 0x09 +#define COBALT_PCICONF_PCISLOT 0x0A +#define COBALT_PCICONF_ETH1 0x0C + +#define PCI_DEVSHFT(x) ((x) << 3) + +/* + * Access the R4030 DMA and I/O Controller + */ +#ifndef _LANGUAGE_ASSEMBLY + +extern inline void r4030_delay(void) +{ +__asm__ __volatile__( + ".set\tnoreorder\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\treorder"); +} + +extern inline unsigned short r4030_read_reg16(unsigned addr) +{ + unsigned short ret = *((volatile unsigned short *)addr); + r4030_delay(); + return ret; +} + +extern inline unsigned int r4030_read_reg32(unsigned addr) +{ + unsigned int ret = *((volatile unsigned int *)addr); + r4030_delay(); + return ret; +} + +extern inline void r4030_write_reg16(unsigned addr, unsigned val) +{ + *((volatile unsigned short *)addr) = val; + r4030_delay(); +} + +extern inline unsigned int r4030_write_reg32(unsigned addr, unsigned val) +{ + *((volatile unsigned int *)addr) = val; + r4030_delay(); +} + +#endif /* !_LANGUAGE_ASSEMBLY */ + +/* + * Handling the VIA ISA host bridge. + */ + +#define VIA_DELAY() \ +{ \ + unsigned char ctr; \ + for (ctr=0;ctr<1;ctr++); \ +} + +#define VIA_PORT_WRITE(x,y) \ +{ \ + *((volatile unsigned char *) (0xb0000000 | x)) = y; \ + VIA_DELAY(); \ +} + +#define VIA_PORT_READ(x) (*((unsigned char *) (0xB0000000 | (x)))) + +#define RESET_VIA_TIMER() \ + asm("sb\t%1,0x70(%0)\n\t" \ + "lb\$0,0x71(%0)" \ + : /* No outputs */ \ + : "r" (0xb0000000), "i" (0x0c)); + +#define VIA_CMOS_ADDR 0x70 +#define VIA_CMOS_DATA 0x71 + +#define VIA_CMOS_CONSOLE_FLG 0x13 /* CMOS byte for console I/O */ +/* + * By convention, the bootflag's low order bit is a valid indicator + * and rest of the byte is serial console configuration information. + * + * This is NOT implemented in the rom code yet, it only tests for + * 0x1 and 0xA5 as off or 1152. If you pick some other speed, the + * kernel will "do the right thing", but the rom will ignore it. + */ + +#ifndef _LANGUAGE_ASSEMBLY /* { */ + +union cobalt_cons_info { + unsigned char ccons_char; + struct { + unsigned char + valid:2, /* CMOS default is 11 */ + kout:1, /* kernel output enabled */ + res1:2, /* 2 bits reserved */ + baud:3; /* Default baud rate */ + } ccons_bits; +}; + +int cobalt_cons_koutok(void); +int cobalt_cons_baudint(void); +int cobalt_cons_baudbaud(void); +#endif /* } _LANGUAGE_ASSEMBLY */ + +#define VIA_CMOS_CONS_VALID 0x1 +#define VIA_CMOS_CONS_OFF 0 +#define VIA_CMOS_CONS_9600 0x2 /* ROM sees disable */ +#define VIA_CMOS_CONS_115K 0x5 /* max value 0x7 */ + +/* + * The Cobalt board id information. The boards have an ID number wired + * into the VIA that is available in the high nibble of register 94. + * This register is available in the VIA configuration space through the + * interface routines qube_pcibios_read/write_config. See cobalt/pci.c + */ +#define VIA_COBALT_BRD_ID_REG 0x94 +#define VIA_COBALT_BRD_REG_to_ID(reg) ((unsigned char) (reg) >> 4) +#define COBALT_BRD_ID_QUBE1 0x3 +#define COBALT_BRD_ID_RAQ1 0x4 +#define COBALT_BRD_ID_QUBE2 0x5 +#define COBALT_BRD_ID_RAQ2 0x6 + +#endif /* __ASM_MIPS_COBALT_H */ + --- ./include/asm-mips/serial.h Thu Jan 4 09:02:09 2001 +++ ./include/asm-mips/serial.h Wed Mar 7 12:16:28 2001 @@ -85,6 +85,15 @@ #define ATLAS_SERIAL_PORT_DEFNS #endif +#ifdef CONFIG_COBALT_MICRO_SERVER +#define COBALT_BASE_BAUD (18432000 / 16) +#define COBALT_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, COBALT_BASE_BAUD, 0x1c800000, 7, STD_COM_FLAGS }, /* ttyS0 */ +#else +#define COBALT_SERIAL_PORT_DEFNS +#endif + /* * Both Galileo boards have the same UART mappings. */ @@ -205,6 +214,7 @@ #define SERIAL_PORT_DFNS \ ATLAS_SERIAL_PORT_DEFNS \ + COBALT_SERIAL_PORT_DEFNS \ EV96100_SERIAL_PORT_DEFNS \ JAZZ_SERIAL_PORT_DEFNS \ STD_SERIAL_PORT_DEFNS \ --- ./include/linux/miscdevice.h Thu Oct 5 11:19:02 2000 +++ ./include/linux/miscdevice.h Thu Mar 8 09:20:33 2001 @@ -18,6 +18,9 @@ #define RTC_MINOR 135 #define EFI_RTC_MINOR 136 /* EFI Time services */ #define SUN_OPENPROM_MINOR 139 + +#define LCD_MINOR 140 + #define NVRAM_MINOR 144 #define I2O_MINOR 166 #define MICROCODE_MINOR 184 --- ./include/linux/netdevice.h Wed Jan 10 20:44:08 2001 +++ ./include/linux/netdevice.h Thu Mar 8 09:20:33 2001 @@ -142,6 +142,11 @@ #include #include +#ifdef CONFIG_COBALT_27 +typedef int (*linkcheck_func_t)(void *cookie); +extern int lcd_register_linkcheck_func(int iface_num, void *func, void *cookie); +#endif /* CONFIG_COBALT_27 */ + struct neighbour; struct neigh_parms; struct sk_buff; --- ./arch/mips/defconfig-cobalt Thu Jan 1 10:00:00 1970 +++ ./arch/mips/defconfig-cobalt Fri Apr 27 10:07:39 2001 @@ -0,0 +1,497 @@ +# +# Automatically generated by make menuconfig: don't edit +# +CONFIG_MIPS=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_ALGOR_P4032 is not set +# CONFIG_BAGET_MIPS is not set +CONFIG_COBALT_MICRO_SERVER=y +# CONFIG_COBALT_28 is not set +# CONFIG_DECSTATION is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_PMC_CP7000 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_PCI is not set +# CONFIG_I8259 is not set +COBALT_MICRO_SERVER=y +CONFIG_NO_SWAPPER=y +CONFIG_COBALT_27=y +CONFIG_NO_KEYBOARD=y +CONFIG_NO_VIDEO_CONSOLE=y +CONFIG_COBALT_LCD=y +CONFIG_PCI=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# CPU selection +# +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_RM7000 is not set +CONFIG_CPU_NEVADA=y +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_WB is not set + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_MIPS_FPU_EMULATOR=y +CONFIG_KCORE_ELF=y +CONFIG_ELF_KERNEL=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PCMCIA is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD7409 is not set +# CONFIG_AMD7409_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_OSB4 is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_REMOTE_DEBUG is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set