diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/de/if_de.c | 79 | ||||
-rw-r--r-- | sys/dev/pci/pci.c | 550 | ||||
-rw-r--r-- | sys/i386/pci/if_de.c | 79 | ||||
-rw-r--r-- | sys/i386/pci/ncr.c | 280 | ||||
-rw-r--r-- | sys/i386/pci/pci.c | 550 | ||||
-rw-r--r-- | sys/i386/pci/pci_config.c | 44 | ||||
-rw-r--r-- | sys/i386/pci/pcibios.c | 59 | ||||
-rw-r--r-- | sys/pci/if_de.c | 79 | ||||
-rw-r--r-- | sys/pci/ncr.c | 280 | ||||
-rw-r--r-- | sys/pci/pci.c | 550 |
10 files changed, 1351 insertions, 1199 deletions
diff --git a/sys/dev/de/if_de.c b/sys/dev/de/if_de.c index 2b9774e..2aeebfa 100644 --- a/sys/dev/de/if_de.c +++ b/sys/dev/de/if_de.c @@ -101,8 +101,7 @@ #include <pci.h> #if NPCI > 0 -#include <i386/pci/pci.h> -#include <i386/pci/pci_device.h> +#include <i386/pci/pcireg.h> #endif #include <i386/isa/icu.h> #include <i386/pci/dc21040.h> @@ -310,7 +309,7 @@ tulip_init( int unit) { tulip_softc_t *sc = tulips[unit]; - unsigned new_cmdmode; + /* XXX unsigned new_cmdmode; */ if (sc->tulip_if.if_flags & IFF_UP) { sc->tulip_if.if_flags |= IFF_RUNNING; @@ -332,7 +331,7 @@ tulip_init( sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; tulip_start(&sc->tulip_if); } - tulip_cmdnode |= TULIP_CMD_THRSHLD160; + sc->tulip_cmdmode |= TULIP_CMD_THRSHLD160; *sc->tulip_csrs.csr_intr = sc->tulip_intrmask; *sc->tulip_csrs.csr_command = sc->tulip_cmdmode; } else { @@ -690,13 +689,12 @@ tulip_start( static int tulip_intr( - int unit) + tulip_softc_t *sc) { - tulip_softc_t *sc = tulips[unit]; tulip_uint32_t csr; unsigned spins = 0; - tulip_intrs[unit]++; + /* XXX tulip_intrs[unit]++; */ while ((csr = *sc->tulip_csrs.csr_status) & (TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR)) { *sc->tulip_csrs.csr_status = csr & sc->tulip_intrmask; @@ -706,7 +704,7 @@ tulip_intr( if ((csr & TULIP_STS_ERRORMASK) == TULIP_STS_ERR_PARITY) { TULIP_RESET(sc); tulip_init(sc->tulip_unit); - return unit; + return (1); } } if (csr & TULIP_STS_RXINTR) @@ -723,7 +721,7 @@ tulip_intr( } if (spins > sc->tulip_high_intrspins) sc->tulip_high_intrspins = spins; - return unit; + return (1); } /* @@ -777,6 +775,7 @@ tulip_read_macaddr( return 0; } +#ifdef MULTICAST static unsigned tulip_mchash( unsigned char *mca) @@ -794,20 +793,24 @@ tulip_mchash( #endif return crc & 0x1FF; } +#endif MULTICAST static void tulip_addr_filter( tulip_softc_t *sc) { tulip_uint32_t *sp = sc->tulip_setupdata; +#ifdef MULTICAST struct ether_multistep step; struct ether_multi *enm; +#endif int i; sc->tulip_flags &= ~TULIP_WANTHASH; sc->tulip_flags |= TULIP_WANTSETUP; sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN; sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; +#ifdef MULTICAST if (sc->tulip_ac.ac_multicnt > 14) { unsigned hash; /* @@ -830,10 +833,12 @@ tulip_addr_filter( sp[41] = ((u_short *) sc->tulip_ac.ac_enaddr)[1]; sp[42] = ((u_short *) sc->tulip_ac.ac_enaddr)[2]; } else { +#endif /* * Else can get perfect filtering for 16 addresses. */ i = 0; +#ifdef MULTICAST ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm); for (; enm != NULL; i++) { *sp++ = ((u_short *) enm->enm_addrlo)[0]; @@ -841,6 +846,7 @@ tulip_addr_filter( *sp++ = ((u_short *) enm->enm_addrlo)[2]; ETHER_NEXT_MULTI(step, enm); } +#endif /* * If an IP address is enabled, turn on broadcast */ @@ -858,7 +864,9 @@ tulip_addr_filter( *sp++ = ((u_short *) sc->tulip_ac.ac_enaddr)[1]; *sp++ = ((u_short *) sc->tulip_ac.ac_enaddr)[2]; } +#ifdef MULTICAST } +#endif } static int @@ -931,6 +939,7 @@ tulip_ioctl( break; } +#ifdef MULTICAST case SIOCADDMULTI: case SIOCDELMULTI: { /* @@ -948,6 +957,7 @@ tulip_ioctl( } break; } +#endif /* MULTICAST */ default: { error = EINVAL; @@ -968,7 +978,9 @@ tulip_attach( int cnt; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; +#ifdef MULTICAST ifp->if_flags |= IFF_MULTICAST; +#endif /* MULTICAST */ *sc->tulip_csrs.csr_sia_connectivity = 0; *sc->tulip_csrs.csr_sia_connectivity = TULIP_SIACONN_10BASET; @@ -1066,18 +1078,14 @@ tulip_initring( * on both EISA and PCI boards, one must be careful in how defines the * DC21040 in the config file. */ -static int tulip_pci_probe(pcici_t config_id); -static int tulip_pci_attach(pcici_t config_id); +static char* tulip_pci_probe (pcici_t config_id, pcidi_t device_id); +static void tulip_pci_attach(pcici_t config_id, int unit); +static u_long tulip_count; struct pci_driver dedevice = { tulip_pci_probe, tulip_pci_attach, - 0x00021011ul, -#if __FreeBSD__ == 1 - "de", -#endif - "digital dc21040 ethernet", - tulip_intr + &tulip_count, }; #define PCI_CFID 0x00 /* Configuration ID */ @@ -1090,39 +1098,41 @@ struct pci_driver dedevice = { #define PCI_CFDA 0x40 /* Configuration Driver Area */ #define TULIP_PCI_CSRSIZE (8 / sizeof(tulip_uint32_t)) -static int +static char* tulip_pci_probe( - pcici_t config_id) + pcici_t config_id, + pcidi_t device_id) { int idx; + if (device_id != 0x00021011ul) + return (NULL); for (idx = 0; idx < NDE; idx++) if (tulips[idx] == NULL) - return idx; - return -1; + return ("digital dc21040 ethernet"); + return (NULL); } -static int +static void tulip_pci_attach( - pcici_t config_id) + pcici_t config_id, + int unit) { tulip_softc_t *sc; - int retval, idx, revinfo, unit; - signed int csr; + int retval, idx /* XXX , revinfo, */; + /* XXX signed int csr; */ vm_offset_t va_csrs, pa_csrs; - int result; + /* XXX int result;*/ tulip_desc_t *rxdescs, *txdescs; - unit = tulip_pci_probe(config_id); - sc = (tulip_softc_t *) malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT); if (sc == NULL) - return -1; + return; rxdescs = (tulip_desc_t *) malloc(sizeof(tulip_desc_t) * TULIP_RXDESCS, M_DEVBUF, M_NOWAIT); if (rxdescs == NULL) { free((caddr_t) sc, M_DEVBUF); - return -1; + return; } txdescs = (tulip_desc_t *) @@ -1130,7 +1140,7 @@ tulip_pci_attach( if (txdescs == NULL) { free((caddr_t) rxdescs, M_DEVBUF); free((caddr_t) sc, M_DEVBUF); - return -1; + return; } bzero(sc, sizeof(sc)); /* Zero out the softc*/ @@ -1148,13 +1158,12 @@ tulip_pci_attach( sc->tulip_unit = unit; sc->tulip_name = "de"; retval = pci_map_mem(config_id, PCI_CBMA, &va_csrs, &pa_csrs); - if (retval) { - printf("de%d: pci_map_mem failed.\n", unit); + if (!retval) { kmem_free(kernel_map, sc->tulip_rxspace, TULIP_RXSPACE + NBPG); free((caddr_t) txdescs, M_DEVBUF); free((caddr_t) rxdescs, M_DEVBUF); free((caddr_t) sc, M_DEVBUF); - return -1; + return; } tulips[unit] = sc; tulip_initcsrs(sc, (volatile tulip_uint32_t *) va_csrs, TULIP_PCI_CSRSIZE); @@ -1171,10 +1180,10 @@ tulip_pci_attach( (sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F, "unknown"); } else { + pci_map_int (config_id, tulip_intr, (void*) sc, &net_imask); TULIP_RESET(sc); tulip_attach(sc); } - return 1; } #endif /* NPCI > 0 */ #endif /* NDE > 0 */ diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index c34523d..396b96f 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci.c,v 1.5 1994/09/28 16:34:07 se Exp $ +** $Id: pci.c,v 2.12 94/10/11 22:20:37 wolf Oct11 $ ** ** General subroutines for the PCI bus on 80*86 systems. ** pci_configure () @@ -33,27 +33,17 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -**------------------------------------------------------------------------- +*************************************************************************** */ #include <pci.h> #if NPCI > 0 -/*======================================================== -** -** Configuration -** -**======================================================== -*/ - -/* -** maximum number of devices which share one interrupt line -*/ - -#ifndef PCI_MAX_DPI -#define PCI_MAX_DPI (4) -#endif /*PCI_MAX_DPI*/ - +#ifndef __FreeBSD2__ +#if __FreeBSD__ >= 2 +#define __FreeBSD2__ +#endif +#endif /*======================================================== ** @@ -64,101 +54,54 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/malloc.h> #include <sys/errno.h> #include <vm/vm.h> #include <vm/vm_param.h> -#include <i386/isa/icu.h> #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> - -#include <i386/pci/pci.h> -#include <i386/pci/pci_device.h> -#include <i386/pci/pcibios.h> +#include <i386/isa/icu.h> +#include <i386/pci/pcireg.h> /* ** Function prototypes missing in system headers */ -#if ! (__FreeBSD__ >= 2) +#ifndef __FreeBSD2__ extern pmap_t pmap_kernel(void); static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize); -#endif - - -/*======================================================== -** -** Autoconfiguration (of isa bus) -** -**======================================================== -*/ /* -** per slot data structure for passing interupts.. -*/ - -static struct { - u_short number; - u_short isanum; - struct { - int (*proc)(int dev); - dev_t unit; - } vector[PCI_MAX_DPI]; -} pcidata [NPCI]; + * Type of the first (asm) part of an interrupt handler. + */ +typedef void inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss)); /* -** check device ready -*/ -static int pciprobe (struct isa_device *dev) -{ - if (dev->id_unit >= NPCI) - return (0); - - if (!pci_conf_mode()) - return (0); - - return (-1); -} + * Usual type of the second (C) part of an interrupt handler. Some bogus + * ones need the arg to be the interrupt frame (and not a copy of it, which + * is all that is possible in C). + */ +typedef void inthand2_t __P((int unit)); /* -** initialize the driver structure -*/ -static int pciattach (struct isa_device *isdp) -{ - pcidata[isdp->id_unit].number = 0; - pcidata[isdp->id_unit].isanum = ffs(isdp->id_irq)-1; - return (1); -} - -/* -** ISA driver structure -*/ - -struct isa_driver pcidriver = { - pciprobe, - pciattach, - "pci" -}; - -/*======================================================== -** -** Interrupt forward from isa to pci devices. -** -**======================================================== +** XXX @FreeBSD2@ +** +** Unfortunately, the mptr argument is _no_ pointer in 2.0 FreeBSD. +** We would prefer a pointer because it enables us to install +** new interrupt handlers at any time. +** In 2.0 FreeBSD later installed interrupt handlers may change +** the xyz_imask, but this would not be recognized by handlers +** which are installed before. */ +static int +register_intr __P((int intr, int device_id, unsigned int flags, + inthand2_t *handler, unsigned int * mptr, int unit)); +extern unsigned intr_mask[ICU_LEN]; -void pciintr (int unit) -{ - u_short i; - if (unit >= NPCI) return; - for (i=0; i<pcidata[unit].number; i++) { - (void)(*pcidata[unit].vector[i].proc) - (pcidata[unit].vector[i].unit); - }; -} - +#endif /* !__FreeBSD2__ */ /*======================================================== ** @@ -183,52 +126,82 @@ void pciintr (int unit) #define PCI_PMEM_START 0xc0000000 #endif -static vm_offset_t pci_paddr = PCI_PMEM_START; +static vm_offset_t pci_paddr = PCI_PMEM_START; +/*-------------------------------------------------------- +** +** The pci device interrupt lines should have been +** assigned by the bios. But if the bios failed to +** to it, we set it. +** +**-------------------------------------------------------- +*/ + +#ifndef PCI_IRQ +#define PCI_IRQ 0 +#endif + +static u_long pci_irq = PCI_IRQ; + /*--------------------------------------------------------- ** ** pci_configure () ** +** Probe all devices on pci bus and attach them. +** +** May be called more than once. +** Any device is attached only once. +** (Attached devices are remembered in pci_seen.) +** **--------------------------------------------------------- */ static void not_supported (pcici_t tag, u_long type); +static unsigned long pci_seen[NPCI]; + +static int pci_conf_count; + void pci_configure() { u_char device,last_device; - u_short bus,last_bus; + u_short bus; pcici_t tag; pcidi_t type; u_long data; int unit; - int intpin; - int isanum; - int pci_mode; + int pci_mechanism; + int pciint; + int irq; + char* name=0; + int newdev=0; - struct pci_driver *drp; + struct pci_driver *drp=0; struct pci_device *dvp; /* ** check pci bus present */ - pci_mode = pci_conf_mode (); - if (!pci_mode) return; - last_bus = pci_last_bus (); - last_device = pci_mode==1 ? 31 : 15; - + pci_mechanism = pci_conf_mode (); + if (!pci_mechanism) return; + last_device = pci_mechanism==1 ? 31 : 15; + /* ** hello world .. */ + + for (bus=0;bus<NPCI;bus++) { #ifndef PCI_QUIET - printf ("pci*: mode=%d, scanning bus 0..%d, device 0..%d.\n", - pci_mode, last_bus, last_device); + printf ("pci%d: scanning device 0..%d, mechanism=%d.\n", + bus, last_device, pci_mechanism); #endif - - for (bus=0;bus<=last_bus; bus++) for (device=0; device<=last_device; device ++) { + + if (pci_seen[bus] & (1ul << device)) + continue; + tag = pcitag (bus, device, 0); type = pci_conf_read (tag, PCI_ID_REG); @@ -238,137 +211,90 @@ void pci_configure() ** lookup device in ioconfiguration: */ - for (dvp = pci_devtab; dvp->pd_device_id; dvp++) { - if (dvp->pd_device_id == type) break; + for (dvp = pci_devtab; dvp->pd_name; dvp++) { + drp = dvp->pd_driver; + if (!drp) + continue; + if ((name=(*drp->probe)(tag, type))) + break; }; - drp = dvp->pd_driver; - - if (!dvp->pd_device_id) { - /* - ** not found - ** try to dig out some information. - ** - ** By Garrett Wollman - ** <wollman@halloran-eldar.lcs.mit.edu> - */ - - int data = pci_conf_read(tag, PCI_CLASS_REG); - vm_offset_t va; - vm_offset_t pa; - int reg; - - switch (data & PCI_CLASS_MASK) { - - case PCI_CLASS_PREHISTORIC: - if ((data & PCI_SUBCLASS_MASK) - != PCI_SUBCLASS_PREHISTORIC_VGA) - break; - - case PCI_CLASS_DISPLAY: - for (reg = PCI_MAP_REG_START; - reg < PCI_MAP_REG_END; - reg += 4) { - data = pci_map_mem(tag, reg, &va, &pa); - if (data == 0) - printf ( - "pci%d:%d: mapped VGA-like device at physaddr 0x%lx\n", - bus, device, (u_long)pa); - - } - continue; - }; + if (!dvp->pd_name) { #ifndef PCI_QUIET + if (pci_conf_count) + continue; printf("pci%d:%d: ", bus, device); not_supported (tag, type); #endif - }; - - if (!drp) { - if(dvp->pd_flags & PDF_LOADABLE) { - printf("%s: loadable device on pci%d:%d\n", - dvp->pd_name, bus, device); - } continue; - } + }; + pci_seen[bus] |= (1ul << device); /* - ** found it. - ** probe returns the device unit. + ** Get and increment the unit. */ - unit = (*drp->probe) (tag); + unit = (*drp->count)++; - if (unit<0) { - printf ("%s <%s>: probe failed on pci%d:%d\n", - dvp->pd_name, drp->name, bus, device); - continue; - }; + /* + ** ignore device ? + */ + + if (!*name) continue; + + /* + ** Announce this device + */ - printf ("%s%d <%s>", dvp->pd_name, unit, drp->name); + newdev++; + printf ("%s%d <%s>", dvp->pd_name, unit, name); /* - ** install interrupts + ** Get the int pin number (pci interrupt number a-d) + ** from the pci configuration space. */ data = pci_conf_read (tag, PCI_INTERRUPT_REG); - intpin = PCI_INTERRUPT_PIN_EXTRACT(data); - if (intpin) { - int idx=NPCI; + pciint = PCI_INTERRUPT_PIN_EXTRACT(data); - /* - ** Usage of int line register (if set by bios) - ** Matt Thomas <thomas@lkg.dec.com> - */ + if (pciint) { - isanum = PCI_INTERRUPT_LINE_EXTRACT(data); - if (isanum) { - - /* - ** @INT@ FIXME!!! - ** - ** Should try to use "register_interupt" - ** at this point. - */ - - printf (" line=%d", isanum); - for (idx = 0; idx < NPCI; idx++) { - if (pcidata[idx].isanum == isanum) - break; - }; - }; + printf (" int %c", 0x60+pciint); /* - ** Or take the device number as index ... + ** If the interrupt line register is not set, + ** set it now from PCI_IRQ. */ - if (idx >= NPCI) idx = device; + if (!(PCI_INTERRUPT_LINE_EXTRACT(data))) { + + irq = pci_irq & 0x0f; + pci_irq >>= 4; + + data = PCI_INTERRUPT_LINE_INSERT(data, irq); + printf (" (config)"); + pci_conf_write (tag, PCI_INTERRUPT_REG, data); + }; + + irq = PCI_INTERRUPT_LINE_EXTRACT(data); /* - ** And install the interrupt. + ** If it's zero, the isa irq number is unknown, + ** and we cannot bind the pci interrupt to isa. */ - if (idx<NPCI) { - u_short entry = pcidata[idx].number; - printf (" irq %c", 0x60+intpin); - if (entry < PCI_MAX_DPI) { - pcidata[idx].vector[entry].proc = drp->intr; - pcidata[idx].vector[entry].unit = unit; - entry++; - }; - printf (" isa=%d [%d]",pcidata[idx].isanum, entry); - pcidata[idx].number=entry; - } else { - printf (" no int"); - }; + if (irq) + printf (" irq %d", irq); + else + printf (" not bound"); }; - + /* ** enable memory access */ - data = pci_conf_read (tag, PCI_COMMAND_STATUS_REG) - & 0xffff | PCI_COMMAND_MEM_ENABLE; + data = (pci_conf_read (tag, PCI_COMMAND_STATUS_REG) + & 0xffff) | PCI_COMMAND_MEM_ENABLE; pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data); @@ -380,13 +306,16 @@ void pci_configure() printf (" on pci%d:%d\n", bus, device); - (void) (*drp->attach) (tag); - } + (*drp->attach) (tag, unit); + }; + }; #ifndef PCI_QUIET - printf ("pci uses physical addresses from 0x%lx to 0x%lx\n", + if (newdev) + printf ("pci uses physical addresses from 0x%lx to 0x%lx\n", (u_long)PCI_PMEM_START, (u_long)pci_paddr); #endif + pci_conf_count++; } /*----------------------------------------------------------------------- @@ -403,7 +332,8 @@ int pci_map_port (pcici_t tag, u_long reg, u_short* pa) /* ** @MAPIO@ not yet implemented. */ - return (ENOSYS); + printf ("pci_map_port failed: not yet implemented\n"); + return (0); } /*----------------------------------------------------------------------- @@ -425,8 +355,11 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) ** sanity check */ - if (reg <= PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) - return (EINVAL); + if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) { + printf ("pci_map_mem failed: bad register=0x%x\n", + (unsigned)reg); + return (0); + }; /* ** get size and type of memory @@ -445,7 +378,9 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) break; default: /* unknown */ - return (EINVAL); + printf ("pci_map_mem failed: bad memory type=0x%x\n", + (unsigned) data); + return (0); }; /* @@ -455,18 +390,19 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) vsize = round_page (-(data & PCI_MAP_MEMORY_ADDRESS_MASK)); - if (!vsize) return (EINVAL); - + if (!vsize) return (0); + /* ** align physical address to virtual size */ - if (data = pci_paddr % vsize) + if ((data = pci_paddr % vsize)) pci_paddr += vsize - data; - vaddr = pmap_mapdev (pci_paddr, vsize); + vaddr = (vm_offset_t) pmap_mapdev (pci_paddr, vsize); + - if (!vaddr) return (EINVAL); + if (!vaddr) return (0); #ifndef PCI_QUIET /* @@ -474,7 +410,7 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) */ printf ("\treg%d: virtual=0x%lx physical=0x%lx\n", - reg, (u_long)vaddr, (u_long)pci_paddr); + (unsigned) reg, (u_long)vaddr, (u_long)pci_paddr); #endif /* @@ -496,50 +432,77 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) pci_paddr += vsize; - return (0); + return (1); } -/*----------------------------------------------------------- +/*----------------------------------------------------------------------- ** -** Mapping of physical to virtual memory +** Map pci interrupts to isa interrupts. ** -**----------------------------------------------------------- +**----------------------------------------------------------------------- */ -#if ! (__FreeBSD__ >= 2) +static unsigned int pci_int_mask [16]; -extern vm_map_t kernel_map; - -static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize) +int pci_map_int (pcici_t tag, int(*func)(), void* arg, unsigned* maskptr) { - vm_offset_t vaddr,value; - u_long result; + int irq; + unsigned mask; - vaddr = vm_map_min (kernel_map); + irq = PCI_INTERRUPT_LINE_EXTRACT( + pci_conf_read (tag, PCI_INTERRUPT_REG)); - result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0, - &vaddr, vsize, TRUE); - - if (result != KERN_SUCCESS) { - printf (" vm_map_find failed(%d)\n", result); + if (irq >= 16 || irq <= 0) { + printf ("pci_map_int failed: no int line set.\n"); return (0); - }; + } + + mask = 1ul << irq; + + if (!maskptr) + maskptr = &pci_int_mask[irq]; + + INTRMASK (*maskptr, mask); + register_intr( + irq, /* isa irq */ + 0, /* deviced?? */ + 0, /* flags? */ + (inthand2_t*) func, /* handler */ +#ifdef __FreeBSD2__ + *maskptr, /* mask */ +#else + maskptr, /* mask pointer */ +#endif + (int) arg); /* handler arg */ + +#ifdef __FreeBSD2__ /* - ** map physical + ** XXX See comment at beginning of file. + ** + ** Have to update all the interrupt masks ... Grrrrr!!! */ - - value = vaddr; - while (vsize >= NBPG) { - pmap_enter (pmap_kernel(), vaddr, paddr, - VM_PROT_READ|VM_PROT_WRITE, TRUE); - vaddr += NBPG; - paddr += NBPG; - vsize -= NBPG; + { + unsigned * mp = &intr_mask[0]; + /* + ** update the isa interrupt masks. + */ + for (mp=&intr_mask[0]; mp<&intr_mask[ICU_LEN]; mp++) + if (*mp & *maskptr) + *mp |= mask; + /* + ** update the pci interrupt masks. + */ + for (mp=&pci_int_mask[0]; mp<&pci_int_mask[16]; mp++) + if (*mp & *maskptr) + *mp |= mask; }; - return (value); -} #endif + + INTREN (mask); + + return (1); +} /*----------------------------------------------------------- ** @@ -554,7 +517,7 @@ struct vt { static struct vt VendorTable[] = { {0x1002, "ATI TECHNOLOGIES INC"}, - {0x1011, "DIGITAL EQUIPMENT CORP."}, + {0x1011, "DIGITAL EQUIPMENT CORPORATION"}, {0x101A, "NCR"}, {0x102B, "MATROX"}, {0x1045, "OPTI"}, @@ -604,18 +567,107 @@ void not_supported (pcici_t tag, u_long type) case 1: case 5: - printf (" map(%lx): io(%lx)\n", reg, data & ~3); + printf (" map(%x): io(%lx)\n", + reg, data & ~3); break; case 0: - printf (" map(%lx): mem32(%lx)\n", reg, data & ~7); + printf (" map(%x): mem32(%lx)\n", + reg, data & ~7); break; case 2: - printf (" map(%lx): mem20(%lx)\n", reg, data & ~7); + printf (" map(%x): mem20(%lx)\n", + reg, data & ~7); break; case 4: - printf (" map(%lx): mem64(%lx)\n", reg, data & ~7); + printf (" map(%x): mem64(%lx)\n", + reg, data & ~7); break; } } } -#endif + +#ifndef __FreeBSD2__ +/*----------------------------------------------------------- +** +** Mapping of physical to virtual memory +** +**----------------------------------------------------------- +*/ + +extern vm_map_t kernel_map; + +static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize) +{ + vm_offset_t vaddr,value; + u_long result; + + vaddr = vm_map_min (kernel_map); + + result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0, + &vaddr, vsize, TRUE); + + if (result != KERN_SUCCESS) { + printf (" vm_map_find failed(%d)\n", result); + return (0); + }; + + /* + ** map physical + */ + + value = vaddr; + while (vsize >= NBPG) { + pmap_enter (pmap_kernel(), vaddr, paddr, + VM_PROT_READ|VM_PROT_WRITE, TRUE); + vaddr += NBPG; + paddr += NBPG; + vsize -= NBPG; + }; + return (value); +} + +/*------------------------------------------------------------ +** +** Emulate the register_intr() function of FreeBSD 2.0 +** +** requires a patch: +** FreeBSD 2.0: "/sys/i386/isa/vector.s" +** 386bsd0.1: "/sys/i386/isa/icu.s" +** 386bsd1.0: Please ask Jesus Monroy Jr. +** +**------------------------------------------------------------ +*/ + +#include <machine/segments.h> + +int pci_int_unit [16]; +inthand2_t* (pci_int_hdlr [16]); +unsigned int * pci_int_mptr [16]; +unsigned int pci_int_count[16]; + +extern void + Vpci3(), Vpci4(), Vpci5(), Vpci6(), Vpci7(), Vpci8(), Vpci9(), + Vpci10(), Vpci11(), Vpci12(), Vpci13(), Vpci14(), Vpci15(); + +static inthand_t* pci_int_glue[16] = { + 0, 0, 0, Vpci3, Vpci4, Vpci5, Vpci6, Vpci7, Vpci8, + Vpci9, Vpci10, Vpci11, Vpci12, Vpci13, Vpci14, Vpci15 }; + +static int +register_intr __P((int intr, int device_id, unsigned int flags, + inthand2_t *handler, unsigned int* mptr, int unit)) +{ + if (intr >= 16 || intr <= 2) + return (EINVAL); + if (pci_int_hdlr [intr]) + return (EBUSY); + + pci_int_hdlr [intr] = handler; + pci_int_unit [intr] = unit; + pci_int_mptr [intr] = mptr; + + setidt(NRSVIDT + intr, pci_int_glue[intr], SDT_SYS386IGT, SEL_KPL); + return (0); +} +#endif /* __FreeBSD2__ */ +#endif /* NPCI */ diff --git a/sys/i386/pci/if_de.c b/sys/i386/pci/if_de.c index 2b9774e..2aeebfa 100644 --- a/sys/i386/pci/if_de.c +++ b/sys/i386/pci/if_de.c @@ -101,8 +101,7 @@ #include <pci.h> #if NPCI > 0 -#include <i386/pci/pci.h> -#include <i386/pci/pci_device.h> +#include <i386/pci/pcireg.h> #endif #include <i386/isa/icu.h> #include <i386/pci/dc21040.h> @@ -310,7 +309,7 @@ tulip_init( int unit) { tulip_softc_t *sc = tulips[unit]; - unsigned new_cmdmode; + /* XXX unsigned new_cmdmode; */ if (sc->tulip_if.if_flags & IFF_UP) { sc->tulip_if.if_flags |= IFF_RUNNING; @@ -332,7 +331,7 @@ tulip_init( sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; tulip_start(&sc->tulip_if); } - tulip_cmdnode |= TULIP_CMD_THRSHLD160; + sc->tulip_cmdmode |= TULIP_CMD_THRSHLD160; *sc->tulip_csrs.csr_intr = sc->tulip_intrmask; *sc->tulip_csrs.csr_command = sc->tulip_cmdmode; } else { @@ -690,13 +689,12 @@ tulip_start( static int tulip_intr( - int unit) + tulip_softc_t *sc) { - tulip_softc_t *sc = tulips[unit]; tulip_uint32_t csr; unsigned spins = 0; - tulip_intrs[unit]++; + /* XXX tulip_intrs[unit]++; */ while ((csr = *sc->tulip_csrs.csr_status) & (TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR)) { *sc->tulip_csrs.csr_status = csr & sc->tulip_intrmask; @@ -706,7 +704,7 @@ tulip_intr( if ((csr & TULIP_STS_ERRORMASK) == TULIP_STS_ERR_PARITY) { TULIP_RESET(sc); tulip_init(sc->tulip_unit); - return unit; + return (1); } } if (csr & TULIP_STS_RXINTR) @@ -723,7 +721,7 @@ tulip_intr( } if (spins > sc->tulip_high_intrspins) sc->tulip_high_intrspins = spins; - return unit; + return (1); } /* @@ -777,6 +775,7 @@ tulip_read_macaddr( return 0; } +#ifdef MULTICAST static unsigned tulip_mchash( unsigned char *mca) @@ -794,20 +793,24 @@ tulip_mchash( #endif return crc & 0x1FF; } +#endif MULTICAST static void tulip_addr_filter( tulip_softc_t *sc) { tulip_uint32_t *sp = sc->tulip_setupdata; +#ifdef MULTICAST struct ether_multistep step; struct ether_multi *enm; +#endif int i; sc->tulip_flags &= ~TULIP_WANTHASH; sc->tulip_flags |= TULIP_WANTSETUP; sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN; sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; +#ifdef MULTICAST if (sc->tulip_ac.ac_multicnt > 14) { unsigned hash; /* @@ -830,10 +833,12 @@ tulip_addr_filter( sp[41] = ((u_short *) sc->tulip_ac.ac_enaddr)[1]; sp[42] = ((u_short *) sc->tulip_ac.ac_enaddr)[2]; } else { +#endif /* * Else can get perfect filtering for 16 addresses. */ i = 0; +#ifdef MULTICAST ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm); for (; enm != NULL; i++) { *sp++ = ((u_short *) enm->enm_addrlo)[0]; @@ -841,6 +846,7 @@ tulip_addr_filter( *sp++ = ((u_short *) enm->enm_addrlo)[2]; ETHER_NEXT_MULTI(step, enm); } +#endif /* * If an IP address is enabled, turn on broadcast */ @@ -858,7 +864,9 @@ tulip_addr_filter( *sp++ = ((u_short *) sc->tulip_ac.ac_enaddr)[1]; *sp++ = ((u_short *) sc->tulip_ac.ac_enaddr)[2]; } +#ifdef MULTICAST } +#endif } static int @@ -931,6 +939,7 @@ tulip_ioctl( break; } +#ifdef MULTICAST case SIOCADDMULTI: case SIOCDELMULTI: { /* @@ -948,6 +957,7 @@ tulip_ioctl( } break; } +#endif /* MULTICAST */ default: { error = EINVAL; @@ -968,7 +978,9 @@ tulip_attach( int cnt; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; +#ifdef MULTICAST ifp->if_flags |= IFF_MULTICAST; +#endif /* MULTICAST */ *sc->tulip_csrs.csr_sia_connectivity = 0; *sc->tulip_csrs.csr_sia_connectivity = TULIP_SIACONN_10BASET; @@ -1066,18 +1078,14 @@ tulip_initring( * on both EISA and PCI boards, one must be careful in how defines the * DC21040 in the config file. */ -static int tulip_pci_probe(pcici_t config_id); -static int tulip_pci_attach(pcici_t config_id); +static char* tulip_pci_probe (pcici_t config_id, pcidi_t device_id); +static void tulip_pci_attach(pcici_t config_id, int unit); +static u_long tulip_count; struct pci_driver dedevice = { tulip_pci_probe, tulip_pci_attach, - 0x00021011ul, -#if __FreeBSD__ == 1 - "de", -#endif - "digital dc21040 ethernet", - tulip_intr + &tulip_count, }; #define PCI_CFID 0x00 /* Configuration ID */ @@ -1090,39 +1098,41 @@ struct pci_driver dedevice = { #define PCI_CFDA 0x40 /* Configuration Driver Area */ #define TULIP_PCI_CSRSIZE (8 / sizeof(tulip_uint32_t)) -static int +static char* tulip_pci_probe( - pcici_t config_id) + pcici_t config_id, + pcidi_t device_id) { int idx; + if (device_id != 0x00021011ul) + return (NULL); for (idx = 0; idx < NDE; idx++) if (tulips[idx] == NULL) - return idx; - return -1; + return ("digital dc21040 ethernet"); + return (NULL); } -static int +static void tulip_pci_attach( - pcici_t config_id) + pcici_t config_id, + int unit) { tulip_softc_t *sc; - int retval, idx, revinfo, unit; - signed int csr; + int retval, idx /* XXX , revinfo, */; + /* XXX signed int csr; */ vm_offset_t va_csrs, pa_csrs; - int result; + /* XXX int result;*/ tulip_desc_t *rxdescs, *txdescs; - unit = tulip_pci_probe(config_id); - sc = (tulip_softc_t *) malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT); if (sc == NULL) - return -1; + return; rxdescs = (tulip_desc_t *) malloc(sizeof(tulip_desc_t) * TULIP_RXDESCS, M_DEVBUF, M_NOWAIT); if (rxdescs == NULL) { free((caddr_t) sc, M_DEVBUF); - return -1; + return; } txdescs = (tulip_desc_t *) @@ -1130,7 +1140,7 @@ tulip_pci_attach( if (txdescs == NULL) { free((caddr_t) rxdescs, M_DEVBUF); free((caddr_t) sc, M_DEVBUF); - return -1; + return; } bzero(sc, sizeof(sc)); /* Zero out the softc*/ @@ -1148,13 +1158,12 @@ tulip_pci_attach( sc->tulip_unit = unit; sc->tulip_name = "de"; retval = pci_map_mem(config_id, PCI_CBMA, &va_csrs, &pa_csrs); - if (retval) { - printf("de%d: pci_map_mem failed.\n", unit); + if (!retval) { kmem_free(kernel_map, sc->tulip_rxspace, TULIP_RXSPACE + NBPG); free((caddr_t) txdescs, M_DEVBUF); free((caddr_t) rxdescs, M_DEVBUF); free((caddr_t) sc, M_DEVBUF); - return -1; + return; } tulips[unit] = sc; tulip_initcsrs(sc, (volatile tulip_uint32_t *) va_csrs, TULIP_PCI_CSRSIZE); @@ -1171,10 +1180,10 @@ tulip_pci_attach( (sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F, "unknown"); } else { + pci_map_int (config_id, tulip_intr, (void*) sc, &net_imask); TULIP_RESET(sc); tulip_attach(sc); } - return 1; } #endif /* NPCI > 0 */ #endif /* NDE > 0 */ diff --git a/sys/i386/pci/ncr.c b/sys/i386/pci/ncr.c index 65bb980..03aa732 100644 --- a/sys/i386/pci/ncr.c +++ b/sys/i386/pci/ncr.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: ncr.c,v 1.5 1994/09/24 02:42:11 rgrimes Exp $ +** $Id: ncr.c,v 2.11 94/10/11 19:03:07 wolf Oct11 $ ** ** Device driver for the NCR 53C810 PCI-SCSI-Controller. ** @@ -9,11 +9,11 @@ **------------------------------------------------------------------------- ** ** Written for 386bsd and FreeBSD by -** wolf@dentaro.gun.de Wolfgang Stanglmeier -** se@mi.Uni-Koeln.de Stefan Esser +** Wolfgang Stanglmeier <wolf@dentaro.gun.de> +** Stefan Esser <se@mi.Uni-Koeln.de> ** ** Ported to NetBSD by -** mycroft@gnu.ai.mit.edu +** Charles M. Hannum <mycroft@gnu.ai.mit.edu> ** **------------------------------------------------------------------------- ** @@ -41,18 +41,11 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -**------------------------------------------------------------------------- +*************************************************************************** */ -#ifndef __NetBSD__ -#ifdef KERNEL -#include <ncr.h> -#else /* KERNEL */ -#define NNCR 1 -#endif /* KERNEL */ -#endif /* !__NetBSD__ */ - #define NCR_VERSION (2) +#define MAX_UNITS (16) /*========================================================== @@ -107,7 +100,7 @@ */ #ifndef SCSI_NCR_MAX_TAGS -#define SCSI_NCR_MAX_TAGS (8) +#define SCSI_NCR_MAX_TAGS (0) #endif /* SCSI_NCR_MAX_TAGS */ /*========================================================== @@ -178,6 +171,7 @@ #include <sys/types.h> #include <sys/param.h> #include <sys/time.h> +#include <sys/proc.h> #ifdef KERNEL #include <sys/systm.h> @@ -190,17 +184,13 @@ #include <vm/vm.h> #endif /* KERNEL */ -#include <i386/pci/ncr_reg.h> +#include <i386/pci/ncrreg.h> #ifdef __NetBSD__ #include <sys/device.h> #include <i386/pci/pcivar.h> -#include <i386/pci/pcireg.h> -#else -#include <i386/pci/pci.h> -#include <i386/pci/pcibios.h> -#include <i386/pci/pci_device.h> #endif +#include <i386/pci/pcireg.h> #include <scsi/scsi_all.h> #include <scsi/scsiconf.h> @@ -369,6 +359,7 @@ int ncr_debug = 0; */ #define CCB_MAGIC (0xf2691ad2) +#define MAX_TAGS (16) /* hard limit */ /*========================================================== ** @@ -394,6 +385,7 @@ int ncr_debug = 0; extern void timeout(); extern void untimeout(); #endif /* KERNEL */ + #define bio_imask biomask #define LUN lu #define TARGET targ #define PRINT_ADDR(xp) printf ("ncr0: targ %d lun %d ",xp->targ,xp->lu) @@ -946,6 +938,8 @@ struct ncb { #ifdef __NetBSD__ struct device sc_dev; struct intrhand sc_ih; +#else + int unit; #endif /*----------------------------------------------- @@ -1195,6 +1189,7 @@ static void ncr_getclock (ncb_p np); static ccb_p ncr_get_ccb (ncb_p np, u_long flags, u_long t,u_long l); static U_INT32 ncr_info (int unit); static void ncr_init (ncb_p np, char * msg, u_long code); +static int ncr_intr (ncb_p np); static void ncr_int_ma (ncb_p np); static void ncr_int_sir (ncb_p np); static void ncr_int_sto (ncb_p np); @@ -1223,11 +1218,9 @@ static void ncr_wakeup (ncb_p np, u_long code); #ifdef __NetBSD__ static int ncr_probe (struct device *, struct device *, void *); static void ncr_attach (struct device *, struct device *, void *); -static int ncr_intr (ncb_p np); #else -static int ncr_probe (pcici_t config_id); -static int ncr_attach (pcici_t config_id); -static int ncr_intr (int dev); +static char* ncr_probe (pcici_t tag, pcidi_t type); +static void ncr_attach (pcici_t tag, int unit); #endif /*========================================================== @@ -1241,9 +1234,8 @@ static int ncr_intr (int dev); #ifdef DIRTY -#include <i386/include/cpufunc.h> - #ifdef __NetBSD__ +#include <i386/include/cpufunc.h> #include <i386/include/pio.h> #include <i386/isa/isareg.h> #define DELAY(x) delay(x) @@ -1326,7 +1318,7 @@ static u_long getirr (void) static char ident[] = - "\n$Id: ncr.c,v 1.4 1994/09/16 13:33:56 davidg Exp $\n"; + "\n$Id: ncr.c,v 2.11 94/10/11 19:03:07 wolf Oct11 $\n"; u_long ncr_version = NCR_VERSION + (u_long) sizeof (struct ncb) @@ -1337,9 +1329,8 @@ u_long ncr_version = NCR_VERSION #ifdef KERNEL #ifndef __NetBSD__ -u_long ncr_units; -u_long nncr=NNCR; -ncb_p ncrp [NNCR]; +u_long nncr=MAX_UNITS; +ncb_p ncrp [MAX_UNITS]; #endif int ncr_cache; /* may _NOT_ be static */ @@ -1371,20 +1362,12 @@ struct cfdriver ncrcd = { #else /* !__NetBSD__ */ -struct pci_driver ncr810_device = { - ncr_probe, - ncr_attach, - NCR_810_ID, - "ncr 53c810 scsi", - ncr_intr -}; +static u_long ncr_count; -struct pci_driver ncr825_device = { +struct pci_driver ncr_device = { ncr_probe, ncr_attach, - NCR_825_ID, - "ncr 53c825 scsi", - ncr_intr + &ncr_count }; #endif /* !__NetBSD__ */ @@ -1429,14 +1412,8 @@ struct scsi_switch ncr_switch = static char *ncr_name (ncb_p np) { static char name[10]; - int idx; - - for (idx = 0; idx < NNCR; idx++) - if (ncrp[idx] == np) { - sprintf(name, "ncr%d", idx); - return (name); - } - return ("ncr?"); + sprintf(name, "ncr%d", np->unit); + return (name); } #endif @@ -3092,7 +3069,7 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np) #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_SCRIPT) printf ("%x: <%x>\n", - (u_long)(src-1), opcode); + (unsigned)(src-1), (unsigned)opcode); #endif /* SCSI_NCR_DEBUG */ /* @@ -3245,13 +3222,22 @@ ncr_probe(parent, self, aux) #else /* !__NetBSD__ */ -static int ncr_probe(pcici_t config_id) + +static char* ncr_probe (pcici_t tag, pcidi_t type) { - if (ncr_units >= NNCR) return (-1); - return (ncr_units); + switch (type) { + + case NCR_810_ID: + return ("ncr 53c810 scsi"); + + case NCR_825_ID: + return ("ncr 53c825 wide scsi"); + } + return (0); } #endif /* !__NetBSD__ */ + /*========================================================== ** @@ -3307,39 +3293,36 @@ ncr_attach(parent, self, aux) #else /* !__NetBSD__ */ -static int ncr_attach (pcici_t config_id) +static void ncr_attach (pcici_t config_id, int unit) { - int retval; - ncb_p np = ncrp[ncr_units]; + ncb_p np; +#if ! (__FreeBSD__ >= 2) + extern unsigned bio_imask; +#endif + /* ** allocate structure */ - if (!np) { - np = (ncb_p) malloc (sizeof (struct ncb), - M_DEVBUF, M_NOWAIT); - if (!np) return (0); - ncrp[ncr_units]=np; - } + np = (ncb_p) malloc (sizeof (struct ncb), M_DEVBUF, M_WAITOK); + if (!np) return; + ncrp[unit]=np; /* ** initialize structure. */ bzero (np, sizeof (*np)); + np->unit = unit; /* ** Try to map the controller chip to ** virtual and physical memory. */ - retval = pci_map_mem (config_id, 0x14, &np->vaddr, &np->paddr); - - if (retval) { - printf ("%s: pci_map_mem failed.\n", ncr_name (np)); - return (retval); - }; + if (!pci_map_mem (config_id, 0x14, &np->vaddr, &np->paddr)) + return; #endif /* !__NetBSD__ */ @@ -3409,9 +3392,18 @@ static int ncr_attach (pcici_t config_id) if (ncr_snooptest (np)) { printf ("CACHE INCORRECTLY CONFIGURED.\n"); - return (0); + return; }; +#ifndef __NetBSD__ + /* + ** Install the interrupt handler. + */ + + if (!pci_map_int (config_id, ncr_intr, np, &bio_imask)) + printf ("\tinterruptless mode: reduced performance.\n"); +#endif + /* ** After SCSI devices have been opened, we cannot ** reset the bus safely, so we do it here. @@ -3431,7 +3423,7 @@ static int ncr_attach (pcici_t config_id) ncr_name (np)); DELAY (1000000); #endif - printf ("%s scanning for targets 0..%d ($Revision: 1.5 $)\n", + printf ("%s scanning for targets 0..%d ($Revision: 2.11 $)\n", ncr_name (np), MAX_TARGET-1); /* @@ -3443,7 +3435,7 @@ static int ncr_attach (pcici_t config_id) #ifdef __NetBSD__ np->sc_link.adapter_softc = np; #else /* !__NetBSD__ */ - np->sc_link.adapter_unit = ncr_units; + np->sc_link.adapter_unit = unit; #endif /* !__NetBSD__ */ np->sc_link.adapter_targ = np->myaddr; np->sc_link.adapter = &ncr_switch; @@ -3455,7 +3447,7 @@ static int ncr_attach (pcici_t config_id) scsi_attachdevs (&np->sc_link); #endif /* !__NetBSD__ */ #else /* ANCIENT */ - scsi_attachdevs (ncr_units, np->myaddr, &ncr_switch); + scsi_attachdevs (unit, np->myaddr, &ncr_switch); #endif /* ANCIENT */ /* @@ -3468,10 +3460,7 @@ static int ncr_attach (pcici_t config_id) ** Done. */ -#ifndef __NetBSD__ - ncr_units++; - return(1); -#endif + return; } /*========================================================== @@ -3483,47 +3472,28 @@ static int ncr_attach (pcici_t config_id) **========================================================== */ -#ifdef __NetBSD__ - int ncr_intr(np) ncb_p np; { int n = 0; -#else /* !__NetBSD__ */ - -static int ncr_intr (int dev) -{ - ncb_p np; - int n=0; - - /* - ** Sanity check - */ - assert (dev<NNCR); - if (dev >= ncr_units) return (0); - np = ncrp[dev]; - -#endif /* !__NetBSD__ */ - #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_TINY) printf ("["); #endif /* SCSI_NCR_DEBUG */ - /* - ** Repeat until no outstanding ints - */ - while (INB(nc_istat) & (INTF|SIP|DIP)) { - ncr_exception (np); + if (INB(nc_istat) & (INTF|SIP|DIP)) { + /* + ** Repeat until no outstanding ints + */ + do { + ncr_exception (np); + } while (INB(nc_istat) & (INTF|SIP|DIP)); + n=1; + np->ticks = 100; }; - /* - ** Slowdown timeout function. - */ - if (n) np->ticks = 100; - #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_TINY) printf ("]\n"); #endif /* SCSI_NCR_DEBUG */ @@ -3637,7 +3607,7 @@ static INT32 ncr_start (struct scsi_xfer * xp) if (ncr_debug & DEBUG_TINY) { PRINT_ADDR(xp); printf ("CMD=%x F=%x L=%x ", cmd->opcode, - xp->flags, xp->datalen); + (unsigned)xp->flags, (unsigned) xp->datalen); } #endif /* SCSI_NCR_DEBUG */ @@ -3765,8 +3735,12 @@ static INT32 ncr_start (struct scsi_xfer * xp) cp2 = cp2->next_ccb; if (cp2) continue; cp->tag=lp->lasttag; - PRINT_ADDR(xp); - printf ("using tag #%d.\n", cp->tag); +#ifdef SCSI_NCR_DEBUG + if (ncr_debug & DEBUG_TAGS) { + PRINT_ADDR(xp); + printf ("using tag #%d.\n", cp->tag); + }; +#endif /* SCSI_NCR_DEBUG */ }; } else { cp->tag=0; @@ -3813,7 +3787,7 @@ static INT32 ncr_start (struct scsi_xfer * xp) } /* - ** can be overwritten by ncrstat + ** can be overwritten by ncrcontrol */ switch (np->order) { case M_SIMPLE_TAG: @@ -3991,7 +3965,9 @@ static INT32 ncr_start (struct scsi_xfer * xp) #ifdef SCSI_NCR_DEBUG if(ncr_debug & DEBUG_QUEUE) printf ("%s: queuepos=%d tryoffset=%d.\n", ncr_name (np), - np->squeueput, np->script->startpos[0]-(vtophys(&np->script->tryloop))); + np->squeueput, + (unsigned)(np->script->startpos[0]- + (vtophys(&np->script->tryloop)))); #endif /* SCSI_NCR_DEBUG */ /* @@ -4049,7 +4025,7 @@ static INT32 ncr_start (struct scsi_xfer * xp) if (!(xp->flags & ITSDONE)) { printf ("%s: abortion failed at %x.\n", - ncr_name (np), INL(nc_dsp)); + ncr_name (np), (unsigned) INL(nc_dsp)); ncr_init (np, "timeout", HS_TIMEOUT); }; @@ -4114,7 +4090,7 @@ void ncr_complete (ncb_p np, ccb_p cp) #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_TINY) - printf ("CCB=%x STAT=%x/%x\n", (u_long)cp & 0xfff, + printf ("CCB=%x STAT=%x/%x\n", (unsigned)cp & 0xfff, cp->host_status,cp->scsi_status); #endif /* SCSI_NCR_DEBUG */ @@ -4279,7 +4255,7 @@ void ncr_complete (ncb_p np, ccb_p cp) */ PRINT_ADDR(xp); printf ("COMMAND FAILED (%x %x) @%x.\n", - cp->host_status, cp->scsi_status, cp); + cp->host_status, cp->scsi_status, (unsigned)cp); xp->error = XS_DRIVER_STUFFUP; } @@ -4361,6 +4337,8 @@ void ncr_wakeup (ncb_p np, u_long code) ** complete all jobs that are not IDLE. */ + int s=splbio(); + ccb_p cp = &np->ccb; while (cp) { switch (cp->host_status) { @@ -4387,6 +4365,7 @@ void ncr_wakeup (ncb_p np, u_long code) }; cp = cp -> link_ccb; }; + splx (s); } /*========================================================== @@ -4758,7 +4737,7 @@ static void ncr_usercmd (ncb_p np) break; case UC_SETTAGS: - if (np->user.data > SCSI_NCR_MAX_TAGS) + if (np->user.data > MAX_TAGS) break; for (t=0; t<MAX_TARGET; t++) { if (!((np->user.target>>t)&1)) continue; @@ -4895,7 +4874,7 @@ static void ncr_timeout (ncb_p np) if (cp->phys.header.launch.l_paddr == vtophys (&np->script->select)) { printf ("%s: timeout ccb=%x (skip)\n", - ncr_name (np), cp); + ncr_name (np), (unsigned)cp); cp->phys.header.launch.l_paddr = vtophys (&np->script->skip); }; @@ -4967,10 +4946,10 @@ static void ncr_timeout (ncb_p np) */ if (np->mcount == 100) { if (np->imask & (np->imask-1)) { - printf ("%s: please configure intr mask %x.\n", + printf ("%s: uses one of the irq in %x.\n", ncr_name (np), np->imask); } else { - printf ("%s: please configure intr %d.\n", + printf ("%s: please configure irq %d.\n", ncr_name (np), ffs (np->imask)-1); }; np->mcount++; @@ -5022,7 +5001,8 @@ void ncr_exception (ncb_p np) printf ("<%d|%x:%x|%x:%x>", INB(nc_scr0), dstat,sist, - INL(nc_dsp),INL(nc_dbc)); + (unsigned)INL(nc_dsp), + (unsigned)INL(nc_dbc)); #endif /* SCSI_NCR_DEBUG */ if ((dstat==DFE) && (sist==PAR)) return; @@ -5117,7 +5097,8 @@ void ncr_exception (ncb_p np) ncr_name (np), INB (nc_ctest0)&7, dstat, sist, INB (nc_sbcl), INB (nc_sxfer),INB (nc_scntl3), - dsp = INL (nc_dsp), INL (nc_dbc)); + (unsigned) (dsp = INL (nc_dsp)), + (unsigned) INL (nc_dbc)); /*---------------------------------------- ** clean up the dma fifo @@ -5243,7 +5224,7 @@ void ncr_exception (ncb_p np) **========================================================== ** ** There seems to be a bug in the 53c810. -** Although a STO-Interupt is pending, +** Although a STO-interrupt is pending, ** it continues executing script commands. ** But it will fail and interrupt (IID) on ** the next instruction where it's looking @@ -5381,11 +5362,14 @@ static void ncr_int_ma (ncb_p np) */ if (ncr_debug & (DEBUG_TINY|DEBUG_PHASE)) { printf ("P%d%d ",cmd&7, sbcl&7); - printf ("RL=%d D=%d SS0=%x ",rest,delta,ss0); + printf ("RL=%d D=%d SS0=%x ", + (unsigned) rest, (unsigned) delta, ss0); }; if (ncr_debug & DEBUG_PHASE) { printf ("\nCP=%x CP2=%x DSP=%x NXT=%x VDSP=%x CMD=%x ", - cp, np->header.cp, dsp, nxtdsp, vdsp, cmd); + (unsigned)cp, (unsigned)np->header.cp, + (unsigned)dsp, + (unsigned)nxtdsp, (unsigned)vdsp, cmd); }; #endif /* SCSI_NCR_DEBUG */ @@ -5407,7 +5391,10 @@ static void ncr_int_ma (ncb_p np) #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_PHASE) { printf ("OCMD=%x\nTBLP=%x OLEN=%x OADR=%x\n", - vdsp[0] >> 24, tblp, olen, oadr); + (unsigned) (vdsp[0] >> 24), + (unsigned) tblp, + (unsigned) olen, + (unsigned) oadr); }; #endif /* SCSI_NCR_DEBUG */ @@ -5419,7 +5406,8 @@ static void ncr_int_ma (ncb_p np) if (cmd & 0x06) { PRINT_ADDR(cp->xfer); printf ("phase change %d-%d %d@%x resid=%d.\n", - cmd&7, sbcl&7, olen, oadr, rest); + cmd&7, sbcl&7, (unsigned)olen, + (unsigned)oadr, (unsigned)rest); OUTB (nc_dcntl, (STD|NOCOM)); return; @@ -5447,7 +5435,10 @@ static void ncr_int_ma (ncb_p np) PRINT_ADDR(cp->xfer); printf ("newcmd[%d] %x %x %x %x.\n", newcmd - cp->patch, - newcmd[0], newcmd[1], newcmd[2], newcmd[3]); + (unsigned)newcmd[0], + (unsigned)newcmd[1], + (unsigned)newcmd[2], + (unsigned)newcmd[3]); } #endif /* SCSI_NCR_DEBUG */ /* @@ -5941,7 +5932,7 @@ void ncr_int_sir (ncb_p np) PRINT_ADDR(cp->xfer); printf ("M_REJECT received (%x:%x).\n", - np->lastmsg, np->msgout[0]); + (unsigned)np->lastmsg, np->msgout[0]); break; case SIR_REJECT_SENT: @@ -5989,10 +5980,10 @@ void ncr_int_sir (ncb_p np) PRINT_ADDR(cp->xfer); printf ("M_DISCONNECT received, but datapointer not saved:\n" - " data=%x save=%x goal=%x.\n", - INL (nc_temp), - np->header.savep, - np->header.goalp); + "\tdata=%x save=%x goal=%x.\n", + (unsigned) INL (nc_temp), + (unsigned) np->header.savep, + (unsigned) np->header.goalp); break; /*-------------------------------------------------------------------- @@ -6047,7 +6038,6 @@ void ncr_int_sir (ncb_p np) ** **----------------------------------------------- */ - /* ** Look for a disconnected job. */ @@ -6209,6 +6199,8 @@ static void ncr_alloc_ccb (ncb_p np, struct scsi_xfer * xp) tp->jump_lcb.l_cmd = (SCR_JUMP); tp->jump_lcb.l_paddr = vtophys (&np->script->abort); np->jump_tcb.l_paddr = vtophys (&tp->jump_tcb); + + ncr_setmaxtags (tp, SCSI_NCR_MAX_TAGS); } /* @@ -6267,7 +6259,7 @@ static void ncr_alloc_ccb (ncb_p np, struct scsi_xfer * xp) #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_ALLOC) { PRINT_ADDR(xp); - printf ("new ccb @%x.\n", cp); + printf ("new ccb @%x.\n", (unsigned) cp); } #endif /* SCSI_NCR_DEBUG */ @@ -6414,7 +6406,7 @@ static int ncr_scatter #ifdef SCSI_NCR_DEBUG if(ncr_debug & DEBUG_SCATTER) printf("ncr?:\tscattering virtual=0x%x size=%d chunk=%d.\n", - (u_long) vaddr, (u_long) datalen, chunk); + (unsigned) vaddr, (unsigned) datalen, (unsigned) chunk); #endif /* SCSI_NCR_DEBUG */ /* @@ -6456,7 +6448,10 @@ static int ncr_scatter #ifdef SCSI_NCR_DEBUG if(ncr_debug & DEBUG_SCATTER) printf ("\tseg #%d addr=%x size=%d (rest=%d).\n", - segment, segaddr, segsize, datalen); + segment, + (unsigned) segaddr, + (unsigned) segsize, + (unsigned) datalen); #endif /* SCSI_NCR_DEBUG */ phys->data[segment].addr = segaddr; @@ -6466,7 +6461,7 @@ static int ncr_scatter if (datalen) { printf("ncr?: scatter/gather failed (residue=%d).\n", - datalen); + (unsigned) datalen); return (-1); }; @@ -6478,7 +6473,7 @@ static int ncr_scatter ** ** Test the pci bus snoop logic :-( ** -** Has to be called with disabled interupts. +** Has to be called with interrupts disabled. ** ** **========================================================== @@ -6522,17 +6517,17 @@ static int ncr_snooptest (struct ncb* np) */ if (host_wr != ncr_rd) { printf ("CACHE TEST FAILED: host wrote %d, ncr read %d.\n", - host_wr, ncr_rd); + (int) host_wr, (int) ncr_rd); err |= 1; }; if (host_rd != ncr_wr) { printf ("CACHE TEST FAILED: ncr wrote %d, host read %d.\n", - ncr_wr, host_rd); + (int) ncr_wr, (int) host_rd); err |= 2; }; if (ncr_bk != ncr_wr) { printf ("CACHE TEST FAILED: ncr wrote %d, read back %d.\n", - ncr_wr, ncr_bk); + (int) ncr_wr, (int) ncr_bk); err |= 4; }; return (err); @@ -6627,6 +6622,7 @@ static struct table_entry device_tab[] = { {"WangDAT", "Model 2600", "01.7", QUIRK_NOMSG}, {"WangDAT", "Model 3200", "02.2", QUIRK_NOMSG}, + {"WangDAT", "Model 1300", "02.4", QUIRK_NOMSG}, {"", "", "", 0} /* catch all: must be last entry. */ }; @@ -6639,17 +6635,17 @@ static u_long ncr_lookup(char * id) d = id+8; r = p->manufacturer; - while (c=*r++) if (c!=*d++) break; + while ((c=*r++)) if (c!=*d++) break; if (c) continue; d = id+16; r = p->model; - while (c=*r++) if (c!=*d++) break; + while ((c=*r++)) if (c!=*d++) break; if (c) continue; d = id+32; r = p->version; - while (c=*r++) if (c!=*d++) break; + while ((c=*r++)) if (c!=*d++) break; if (c) continue; return (p->info); @@ -6712,3 +6708,5 @@ static void ncr_getclock (ncb_p np) /*=========================================================================*/ #endif /* KERNEL */ + + diff --git a/sys/i386/pci/pci.c b/sys/i386/pci/pci.c index c34523d..396b96f 100644 --- a/sys/i386/pci/pci.c +++ b/sys/i386/pci/pci.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci.c,v 1.5 1994/09/28 16:34:07 se Exp $ +** $Id: pci.c,v 2.12 94/10/11 22:20:37 wolf Oct11 $ ** ** General subroutines for the PCI bus on 80*86 systems. ** pci_configure () @@ -33,27 +33,17 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -**------------------------------------------------------------------------- +*************************************************************************** */ #include <pci.h> #if NPCI > 0 -/*======================================================== -** -** Configuration -** -**======================================================== -*/ - -/* -** maximum number of devices which share one interrupt line -*/ - -#ifndef PCI_MAX_DPI -#define PCI_MAX_DPI (4) -#endif /*PCI_MAX_DPI*/ - +#ifndef __FreeBSD2__ +#if __FreeBSD__ >= 2 +#define __FreeBSD2__ +#endif +#endif /*======================================================== ** @@ -64,101 +54,54 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/malloc.h> #include <sys/errno.h> #include <vm/vm.h> #include <vm/vm_param.h> -#include <i386/isa/icu.h> #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> - -#include <i386/pci/pci.h> -#include <i386/pci/pci_device.h> -#include <i386/pci/pcibios.h> +#include <i386/isa/icu.h> +#include <i386/pci/pcireg.h> /* ** Function prototypes missing in system headers */ -#if ! (__FreeBSD__ >= 2) +#ifndef __FreeBSD2__ extern pmap_t pmap_kernel(void); static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize); -#endif - - -/*======================================================== -** -** Autoconfiguration (of isa bus) -** -**======================================================== -*/ /* -** per slot data structure for passing interupts.. -*/ - -static struct { - u_short number; - u_short isanum; - struct { - int (*proc)(int dev); - dev_t unit; - } vector[PCI_MAX_DPI]; -} pcidata [NPCI]; + * Type of the first (asm) part of an interrupt handler. + */ +typedef void inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss)); /* -** check device ready -*/ -static int pciprobe (struct isa_device *dev) -{ - if (dev->id_unit >= NPCI) - return (0); - - if (!pci_conf_mode()) - return (0); - - return (-1); -} + * Usual type of the second (C) part of an interrupt handler. Some bogus + * ones need the arg to be the interrupt frame (and not a copy of it, which + * is all that is possible in C). + */ +typedef void inthand2_t __P((int unit)); /* -** initialize the driver structure -*/ -static int pciattach (struct isa_device *isdp) -{ - pcidata[isdp->id_unit].number = 0; - pcidata[isdp->id_unit].isanum = ffs(isdp->id_irq)-1; - return (1); -} - -/* -** ISA driver structure -*/ - -struct isa_driver pcidriver = { - pciprobe, - pciattach, - "pci" -}; - -/*======================================================== -** -** Interrupt forward from isa to pci devices. -** -**======================================================== +** XXX @FreeBSD2@ +** +** Unfortunately, the mptr argument is _no_ pointer in 2.0 FreeBSD. +** We would prefer a pointer because it enables us to install +** new interrupt handlers at any time. +** In 2.0 FreeBSD later installed interrupt handlers may change +** the xyz_imask, but this would not be recognized by handlers +** which are installed before. */ +static int +register_intr __P((int intr, int device_id, unsigned int flags, + inthand2_t *handler, unsigned int * mptr, int unit)); +extern unsigned intr_mask[ICU_LEN]; -void pciintr (int unit) -{ - u_short i; - if (unit >= NPCI) return; - for (i=0; i<pcidata[unit].number; i++) { - (void)(*pcidata[unit].vector[i].proc) - (pcidata[unit].vector[i].unit); - }; -} - +#endif /* !__FreeBSD2__ */ /*======================================================== ** @@ -183,52 +126,82 @@ void pciintr (int unit) #define PCI_PMEM_START 0xc0000000 #endif -static vm_offset_t pci_paddr = PCI_PMEM_START; +static vm_offset_t pci_paddr = PCI_PMEM_START; +/*-------------------------------------------------------- +** +** The pci device interrupt lines should have been +** assigned by the bios. But if the bios failed to +** to it, we set it. +** +**-------------------------------------------------------- +*/ + +#ifndef PCI_IRQ +#define PCI_IRQ 0 +#endif + +static u_long pci_irq = PCI_IRQ; + /*--------------------------------------------------------- ** ** pci_configure () ** +** Probe all devices on pci bus and attach them. +** +** May be called more than once. +** Any device is attached only once. +** (Attached devices are remembered in pci_seen.) +** **--------------------------------------------------------- */ static void not_supported (pcici_t tag, u_long type); +static unsigned long pci_seen[NPCI]; + +static int pci_conf_count; + void pci_configure() { u_char device,last_device; - u_short bus,last_bus; + u_short bus; pcici_t tag; pcidi_t type; u_long data; int unit; - int intpin; - int isanum; - int pci_mode; + int pci_mechanism; + int pciint; + int irq; + char* name=0; + int newdev=0; - struct pci_driver *drp; + struct pci_driver *drp=0; struct pci_device *dvp; /* ** check pci bus present */ - pci_mode = pci_conf_mode (); - if (!pci_mode) return; - last_bus = pci_last_bus (); - last_device = pci_mode==1 ? 31 : 15; - + pci_mechanism = pci_conf_mode (); + if (!pci_mechanism) return; + last_device = pci_mechanism==1 ? 31 : 15; + /* ** hello world .. */ + + for (bus=0;bus<NPCI;bus++) { #ifndef PCI_QUIET - printf ("pci*: mode=%d, scanning bus 0..%d, device 0..%d.\n", - pci_mode, last_bus, last_device); + printf ("pci%d: scanning device 0..%d, mechanism=%d.\n", + bus, last_device, pci_mechanism); #endif - - for (bus=0;bus<=last_bus; bus++) for (device=0; device<=last_device; device ++) { + + if (pci_seen[bus] & (1ul << device)) + continue; + tag = pcitag (bus, device, 0); type = pci_conf_read (tag, PCI_ID_REG); @@ -238,137 +211,90 @@ void pci_configure() ** lookup device in ioconfiguration: */ - for (dvp = pci_devtab; dvp->pd_device_id; dvp++) { - if (dvp->pd_device_id == type) break; + for (dvp = pci_devtab; dvp->pd_name; dvp++) { + drp = dvp->pd_driver; + if (!drp) + continue; + if ((name=(*drp->probe)(tag, type))) + break; }; - drp = dvp->pd_driver; - - if (!dvp->pd_device_id) { - /* - ** not found - ** try to dig out some information. - ** - ** By Garrett Wollman - ** <wollman@halloran-eldar.lcs.mit.edu> - */ - - int data = pci_conf_read(tag, PCI_CLASS_REG); - vm_offset_t va; - vm_offset_t pa; - int reg; - - switch (data & PCI_CLASS_MASK) { - - case PCI_CLASS_PREHISTORIC: - if ((data & PCI_SUBCLASS_MASK) - != PCI_SUBCLASS_PREHISTORIC_VGA) - break; - - case PCI_CLASS_DISPLAY: - for (reg = PCI_MAP_REG_START; - reg < PCI_MAP_REG_END; - reg += 4) { - data = pci_map_mem(tag, reg, &va, &pa); - if (data == 0) - printf ( - "pci%d:%d: mapped VGA-like device at physaddr 0x%lx\n", - bus, device, (u_long)pa); - - } - continue; - }; + if (!dvp->pd_name) { #ifndef PCI_QUIET + if (pci_conf_count) + continue; printf("pci%d:%d: ", bus, device); not_supported (tag, type); #endif - }; - - if (!drp) { - if(dvp->pd_flags & PDF_LOADABLE) { - printf("%s: loadable device on pci%d:%d\n", - dvp->pd_name, bus, device); - } continue; - } + }; + pci_seen[bus] |= (1ul << device); /* - ** found it. - ** probe returns the device unit. + ** Get and increment the unit. */ - unit = (*drp->probe) (tag); + unit = (*drp->count)++; - if (unit<0) { - printf ("%s <%s>: probe failed on pci%d:%d\n", - dvp->pd_name, drp->name, bus, device); - continue; - }; + /* + ** ignore device ? + */ + + if (!*name) continue; + + /* + ** Announce this device + */ - printf ("%s%d <%s>", dvp->pd_name, unit, drp->name); + newdev++; + printf ("%s%d <%s>", dvp->pd_name, unit, name); /* - ** install interrupts + ** Get the int pin number (pci interrupt number a-d) + ** from the pci configuration space. */ data = pci_conf_read (tag, PCI_INTERRUPT_REG); - intpin = PCI_INTERRUPT_PIN_EXTRACT(data); - if (intpin) { - int idx=NPCI; + pciint = PCI_INTERRUPT_PIN_EXTRACT(data); - /* - ** Usage of int line register (if set by bios) - ** Matt Thomas <thomas@lkg.dec.com> - */ + if (pciint) { - isanum = PCI_INTERRUPT_LINE_EXTRACT(data); - if (isanum) { - - /* - ** @INT@ FIXME!!! - ** - ** Should try to use "register_interupt" - ** at this point. - */ - - printf (" line=%d", isanum); - for (idx = 0; idx < NPCI; idx++) { - if (pcidata[idx].isanum == isanum) - break; - }; - }; + printf (" int %c", 0x60+pciint); /* - ** Or take the device number as index ... + ** If the interrupt line register is not set, + ** set it now from PCI_IRQ. */ - if (idx >= NPCI) idx = device; + if (!(PCI_INTERRUPT_LINE_EXTRACT(data))) { + + irq = pci_irq & 0x0f; + pci_irq >>= 4; + + data = PCI_INTERRUPT_LINE_INSERT(data, irq); + printf (" (config)"); + pci_conf_write (tag, PCI_INTERRUPT_REG, data); + }; + + irq = PCI_INTERRUPT_LINE_EXTRACT(data); /* - ** And install the interrupt. + ** If it's zero, the isa irq number is unknown, + ** and we cannot bind the pci interrupt to isa. */ - if (idx<NPCI) { - u_short entry = pcidata[idx].number; - printf (" irq %c", 0x60+intpin); - if (entry < PCI_MAX_DPI) { - pcidata[idx].vector[entry].proc = drp->intr; - pcidata[idx].vector[entry].unit = unit; - entry++; - }; - printf (" isa=%d [%d]",pcidata[idx].isanum, entry); - pcidata[idx].number=entry; - } else { - printf (" no int"); - }; + if (irq) + printf (" irq %d", irq); + else + printf (" not bound"); }; - + /* ** enable memory access */ - data = pci_conf_read (tag, PCI_COMMAND_STATUS_REG) - & 0xffff | PCI_COMMAND_MEM_ENABLE; + data = (pci_conf_read (tag, PCI_COMMAND_STATUS_REG) + & 0xffff) | PCI_COMMAND_MEM_ENABLE; pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data); @@ -380,13 +306,16 @@ void pci_configure() printf (" on pci%d:%d\n", bus, device); - (void) (*drp->attach) (tag); - } + (*drp->attach) (tag, unit); + }; + }; #ifndef PCI_QUIET - printf ("pci uses physical addresses from 0x%lx to 0x%lx\n", + if (newdev) + printf ("pci uses physical addresses from 0x%lx to 0x%lx\n", (u_long)PCI_PMEM_START, (u_long)pci_paddr); #endif + pci_conf_count++; } /*----------------------------------------------------------------------- @@ -403,7 +332,8 @@ int pci_map_port (pcici_t tag, u_long reg, u_short* pa) /* ** @MAPIO@ not yet implemented. */ - return (ENOSYS); + printf ("pci_map_port failed: not yet implemented\n"); + return (0); } /*----------------------------------------------------------------------- @@ -425,8 +355,11 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) ** sanity check */ - if (reg <= PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) - return (EINVAL); + if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) { + printf ("pci_map_mem failed: bad register=0x%x\n", + (unsigned)reg); + return (0); + }; /* ** get size and type of memory @@ -445,7 +378,9 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) break; default: /* unknown */ - return (EINVAL); + printf ("pci_map_mem failed: bad memory type=0x%x\n", + (unsigned) data); + return (0); }; /* @@ -455,18 +390,19 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) vsize = round_page (-(data & PCI_MAP_MEMORY_ADDRESS_MASK)); - if (!vsize) return (EINVAL); - + if (!vsize) return (0); + /* ** align physical address to virtual size */ - if (data = pci_paddr % vsize) + if ((data = pci_paddr % vsize)) pci_paddr += vsize - data; - vaddr = pmap_mapdev (pci_paddr, vsize); + vaddr = (vm_offset_t) pmap_mapdev (pci_paddr, vsize); + - if (!vaddr) return (EINVAL); + if (!vaddr) return (0); #ifndef PCI_QUIET /* @@ -474,7 +410,7 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) */ printf ("\treg%d: virtual=0x%lx physical=0x%lx\n", - reg, (u_long)vaddr, (u_long)pci_paddr); + (unsigned) reg, (u_long)vaddr, (u_long)pci_paddr); #endif /* @@ -496,50 +432,77 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) pci_paddr += vsize; - return (0); + return (1); } -/*----------------------------------------------------------- +/*----------------------------------------------------------------------- ** -** Mapping of physical to virtual memory +** Map pci interrupts to isa interrupts. ** -**----------------------------------------------------------- +**----------------------------------------------------------------------- */ -#if ! (__FreeBSD__ >= 2) +static unsigned int pci_int_mask [16]; -extern vm_map_t kernel_map; - -static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize) +int pci_map_int (pcici_t tag, int(*func)(), void* arg, unsigned* maskptr) { - vm_offset_t vaddr,value; - u_long result; + int irq; + unsigned mask; - vaddr = vm_map_min (kernel_map); + irq = PCI_INTERRUPT_LINE_EXTRACT( + pci_conf_read (tag, PCI_INTERRUPT_REG)); - result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0, - &vaddr, vsize, TRUE); - - if (result != KERN_SUCCESS) { - printf (" vm_map_find failed(%d)\n", result); + if (irq >= 16 || irq <= 0) { + printf ("pci_map_int failed: no int line set.\n"); return (0); - }; + } + + mask = 1ul << irq; + + if (!maskptr) + maskptr = &pci_int_mask[irq]; + + INTRMASK (*maskptr, mask); + register_intr( + irq, /* isa irq */ + 0, /* deviced?? */ + 0, /* flags? */ + (inthand2_t*) func, /* handler */ +#ifdef __FreeBSD2__ + *maskptr, /* mask */ +#else + maskptr, /* mask pointer */ +#endif + (int) arg); /* handler arg */ + +#ifdef __FreeBSD2__ /* - ** map physical + ** XXX See comment at beginning of file. + ** + ** Have to update all the interrupt masks ... Grrrrr!!! */ - - value = vaddr; - while (vsize >= NBPG) { - pmap_enter (pmap_kernel(), vaddr, paddr, - VM_PROT_READ|VM_PROT_WRITE, TRUE); - vaddr += NBPG; - paddr += NBPG; - vsize -= NBPG; + { + unsigned * mp = &intr_mask[0]; + /* + ** update the isa interrupt masks. + */ + for (mp=&intr_mask[0]; mp<&intr_mask[ICU_LEN]; mp++) + if (*mp & *maskptr) + *mp |= mask; + /* + ** update the pci interrupt masks. + */ + for (mp=&pci_int_mask[0]; mp<&pci_int_mask[16]; mp++) + if (*mp & *maskptr) + *mp |= mask; }; - return (value); -} #endif + + INTREN (mask); + + return (1); +} /*----------------------------------------------------------- ** @@ -554,7 +517,7 @@ struct vt { static struct vt VendorTable[] = { {0x1002, "ATI TECHNOLOGIES INC"}, - {0x1011, "DIGITAL EQUIPMENT CORP."}, + {0x1011, "DIGITAL EQUIPMENT CORPORATION"}, {0x101A, "NCR"}, {0x102B, "MATROX"}, {0x1045, "OPTI"}, @@ -604,18 +567,107 @@ void not_supported (pcici_t tag, u_long type) case 1: case 5: - printf (" map(%lx): io(%lx)\n", reg, data & ~3); + printf (" map(%x): io(%lx)\n", + reg, data & ~3); break; case 0: - printf (" map(%lx): mem32(%lx)\n", reg, data & ~7); + printf (" map(%x): mem32(%lx)\n", + reg, data & ~7); break; case 2: - printf (" map(%lx): mem20(%lx)\n", reg, data & ~7); + printf (" map(%x): mem20(%lx)\n", + reg, data & ~7); break; case 4: - printf (" map(%lx): mem64(%lx)\n", reg, data & ~7); + printf (" map(%x): mem64(%lx)\n", + reg, data & ~7); break; } } } -#endif + +#ifndef __FreeBSD2__ +/*----------------------------------------------------------- +** +** Mapping of physical to virtual memory +** +**----------------------------------------------------------- +*/ + +extern vm_map_t kernel_map; + +static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize) +{ + vm_offset_t vaddr,value; + u_long result; + + vaddr = vm_map_min (kernel_map); + + result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0, + &vaddr, vsize, TRUE); + + if (result != KERN_SUCCESS) { + printf (" vm_map_find failed(%d)\n", result); + return (0); + }; + + /* + ** map physical + */ + + value = vaddr; + while (vsize >= NBPG) { + pmap_enter (pmap_kernel(), vaddr, paddr, + VM_PROT_READ|VM_PROT_WRITE, TRUE); + vaddr += NBPG; + paddr += NBPG; + vsize -= NBPG; + }; + return (value); +} + +/*------------------------------------------------------------ +** +** Emulate the register_intr() function of FreeBSD 2.0 +** +** requires a patch: +** FreeBSD 2.0: "/sys/i386/isa/vector.s" +** 386bsd0.1: "/sys/i386/isa/icu.s" +** 386bsd1.0: Please ask Jesus Monroy Jr. +** +**------------------------------------------------------------ +*/ + +#include <machine/segments.h> + +int pci_int_unit [16]; +inthand2_t* (pci_int_hdlr [16]); +unsigned int * pci_int_mptr [16]; +unsigned int pci_int_count[16]; + +extern void + Vpci3(), Vpci4(), Vpci5(), Vpci6(), Vpci7(), Vpci8(), Vpci9(), + Vpci10(), Vpci11(), Vpci12(), Vpci13(), Vpci14(), Vpci15(); + +static inthand_t* pci_int_glue[16] = { + 0, 0, 0, Vpci3, Vpci4, Vpci5, Vpci6, Vpci7, Vpci8, + Vpci9, Vpci10, Vpci11, Vpci12, Vpci13, Vpci14, Vpci15 }; + +static int +register_intr __P((int intr, int device_id, unsigned int flags, + inthand2_t *handler, unsigned int* mptr, int unit)) +{ + if (intr >= 16 || intr <= 2) + return (EINVAL); + if (pci_int_hdlr [intr]) + return (EBUSY); + + pci_int_hdlr [intr] = handler; + pci_int_unit [intr] = unit; + pci_int_mptr [intr] = mptr; + + setidt(NRSVIDT + intr, pci_int_glue[intr], SDT_SYS386IGT, SEL_KPL); + return (0); +} +#endif /* __FreeBSD2__ */ +#endif /* NPCI */ diff --git a/sys/i386/pci/pci_config.c b/sys/i386/pci/pci_config.c index 3eddfa5..29cbedf 100644 --- a/sys/i386/pci/pci_config.c +++ b/sys/i386/pci/pci_config.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci_config.c,v 1.5 1994/09/28 16:34:09 se Exp $ +** $Id: pci_config.c,v 2.3 94/10/09 21:10:21 wolf Oct11 $ ** ** @PCI@ this should be part of "ioconf.c". ** @@ -32,50 +32,40 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -**------------------------------------------------------------------------- +*************************************************************************** */ #include <sys/types.h> -#include <i386/pci/pci.h> -#include <i386/pci/pci_device.h> +#include <i386/pci/pcireg.h> -#include "ncr.h" +#include <ncr.h> #if NNCR>0 -extern struct pci_driver ncr810_device; -extern struct pci_driver ncr825_device; +extern struct pci_driver ncr_device; #endif -#include "de.h" +#include <de.h> #if NDE > 0 extern struct pci_driver dedevice; #endif -extern struct pci_driver intel82378_device; -extern struct pci_driver intel82424_device; -extern struct pci_driver intel82375_device; -extern struct pci_driver intel82434_device; +extern struct pci_driver chipset_device; +extern struct pci_driver vga_device; +extern struct pci_driver ign_device; +extern struct pci_driver lkm_device; struct pci_device pci_devtab[] = { #if NNCR>0 - {&ncr810_device, 0x00011000ul, "ncr", 0}, - {&ncr825_device, 0x00031000ul, "ncr", 0}, -#else - {0, 0x00011000ul, "ncr", PDF_LOADABLE}, - {0, 0x00031000ul, "ncr", PDF_LOADABLE}, + {&ncr_device, "ncr", 0 }, #endif #if NDE>0 - {&dedevice, 0x00021011ul, "de", 0}, /* FIXME!!! */ -#else - {0, 0x00021011ul, "de", PDF_LOADABLE}, /* FIXME!!! */ + {&dedevice, "de", 0 }, #endif - {0, 0x10001042ul, "wd", PDF_COVERED}, - - {&intel82378_device, 0x04848086, "ichip", 0}, - {&intel82424_device, 0x04838086, "ichip", 0}, - {&intel82375_device, 0x04828086, "ichip", 0}, - {&intel82434_device, 0x04a38086, "ichip", 0}, - {0, 0, 0, 0} + {&chipset_device, "chip", 0 }, + {&vga_device, "graphics", 0 }, + {&ign_device, "ign", 0 }, + {&lkm_device, "lkm", 0 }, + {0, 0, 0 } }; diff --git a/sys/i386/pci/pcibios.c b/sys/i386/pci/pcibios.c index 50e6ecb..2069387 100644 --- a/sys/i386/pci/pcibios.c +++ b/sys/i386/pci/pcibios.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pcibios.c,v 2.1 94/09/16 08:01:26 wolf Rel $ +** $Id: pcibios.c,v 2.6 94/10/11 19:01:25 wolf Oct11 $ ** ** #define for pci-bus bios functions. ** @@ -32,15 +32,22 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -**------------------------------------------------------------------------- +*************************************************************************** */ +#include <pci.h> +#if NPCI > 0 -#include "types.h" -#include "i386/isa/isa.h" -#include "i386/pci/pci.h" -#include "i386/pci/pcibios.h" -#include "i386/include/cpufunc.h" +#if __FreeBSD__ >= 2 +#define HAS_CPUFUNC_H +#endif + +#include <types.h> +#include <i386/isa/isa.h> +#include <i386/pci/pcireg.h> +#ifdef HAS_CPUFUNC_H +#include <i386/include/cpufunc.h> +#endif extern int printf(); @@ -54,9 +61,7 @@ static char pci_mode; **-------------------------------------------------------------------- */ -#undef DIRTY - -#ifdef DIRTY +#ifndef HAS_CPUFUNC_H #undef inl #define inl(port) \ @@ -81,7 +86,7 @@ static char pci_mode; #define outb(port, data) \ {__asm __volatile("outb %0, %1"::"a" ((u_char)(data)), "d" ((u_short)(port)));} -#endif +#endif /* HAS_CPUFUNC_H */ /*-------------------------------------------------------------------- ** @@ -194,7 +199,7 @@ u_long pci_conf_read (pcici_t tag, u_long reg) switch (pci_mode) { case 1: - addr = tag.cfg1 | reg & 0xfc; + addr = tag.cfg1 | (reg & 0xfc); #ifdef PCI_DEBUG printf ("pci_conf_read(1): addr=%x ", addr); #endif @@ -204,7 +209,7 @@ u_long pci_conf_read (pcici_t tag, u_long reg) break; case 2: - addr = tag.cfg2.port | reg & 0xfc; + addr = tag.cfg2.port | (reg & 0xfc); #ifdef PCI_DEBUG printf ("pci_conf_read(2): addr=%x ", addr); #endif @@ -242,7 +247,7 @@ void pci_conf_write (pcici_t tag, u_long reg, u_long data) switch (pci_mode) { case 1: - addr = tag.cfg1 | reg & 0xfc; + addr = tag.cfg1 | (reg & 0xfc); #ifdef PCI_DEBUG printf ("pci_conf_write(1): addr=%x data=%x\n", addr, data); @@ -253,7 +258,7 @@ void pci_conf_write (pcici_t tag, u_long reg, u_long data) break; case 2: - addr = tag.cfg2.port | reg & 0xfc; + addr = tag.cfg2.port | (reg & 0xfc); #ifdef PCI_DEBUG printf ("pci_conf_write(2): addr=%x data=%x\n", addr, data); @@ -268,26 +273,4 @@ void pci_conf_write (pcici_t tag, u_long reg, u_long data) break; }; } - -/*-------------------------------------------------------------------- -** -** Get the number of available PCI busses. -** -**-------------------------------------------------------------------- -*/ - -/* -** A certain chipset seems to ignore the bus number. -** Until fixed, check only bus 0. -** Maybe it's a good idea to ask the real pci bios -** if available. -*/ - -#ifndef PCI_LAST_BUS -#define PCI_LAST_BUS (0) -#endif /* PCI_LAST_BUS */ - -int pci_last_bus (void) -{ - return (PCI_LAST_BUS); -} +#endif /* NPCI > 0 */ diff --git a/sys/pci/if_de.c b/sys/pci/if_de.c index 2b9774e..2aeebfa 100644 --- a/sys/pci/if_de.c +++ b/sys/pci/if_de.c @@ -101,8 +101,7 @@ #include <pci.h> #if NPCI > 0 -#include <i386/pci/pci.h> -#include <i386/pci/pci_device.h> +#include <i386/pci/pcireg.h> #endif #include <i386/isa/icu.h> #include <i386/pci/dc21040.h> @@ -310,7 +309,7 @@ tulip_init( int unit) { tulip_softc_t *sc = tulips[unit]; - unsigned new_cmdmode; + /* XXX unsigned new_cmdmode; */ if (sc->tulip_if.if_flags & IFF_UP) { sc->tulip_if.if_flags |= IFF_RUNNING; @@ -332,7 +331,7 @@ tulip_init( sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; tulip_start(&sc->tulip_if); } - tulip_cmdnode |= TULIP_CMD_THRSHLD160; + sc->tulip_cmdmode |= TULIP_CMD_THRSHLD160; *sc->tulip_csrs.csr_intr = sc->tulip_intrmask; *sc->tulip_csrs.csr_command = sc->tulip_cmdmode; } else { @@ -690,13 +689,12 @@ tulip_start( static int tulip_intr( - int unit) + tulip_softc_t *sc) { - tulip_softc_t *sc = tulips[unit]; tulip_uint32_t csr; unsigned spins = 0; - tulip_intrs[unit]++; + /* XXX tulip_intrs[unit]++; */ while ((csr = *sc->tulip_csrs.csr_status) & (TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR)) { *sc->tulip_csrs.csr_status = csr & sc->tulip_intrmask; @@ -706,7 +704,7 @@ tulip_intr( if ((csr & TULIP_STS_ERRORMASK) == TULIP_STS_ERR_PARITY) { TULIP_RESET(sc); tulip_init(sc->tulip_unit); - return unit; + return (1); } } if (csr & TULIP_STS_RXINTR) @@ -723,7 +721,7 @@ tulip_intr( } if (spins > sc->tulip_high_intrspins) sc->tulip_high_intrspins = spins; - return unit; + return (1); } /* @@ -777,6 +775,7 @@ tulip_read_macaddr( return 0; } +#ifdef MULTICAST static unsigned tulip_mchash( unsigned char *mca) @@ -794,20 +793,24 @@ tulip_mchash( #endif return crc & 0x1FF; } +#endif MULTICAST static void tulip_addr_filter( tulip_softc_t *sc) { tulip_uint32_t *sp = sc->tulip_setupdata; +#ifdef MULTICAST struct ether_multistep step; struct ether_multi *enm; +#endif int i; sc->tulip_flags &= ~TULIP_WANTHASH; sc->tulip_flags |= TULIP_WANTSETUP; sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN; sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; +#ifdef MULTICAST if (sc->tulip_ac.ac_multicnt > 14) { unsigned hash; /* @@ -830,10 +833,12 @@ tulip_addr_filter( sp[41] = ((u_short *) sc->tulip_ac.ac_enaddr)[1]; sp[42] = ((u_short *) sc->tulip_ac.ac_enaddr)[2]; } else { +#endif /* * Else can get perfect filtering for 16 addresses. */ i = 0; +#ifdef MULTICAST ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm); for (; enm != NULL; i++) { *sp++ = ((u_short *) enm->enm_addrlo)[0]; @@ -841,6 +846,7 @@ tulip_addr_filter( *sp++ = ((u_short *) enm->enm_addrlo)[2]; ETHER_NEXT_MULTI(step, enm); } +#endif /* * If an IP address is enabled, turn on broadcast */ @@ -858,7 +864,9 @@ tulip_addr_filter( *sp++ = ((u_short *) sc->tulip_ac.ac_enaddr)[1]; *sp++ = ((u_short *) sc->tulip_ac.ac_enaddr)[2]; } +#ifdef MULTICAST } +#endif } static int @@ -931,6 +939,7 @@ tulip_ioctl( break; } +#ifdef MULTICAST case SIOCADDMULTI: case SIOCDELMULTI: { /* @@ -948,6 +957,7 @@ tulip_ioctl( } break; } +#endif /* MULTICAST */ default: { error = EINVAL; @@ -968,7 +978,9 @@ tulip_attach( int cnt; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; +#ifdef MULTICAST ifp->if_flags |= IFF_MULTICAST; +#endif /* MULTICAST */ *sc->tulip_csrs.csr_sia_connectivity = 0; *sc->tulip_csrs.csr_sia_connectivity = TULIP_SIACONN_10BASET; @@ -1066,18 +1078,14 @@ tulip_initring( * on both EISA and PCI boards, one must be careful in how defines the * DC21040 in the config file. */ -static int tulip_pci_probe(pcici_t config_id); -static int tulip_pci_attach(pcici_t config_id); +static char* tulip_pci_probe (pcici_t config_id, pcidi_t device_id); +static void tulip_pci_attach(pcici_t config_id, int unit); +static u_long tulip_count; struct pci_driver dedevice = { tulip_pci_probe, tulip_pci_attach, - 0x00021011ul, -#if __FreeBSD__ == 1 - "de", -#endif - "digital dc21040 ethernet", - tulip_intr + &tulip_count, }; #define PCI_CFID 0x00 /* Configuration ID */ @@ -1090,39 +1098,41 @@ struct pci_driver dedevice = { #define PCI_CFDA 0x40 /* Configuration Driver Area */ #define TULIP_PCI_CSRSIZE (8 / sizeof(tulip_uint32_t)) -static int +static char* tulip_pci_probe( - pcici_t config_id) + pcici_t config_id, + pcidi_t device_id) { int idx; + if (device_id != 0x00021011ul) + return (NULL); for (idx = 0; idx < NDE; idx++) if (tulips[idx] == NULL) - return idx; - return -1; + return ("digital dc21040 ethernet"); + return (NULL); } -static int +static void tulip_pci_attach( - pcici_t config_id) + pcici_t config_id, + int unit) { tulip_softc_t *sc; - int retval, idx, revinfo, unit; - signed int csr; + int retval, idx /* XXX , revinfo, */; + /* XXX signed int csr; */ vm_offset_t va_csrs, pa_csrs; - int result; + /* XXX int result;*/ tulip_desc_t *rxdescs, *txdescs; - unit = tulip_pci_probe(config_id); - sc = (tulip_softc_t *) malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT); if (sc == NULL) - return -1; + return; rxdescs = (tulip_desc_t *) malloc(sizeof(tulip_desc_t) * TULIP_RXDESCS, M_DEVBUF, M_NOWAIT); if (rxdescs == NULL) { free((caddr_t) sc, M_DEVBUF); - return -1; + return; } txdescs = (tulip_desc_t *) @@ -1130,7 +1140,7 @@ tulip_pci_attach( if (txdescs == NULL) { free((caddr_t) rxdescs, M_DEVBUF); free((caddr_t) sc, M_DEVBUF); - return -1; + return; } bzero(sc, sizeof(sc)); /* Zero out the softc*/ @@ -1148,13 +1158,12 @@ tulip_pci_attach( sc->tulip_unit = unit; sc->tulip_name = "de"; retval = pci_map_mem(config_id, PCI_CBMA, &va_csrs, &pa_csrs); - if (retval) { - printf("de%d: pci_map_mem failed.\n", unit); + if (!retval) { kmem_free(kernel_map, sc->tulip_rxspace, TULIP_RXSPACE + NBPG); free((caddr_t) txdescs, M_DEVBUF); free((caddr_t) rxdescs, M_DEVBUF); free((caddr_t) sc, M_DEVBUF); - return -1; + return; } tulips[unit] = sc; tulip_initcsrs(sc, (volatile tulip_uint32_t *) va_csrs, TULIP_PCI_CSRSIZE); @@ -1171,10 +1180,10 @@ tulip_pci_attach( (sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F, "unknown"); } else { + pci_map_int (config_id, tulip_intr, (void*) sc, &net_imask); TULIP_RESET(sc); tulip_attach(sc); } - return 1; } #endif /* NPCI > 0 */ #endif /* NDE > 0 */ diff --git a/sys/pci/ncr.c b/sys/pci/ncr.c index 65bb980..03aa732 100644 --- a/sys/pci/ncr.c +++ b/sys/pci/ncr.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: ncr.c,v 1.5 1994/09/24 02:42:11 rgrimes Exp $ +** $Id: ncr.c,v 2.11 94/10/11 19:03:07 wolf Oct11 $ ** ** Device driver for the NCR 53C810 PCI-SCSI-Controller. ** @@ -9,11 +9,11 @@ **------------------------------------------------------------------------- ** ** Written for 386bsd and FreeBSD by -** wolf@dentaro.gun.de Wolfgang Stanglmeier -** se@mi.Uni-Koeln.de Stefan Esser +** Wolfgang Stanglmeier <wolf@dentaro.gun.de> +** Stefan Esser <se@mi.Uni-Koeln.de> ** ** Ported to NetBSD by -** mycroft@gnu.ai.mit.edu +** Charles M. Hannum <mycroft@gnu.ai.mit.edu> ** **------------------------------------------------------------------------- ** @@ -41,18 +41,11 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -**------------------------------------------------------------------------- +*************************************************************************** */ -#ifndef __NetBSD__ -#ifdef KERNEL -#include <ncr.h> -#else /* KERNEL */ -#define NNCR 1 -#endif /* KERNEL */ -#endif /* !__NetBSD__ */ - #define NCR_VERSION (2) +#define MAX_UNITS (16) /*========================================================== @@ -107,7 +100,7 @@ */ #ifndef SCSI_NCR_MAX_TAGS -#define SCSI_NCR_MAX_TAGS (8) +#define SCSI_NCR_MAX_TAGS (0) #endif /* SCSI_NCR_MAX_TAGS */ /*========================================================== @@ -178,6 +171,7 @@ #include <sys/types.h> #include <sys/param.h> #include <sys/time.h> +#include <sys/proc.h> #ifdef KERNEL #include <sys/systm.h> @@ -190,17 +184,13 @@ #include <vm/vm.h> #endif /* KERNEL */ -#include <i386/pci/ncr_reg.h> +#include <i386/pci/ncrreg.h> #ifdef __NetBSD__ #include <sys/device.h> #include <i386/pci/pcivar.h> -#include <i386/pci/pcireg.h> -#else -#include <i386/pci/pci.h> -#include <i386/pci/pcibios.h> -#include <i386/pci/pci_device.h> #endif +#include <i386/pci/pcireg.h> #include <scsi/scsi_all.h> #include <scsi/scsiconf.h> @@ -369,6 +359,7 @@ int ncr_debug = 0; */ #define CCB_MAGIC (0xf2691ad2) +#define MAX_TAGS (16) /* hard limit */ /*========================================================== ** @@ -394,6 +385,7 @@ int ncr_debug = 0; extern void timeout(); extern void untimeout(); #endif /* KERNEL */ + #define bio_imask biomask #define LUN lu #define TARGET targ #define PRINT_ADDR(xp) printf ("ncr0: targ %d lun %d ",xp->targ,xp->lu) @@ -946,6 +938,8 @@ struct ncb { #ifdef __NetBSD__ struct device sc_dev; struct intrhand sc_ih; +#else + int unit; #endif /*----------------------------------------------- @@ -1195,6 +1189,7 @@ static void ncr_getclock (ncb_p np); static ccb_p ncr_get_ccb (ncb_p np, u_long flags, u_long t,u_long l); static U_INT32 ncr_info (int unit); static void ncr_init (ncb_p np, char * msg, u_long code); +static int ncr_intr (ncb_p np); static void ncr_int_ma (ncb_p np); static void ncr_int_sir (ncb_p np); static void ncr_int_sto (ncb_p np); @@ -1223,11 +1218,9 @@ static void ncr_wakeup (ncb_p np, u_long code); #ifdef __NetBSD__ static int ncr_probe (struct device *, struct device *, void *); static void ncr_attach (struct device *, struct device *, void *); -static int ncr_intr (ncb_p np); #else -static int ncr_probe (pcici_t config_id); -static int ncr_attach (pcici_t config_id); -static int ncr_intr (int dev); +static char* ncr_probe (pcici_t tag, pcidi_t type); +static void ncr_attach (pcici_t tag, int unit); #endif /*========================================================== @@ -1241,9 +1234,8 @@ static int ncr_intr (int dev); #ifdef DIRTY -#include <i386/include/cpufunc.h> - #ifdef __NetBSD__ +#include <i386/include/cpufunc.h> #include <i386/include/pio.h> #include <i386/isa/isareg.h> #define DELAY(x) delay(x) @@ -1326,7 +1318,7 @@ static u_long getirr (void) static char ident[] = - "\n$Id: ncr.c,v 1.4 1994/09/16 13:33:56 davidg Exp $\n"; + "\n$Id: ncr.c,v 2.11 94/10/11 19:03:07 wolf Oct11 $\n"; u_long ncr_version = NCR_VERSION + (u_long) sizeof (struct ncb) @@ -1337,9 +1329,8 @@ u_long ncr_version = NCR_VERSION #ifdef KERNEL #ifndef __NetBSD__ -u_long ncr_units; -u_long nncr=NNCR; -ncb_p ncrp [NNCR]; +u_long nncr=MAX_UNITS; +ncb_p ncrp [MAX_UNITS]; #endif int ncr_cache; /* may _NOT_ be static */ @@ -1371,20 +1362,12 @@ struct cfdriver ncrcd = { #else /* !__NetBSD__ */ -struct pci_driver ncr810_device = { - ncr_probe, - ncr_attach, - NCR_810_ID, - "ncr 53c810 scsi", - ncr_intr -}; +static u_long ncr_count; -struct pci_driver ncr825_device = { +struct pci_driver ncr_device = { ncr_probe, ncr_attach, - NCR_825_ID, - "ncr 53c825 scsi", - ncr_intr + &ncr_count }; #endif /* !__NetBSD__ */ @@ -1429,14 +1412,8 @@ struct scsi_switch ncr_switch = static char *ncr_name (ncb_p np) { static char name[10]; - int idx; - - for (idx = 0; idx < NNCR; idx++) - if (ncrp[idx] == np) { - sprintf(name, "ncr%d", idx); - return (name); - } - return ("ncr?"); + sprintf(name, "ncr%d", np->unit); + return (name); } #endif @@ -3092,7 +3069,7 @@ static void ncr_script_copy_and_bind (struct script *script, ncb_p np) #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_SCRIPT) printf ("%x: <%x>\n", - (u_long)(src-1), opcode); + (unsigned)(src-1), (unsigned)opcode); #endif /* SCSI_NCR_DEBUG */ /* @@ -3245,13 +3222,22 @@ ncr_probe(parent, self, aux) #else /* !__NetBSD__ */ -static int ncr_probe(pcici_t config_id) + +static char* ncr_probe (pcici_t tag, pcidi_t type) { - if (ncr_units >= NNCR) return (-1); - return (ncr_units); + switch (type) { + + case NCR_810_ID: + return ("ncr 53c810 scsi"); + + case NCR_825_ID: + return ("ncr 53c825 wide scsi"); + } + return (0); } #endif /* !__NetBSD__ */ + /*========================================================== ** @@ -3307,39 +3293,36 @@ ncr_attach(parent, self, aux) #else /* !__NetBSD__ */ -static int ncr_attach (pcici_t config_id) +static void ncr_attach (pcici_t config_id, int unit) { - int retval; - ncb_p np = ncrp[ncr_units]; + ncb_p np; +#if ! (__FreeBSD__ >= 2) + extern unsigned bio_imask; +#endif + /* ** allocate structure */ - if (!np) { - np = (ncb_p) malloc (sizeof (struct ncb), - M_DEVBUF, M_NOWAIT); - if (!np) return (0); - ncrp[ncr_units]=np; - } + np = (ncb_p) malloc (sizeof (struct ncb), M_DEVBUF, M_WAITOK); + if (!np) return; + ncrp[unit]=np; /* ** initialize structure. */ bzero (np, sizeof (*np)); + np->unit = unit; /* ** Try to map the controller chip to ** virtual and physical memory. */ - retval = pci_map_mem (config_id, 0x14, &np->vaddr, &np->paddr); - - if (retval) { - printf ("%s: pci_map_mem failed.\n", ncr_name (np)); - return (retval); - }; + if (!pci_map_mem (config_id, 0x14, &np->vaddr, &np->paddr)) + return; #endif /* !__NetBSD__ */ @@ -3409,9 +3392,18 @@ static int ncr_attach (pcici_t config_id) if (ncr_snooptest (np)) { printf ("CACHE INCORRECTLY CONFIGURED.\n"); - return (0); + return; }; +#ifndef __NetBSD__ + /* + ** Install the interrupt handler. + */ + + if (!pci_map_int (config_id, ncr_intr, np, &bio_imask)) + printf ("\tinterruptless mode: reduced performance.\n"); +#endif + /* ** After SCSI devices have been opened, we cannot ** reset the bus safely, so we do it here. @@ -3431,7 +3423,7 @@ static int ncr_attach (pcici_t config_id) ncr_name (np)); DELAY (1000000); #endif - printf ("%s scanning for targets 0..%d ($Revision: 1.5 $)\n", + printf ("%s scanning for targets 0..%d ($Revision: 2.11 $)\n", ncr_name (np), MAX_TARGET-1); /* @@ -3443,7 +3435,7 @@ static int ncr_attach (pcici_t config_id) #ifdef __NetBSD__ np->sc_link.adapter_softc = np; #else /* !__NetBSD__ */ - np->sc_link.adapter_unit = ncr_units; + np->sc_link.adapter_unit = unit; #endif /* !__NetBSD__ */ np->sc_link.adapter_targ = np->myaddr; np->sc_link.adapter = &ncr_switch; @@ -3455,7 +3447,7 @@ static int ncr_attach (pcici_t config_id) scsi_attachdevs (&np->sc_link); #endif /* !__NetBSD__ */ #else /* ANCIENT */ - scsi_attachdevs (ncr_units, np->myaddr, &ncr_switch); + scsi_attachdevs (unit, np->myaddr, &ncr_switch); #endif /* ANCIENT */ /* @@ -3468,10 +3460,7 @@ static int ncr_attach (pcici_t config_id) ** Done. */ -#ifndef __NetBSD__ - ncr_units++; - return(1); -#endif + return; } /*========================================================== @@ -3483,47 +3472,28 @@ static int ncr_attach (pcici_t config_id) **========================================================== */ -#ifdef __NetBSD__ - int ncr_intr(np) ncb_p np; { int n = 0; -#else /* !__NetBSD__ */ - -static int ncr_intr (int dev) -{ - ncb_p np; - int n=0; - - /* - ** Sanity check - */ - assert (dev<NNCR); - if (dev >= ncr_units) return (0); - np = ncrp[dev]; - -#endif /* !__NetBSD__ */ - #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_TINY) printf ("["); #endif /* SCSI_NCR_DEBUG */ - /* - ** Repeat until no outstanding ints - */ - while (INB(nc_istat) & (INTF|SIP|DIP)) { - ncr_exception (np); + if (INB(nc_istat) & (INTF|SIP|DIP)) { + /* + ** Repeat until no outstanding ints + */ + do { + ncr_exception (np); + } while (INB(nc_istat) & (INTF|SIP|DIP)); + n=1; + np->ticks = 100; }; - /* - ** Slowdown timeout function. - */ - if (n) np->ticks = 100; - #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_TINY) printf ("]\n"); #endif /* SCSI_NCR_DEBUG */ @@ -3637,7 +3607,7 @@ static INT32 ncr_start (struct scsi_xfer * xp) if (ncr_debug & DEBUG_TINY) { PRINT_ADDR(xp); printf ("CMD=%x F=%x L=%x ", cmd->opcode, - xp->flags, xp->datalen); + (unsigned)xp->flags, (unsigned) xp->datalen); } #endif /* SCSI_NCR_DEBUG */ @@ -3765,8 +3735,12 @@ static INT32 ncr_start (struct scsi_xfer * xp) cp2 = cp2->next_ccb; if (cp2) continue; cp->tag=lp->lasttag; - PRINT_ADDR(xp); - printf ("using tag #%d.\n", cp->tag); +#ifdef SCSI_NCR_DEBUG + if (ncr_debug & DEBUG_TAGS) { + PRINT_ADDR(xp); + printf ("using tag #%d.\n", cp->tag); + }; +#endif /* SCSI_NCR_DEBUG */ }; } else { cp->tag=0; @@ -3813,7 +3787,7 @@ static INT32 ncr_start (struct scsi_xfer * xp) } /* - ** can be overwritten by ncrstat + ** can be overwritten by ncrcontrol */ switch (np->order) { case M_SIMPLE_TAG: @@ -3991,7 +3965,9 @@ static INT32 ncr_start (struct scsi_xfer * xp) #ifdef SCSI_NCR_DEBUG if(ncr_debug & DEBUG_QUEUE) printf ("%s: queuepos=%d tryoffset=%d.\n", ncr_name (np), - np->squeueput, np->script->startpos[0]-(vtophys(&np->script->tryloop))); + np->squeueput, + (unsigned)(np->script->startpos[0]- + (vtophys(&np->script->tryloop)))); #endif /* SCSI_NCR_DEBUG */ /* @@ -4049,7 +4025,7 @@ static INT32 ncr_start (struct scsi_xfer * xp) if (!(xp->flags & ITSDONE)) { printf ("%s: abortion failed at %x.\n", - ncr_name (np), INL(nc_dsp)); + ncr_name (np), (unsigned) INL(nc_dsp)); ncr_init (np, "timeout", HS_TIMEOUT); }; @@ -4114,7 +4090,7 @@ void ncr_complete (ncb_p np, ccb_p cp) #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_TINY) - printf ("CCB=%x STAT=%x/%x\n", (u_long)cp & 0xfff, + printf ("CCB=%x STAT=%x/%x\n", (unsigned)cp & 0xfff, cp->host_status,cp->scsi_status); #endif /* SCSI_NCR_DEBUG */ @@ -4279,7 +4255,7 @@ void ncr_complete (ncb_p np, ccb_p cp) */ PRINT_ADDR(xp); printf ("COMMAND FAILED (%x %x) @%x.\n", - cp->host_status, cp->scsi_status, cp); + cp->host_status, cp->scsi_status, (unsigned)cp); xp->error = XS_DRIVER_STUFFUP; } @@ -4361,6 +4337,8 @@ void ncr_wakeup (ncb_p np, u_long code) ** complete all jobs that are not IDLE. */ + int s=splbio(); + ccb_p cp = &np->ccb; while (cp) { switch (cp->host_status) { @@ -4387,6 +4365,7 @@ void ncr_wakeup (ncb_p np, u_long code) }; cp = cp -> link_ccb; }; + splx (s); } /*========================================================== @@ -4758,7 +4737,7 @@ static void ncr_usercmd (ncb_p np) break; case UC_SETTAGS: - if (np->user.data > SCSI_NCR_MAX_TAGS) + if (np->user.data > MAX_TAGS) break; for (t=0; t<MAX_TARGET; t++) { if (!((np->user.target>>t)&1)) continue; @@ -4895,7 +4874,7 @@ static void ncr_timeout (ncb_p np) if (cp->phys.header.launch.l_paddr == vtophys (&np->script->select)) { printf ("%s: timeout ccb=%x (skip)\n", - ncr_name (np), cp); + ncr_name (np), (unsigned)cp); cp->phys.header.launch.l_paddr = vtophys (&np->script->skip); }; @@ -4967,10 +4946,10 @@ static void ncr_timeout (ncb_p np) */ if (np->mcount == 100) { if (np->imask & (np->imask-1)) { - printf ("%s: please configure intr mask %x.\n", + printf ("%s: uses one of the irq in %x.\n", ncr_name (np), np->imask); } else { - printf ("%s: please configure intr %d.\n", + printf ("%s: please configure irq %d.\n", ncr_name (np), ffs (np->imask)-1); }; np->mcount++; @@ -5022,7 +5001,8 @@ void ncr_exception (ncb_p np) printf ("<%d|%x:%x|%x:%x>", INB(nc_scr0), dstat,sist, - INL(nc_dsp),INL(nc_dbc)); + (unsigned)INL(nc_dsp), + (unsigned)INL(nc_dbc)); #endif /* SCSI_NCR_DEBUG */ if ((dstat==DFE) && (sist==PAR)) return; @@ -5117,7 +5097,8 @@ void ncr_exception (ncb_p np) ncr_name (np), INB (nc_ctest0)&7, dstat, sist, INB (nc_sbcl), INB (nc_sxfer),INB (nc_scntl3), - dsp = INL (nc_dsp), INL (nc_dbc)); + (unsigned) (dsp = INL (nc_dsp)), + (unsigned) INL (nc_dbc)); /*---------------------------------------- ** clean up the dma fifo @@ -5243,7 +5224,7 @@ void ncr_exception (ncb_p np) **========================================================== ** ** There seems to be a bug in the 53c810. -** Although a STO-Interupt is pending, +** Although a STO-interrupt is pending, ** it continues executing script commands. ** But it will fail and interrupt (IID) on ** the next instruction where it's looking @@ -5381,11 +5362,14 @@ static void ncr_int_ma (ncb_p np) */ if (ncr_debug & (DEBUG_TINY|DEBUG_PHASE)) { printf ("P%d%d ",cmd&7, sbcl&7); - printf ("RL=%d D=%d SS0=%x ",rest,delta,ss0); + printf ("RL=%d D=%d SS0=%x ", + (unsigned) rest, (unsigned) delta, ss0); }; if (ncr_debug & DEBUG_PHASE) { printf ("\nCP=%x CP2=%x DSP=%x NXT=%x VDSP=%x CMD=%x ", - cp, np->header.cp, dsp, nxtdsp, vdsp, cmd); + (unsigned)cp, (unsigned)np->header.cp, + (unsigned)dsp, + (unsigned)nxtdsp, (unsigned)vdsp, cmd); }; #endif /* SCSI_NCR_DEBUG */ @@ -5407,7 +5391,10 @@ static void ncr_int_ma (ncb_p np) #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_PHASE) { printf ("OCMD=%x\nTBLP=%x OLEN=%x OADR=%x\n", - vdsp[0] >> 24, tblp, olen, oadr); + (unsigned) (vdsp[0] >> 24), + (unsigned) tblp, + (unsigned) olen, + (unsigned) oadr); }; #endif /* SCSI_NCR_DEBUG */ @@ -5419,7 +5406,8 @@ static void ncr_int_ma (ncb_p np) if (cmd & 0x06) { PRINT_ADDR(cp->xfer); printf ("phase change %d-%d %d@%x resid=%d.\n", - cmd&7, sbcl&7, olen, oadr, rest); + cmd&7, sbcl&7, (unsigned)olen, + (unsigned)oadr, (unsigned)rest); OUTB (nc_dcntl, (STD|NOCOM)); return; @@ -5447,7 +5435,10 @@ static void ncr_int_ma (ncb_p np) PRINT_ADDR(cp->xfer); printf ("newcmd[%d] %x %x %x %x.\n", newcmd - cp->patch, - newcmd[0], newcmd[1], newcmd[2], newcmd[3]); + (unsigned)newcmd[0], + (unsigned)newcmd[1], + (unsigned)newcmd[2], + (unsigned)newcmd[3]); } #endif /* SCSI_NCR_DEBUG */ /* @@ -5941,7 +5932,7 @@ void ncr_int_sir (ncb_p np) PRINT_ADDR(cp->xfer); printf ("M_REJECT received (%x:%x).\n", - np->lastmsg, np->msgout[0]); + (unsigned)np->lastmsg, np->msgout[0]); break; case SIR_REJECT_SENT: @@ -5989,10 +5980,10 @@ void ncr_int_sir (ncb_p np) PRINT_ADDR(cp->xfer); printf ("M_DISCONNECT received, but datapointer not saved:\n" - " data=%x save=%x goal=%x.\n", - INL (nc_temp), - np->header.savep, - np->header.goalp); + "\tdata=%x save=%x goal=%x.\n", + (unsigned) INL (nc_temp), + (unsigned) np->header.savep, + (unsigned) np->header.goalp); break; /*-------------------------------------------------------------------- @@ -6047,7 +6038,6 @@ void ncr_int_sir (ncb_p np) ** **----------------------------------------------- */ - /* ** Look for a disconnected job. */ @@ -6209,6 +6199,8 @@ static void ncr_alloc_ccb (ncb_p np, struct scsi_xfer * xp) tp->jump_lcb.l_cmd = (SCR_JUMP); tp->jump_lcb.l_paddr = vtophys (&np->script->abort); np->jump_tcb.l_paddr = vtophys (&tp->jump_tcb); + + ncr_setmaxtags (tp, SCSI_NCR_MAX_TAGS); } /* @@ -6267,7 +6259,7 @@ static void ncr_alloc_ccb (ncb_p np, struct scsi_xfer * xp) #ifdef SCSI_NCR_DEBUG if (ncr_debug & DEBUG_ALLOC) { PRINT_ADDR(xp); - printf ("new ccb @%x.\n", cp); + printf ("new ccb @%x.\n", (unsigned) cp); } #endif /* SCSI_NCR_DEBUG */ @@ -6414,7 +6406,7 @@ static int ncr_scatter #ifdef SCSI_NCR_DEBUG if(ncr_debug & DEBUG_SCATTER) printf("ncr?:\tscattering virtual=0x%x size=%d chunk=%d.\n", - (u_long) vaddr, (u_long) datalen, chunk); + (unsigned) vaddr, (unsigned) datalen, (unsigned) chunk); #endif /* SCSI_NCR_DEBUG */ /* @@ -6456,7 +6448,10 @@ static int ncr_scatter #ifdef SCSI_NCR_DEBUG if(ncr_debug & DEBUG_SCATTER) printf ("\tseg #%d addr=%x size=%d (rest=%d).\n", - segment, segaddr, segsize, datalen); + segment, + (unsigned) segaddr, + (unsigned) segsize, + (unsigned) datalen); #endif /* SCSI_NCR_DEBUG */ phys->data[segment].addr = segaddr; @@ -6466,7 +6461,7 @@ static int ncr_scatter if (datalen) { printf("ncr?: scatter/gather failed (residue=%d).\n", - datalen); + (unsigned) datalen); return (-1); }; @@ -6478,7 +6473,7 @@ static int ncr_scatter ** ** Test the pci bus snoop logic :-( ** -** Has to be called with disabled interupts. +** Has to be called with interrupts disabled. ** ** **========================================================== @@ -6522,17 +6517,17 @@ static int ncr_snooptest (struct ncb* np) */ if (host_wr != ncr_rd) { printf ("CACHE TEST FAILED: host wrote %d, ncr read %d.\n", - host_wr, ncr_rd); + (int) host_wr, (int) ncr_rd); err |= 1; }; if (host_rd != ncr_wr) { printf ("CACHE TEST FAILED: ncr wrote %d, host read %d.\n", - ncr_wr, host_rd); + (int) ncr_wr, (int) host_rd); err |= 2; }; if (ncr_bk != ncr_wr) { printf ("CACHE TEST FAILED: ncr wrote %d, read back %d.\n", - ncr_wr, ncr_bk); + (int) ncr_wr, (int) ncr_bk); err |= 4; }; return (err); @@ -6627,6 +6622,7 @@ static struct table_entry device_tab[] = { {"WangDAT", "Model 2600", "01.7", QUIRK_NOMSG}, {"WangDAT", "Model 3200", "02.2", QUIRK_NOMSG}, + {"WangDAT", "Model 1300", "02.4", QUIRK_NOMSG}, {"", "", "", 0} /* catch all: must be last entry. */ }; @@ -6639,17 +6635,17 @@ static u_long ncr_lookup(char * id) d = id+8; r = p->manufacturer; - while (c=*r++) if (c!=*d++) break; + while ((c=*r++)) if (c!=*d++) break; if (c) continue; d = id+16; r = p->model; - while (c=*r++) if (c!=*d++) break; + while ((c=*r++)) if (c!=*d++) break; if (c) continue; d = id+32; r = p->version; - while (c=*r++) if (c!=*d++) break; + while ((c=*r++)) if (c!=*d++) break; if (c) continue; return (p->info); @@ -6712,3 +6708,5 @@ static void ncr_getclock (ncb_p np) /*=========================================================================*/ #endif /* KERNEL */ + + diff --git a/sys/pci/pci.c b/sys/pci/pci.c index c34523d..396b96f 100644 --- a/sys/pci/pci.c +++ b/sys/pci/pci.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci.c,v 1.5 1994/09/28 16:34:07 se Exp $ +** $Id: pci.c,v 2.12 94/10/11 22:20:37 wolf Oct11 $ ** ** General subroutines for the PCI bus on 80*86 systems. ** pci_configure () @@ -33,27 +33,17 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -**------------------------------------------------------------------------- +*************************************************************************** */ #include <pci.h> #if NPCI > 0 -/*======================================================== -** -** Configuration -** -**======================================================== -*/ - -/* -** maximum number of devices which share one interrupt line -*/ - -#ifndef PCI_MAX_DPI -#define PCI_MAX_DPI (4) -#endif /*PCI_MAX_DPI*/ - +#ifndef __FreeBSD2__ +#if __FreeBSD__ >= 2 +#define __FreeBSD2__ +#endif +#endif /*======================================================== ** @@ -64,101 +54,54 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/malloc.h> #include <sys/errno.h> #include <vm/vm.h> #include <vm/vm_param.h> -#include <i386/isa/icu.h> #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> - -#include <i386/pci/pci.h> -#include <i386/pci/pci_device.h> -#include <i386/pci/pcibios.h> +#include <i386/isa/icu.h> +#include <i386/pci/pcireg.h> /* ** Function prototypes missing in system headers */ -#if ! (__FreeBSD__ >= 2) +#ifndef __FreeBSD2__ extern pmap_t pmap_kernel(void); static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize); -#endif - - -/*======================================================== -** -** Autoconfiguration (of isa bus) -** -**======================================================== -*/ /* -** per slot data structure for passing interupts.. -*/ - -static struct { - u_short number; - u_short isanum; - struct { - int (*proc)(int dev); - dev_t unit; - } vector[PCI_MAX_DPI]; -} pcidata [NPCI]; + * Type of the first (asm) part of an interrupt handler. + */ +typedef void inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss)); /* -** check device ready -*/ -static int pciprobe (struct isa_device *dev) -{ - if (dev->id_unit >= NPCI) - return (0); - - if (!pci_conf_mode()) - return (0); - - return (-1); -} + * Usual type of the second (C) part of an interrupt handler. Some bogus + * ones need the arg to be the interrupt frame (and not a copy of it, which + * is all that is possible in C). + */ +typedef void inthand2_t __P((int unit)); /* -** initialize the driver structure -*/ -static int pciattach (struct isa_device *isdp) -{ - pcidata[isdp->id_unit].number = 0; - pcidata[isdp->id_unit].isanum = ffs(isdp->id_irq)-1; - return (1); -} - -/* -** ISA driver structure -*/ - -struct isa_driver pcidriver = { - pciprobe, - pciattach, - "pci" -}; - -/*======================================================== -** -** Interrupt forward from isa to pci devices. -** -**======================================================== +** XXX @FreeBSD2@ +** +** Unfortunately, the mptr argument is _no_ pointer in 2.0 FreeBSD. +** We would prefer a pointer because it enables us to install +** new interrupt handlers at any time. +** In 2.0 FreeBSD later installed interrupt handlers may change +** the xyz_imask, but this would not be recognized by handlers +** which are installed before. */ +static int +register_intr __P((int intr, int device_id, unsigned int flags, + inthand2_t *handler, unsigned int * mptr, int unit)); +extern unsigned intr_mask[ICU_LEN]; -void pciintr (int unit) -{ - u_short i; - if (unit >= NPCI) return; - for (i=0; i<pcidata[unit].number; i++) { - (void)(*pcidata[unit].vector[i].proc) - (pcidata[unit].vector[i].unit); - }; -} - +#endif /* !__FreeBSD2__ */ /*======================================================== ** @@ -183,52 +126,82 @@ void pciintr (int unit) #define PCI_PMEM_START 0xc0000000 #endif -static vm_offset_t pci_paddr = PCI_PMEM_START; +static vm_offset_t pci_paddr = PCI_PMEM_START; +/*-------------------------------------------------------- +** +** The pci device interrupt lines should have been +** assigned by the bios. But if the bios failed to +** to it, we set it. +** +**-------------------------------------------------------- +*/ + +#ifndef PCI_IRQ +#define PCI_IRQ 0 +#endif + +static u_long pci_irq = PCI_IRQ; + /*--------------------------------------------------------- ** ** pci_configure () ** +** Probe all devices on pci bus and attach them. +** +** May be called more than once. +** Any device is attached only once. +** (Attached devices are remembered in pci_seen.) +** **--------------------------------------------------------- */ static void not_supported (pcici_t tag, u_long type); +static unsigned long pci_seen[NPCI]; + +static int pci_conf_count; + void pci_configure() { u_char device,last_device; - u_short bus,last_bus; + u_short bus; pcici_t tag; pcidi_t type; u_long data; int unit; - int intpin; - int isanum; - int pci_mode; + int pci_mechanism; + int pciint; + int irq; + char* name=0; + int newdev=0; - struct pci_driver *drp; + struct pci_driver *drp=0; struct pci_device *dvp; /* ** check pci bus present */ - pci_mode = pci_conf_mode (); - if (!pci_mode) return; - last_bus = pci_last_bus (); - last_device = pci_mode==1 ? 31 : 15; - + pci_mechanism = pci_conf_mode (); + if (!pci_mechanism) return; + last_device = pci_mechanism==1 ? 31 : 15; + /* ** hello world .. */ + + for (bus=0;bus<NPCI;bus++) { #ifndef PCI_QUIET - printf ("pci*: mode=%d, scanning bus 0..%d, device 0..%d.\n", - pci_mode, last_bus, last_device); + printf ("pci%d: scanning device 0..%d, mechanism=%d.\n", + bus, last_device, pci_mechanism); #endif - - for (bus=0;bus<=last_bus; bus++) for (device=0; device<=last_device; device ++) { + + if (pci_seen[bus] & (1ul << device)) + continue; + tag = pcitag (bus, device, 0); type = pci_conf_read (tag, PCI_ID_REG); @@ -238,137 +211,90 @@ void pci_configure() ** lookup device in ioconfiguration: */ - for (dvp = pci_devtab; dvp->pd_device_id; dvp++) { - if (dvp->pd_device_id == type) break; + for (dvp = pci_devtab; dvp->pd_name; dvp++) { + drp = dvp->pd_driver; + if (!drp) + continue; + if ((name=(*drp->probe)(tag, type))) + break; }; - drp = dvp->pd_driver; - - if (!dvp->pd_device_id) { - /* - ** not found - ** try to dig out some information. - ** - ** By Garrett Wollman - ** <wollman@halloran-eldar.lcs.mit.edu> - */ - - int data = pci_conf_read(tag, PCI_CLASS_REG); - vm_offset_t va; - vm_offset_t pa; - int reg; - - switch (data & PCI_CLASS_MASK) { - - case PCI_CLASS_PREHISTORIC: - if ((data & PCI_SUBCLASS_MASK) - != PCI_SUBCLASS_PREHISTORIC_VGA) - break; - - case PCI_CLASS_DISPLAY: - for (reg = PCI_MAP_REG_START; - reg < PCI_MAP_REG_END; - reg += 4) { - data = pci_map_mem(tag, reg, &va, &pa); - if (data == 0) - printf ( - "pci%d:%d: mapped VGA-like device at physaddr 0x%lx\n", - bus, device, (u_long)pa); - - } - continue; - }; + if (!dvp->pd_name) { #ifndef PCI_QUIET + if (pci_conf_count) + continue; printf("pci%d:%d: ", bus, device); not_supported (tag, type); #endif - }; - - if (!drp) { - if(dvp->pd_flags & PDF_LOADABLE) { - printf("%s: loadable device on pci%d:%d\n", - dvp->pd_name, bus, device); - } continue; - } + }; + pci_seen[bus] |= (1ul << device); /* - ** found it. - ** probe returns the device unit. + ** Get and increment the unit. */ - unit = (*drp->probe) (tag); + unit = (*drp->count)++; - if (unit<0) { - printf ("%s <%s>: probe failed on pci%d:%d\n", - dvp->pd_name, drp->name, bus, device); - continue; - }; + /* + ** ignore device ? + */ + + if (!*name) continue; + + /* + ** Announce this device + */ - printf ("%s%d <%s>", dvp->pd_name, unit, drp->name); + newdev++; + printf ("%s%d <%s>", dvp->pd_name, unit, name); /* - ** install interrupts + ** Get the int pin number (pci interrupt number a-d) + ** from the pci configuration space. */ data = pci_conf_read (tag, PCI_INTERRUPT_REG); - intpin = PCI_INTERRUPT_PIN_EXTRACT(data); - if (intpin) { - int idx=NPCI; + pciint = PCI_INTERRUPT_PIN_EXTRACT(data); - /* - ** Usage of int line register (if set by bios) - ** Matt Thomas <thomas@lkg.dec.com> - */ + if (pciint) { - isanum = PCI_INTERRUPT_LINE_EXTRACT(data); - if (isanum) { - - /* - ** @INT@ FIXME!!! - ** - ** Should try to use "register_interupt" - ** at this point. - */ - - printf (" line=%d", isanum); - for (idx = 0; idx < NPCI; idx++) { - if (pcidata[idx].isanum == isanum) - break; - }; - }; + printf (" int %c", 0x60+pciint); /* - ** Or take the device number as index ... + ** If the interrupt line register is not set, + ** set it now from PCI_IRQ. */ - if (idx >= NPCI) idx = device; + if (!(PCI_INTERRUPT_LINE_EXTRACT(data))) { + + irq = pci_irq & 0x0f; + pci_irq >>= 4; + + data = PCI_INTERRUPT_LINE_INSERT(data, irq); + printf (" (config)"); + pci_conf_write (tag, PCI_INTERRUPT_REG, data); + }; + + irq = PCI_INTERRUPT_LINE_EXTRACT(data); /* - ** And install the interrupt. + ** If it's zero, the isa irq number is unknown, + ** and we cannot bind the pci interrupt to isa. */ - if (idx<NPCI) { - u_short entry = pcidata[idx].number; - printf (" irq %c", 0x60+intpin); - if (entry < PCI_MAX_DPI) { - pcidata[idx].vector[entry].proc = drp->intr; - pcidata[idx].vector[entry].unit = unit; - entry++; - }; - printf (" isa=%d [%d]",pcidata[idx].isanum, entry); - pcidata[idx].number=entry; - } else { - printf (" no int"); - }; + if (irq) + printf (" irq %d", irq); + else + printf (" not bound"); }; - + /* ** enable memory access */ - data = pci_conf_read (tag, PCI_COMMAND_STATUS_REG) - & 0xffff | PCI_COMMAND_MEM_ENABLE; + data = (pci_conf_read (tag, PCI_COMMAND_STATUS_REG) + & 0xffff) | PCI_COMMAND_MEM_ENABLE; pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data); @@ -380,13 +306,16 @@ void pci_configure() printf (" on pci%d:%d\n", bus, device); - (void) (*drp->attach) (tag); - } + (*drp->attach) (tag, unit); + }; + }; #ifndef PCI_QUIET - printf ("pci uses physical addresses from 0x%lx to 0x%lx\n", + if (newdev) + printf ("pci uses physical addresses from 0x%lx to 0x%lx\n", (u_long)PCI_PMEM_START, (u_long)pci_paddr); #endif + pci_conf_count++; } /*----------------------------------------------------------------------- @@ -403,7 +332,8 @@ int pci_map_port (pcici_t tag, u_long reg, u_short* pa) /* ** @MAPIO@ not yet implemented. */ - return (ENOSYS); + printf ("pci_map_port failed: not yet implemented\n"); + return (0); } /*----------------------------------------------------------------------- @@ -425,8 +355,11 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) ** sanity check */ - if (reg <= PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) - return (EINVAL); + if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) { + printf ("pci_map_mem failed: bad register=0x%x\n", + (unsigned)reg); + return (0); + }; /* ** get size and type of memory @@ -445,7 +378,9 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) break; default: /* unknown */ - return (EINVAL); + printf ("pci_map_mem failed: bad memory type=0x%x\n", + (unsigned) data); + return (0); }; /* @@ -455,18 +390,19 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) vsize = round_page (-(data & PCI_MAP_MEMORY_ADDRESS_MASK)); - if (!vsize) return (EINVAL); - + if (!vsize) return (0); + /* ** align physical address to virtual size */ - if (data = pci_paddr % vsize) + if ((data = pci_paddr % vsize)) pci_paddr += vsize - data; - vaddr = pmap_mapdev (pci_paddr, vsize); + vaddr = (vm_offset_t) pmap_mapdev (pci_paddr, vsize); + - if (!vaddr) return (EINVAL); + if (!vaddr) return (0); #ifndef PCI_QUIET /* @@ -474,7 +410,7 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) */ printf ("\treg%d: virtual=0x%lx physical=0x%lx\n", - reg, (u_long)vaddr, (u_long)pci_paddr); + (unsigned) reg, (u_long)vaddr, (u_long)pci_paddr); #endif /* @@ -496,50 +432,77 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) pci_paddr += vsize; - return (0); + return (1); } -/*----------------------------------------------------------- +/*----------------------------------------------------------------------- ** -** Mapping of physical to virtual memory +** Map pci interrupts to isa interrupts. ** -**----------------------------------------------------------- +**----------------------------------------------------------------------- */ -#if ! (__FreeBSD__ >= 2) +static unsigned int pci_int_mask [16]; -extern vm_map_t kernel_map; - -static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize) +int pci_map_int (pcici_t tag, int(*func)(), void* arg, unsigned* maskptr) { - vm_offset_t vaddr,value; - u_long result; + int irq; + unsigned mask; - vaddr = vm_map_min (kernel_map); + irq = PCI_INTERRUPT_LINE_EXTRACT( + pci_conf_read (tag, PCI_INTERRUPT_REG)); - result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0, - &vaddr, vsize, TRUE); - - if (result != KERN_SUCCESS) { - printf (" vm_map_find failed(%d)\n", result); + if (irq >= 16 || irq <= 0) { + printf ("pci_map_int failed: no int line set.\n"); return (0); - }; + } + + mask = 1ul << irq; + + if (!maskptr) + maskptr = &pci_int_mask[irq]; + + INTRMASK (*maskptr, mask); + register_intr( + irq, /* isa irq */ + 0, /* deviced?? */ + 0, /* flags? */ + (inthand2_t*) func, /* handler */ +#ifdef __FreeBSD2__ + *maskptr, /* mask */ +#else + maskptr, /* mask pointer */ +#endif + (int) arg); /* handler arg */ + +#ifdef __FreeBSD2__ /* - ** map physical + ** XXX See comment at beginning of file. + ** + ** Have to update all the interrupt masks ... Grrrrr!!! */ - - value = vaddr; - while (vsize >= NBPG) { - pmap_enter (pmap_kernel(), vaddr, paddr, - VM_PROT_READ|VM_PROT_WRITE, TRUE); - vaddr += NBPG; - paddr += NBPG; - vsize -= NBPG; + { + unsigned * mp = &intr_mask[0]; + /* + ** update the isa interrupt masks. + */ + for (mp=&intr_mask[0]; mp<&intr_mask[ICU_LEN]; mp++) + if (*mp & *maskptr) + *mp |= mask; + /* + ** update the pci interrupt masks. + */ + for (mp=&pci_int_mask[0]; mp<&pci_int_mask[16]; mp++) + if (*mp & *maskptr) + *mp |= mask; }; - return (value); -} #endif + + INTREN (mask); + + return (1); +} /*----------------------------------------------------------- ** @@ -554,7 +517,7 @@ struct vt { static struct vt VendorTable[] = { {0x1002, "ATI TECHNOLOGIES INC"}, - {0x1011, "DIGITAL EQUIPMENT CORP."}, + {0x1011, "DIGITAL EQUIPMENT CORPORATION"}, {0x101A, "NCR"}, {0x102B, "MATROX"}, {0x1045, "OPTI"}, @@ -604,18 +567,107 @@ void not_supported (pcici_t tag, u_long type) case 1: case 5: - printf (" map(%lx): io(%lx)\n", reg, data & ~3); + printf (" map(%x): io(%lx)\n", + reg, data & ~3); break; case 0: - printf (" map(%lx): mem32(%lx)\n", reg, data & ~7); + printf (" map(%x): mem32(%lx)\n", + reg, data & ~7); break; case 2: - printf (" map(%lx): mem20(%lx)\n", reg, data & ~7); + printf (" map(%x): mem20(%lx)\n", + reg, data & ~7); break; case 4: - printf (" map(%lx): mem64(%lx)\n", reg, data & ~7); + printf (" map(%x): mem64(%lx)\n", + reg, data & ~7); break; } } } -#endif + +#ifndef __FreeBSD2__ +/*----------------------------------------------------------- +** +** Mapping of physical to virtual memory +** +**----------------------------------------------------------- +*/ + +extern vm_map_t kernel_map; + +static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize) +{ + vm_offset_t vaddr,value; + u_long result; + + vaddr = vm_map_min (kernel_map); + + result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0, + &vaddr, vsize, TRUE); + + if (result != KERN_SUCCESS) { + printf (" vm_map_find failed(%d)\n", result); + return (0); + }; + + /* + ** map physical + */ + + value = vaddr; + while (vsize >= NBPG) { + pmap_enter (pmap_kernel(), vaddr, paddr, + VM_PROT_READ|VM_PROT_WRITE, TRUE); + vaddr += NBPG; + paddr += NBPG; + vsize -= NBPG; + }; + return (value); +} + +/*------------------------------------------------------------ +** +** Emulate the register_intr() function of FreeBSD 2.0 +** +** requires a patch: +** FreeBSD 2.0: "/sys/i386/isa/vector.s" +** 386bsd0.1: "/sys/i386/isa/icu.s" +** 386bsd1.0: Please ask Jesus Monroy Jr. +** +**------------------------------------------------------------ +*/ + +#include <machine/segments.h> + +int pci_int_unit [16]; +inthand2_t* (pci_int_hdlr [16]); +unsigned int * pci_int_mptr [16]; +unsigned int pci_int_count[16]; + +extern void + Vpci3(), Vpci4(), Vpci5(), Vpci6(), Vpci7(), Vpci8(), Vpci9(), + Vpci10(), Vpci11(), Vpci12(), Vpci13(), Vpci14(), Vpci15(); + +static inthand_t* pci_int_glue[16] = { + 0, 0, 0, Vpci3, Vpci4, Vpci5, Vpci6, Vpci7, Vpci8, + Vpci9, Vpci10, Vpci11, Vpci12, Vpci13, Vpci14, Vpci15 }; + +static int +register_intr __P((int intr, int device_id, unsigned int flags, + inthand2_t *handler, unsigned int* mptr, int unit)) +{ + if (intr >= 16 || intr <= 2) + return (EINVAL); + if (pci_int_hdlr [intr]) + return (EBUSY); + + pci_int_hdlr [intr] = handler; + pci_int_unit [intr] = unit; + pci_int_mptr [intr] = mptr; + + setidt(NRSVIDT + intr, pci_int_glue[intr], SDT_SYS386IGT, SEL_KPL); + return (0); +} +#endif /* __FreeBSD2__ */ +#endif /* NPCI */ |