diff options
Diffstat (limited to 'sys/dev/sr/if_sr.c')
-rw-r--r-- | sys/dev/sr/if_sr.c | 846 |
1 files changed, 244 insertions, 602 deletions
diff --git a/sys/dev/sr/if_sr.c b/sys/dev/sr/if_sr.c index a52369b..d28522a 100644 --- a/sys/dev/sr/if_sr.c +++ b/sys/dev/sr/if_sr.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. * @@ -47,10 +47,9 @@ * */ -#include "sr.h" #include "opt_netgraph.h" #ifdef NETGRAPH -#include <i386/isa/if_sr.h> +#include <dev/sr/if_sr.h> #endif /* NETGRAPH */ #include <sys/param.h> @@ -61,6 +60,11 @@ #include <sys/sockio.h> #include <sys/socket.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 <net/if.h> #ifdef NETGRAPH @@ -73,9 +77,8 @@ #include <machine/md_var.h> -#include <i386/isa/if_srregs.h> -#include <i386/isa/ic/hd64570.h> -#include <i386/isa/isa_device.h> +#include <dev/ic/hd64570.h> +#include <dev/sr/if_srregs.h> #ifdef NETGRAPH #include <netgraph/ng_message.h> @@ -83,10 +86,6 @@ #endif /* NETGRAPH */ /* #define USE_MODEMCK */ -#ifndef COMPAT_OLDISA -#error "The sr device requires the old isa compatibility shims" -#endif - #ifndef BUGGY #define BUGGY 0 #endif @@ -95,67 +94,12 @@ #define PPP_HEADER_LEN 4 #endif /* NETGRAPH */ -/* - * These macros are used to hide the difference between the way the - * ISA N2 cards and the PCI N2 cards access the Hitachi 64570 SCA. - */ -#define SRC_GET8(base,off) (*hc->src_get8)(base,(u_int)&off) -#define SRC_GET16(base,off) (*hc->src_get16)(base,(u_int)&off) -#define SRC_PUT8(base,off,d) (*hc->src_put8)(base,(u_int)&off,d) -#define SRC_PUT16(base,off,d) (*hc->src_put16)(base,(u_int)&off,d) - -/* - * These macros enable/disable the DPRAM and select the correct - * DPRAM page. - */ -#define SRC_GET_WIN(addr) ((addr >> SRC_WIN_SHFT) & SR_PG_MSK) - -#define SRC_SET_ON(iobase) outb(iobase+SR_PCR, \ - SR_PCR_MEM_WIN | inb(iobase+SR_PCR)) -#define SRC_SET_MEM(iobase,win) outb(iobase+SR_PSR, SRC_GET_WIN(win) | \ - (inb(iobase+SR_PSR) & ~SR_PG_MSK)) -#define SRC_SET_OFF(iobase) outb(iobase+SR_PCR, \ - ~SR_PCR_MEM_WIN & inb(iobase+SR_PCR)) - -/* - * Define the hardware (card information) structure needed to keep - * track of the device itself... There is only one per card. - */ -struct sr_hardc { - struct sr_hardc *next; /* PCI card linkage */ - struct sr_softc *sc; /* software channels */ - int cunit; /* card w/in system */ - - u_short iobase; /* I/O Base Address */ - int cardtype; - int numports; /* # of ports on cd */ - int mempages; - u_int memsize; /* DPRAM size: bytes */ - u_int winmsk; - vm_offset_t sca_base; - vm_offset_t mem_pstart; /* start of buffer */ - caddr_t mem_start; /* start of DP RAM */ - caddr_t mem_end; /* end of DP RAM */ - caddr_t plx_base; - - sca_regs *sca; /* register array */ - - /* - * We vectorize the following functions to allow re-use between the - * ISA card's needs and those of the PCI card. - */ - void (*src_put8)(u_int base, u_int off, u_int val); - void (*src_put16)(u_int base, u_int off, u_int val); - u_int (*src_get8)(u_int base, u_int off); - u_int (*src_get16)(u_int base, u_int off); -}; - static int next_sc_unit = 0; #ifndef NETGRAPH +#ifdef USE_MODEMCK static int sr_watcher = 0; +#endif #endif /* NETGRAPH */ -static struct sr_hardc sr_hardc[NSR]; -static struct sr_hardc *sr_hardc_pci; /* * Define the software interface for the card... There is one for @@ -228,39 +172,6 @@ struct sr_softc { #endif /* NETGRAPH */ /* - * List of valid interrupt numbers for the N2 ISA card. - */ -static int sr_irqtable[16] = { - 0, /* 0 */ - 0, /* 1 */ - 0, /* 2 */ - 1, /* 3 */ - 1, /* 4 */ - 1, /* 5 */ - 0, /* 6 */ - 1, /* 7 */ - 0, /* 8 */ - 0, /* 9 */ - 1, /* 10 */ - 1, /* 11 */ - 1, /* 12 */ - 0, /* 13 */ - 0, /* 14 */ - 1 /* 15 */ -}; - -static int srprobe(struct isa_device *id); -static int srattach_isa(struct isa_device *id); - -struct isa_driver srdriver = { - INTR_TYPE_NET, - srprobe, - srattach_isa, - "sr" -}; -COMPAT_ISA_DRIVER(sr, srdriver); - -/* * Baud Rate table for Sync Mode. * Each entry consists of 3 elements: * Baud Rate (x100) , TMC, BR @@ -308,13 +219,14 @@ int etc0vals[] = { }; #endif -struct sr_hardc *srattach_pci(int unit, vm_offset_t plx_vaddr, - vm_offset_t sca_vaddr); -void srintr_hc(struct sr_hardc *hc); - -static ointhand2_t srintr; +devclass_t sr_devclass; +#ifndef NETGRAPH +MODULE_DEPEND(if_sr, sppp, 1, 1, 1); +#else +MODULE_DEPEND(ng_sync_sr, netgraph, 1, 1, 1); +#endif -static int srattach(struct sr_hardc *hc); +static void srintr(void *arg); static void sr_xmit(struct sr_softc *sc); #ifndef NETGRAPH static void srstart(struct ifnet *ifp); @@ -340,20 +252,13 @@ static void sr_dmac_intr(struct sr_hardc *hc, u_char isr); static void sr_msci_intr(struct sr_hardc *hc, u_char isr); static void sr_timer_intr(struct sr_hardc *hc, u_char isr); #ifndef NETGRAPH +#ifdef USE_MODEMCK static void sr_modemck(void *x); +#endif #else static void sr_modemck(struct sr_softc *x); #endif /* NETGRAPH */ -static u_int src_get8_io(u_int base, u_int off); -static u_int src_get16_io(u_int base, u_int off); -static void src_put8_io(u_int base, u_int off, u_int val); -static void src_put16_io(u_int base, u_int off, u_int val); -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); - #ifdef NETGRAPH static void ngsr_watchdog_frame(void * arg); static void ngsr_init(void* ignored); @@ -386,495 +291,99 @@ static int ngsr_done_init = 0; #endif /* NETGRAPH */ /* - * I/O for ISA N2 card(s) - */ -#define SRC_REG(iobase,y) ((((y) & 0xf) + (((y) & 0xf0) << 6) + \ - (iobase)) | 0x8000) - -static u_int -src_get8_io(u_int base, u_int off) -{ - return inb(SRC_REG(base, off)); -} - -static u_int -src_get16_io(u_int base, u_int off) -{ - return inw(SRC_REG(base, off)); -} - -static void -src_put8_io(u_int base, u_int off, u_int val) -{ - outb(SRC_REG(base, off), val); -} - -static void -src_put16_io(u_int base, u_int off, u_int val) -{ - outw(SRC_REG(base, off), val); -} - -/* - * 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; -} - -/* - * Probe for an ISA card. If it is there, size its memory. Then get the - * rest of its information and fill it in. - */ -static int -srprobe(struct isa_device *id) -{ - struct sr_hardc *hc = &sr_hardc[id->id_unit]; - u_int pgs, i, tmp; - u_short port; - u_short *smem; - u_char mar; - sca_regs *sca = 0; - - /* - * Now see if the card is realy there. - */ - hc->cardtype = SR_CRD_N2; - - /* - * We have to fill these in early because the SRC_PUT* and SRC_GET* - * macros use them. - */ - hc->src_get8 = src_get8_io; - hc->src_get16 = src_get16_io; - hc->src_put8 = src_put8_io; - hc->src_put16 = src_put16_io; - - hc->sca = 0; - port = id->id_iobase; - hc->numports = NCHAN; /* assumed # of channels on the card */ - - if (id->id_flags & SR_FLAGS_NCHAN_MSK) - hc->numports = id->id_flags & SR_FLAGS_NCHAN_MSK; - - outb(port + SR_PCR, 0); /* turn off the card */ - - /* - * Next, we'll test the Base Address Register to retension of - * data... ... seeing if we're *really* talking to an N2. - */ - for (i = 0; i < 0x100; i++) { - outb(port + SR_BAR, i); - inb(port + SR_PCR); - tmp = inb(port + SR_BAR); - if (tmp != i) { - printf("sr%d: probe failed BAR %x, %x.\n", - id->id_unit, i, tmp); - return 0; - } - } - - /* - * Now see if we can see the SCA. - */ - outb(port + SR_PCR, SR_PCR_SCARUN | inb(port + SR_PCR)); - SRC_PUT8(port, sca->wcrl, 0); - SRC_PUT8(port, sca->wcrm, 0); - SRC_PUT8(port, sca->wcrh, 0); - SRC_PUT8(port, sca->pcr, 0); - SRC_PUT8(port, sca->msci[0].tmc, 0); - inb(port); - - tmp = SRC_GET8(port, sca->msci[0].tmc); - if (tmp != 0) { - printf("sr%d: Error reading SCA 0, %x\n", id->id_unit, tmp); - return 0; - } - SRC_PUT8(port, sca->msci[0].tmc, 0x5A); - inb(port); - - tmp = SRC_GET8(port, sca->msci[0].tmc); - if (tmp != 0x5A) { - printf("sr%d: Error reading SCA 0x5A, %x\n", id->id_unit, tmp); - return 0; - } - SRC_PUT16(port, sca->dmac[0].cda, 0); - inb(port); - - tmp = SRC_GET16(port, sca->dmac[0].cda); - if (tmp != 0) { - printf("sr%d: Error reading SCA 0, %x\n", id->id_unit, tmp); - return 0; - } - SRC_PUT16(port, sca->dmac[0].cda, 0x55AA); - inb(port); - - tmp = SRC_GET16(port, sca->dmac[0].cda); - if (tmp != 0x55AA) { - printf("sr%d: Error reading SCA 0x55AA, %x\n", - id->id_unit, tmp); - return 0; - } - /* - * OK, the board's interface registers seem to work. Now we'll see - * if the Dual-Ported RAM is fully accessible... - */ - outb(port + SR_PCR, SR_PCR_EN_VPM | SR_PCR_ISA16); - outb(port + SR_PSR, SR_PSR_WIN_16K); - - /* - * Take the kernel "virtual" address supplied to us and convert - * it to a "real" address. Then program the card to use that. - */ - mar = (kvtop(id->id_maddr) >> 16) & SR_PCR_16M_SEL; - outb(port + SR_PCR, mar | inb(port + SR_PCR)); - mar = kvtop(id->id_maddr) >> 12; - outb(port + SR_BAR, mar); - outb(port + SR_PCR, inb(port + SR_PCR) | SR_PCR_MEM_WIN); - smem = (u_short *)id->id_maddr; /* DP RAM Address */ - - /* - * Here we will perform the memory scan to size the device. - * - * This is done by marking each potential page with a magic number. - * We then loop through the pages looking for that magic number. As - * soon as we no longer see that magic number, we'll quit the scan, - * knowing that no more memory is present. This provides the number - * of pages present on the card. - * - * Note: We're sizing 16K memory granules. - */ - for (i = 0; i <= SR_PSR_PG_SEL; i++) { - outb(port + SR_PSR, - (inb(port + SR_PSR) & ~SR_PSR_PG_SEL) | i); - - *smem = 0xAA55; - } - - for (i = 0; i <= SR_PSR_PG_SEL; i++) { - outb(port + SR_PSR, - (inb(port + SR_PSR) & ~SR_PSR_PG_SEL) | i); - - if (*smem != 0xAA55) { - /* - * If we have less than 64k of memory, give up. That - * is 4 x 16k pages. - */ - if (i < 4) { - printf("sr%d: Bad mem page %d, mem %x, %x.\n", - id->id_unit, i, 0xAA55, *smem); - return 0; - } - break; - } - *smem = i; - } - - hc->mempages = i; - hc->memsize = i * SRC_WIN_SIZ; - hc->winmsk = SRC_WIN_MSK; - pgs = i; /* final count of 16K pages */ - - /* - * This next loop erases the contents of that page in DPRAM - */ - for (i = 0; i <= pgs; i++) { - outb(port + SR_PSR, - (inb(port + SR_PSR) & ~SR_PSR_PG_SEL) | i); - bzero(smem, SRC_WIN_SIZ); - } - - SRC_SET_OFF(port); - - /* - * We have a card here, fill in what we can. - */ - id->id_msize = SRC_WIN_SIZ; - hc->iobase = id->id_iobase; - hc->sca_base = id->id_iobase; - hc->mem_start = id->id_maddr; - hc->mem_end = (id->id_maddr + id->id_msize) - 1; - hc->mem_pstart = 0; - hc->cunit = id->id_unit; - - /* - * Do a little sanity check. - */ - if (sr_irqtable[ffs(id->id_irq) - 1] == 0) - printf("sr%d: Warning: illegal interrupt %d chosen.\n", - id->id_unit, ffs(id->id_irq) - 1); - - /* - * Bogus card configuration - */ - if ((hc->numports > NCHAN) /* only 2 ports/card */ - ||(hc->memsize > (512 * 1024))) /* no more than 256K */ - return 0; - - return SRC_IO_SIZ; /* return the amount of IO addresses used. */ -} - -/* - * srattach_isa and srattach_pci allocate memory for hardc, softc and - * data buffers. It also does any initialization that is bus specific. - * At the end they call the common srattach() function. + * Register the ports on the adapter. + * Fill in the info for each port. +#ifndef NETGRAPH + * Attach each port to sppp and bpf. +#endif */ -static int -srattach_isa(struct isa_device *id) +int +sr_attach(device_t device) { - u_char mar; - struct sr_hardc *hc = &sr_hardc[id->id_unit]; + int intf_sw, pndx; + u_int32_t flags; + u_int fecr, *fecrp; + struct sr_hardc *hc; + struct sr_softc *sc; +#ifndef NETGRAPH + struct ifnet *ifp; +#endif /* NETGRAPH */ + int unit; /* index: channel w/in card */ - /* - * Allocate the software interface table(s) - */ - MALLOC(hc->sc, struct sr_softc *, + hc = (struct sr_hardc *)device_get_softc(device); + MALLOC(sc, struct sr_softc *, hc->numports * sizeof(struct sr_softc), M_DEVBUF, M_WAITOK | M_ZERO); - if (hc->sc == NULL) - return(0); - - id->id_ointr = srintr; - - outb(hc->iobase + SR_PCR, inb(hc->iobase + SR_PCR) | SR_PCR_SCARUN); - outb(hc->iobase + SR_PSR, inb(hc->iobase + SR_PSR) | SR_PSR_EN_SCA_DMA); - outb(hc->iobase + SR_MCR, - SR_MCR_DTR0 | SR_MCR_DTR1 | SR_MCR_TE0 | SR_MCR_TE1); - - SRC_SET_ON(hc->iobase); - - /* - * Configure the card. Mem address, irq, - */ - mar = (kvtop(id->id_maddr) >> 16) & SR_PCR_16M_SEL; - outb(hc->iobase + SR_PCR, - mar | (inb(hc->iobase + SR_PCR) & ~SR_PCR_16M_SEL)); - mar = kvtop(id->id_maddr) >> 12; - outb(hc->iobase + SR_BAR, mar); + if (sc == NULL) + goto errexit; + hc->sc = sc; /* * Get the TX clock direction and configuration. The default is a * single external clock which is used by RX and TX. */ + switch(hc->cardtype) { + case SR_CRD_N2: + flags = device_get_flags(device); #ifdef N2_TEST_SPEED - if (sr_test_speed[0] > 0) - hc->sc[0].clk_cfg = SR_FLAGS_INT_CLK; - else if (id->id_flags & SR_FLAGS_0_CLK_MSK) - hc->sc[0].clk_cfg = - (id->id_flags & SR_FLAGS_0_CLK_MSK) - >> SR_FLAGS_CLK_SHFT; -#else - if (id->id_flags & SR_FLAGS_0_CLK_MSK) - hc->sc[0].clk_cfg = - (id->id_flags & SR_FLAGS_0_CLK_MSK) - >> SR_FLAGS_CLK_SHFT; -#endif - - if (hc->numports == 2) -#ifdef N2_TEST_SPEED - if (sr_test_speed[1] > 0) + if (sr_test_speed[0] > 0) hc->sc[0].clk_cfg = SR_FLAGS_INT_CLK; else #endif - if (id->id_flags & SR_FLAGS_1_CLK_MSK) - hc->sc[1].clk_cfg = (id->id_flags & SR_FLAGS_1_CLK_MSK) - >> (SR_FLAGS_CLK_SHFT + SR_FLAGS_CLK_CHAN_SHFT); - - return srattach(hc); -} - -struct sr_hardc * -srattach_pci(int unit, vm_offset_t plx_vaddr, vm_offset_t sca_vaddr) -{ - int numports, pndx; - u_int fecr, *fecrp = (u_int *)(sca_vaddr + SR_FECR); - struct sr_hardc *hc, **hcp; - - /* - * 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 *)(plx_vaddr + 0x00)) = 0xfffff000; - *((u_int *)(plx_vaddr + 0x04)) = 1; - *((u_int *)(plx_vaddr + 0x18)) = 0x40030043; - *((u_int *)(plx_vaddr + 0x1c)) = 0xff000000; - *((u_int *)(plx_vaddr + 0x20)) = 0; - *((u_int *)(plx_vaddr + 0x28)) = 0xe9; - *((u_int *)(plx_vaddr + 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. - */ - 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 (numports == 0) - return NULL; - - hc = sr_hardc_pci; - hcp = &sr_hardc_pci; - - while (hc) { - hcp = &hc->next; - hc = hc->next; - } - - MALLOC(hc, struct sr_hardc *, sizeof(*hc), M_DEVBUF, M_WAITOK | M_ZERO); - if (hc == NULL) - return NULL; - - MALLOC(hc->sc, struct sr_softc *, numports * sizeof(struct sr_softc), - M_DEVBUF, M_WAITOK | M_ZERO); - if (hc->sc == NULL) { - FREE(hc, M_DEVBUF); - return NULL; - } - *hcp = hc; - - hc->numports = numports; - hc->cunit = unit; - hc->cardtype = SR_CRD_N2PCI; - hc->plx_base = (caddr_t)plx_vaddr; - hc->sca_base = sca_vaddr; - - 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", unit); - return NULL; - } - 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); - - for (pndx = 0; pndx < numports; pndx++) { - int intf_sw; - struct sr_softc *sc; - - sc = &hc->sc[pndx]; - - switch (pndx) { - case 1: - intf_sw = fecr & SR_FECR_ID1 >> SR_FE_ID1_SHFT; - break; - case 0: - default: - intf_sw = fecr & SR_FECR_ID0 >> SR_FE_ID0_SHFT; - } + if (flags & SR_FLAGS_0_CLK_MSK) + hc->sc[0].clk_cfg = + (flags & SR_FLAGS_0_CLK_MSK) + >> SR_FLAGS_CLK_SHFT; + if (hc->numports == 2) #ifdef N2_TEST_SPEED - if (sr_test_speed[pndx] > 0) - sc->clk_cfg = SR_FLAGS_INT_CLK; - else + if (sr_test_speed[1] > 0) + hc->sc[0].clk_cfg = SR_FLAGS_INT_CLK; + else #endif - switch (intf_sw) { - default: - case SR_FE_ID_RS232: - case SR_FE_ID_HSSI: - case SR_FE_ID_RS422: - case SR_FE_ID_TEST: - break; - - case SR_FE_ID_V35: - sc->clk_cfg = SR_FLAGS_EXT_SEP_CLK; - break; - - case SR_FE_ID_X21: - sc->clk_cfg = SR_FLAGS_EXT_CLK; + if (flags & SR_FLAGS_1_CLK_MSK) + hc->sc[1].clk_cfg = (flags & SR_FLAGS_1_CLK_MSK) + >> (SR_FLAGS_CLK_SHFT + + SR_FLAGS_CLK_CHAN_SHFT); + break; + case SR_CRD_N2PCI: + fecrp = (u_int *)(hc->sca_base + SR_FECR); + fecr = *fecrp; + for (pndx = 0; pndx < hc->numports; pndx++, sc++) { + switch (pndx) { + case 1: + intf_sw = fecr & SR_FECR_ID1 >> SR_FE_ID1_SHFT; break; + case 0: + default: + intf_sw = fecr & SR_FECR_ID0 >> SR_FE_ID0_SHFT; } - } - - *fecrp = SR_FECR_DTR0 - | SR_FECR_DTR1 - | SR_FECR_TE0 - | SR_FECR_TE1; - srattach(hc); - - return hc; -} - -/* - * Register the ports on the adapter. - * Fill in the info for each port. -#ifndef NETGRAPH - * Attach each port to sppp and bpf. +#ifdef N2_TEST_SPEED + if (sr_test_speed[pndx] > 0) + sc->clk_cfg = SR_FLAGS_INT_CLK; + else #endif - */ -static int -srattach(struct sr_hardc *hc) -{ - struct sr_softc *sc = hc->sc; -#ifndef NETGRAPH - struct ifnet *ifp; -#endif /* NETGRAPH */ - int unit; /* index: channel w/in card */ + switch (intf_sw) { + default: + case SR_FE_ID_RS232: + case SR_FE_ID_HSSI: + case SR_FE_ID_RS422: + case SR_FE_ID_TEST: + break; + + case SR_FE_ID_V35: + sc->clk_cfg = SR_FLAGS_EXT_SEP_CLK; + break; + + case SR_FE_ID_X21: + sc->clk_cfg = SR_FLAGS_EXT_CLK; + break; + } + } + sc = hc->sc; + break; + } /* * Report Card configuration information before we start configuring @@ -887,6 +396,10 @@ srattach(struct sr_hardc *hc) src_init(hc); sr_init_sca(hc); + if (BUS_SETUP_INTR(device_get_parent(device), device, hc->res_irq, + INTR_TYPE_NET, srintr, hc, &hc->intr_cookie) != 0) + goto errexit; + /* * Now configure each port on the card. */ @@ -926,11 +439,11 @@ srattach(struct sr_hardc *hc) */ if (ngsr_done_init == 0) ngsr_init(NULL); if (ng_make_node_common(&typestruct, &sc->node) != 0) - return (0); + goto errexit; sprintf(sc->nodename, "%s%d", NG_SR_NODE_TYPE, sc->unit); if (ng_name_node(sc->node, sc->nodename)) { NG_NODE_UNREF(sc->node); /* make it go away again */ - return (0); + goto errexit; } NG_NODE_SET_PRIVATE(sc->node, sc); callout_handle_init(&sc->handle); @@ -945,7 +458,145 @@ srattach(struct sr_hardc *hc) if (hc->mempages) SRC_SET_OFF(hc->iobase); - return 1; + return (0); + +errexit: + sr_deallocate_resources(device); + return (ENXIO); +} + +int +sr_detach(device_t device) +{ + device_t parent = device_get_parent(device); + struct sr_hardc *hc = device_get_softc(device); + + if (hc->intr_cookie != NULL) { + if (BUS_TEARDOWN_INTR(parent, device, + hc->res_irq, hc->intr_cookie) != 0) { + printf("intr teardown failed.. continuing\n"); + } + hc->intr_cookie = NULL; + } + + /* XXX Stop the DMA. */ + + /* + * deallocate any system resources we may have + * allocated on behalf of this driver. + */ + FREE(hc->sc, M_DEVBUF); + hc->sc = NULL; + hc->mem_start = NULL; + return (sr_deallocate_resources(device)); +} + +int +sr_allocate_ioport(device_t device, int rid, u_long size) +{ + struct sr_hardc *hc = device_get_softc(device); + + hc->rid_ioport = rid; + hc->res_ioport = bus_alloc_resource(device, SYS_RES_IOPORT, + &hc->rid_ioport, 0ul, ~0ul, size, RF_ACTIVE); + if (hc->res_ioport == NULL) { + goto errexit; + } + return (0); + +errexit: + sr_deallocate_resources(device); + return (ENXIO); +} + +int +sr_allocate_irq(device_t device, int rid, u_long size) +{ + struct sr_hardc *hc = device_get_softc(device); + + hc->rid_irq = rid; + hc->res_irq = bus_alloc_resource(device, SYS_RES_IRQ, + &hc->rid_irq, 0ul, ~0ul, 1, RF_SHAREABLE|RF_ACTIVE); + if (hc->res_irq == NULL) { + goto errexit; + } + return (0); + +errexit: + sr_deallocate_resources(device); + return (ENXIO); +} + +int +sr_allocate_memory(device_t device, int rid, u_long size) +{ + struct sr_hardc *hc = device_get_softc(device); + + hc->rid_memory = rid; + hc->res_memory = bus_alloc_resource(device, SYS_RES_MEMORY, + &hc->rid_memory, 0ul, ~0ul, size, RF_ACTIVE); + if (hc->res_memory == NULL) { + goto errexit; + } + return (0); + +errexit: + sr_deallocate_resources(device); + return (ENXIO); +} + +int +sr_allocate_plx_memory(device_t device, int rid, u_long size) +{ + struct sr_hardc *hc = device_get_softc(device); + + hc->rid_plx_memory = rid; + hc->res_plx_memory = bus_alloc_resource(device, SYS_RES_MEMORY, + &hc->rid_plx_memory, 0ul, ~0ul, size, RF_ACTIVE); + if (hc->res_plx_memory == NULL) { + goto errexit; + } + return (0); + +errexit: + sr_deallocate_resources(device); + return (ENXIO); +} + +int +sr_deallocate_resources(device_t device) +{ + struct sr_hardc *hc = device_get_softc(device); + + if (hc->res_irq != 0) { + bus_deactivate_resource(device, SYS_RES_IRQ, + hc->rid_irq, hc->res_irq); + bus_release_resource(device, SYS_RES_IRQ, + hc->rid_irq, hc->res_irq); + hc->res_irq = 0; + } + if (hc->res_ioport != 0) { + bus_deactivate_resource(device, SYS_RES_IOPORT, + hc->rid_ioport, hc->res_ioport); + bus_release_resource(device, SYS_RES_IOPORT, + hc->rid_ioport, hc->res_ioport); + hc->res_ioport = 0; + } + if (hc->res_memory != 0) { + bus_deactivate_resource(device, SYS_RES_MEMORY, + hc->rid_memory, hc->res_memory); + bus_release_resource(device, SYS_RES_MEMORY, + hc->rid_memory, hc->res_memory); + hc->res_memory = 0; + } + if (hc->res_plx_memory != 0) { + bus_deactivate_resource(device, SYS_RES_MEMORY, + hc->rid_plx_memory, hc->res_plx_memory); + bus_release_resource(device, SYS_RES_MEMORY, + hc->rid_plx_memory, hc->res_plx_memory); + hc->res_plx_memory = 0; + } + return (0); } /* @@ -957,19 +608,9 @@ srattach(struct sr_hardc *hc) * Repeat until there no interrupts remain. */ static void -srintr(int unit) -{ - struct sr_hardc *hc; - - hc = &sr_hardc[unit]; - srintr_hc(hc); - - return; -} - -void -srintr_hc(struct sr_hardc *hc) +srintr(void *arg) { + struct sr_hardc *hc = (struct sr_hardc *)arg; sca_regs *sca = hc->sca; /* MSCI register tree */ u_char isr0, isr1, isr2; /* interrupt statii captured */ @@ -2548,7 +2189,7 @@ sr_get_packets(struct sr_softc *sc) int got_st3, got_cda, got_eda; int tries = 5; - while((rxstat == 0xff) && --tries) + while ((rxstat == 0xff) && --tries) sr_packet_avail(sc, &len, &rxstat); /* @@ -2556,7 +2197,7 @@ sr_get_packets(struct sr_softc *sc) * sometimes and then the status is not * filled in yet. */ - if(tries && (tries != 5)) + if (tries && (tries != 5)) continue; /* @@ -2890,6 +2531,7 @@ sr_dmac_intr(struct sr_hardc *hc, u_char isr1) } } #ifndef NETGRAPH +#ifdef USE_MODEMCK /* * Perform timeout on an FR channel * @@ -3005,7 +2647,7 @@ sr_modemck(void *arg) splx(s); } - +#endif #else /* NETGRAPH */ /* * If a port is open/active, it's DCD state is checked @@ -3064,7 +2706,7 @@ ngsr_watchdog_frame(void * arg) int s; int speed; - if(sc->running == 0) + if (sc->running == 0) return; /* if we are not running let timeouts die */ /* * calculate the apparent throughputs |