diff options
author | jhay <jhay@FreeBSD.org> | 2001-01-30 10:02:10 +0000 |
---|---|---|
committer | jhay <jhay@FreeBSD.org> | 2001-01-30 10:02:10 +0000 |
commit | 306e6760c1d526abaababcaf26ca7c00f45d0ef3 (patch) | |
tree | fbe14b49ea00192f79b9178d57d2ad8346eb5060 /sys/dev/sr/if_sr_pci.c | |
parent | 11691d89b0272451da2f382c49e0d48bced70b65 (diff) | |
download | FreeBSD-src-306e6760c1d526abaababcaf26ca7c00f45d0ef3.zip FreeBSD-src-306e6760c1d526abaababcaf26ca7c00f45d0ef3.tar.gz |
Newbusify the sr device and move it to its new location.
Diffstat (limited to 'sys/dev/sr/if_sr_pci.c')
-rw-r--r-- | sys/dev/sr/if_sr_pci.c | 246 |
1 files changed, 178 insertions, 68 deletions
diff --git a/sys/dev/sr/if_sr_pci.c b/sys/dev/sr/if_sr_pci.c index b8ac2cc..5b2b95a 100644 --- a/sys/dev/sr/if_sr_pci.c +++ b/sys/dev/sr/if_sr_pci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996 John Hay. + * Copyright (c) 1996 - 2001 John Hay. * Copyright (c) 1996 SDL Communications, Inc. * All rights reserved. * @@ -30,109 +30,219 @@ * $FreeBSD$ */ -#ifdef COMPILING_LINT -#warning "The sr pci driver is broken and is not compiled with LINT" -#else - -#include "sr.h" #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/malloc.h> +#include <sys/bus.h> +#include <machine/bus.h> +#include <machine/resource.h> +#include <machine/bus_pio.h> +#include <machine/bus_memio.h> +#include <sys/rman.h> #include <pci/pcivar.h> +#include <machine/md_var.h> -#ifndef COMPAT_OLDPCI -#error "The sr device requires the old pci compatibility shims" -#endif +#include <dev/ic/hd64570.h> +#include <dev/sr/if_srregs.h> #ifndef BUGGY #define BUGGY 0 #endif -/* - * The must match with the real functions in if_sr.c - */ -extern void *srattach_pci(int unit, - vm_offset_t plx_vaddr, - vm_offset_t sca_vaddr); -extern void srintr_hc(void *hc); - -static const char *sr_pci_probe(pcici_t tag, pcidi_t type); -static void sr_pci_attach(pcici_t config_id, int unit); +static int sr_pci_probe(device_t); +static int sr_pci_attach(device_t); -static u_long src_count = NSR; +static device_method_t sr_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, sr_pci_probe), + DEVMETHOD(device_attach, sr_pci_attach), + DEVMETHOD(device_detach, sr_detach), + { 0, 0 } +}; -static struct pci_device sr_pci_driver = -{ - "src", - sr_pci_probe, - sr_pci_attach, - &src_count, - NULL +static driver_t sr_pci_driver = { + "sr", + sr_pci_methods, + sizeof(struct sr_hardc), }; -COMPAT_PCI_DRIVER (sr_pci, sr_pci_driver); +DRIVER_MODULE(if_sr, pci, sr_pci_driver, sr_devclass, 0, 0); + +static u_int src_get8_mem(u_int base, u_int off); +static u_int src_get16_mem(u_int base, u_int off); +static void src_put8_mem(u_int base, u_int off, u_int val); +static void src_put16_mem(u_int base, u_int off, u_int val); -static const char * -sr_pci_probe(pcici_t tag, pcidi_t type) +static int +sr_pci_probe(device_t device) { + u_int32_t type = pci_get_devid(device); + switch(type) { case 0x556812aa: - return ("RISCom/N2pci"); + device_set_desc(device, "RISCom/N2pci"); + return (0); break; case 0x55684778: case 0x55684877: /* * XXX This can probably be removed sometime. */ - return ("RISCom/N2pci (old id)"); + device_set_desc(device, "RISCom/N2pci (old id)"); + return (0); break; default: break; } - return (0); + return (ENXIO); } -static void -sr_pci_attach(pcici_t config_id, int unit) +static int +sr_pci_attach(device_t device) { - void *hc; -#if BUGGY > 0 - u_int *fecr; -#endif - vm_offset_t plx_vaddr, plx_paddr, sca_vaddr, sca_paddr; - -#if BUGGY > 0 - printf("srp: ID %x\n", pci_conf_read(config_id, 0)); - printf("srp: BADR0 %x\n", pci_conf_read(config_id, 0x10)); - printf("srp: BADR1 %x\n", pci_conf_read(config_id, 0x18)); -#endif - if(!pci_map_mem(config_id, 0x10, &plx_vaddr, &plx_paddr)) { - printf("srp: map failed.\n"); - return; + int numports; + u_int fecr, *fecrp; + struct sr_hardc *hc; + + hc = (struct sr_hardc *)device_get_softc(device); + bzero(hc, sizeof(struct sr_hardc)); + + if (sr_allocate_plx_memory(device, 0x10, 1)) + goto errexit; + + if (sr_allocate_memory(device, 0x18, 1)) + goto errexit; + + if (sr_allocate_irq(device, 0, 1)) + goto errexit; + + hc->plx_base = rman_get_virtual(hc->res_plx_memory); + hc->sca_base = (vm_offset_t)rman_get_virtual(hc->res_memory); + + hc->cunit = device_get_unit(device); + + + /* + * Configure the PLX. This is magic. I'm doing it just like I'm told + * to. :-) + * + * offset + * 0x00 - Map Range - Mem-mapped to locate anywhere + * 0x04 - Re-Map - PCI address decode enable + * 0x18 - Bus Region - 32-bit bus, ready enable + * 0x1c - Master Range - include all 16 MB + * 0x20 - Master RAM - Map SCA Base at 0 + * 0x28 - Master Remap - direct master memory enable + * 0x68 - Interrupt - Enable interrupt (0 to disable) + * + * Note: This is "cargo cult" stuff. - jrc + */ + *((u_int *)(hc->plx_base + 0x00)) = 0xfffff000; + *((u_int *)(hc->plx_base + 0x04)) = 1; + *((u_int *)(hc->plx_base + 0x18)) = 0x40030043; + *((u_int *)(hc->plx_base + 0x1c)) = 0xff000000; + *((u_int *)(hc->plx_base + 0x20)) = 0; + *((u_int *)(hc->plx_base + 0x28)) = 0xe9; + *((u_int *)(hc->plx_base + 0x68)) = 0x10900; + + /* + * Get info from card. + * + * Only look for the second port if the first exists. Too many things + * will break if we have only a second port. + */ + fecrp = (u_int *)(hc->sca_base + SR_FECR); + fecr = *fecrp; + numports = 0; + + if (((fecr & SR_FECR_ID0) >> SR_FE_ID0_SHFT) != SR_FE_ID_NONE) { + numports++; + if (((fecr & SR_FECR_ID1) >> SR_FE_ID1_SHFT) != SR_FE_ID_NONE) + numports++; } -#if BUGGY > 0 - printf("srp: vaddr %x, paddr %x\n", plx_vaddr, plx_paddr); -#endif - if(!pci_map_mem(config_id, 0x18, &sca_vaddr, &sca_paddr)) { - printf("srp: map failed.\n"); - return; + if (numports == 0) + goto errexit; + + hc->numports = numports; + hc->cardtype = SR_CRD_N2PCI; + + hc->src_put8 = src_put8_mem; + hc->src_put16 = src_put16_mem; + hc->src_get8 = src_get8_mem; + hc->src_get16 = src_get16_mem; + + /* + * Malloc area for tx and rx buffers. For now allocate SRC_WIN_SIZ + * (16k) for each buffer. + * + * Allocate the block below 16M because the N2pci card can only access + * 16M memory at a time. + * + * (We could actually allocate a contiguous block above the 16MB limit, + * but this would complicate card programming more than we want to + * right now -jrc) + */ + hc->memsize = 2 * hc->numports * SRC_WIN_SIZ; + hc->mem_start = contigmalloc(hc->memsize, + M_DEVBUF, + M_NOWAIT, + 0ul, + 0xfffffful, + 0x10000, + 0x1000000); + + if (hc->mem_start == NULL) { + printf("src%d: pci: failed to allocate buffer space.\n", + hc->cunit); + goto errexit; } -#if BUGGY > 0 - printf("srp: vaddr %x, paddr %x\n", sca_vaddr, sca_paddr); - fecr = (u_int *)(sca_vaddr + 0x200); - printf("srp: FECR %x\n", *fecr); -#endif + hc->winmsk = 0xffffffff; + hc->mem_end = (caddr_t)((u_int)hc->mem_start + hc->memsize); + hc->mem_pstart = kvtop(hc->mem_start); + bzero(hc->mem_start, hc->memsize); - hc = srattach_pci(unit, plx_vaddr, sca_vaddr); - if(!hc) - return; + *fecrp = SR_FECR_DTR0 + | SR_FECR_DTR1 + | SR_FECR_TE0 + | SR_FECR_TE1; - if(!pci_map_int(config_id, srintr_hc, (void *)hc, &net_imask)) { - free(hc, M_DEVBUF); - return; - } + if (sr_attach(device)) + goto errexit; + + return (0); +errexit: + sr_deallocate_resources(device); + return (ENXIO); +} + +/* + * I/O for PCI N2 card(s) + */ +#define SRC_PCI_SCA_REG(y) ((y & 2) ? ((y & 0xfd) + 0x100) : y) + +static u_int +src_get8_mem(u_int base, u_int off) +{ + return *((u_char *)(base + SRC_PCI_SCA_REG(off))); +} + +static u_int +src_get16_mem(u_int base, u_int off) +{ + return *((u_short *)(base + SRC_PCI_SCA_REG(off))); +} + +static void +src_put8_mem(u_int base, u_int off, u_int val) +{ + *((u_char *)(base + SRC_PCI_SCA_REG(off))) = (u_char)val; +} + +static void +src_put16_mem(u_int base, u_int off, u_int val) +{ + *((u_short *)(base + SRC_PCI_SCA_REG(off))) = (u_short)val; } -#endif |