summaryrefslogtreecommitdiffstats
path: root/sys/dev/sr/if_sr.c
diff options
context:
space:
mode:
authorjhay <jhay@FreeBSD.org>2001-01-30 10:02:10 +0000
committerjhay <jhay@FreeBSD.org>2001-01-30 10:02:10 +0000
commit306e6760c1d526abaababcaf26ca7c00f45d0ef3 (patch)
treefbe14b49ea00192f79b9178d57d2ad8346eb5060 /sys/dev/sr/if_sr.c
parent11691d89b0272451da2f382c49e0d48bced70b65 (diff)
downloadFreeBSD-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.c')
-rw-r--r--sys/dev/sr/if_sr.c846
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
OpenPOWER on IntegriCloud