diff options
author | jhay <jhay@FreeBSD.org> | 2001-01-24 18:45:29 +0000 |
---|---|---|
committer | jhay <jhay@FreeBSD.org> | 2001-01-24 18:45:29 +0000 |
commit | 1acb4466b06b7dde27e22ccf97f77182199cd3b0 (patch) | |
tree | 4106297a7393c56a7e57c90646ff94da95b89e9d /sys/dev/ar | |
parent | 4c773ee5aad277b37efa1e792875eebd015806f2 (diff) | |
download | FreeBSD-src-1acb4466b06b7dde27e22ccf97f77182199cd3b0.zip FreeBSD-src-1acb4466b06b7dde27e22ccf97f77182199cd3b0.tar.gz |
Newbusify ar(4).
Diffstat (limited to 'sys/dev/ar')
-rw-r--r-- | sys/dev/ar/if_ar.c | 460 | ||||
-rw-r--r-- | sys/dev/ar/if_ar_isa.c | 460 | ||||
-rw-r--r-- | sys/dev/ar/if_ar_pci.c | 154 | ||||
-rw-r--r-- | sys/dev/ar/if_arregs.h | 59 |
4 files changed, 725 insertions, 408 deletions
diff --git a/sys/dev/ar/if_ar.c b/sys/dev/ar/if_ar.c index 942b021..231ca6b 100644 --- a/sys/dev/ar/if_ar.c +++ b/sys/dev/ar/if_ar.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1999 John Hay. All rights reserved. + * Copyright (c) 1995 - 2001 John Hay. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,16 +46,24 @@ */ #include "opt_netgraph.h" -#include "ar.h" #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/mbuf.h> -#include <sys/sockio.h> #include <sys/socket.h> +#include <sys/sockio.h> +#include <sys/module.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 <isa/isavar.h> +#include "isa_if.h" #include <net/if.h> #ifdef NETGRAPH @@ -70,13 +78,8 @@ #include <machine/md_var.h> -#include <i386/isa/if_arregs.h> #include <i386/isa/ic/hd64570.h> -#include <i386/isa/isa_device.h> - -#ifndef COMPAT_OLDISA -#error "The ar device requires the old isa compatibility shims" -#endif +#include <i386/isa/if_arregs.h> #ifndef NETGRAPH #include "sppp.h" @@ -95,42 +98,6 @@ #define PPP_HEADER_LEN 4 -#define ARC_GET_WIN(addr) ((addr >> ARC_WIN_SHFT) & AR_WIN_MSK) - -#define ARC_SET_MEM(iobase,win) outb(iobase+AR_MSCA_EN, AR_ENA_MEM | \ - ARC_GET_WIN(win)) -#define ARC_SET_SCA(iobase,ch) outb(iobase+AR_MSCA_EN, AR_ENA_MEM | \ - AR_ENA_SCA | (ch ? AR_SEL_SCA_1:AR_SEL_SCA_0)) -#define ARC_SET_OFF(iobase) outb(iobase+AR_MSCA_EN, 0) - -struct ar_hardc { - int cunit; - struct ar_softc *sc; - u_short iobase; - int isa_irq; - int numports; - caddr_t mem_start; - caddr_t mem_end; - u_char *orbase; - - u_int memsize; /* in bytes */ - u_int winsize; /* in bytes */ - u_int winmsk; - u_char bustype; /* ISA, MCA, PCI.... */ - u_char interface[NPORT];/* X21, V.35, EIA-530.... */ - u_char revision; - u_char handshake; /* handshake lines supported by card. */ - - u_char txc_dtr[NPORT/NCHAN]; /* the register is write only */ - u_int txc_dtr_off[NPORT/NCHAN]; - - sca_regs *sca[NPORT/NCHAN]; - -}; - -static int next_ar_unit = 0; -static struct ar_hardc ar_hardc[NAR]; - struct ar_softc { #ifndef NETGRAPH struct sppp ifsppp; @@ -188,15 +155,14 @@ struct ar_softc { #endif /* NETGRAPH */ }; +static int next_ar_unit = 0; + #ifdef NETGRAPH #define DOG_HOLDOFF 6 /* dog holds off for 6 secs */ #define QUITE_A_WHILE 300 /* 5 MINUTES */ #define LOTS_OF_PACKETS 100 #endif /* NETGRAPH */ -static int arprobe(struct isa_device *id); -static int arattach_isa(struct isa_device *id); - /* * This translate from irq numbers to * the value that the arnet card needs @@ -222,19 +188,36 @@ static int irqtable[16] = { 7 /* 15 */ }; -struct isa_driver ardriver = { - INTR_TYPE_NET, - arprobe, - arattach_isa, - "ar" +static int ar_isa_probe (device_t); +static int ar_isa_attach (device_t); + +static struct isa_pnp_id ar_ids[] = { + {0, NULL} +}; + +static device_method_t ar_methods[] = { + DEVMETHOD(device_probe, ar_isa_probe), + DEVMETHOD(device_attach, ar_isa_attach), + DEVMETHOD(device_detach, ar_detach), + { 0, 0 } +}; + +static driver_t ar_isa_driver = { + "ar", + ar_methods, + sizeof (struct ar_hardc) }; -COMPAT_ISA_DRIVER(ar, ardriver); -struct ar_hardc *arattach_pci(int unit, vm_offset_t mem_addr); -void arintr_hc(struct ar_hardc *hc); +devclass_t ar_devclass; + +DRIVER_MODULE(if_ar, isa, ar_isa_driver, ar_devclass, 0, 0); +#ifndef NETGRAPH +MODULE_DEPEND(if_ar, sppp, 1, 1, 1); +#else +MODULE_DEPEND(ng_sync_ar, netgraph, 1, 1, 1); +#endif -static ointhand2_t arintr; -static int arattach(struct ar_hardc *hc); +static void arintr(void *arg); static void ar_xmit(struct ar_softc *sc); #ifndef NETGRAPH static void arstart(struct ifnet *ifp); @@ -293,20 +276,22 @@ static int ngar_done_init = 0; #endif /* NETGRAPH */ /* - * Register the Adapter. * Probe to see if it is there. * Get its information and fill it in. */ static int -arprobe(struct isa_device *id) +ar_isa_probe(device_t device) { - struct ar_hardc *hc = &ar_hardc[id->id_unit]; - u_int tmp; - u_short port; + int error; + u_long membase, memsize, port_start, port_count; - /* - * Register the card. - */ + error = ISA_PNP_PROBE(device_get_parent(device), device, ar_ids); + if(error == ENXIO || error == 0) + return (error); + + if((error = ar_allocate_ioport(device, 0, ARC_IO_SIZ))) { + return (ENXIO); + } /* * Now see if the card is realy there. @@ -314,15 +299,48 @@ arprobe(struct isa_device *id) * XXX For now I just check the undocumented ports * for "570". We will probably have to do more checking. */ - port = id->id_iobase; + error = bus_get_resource(device, SYS_RES_IOPORT, 0, &port_start, + &port_count); + + if((inb(port_start + AR_ID_5) != '5') || + (inb(port_start + AR_ID_7) != '7') || + (inb(port_start + AR_ID_0) != '0')) { + ar_deallocate_resources(device); + return (ENXIO); + } + membase = bus_get_resource_start(device, SYS_RES_MEMORY, 0); + memsize = inb(port_start + AR_REV); + memsize = 1 << ((memsize & AR_WSIZ_MSK) >> AR_WSIZ_SHFT); + memsize *= ARC_WIN_SIZ; + error = bus_set_resource(device, SYS_RES_MEMORY, 0, membase, memsize); + ar_deallocate_resources(device); - if((inb(port+AR_ID_5) != '5') || (inb(port+AR_ID_7) != '7') || - (inb(port+AR_ID_0) != '0')) - return 0; - /* - * We have a card here, fill in what we can. - */ - tmp = inb(port + AR_BMI); + return (error); +} + +/* + * Malloc memory for the softc structures. + * Reset the card to put it in a known state. + * Register the ports on the adapter. + * Fill in the info for each port. + * Attach each port to sppp and bpf. + */ +static int +ar_isa_attach(device_t device) +{ + u_int tmp; + u_long irq, junk; + struct ar_hardc *hc; + + hc = (struct ar_hardc *)device_get_softc(device); + if(ar_allocate_ioport(device, 0, ARC_IO_SIZ)) + return (ENXIO); + hc->bt = rman_get_bustag(hc->res_ioport); + hc->bh = rman_get_bushandle(hc->res_ioport); + + hc->iobase = rman_get_start(hc->res_ioport); + + tmp = inb(hc->iobase + AR_BMI); hc->bustype = tmp & AR_BUS_MSK; hc->memsize = (tmp & AR_MEM_MSK) >> AR_MEM_SHFT; hc->memsize = 1 << hc->memsize; @@ -331,109 +349,70 @@ arprobe(struct isa_device *id) hc->interface[1] = hc->interface[0]; hc->interface[2] = hc->interface[0]; hc->interface[3] = hc->interface[0]; - tmp = inb(port + AR_REV); + tmp = inb(hc->iobase + AR_REV); hc->revision = tmp & AR_REV_MSK; hc->winsize = 1 << ((tmp & AR_WSIZ_MSK) >> AR_WSIZ_SHFT); hc->winsize *= ARC_WIN_SIZ; hc->winmsk = hc->winsize - 1; - hc->numports = inb(port + AR_PNUM); - hc->handshake = inb(port + AR_HNDSH); + hc->numports = inb(hc->iobase + AR_PNUM); + hc->handshake = inb(hc->iobase + AR_HNDSH); - id->id_msize = hc->winsize; + if(ar_allocate_memory(device, 0, hc->winsize)) + return (ENXIO); - hc->iobase = id->id_iobase; - hc->mem_start = id->id_maddr; - hc->mem_end = id->id_maddr + id->id_msize; - hc->cunit = id->id_unit; - hc->isa_irq = id->id_irq; + hc->mem_start = rman_get_virtual(hc->res_memory); + hc->mem_end = hc->mem_start + hc->winsize; + hc->cunit = device_get_unit(device); switch(hc->interface[0]) { case AR_IFACE_EIA_232: printf("ar%d: The EIA 232 interface is not supported.\n", - id->id_unit); - return 0; + hc->cunit); + ar_deallocate_resources(device); + return (ENXIO); case AR_IFACE_V_35: break; case AR_IFACE_EIA_530: printf("ar%d: WARNING: The EIA 530 interface is untested.\n", - id->id_unit); + hc->cunit); break; case AR_IFACE_X_21: break; case AR_IFACE_COMBO: printf("ar%d: WARNING: The COMBO interface is untested.\n", - id->id_unit); + hc->cunit); break; } /* * Do a little sanity check. */ - if((hc->numports > NPORT) || (hc->memsize > (512*1024))) - return 0; - - return ARC_IO_SIZ; /* return the amount of IO addresses used. */ -} - -/* - * Malloc memory for the softc structures. - * Reset the card to put it in a known state. - * Register the ports on the adapter. - * Fill in the info for each port. - * Attach each port to sppp and bpf. - */ -static int -arattach_isa(struct isa_device *id) -{ - struct ar_hardc *hc = &ar_hardc[id->id_unit]; - id->id_ointr = arintr; - return arattach(hc); -} - -struct ar_hardc * -arattach_pci(int unit, vm_offset_t mem_addr) -{ - struct ar_hardc *hc; - u_int i, tmp; - - hc = malloc(sizeof(struct ar_hardc), M_DEVBUF, M_WAITOK | M_ZERO); - - hc->cunit = unit; - hc->mem_start = (caddr_t)mem_addr; - hc->sca[0] = (sca_regs *)(mem_addr + AR_PCI_SCA_1_OFFSET); - hc->sca[1] = (sca_regs *)(mem_addr + AR_PCI_SCA_2_OFFSET); - hc->iobase = 0; - hc->orbase = (u_char *)(mem_addr + AR_PCI_ORBASE_OFFSET); + if((hc->numports > NPORT) || (hc->memsize > (512*1024))) { + ar_deallocate_resources(device); + return (ENXIO); + } - tmp = hc->orbase[AR_BMI * 4]; - hc->bustype = tmp & AR_BUS_MSK; - hc->memsize = (tmp & AR_MEM_MSK) >> AR_MEM_SHFT; - hc->memsize = 1 << hc->memsize; - hc->memsize <<= 16; - hc->interface[0] = (tmp & AR_IFACE_MSK); - tmp = hc->orbase[AR_REV * 4]; - hc->revision = tmp & AR_REV_MSK; - hc->winsize = (1 << ((tmp & AR_WSIZ_MSK) >> AR_WSIZ_SHFT)) * 16 * 1024; - hc->mem_end = (caddr_t)(mem_addr + hc->winsize); - hc->winmsk = hc->winsize - 1; - hc->numports = hc->orbase[AR_PNUM * 4]; - hc->handshake = hc->orbase[AR_HNDSH * 4]; + if(ar_allocate_irq(device, 0, 1)) + return (ENXIO); - for(i = 1; i < hc->numports; i++) - hc->interface[i] = hc->interface[0]; + if(bus_get_resource(device, SYS_RES_IRQ, 0, &irq, &junk)) { + ar_deallocate_resources(device); + return (ENXIO); + } + hc->isa_irq = irq; - TRC(printf("arp%d: bus %x, rev %d, memstart %p, winsize %d, " - "winmsk %x, interface %x\n", - unit, hc->bustype, hc->revision, hc->mem_start, hc->winsize, - hc->winmsk, hc->interface[0])); + if(ar_attach(device)) { + ar_deallocate_resources(device); + return (ENXIO); + } - arattach(hc); - return hc; + return (0); } -static int -arattach(struct ar_hardc *hc) +int +ar_attach(device_t device) { + struct ar_hardc *hc; struct ar_softc *sc; #ifndef NETGRAPH struct ifnet *ifp; @@ -441,6 +420,8 @@ arattach(struct ar_hardc *hc) #endif /* NETGRAPH */ int unit; + hc = (struct ar_hardc *)device_get_softc(device); + printf("arc%d: %uK RAM, %u ports, rev %u.\n", hc->cunit, hc->memsize/1024, @@ -449,6 +430,10 @@ arattach(struct ar_hardc *hc) arc_init(hc); + if(BUS_SETUP_INTR(device_get_parent(device), device, hc->res_irq, + INTR_TYPE_NET, arintr, hc, &hc->intr_cookie) != 0) + return (1); + sc = hc->sc; for(unit=0;unit<hc->numports;unit+=NCHAN) @@ -508,11 +493,11 @@ arattach(struct ar_hardc *hc) */ if (ngar_done_init == 0) ngar_init(NULL); if (ng_make_node_common(&typestruct, &sc->node) != 0) - return (0); + return (1); sprintf(sc->nodename, "%s%d", NG_AR_NODE_TYPE, sc->unit); if (ng_name_node(sc->node, sc->nodename)) { NG_NODE_UNREF(sc->node); /* drop it again */ - return (0); + return (1); } NG_NODE_SET_PRIVATE(sc->node, sc); callout_handle_init(&sc->handle); @@ -527,7 +512,139 @@ arattach(struct ar_hardc *hc) if(hc->bustype == AR_BUS_ISA) ARC_SET_OFF(hc->iobase); - return 1; + return (0); +} + +int +ar_detach(device_t device) +{ + device_t parent = device_get_parent(device); + struct ar_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; + } + + /* + * 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 (ar_deallocate_resources(device)); +} + +int +ar_allocate_ioport(device_t device, int rid, u_long size) +{ + struct ar_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: + ar_deallocate_resources(device); + return (ENXIO); +} + +int +ar_allocate_irq(device_t device, int rid, u_long size) +{ + struct ar_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: + ar_deallocate_resources(device); + return (ENXIO); +} + +int +ar_allocate_memory(device_t device, int rid, u_long size) +{ + struct ar_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: + ar_deallocate_resources(device); + return (ENXIO); +} + +int +ar_allocate_plx_memory(device_t device, int rid, u_long size) +{ + struct ar_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: + ar_deallocate_resources(device); + return (ENXIO); +} + +int +ar_deallocate_resources(device_t device) +{ + struct ar_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); } /* @@ -537,18 +654,9 @@ arattach(struct ar_hardc *hc) * Repeat until there is no more interrupts. */ static void -arintr(int unit) -{ - struct ar_hardc *hc; - - hc = &ar_hardc[unit]; - arintr_hc(hc); - return; -} - -void -arintr_hc(struct ar_hardc *hc) +arintr(void *arg) { + struct ar_hardc *hc = (struct ar_hardc *)arg; sca_regs *sca; u_char isr0, isr1, isr2, arisr; int scano; @@ -838,10 +946,10 @@ arioctl(struct ifnet *ifp, u_long cmd, caddr_t data) TRC(printf("ar%d: ioctl: ifsppp.pp_flags = %x, if_flags %x.\n", ifp->if_unit, ((struct sppp *)ifp)->pp_flags, ifp->if_flags);) if(error) - return error; + return (error); if((cmd != SIOCSIFFLAGS) && cmd != (SIOCSIFADDR)) - return 0; + return (0); TRC(printf("ar%d: arioctl %s.\n", ifp->if_unit, (cmd == SIOCSIFFLAGS) ? "SIOCSIFFLAGS" : "SIOCSIFADDR");) @@ -862,7 +970,7 @@ arioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sppp_flush(ifp); } splx(s); - return 0; + return (0); } #endif /* NETGRAPH */ @@ -1051,7 +1159,7 @@ ar_read_pim_iface(volatile struct ar_hardc *hc, int channel) TRC(printf("x = %x", x)); if(x & AR_PIM_DATA) { printf("No PIM installed\n"); - return(AR_IFACE_UNKNOWN); + return (AR_IFACE_UNKNOWN); } x = (x >> 1) & 0x01; @@ -1105,20 +1213,20 @@ ar_read_pim_iface(volatile struct ar_hardc *hc, int channel) *pimctrl = AR_PIM_MODEG; *pimctrl = AR_PIM_MODEG | AR_PIM_AUTO_LED; if(ctype > 255) - return(AR_IFACE_UNKNOWN); + return (AR_IFACE_UNKNOWN); if(ctype > 239) - return(AR_IFACE_V_35); + return (AR_IFACE_V_35); if(ctype > 207) - return(AR_IFACE_EIA_232); + return (AR_IFACE_EIA_232); if(ctype > 178) - return(AR_IFACE_X_21); + return (AR_IFACE_X_21); if(ctype > 150) - return(AR_IFACE_EIA_530); + return (AR_IFACE_EIA_530); if(ctype > 25) - return(AR_IFACE_UNKNOWN); + return (AR_IFACE_UNKNOWN); if(ctype > 7) - return(AR_IFACE_LOOPBACK); - return(AR_IFACE_UNKNOWN); + return (AR_IFACE_LOOPBACK); + return (AR_IFACE_UNKNOWN); } /* @@ -1173,10 +1281,10 @@ arc_init(struct ar_hardc *hc) * Mem address, irq, */ mar = kvtop(hc->mem_start) >> 16; - isr = irqtable[ffs(hc->isa_irq) - 1] << 1; + isr = irqtable[hc->isa_irq] << 1; if(isr == 0) printf("ar%d: Warning illegal interrupt %d\n", - hc->cunit, ffs(hc->isa_irq) - 1); + hc->cunit, hc->isa_irq); isr = isr | ((kvtop(hc->mem_start) & 0xc000) >> 10); hc->sca[0] = (sca_regs *)hc->mem_start; @@ -1577,7 +1685,7 @@ ar_packet_avail(struct ar_softc *sc, *rxstat = rxdesc->stat; TRC(printf("ar%d: PKT AVAIL len %d, %x.\n", sc->unit, *len, *rxstat)); - return 1; + return (1); } rxdesc++; @@ -1588,7 +1696,7 @@ ar_packet_avail(struct ar_softc *sc, *len = 0; *rxstat = 0; - return 0; + return (0); } @@ -2276,7 +2384,7 @@ ngar_rcvmsg(node_p node, item_p item, hook_p lasthook) /* * get data from another node and transmit it to the correct channel */ -static int +static int ngar_rcvdata(hook_p hook, item_p item) { int s; diff --git a/sys/dev/ar/if_ar_isa.c b/sys/dev/ar/if_ar_isa.c index 942b021..231ca6b 100644 --- a/sys/dev/ar/if_ar_isa.c +++ b/sys/dev/ar/if_ar_isa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1999 John Hay. All rights reserved. + * Copyright (c) 1995 - 2001 John Hay. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,16 +46,24 @@ */ #include "opt_netgraph.h" -#include "ar.h" #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/mbuf.h> -#include <sys/sockio.h> #include <sys/socket.h> +#include <sys/sockio.h> +#include <sys/module.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 <isa/isavar.h> +#include "isa_if.h" #include <net/if.h> #ifdef NETGRAPH @@ -70,13 +78,8 @@ #include <machine/md_var.h> -#include <i386/isa/if_arregs.h> #include <i386/isa/ic/hd64570.h> -#include <i386/isa/isa_device.h> - -#ifndef COMPAT_OLDISA -#error "The ar device requires the old isa compatibility shims" -#endif +#include <i386/isa/if_arregs.h> #ifndef NETGRAPH #include "sppp.h" @@ -95,42 +98,6 @@ #define PPP_HEADER_LEN 4 -#define ARC_GET_WIN(addr) ((addr >> ARC_WIN_SHFT) & AR_WIN_MSK) - -#define ARC_SET_MEM(iobase,win) outb(iobase+AR_MSCA_EN, AR_ENA_MEM | \ - ARC_GET_WIN(win)) -#define ARC_SET_SCA(iobase,ch) outb(iobase+AR_MSCA_EN, AR_ENA_MEM | \ - AR_ENA_SCA | (ch ? AR_SEL_SCA_1:AR_SEL_SCA_0)) -#define ARC_SET_OFF(iobase) outb(iobase+AR_MSCA_EN, 0) - -struct ar_hardc { - int cunit; - struct ar_softc *sc; - u_short iobase; - int isa_irq; - int numports; - caddr_t mem_start; - caddr_t mem_end; - u_char *orbase; - - u_int memsize; /* in bytes */ - u_int winsize; /* in bytes */ - u_int winmsk; - u_char bustype; /* ISA, MCA, PCI.... */ - u_char interface[NPORT];/* X21, V.35, EIA-530.... */ - u_char revision; - u_char handshake; /* handshake lines supported by card. */ - - u_char txc_dtr[NPORT/NCHAN]; /* the register is write only */ - u_int txc_dtr_off[NPORT/NCHAN]; - - sca_regs *sca[NPORT/NCHAN]; - -}; - -static int next_ar_unit = 0; -static struct ar_hardc ar_hardc[NAR]; - struct ar_softc { #ifndef NETGRAPH struct sppp ifsppp; @@ -188,15 +155,14 @@ struct ar_softc { #endif /* NETGRAPH */ }; +static int next_ar_unit = 0; + #ifdef NETGRAPH #define DOG_HOLDOFF 6 /* dog holds off for 6 secs */ #define QUITE_A_WHILE 300 /* 5 MINUTES */ #define LOTS_OF_PACKETS 100 #endif /* NETGRAPH */ -static int arprobe(struct isa_device *id); -static int arattach_isa(struct isa_device *id); - /* * This translate from irq numbers to * the value that the arnet card needs @@ -222,19 +188,36 @@ static int irqtable[16] = { 7 /* 15 */ }; -struct isa_driver ardriver = { - INTR_TYPE_NET, - arprobe, - arattach_isa, - "ar" +static int ar_isa_probe (device_t); +static int ar_isa_attach (device_t); + +static struct isa_pnp_id ar_ids[] = { + {0, NULL} +}; + +static device_method_t ar_methods[] = { + DEVMETHOD(device_probe, ar_isa_probe), + DEVMETHOD(device_attach, ar_isa_attach), + DEVMETHOD(device_detach, ar_detach), + { 0, 0 } +}; + +static driver_t ar_isa_driver = { + "ar", + ar_methods, + sizeof (struct ar_hardc) }; -COMPAT_ISA_DRIVER(ar, ardriver); -struct ar_hardc *arattach_pci(int unit, vm_offset_t mem_addr); -void arintr_hc(struct ar_hardc *hc); +devclass_t ar_devclass; + +DRIVER_MODULE(if_ar, isa, ar_isa_driver, ar_devclass, 0, 0); +#ifndef NETGRAPH +MODULE_DEPEND(if_ar, sppp, 1, 1, 1); +#else +MODULE_DEPEND(ng_sync_ar, netgraph, 1, 1, 1); +#endif -static ointhand2_t arintr; -static int arattach(struct ar_hardc *hc); +static void arintr(void *arg); static void ar_xmit(struct ar_softc *sc); #ifndef NETGRAPH static void arstart(struct ifnet *ifp); @@ -293,20 +276,22 @@ static int ngar_done_init = 0; #endif /* NETGRAPH */ /* - * Register the Adapter. * Probe to see if it is there. * Get its information and fill it in. */ static int -arprobe(struct isa_device *id) +ar_isa_probe(device_t device) { - struct ar_hardc *hc = &ar_hardc[id->id_unit]; - u_int tmp; - u_short port; + int error; + u_long membase, memsize, port_start, port_count; - /* - * Register the card. - */ + error = ISA_PNP_PROBE(device_get_parent(device), device, ar_ids); + if(error == ENXIO || error == 0) + return (error); + + if((error = ar_allocate_ioport(device, 0, ARC_IO_SIZ))) { + return (ENXIO); + } /* * Now see if the card is realy there. @@ -314,15 +299,48 @@ arprobe(struct isa_device *id) * XXX For now I just check the undocumented ports * for "570". We will probably have to do more checking. */ - port = id->id_iobase; + error = bus_get_resource(device, SYS_RES_IOPORT, 0, &port_start, + &port_count); + + if((inb(port_start + AR_ID_5) != '5') || + (inb(port_start + AR_ID_7) != '7') || + (inb(port_start + AR_ID_0) != '0')) { + ar_deallocate_resources(device); + return (ENXIO); + } + membase = bus_get_resource_start(device, SYS_RES_MEMORY, 0); + memsize = inb(port_start + AR_REV); + memsize = 1 << ((memsize & AR_WSIZ_MSK) >> AR_WSIZ_SHFT); + memsize *= ARC_WIN_SIZ; + error = bus_set_resource(device, SYS_RES_MEMORY, 0, membase, memsize); + ar_deallocate_resources(device); - if((inb(port+AR_ID_5) != '5') || (inb(port+AR_ID_7) != '7') || - (inb(port+AR_ID_0) != '0')) - return 0; - /* - * We have a card here, fill in what we can. - */ - tmp = inb(port + AR_BMI); + return (error); +} + +/* + * Malloc memory for the softc structures. + * Reset the card to put it in a known state. + * Register the ports on the adapter. + * Fill in the info for each port. + * Attach each port to sppp and bpf. + */ +static int +ar_isa_attach(device_t device) +{ + u_int tmp; + u_long irq, junk; + struct ar_hardc *hc; + + hc = (struct ar_hardc *)device_get_softc(device); + if(ar_allocate_ioport(device, 0, ARC_IO_SIZ)) + return (ENXIO); + hc->bt = rman_get_bustag(hc->res_ioport); + hc->bh = rman_get_bushandle(hc->res_ioport); + + hc->iobase = rman_get_start(hc->res_ioport); + + tmp = inb(hc->iobase + AR_BMI); hc->bustype = tmp & AR_BUS_MSK; hc->memsize = (tmp & AR_MEM_MSK) >> AR_MEM_SHFT; hc->memsize = 1 << hc->memsize; @@ -331,109 +349,70 @@ arprobe(struct isa_device *id) hc->interface[1] = hc->interface[0]; hc->interface[2] = hc->interface[0]; hc->interface[3] = hc->interface[0]; - tmp = inb(port + AR_REV); + tmp = inb(hc->iobase + AR_REV); hc->revision = tmp & AR_REV_MSK; hc->winsize = 1 << ((tmp & AR_WSIZ_MSK) >> AR_WSIZ_SHFT); hc->winsize *= ARC_WIN_SIZ; hc->winmsk = hc->winsize - 1; - hc->numports = inb(port + AR_PNUM); - hc->handshake = inb(port + AR_HNDSH); + hc->numports = inb(hc->iobase + AR_PNUM); + hc->handshake = inb(hc->iobase + AR_HNDSH); - id->id_msize = hc->winsize; + if(ar_allocate_memory(device, 0, hc->winsize)) + return (ENXIO); - hc->iobase = id->id_iobase; - hc->mem_start = id->id_maddr; - hc->mem_end = id->id_maddr + id->id_msize; - hc->cunit = id->id_unit; - hc->isa_irq = id->id_irq; + hc->mem_start = rman_get_virtual(hc->res_memory); + hc->mem_end = hc->mem_start + hc->winsize; + hc->cunit = device_get_unit(device); switch(hc->interface[0]) { case AR_IFACE_EIA_232: printf("ar%d: The EIA 232 interface is not supported.\n", - id->id_unit); - return 0; + hc->cunit); + ar_deallocate_resources(device); + return (ENXIO); case AR_IFACE_V_35: break; case AR_IFACE_EIA_530: printf("ar%d: WARNING: The EIA 530 interface is untested.\n", - id->id_unit); + hc->cunit); break; case AR_IFACE_X_21: break; case AR_IFACE_COMBO: printf("ar%d: WARNING: The COMBO interface is untested.\n", - id->id_unit); + hc->cunit); break; } /* * Do a little sanity check. */ - if((hc->numports > NPORT) || (hc->memsize > (512*1024))) - return 0; - - return ARC_IO_SIZ; /* return the amount of IO addresses used. */ -} - -/* - * Malloc memory for the softc structures. - * Reset the card to put it in a known state. - * Register the ports on the adapter. - * Fill in the info for each port. - * Attach each port to sppp and bpf. - */ -static int -arattach_isa(struct isa_device *id) -{ - struct ar_hardc *hc = &ar_hardc[id->id_unit]; - id->id_ointr = arintr; - return arattach(hc); -} - -struct ar_hardc * -arattach_pci(int unit, vm_offset_t mem_addr) -{ - struct ar_hardc *hc; - u_int i, tmp; - - hc = malloc(sizeof(struct ar_hardc), M_DEVBUF, M_WAITOK | M_ZERO); - - hc->cunit = unit; - hc->mem_start = (caddr_t)mem_addr; - hc->sca[0] = (sca_regs *)(mem_addr + AR_PCI_SCA_1_OFFSET); - hc->sca[1] = (sca_regs *)(mem_addr + AR_PCI_SCA_2_OFFSET); - hc->iobase = 0; - hc->orbase = (u_char *)(mem_addr + AR_PCI_ORBASE_OFFSET); + if((hc->numports > NPORT) || (hc->memsize > (512*1024))) { + ar_deallocate_resources(device); + return (ENXIO); + } - tmp = hc->orbase[AR_BMI * 4]; - hc->bustype = tmp & AR_BUS_MSK; - hc->memsize = (tmp & AR_MEM_MSK) >> AR_MEM_SHFT; - hc->memsize = 1 << hc->memsize; - hc->memsize <<= 16; - hc->interface[0] = (tmp & AR_IFACE_MSK); - tmp = hc->orbase[AR_REV * 4]; - hc->revision = tmp & AR_REV_MSK; - hc->winsize = (1 << ((tmp & AR_WSIZ_MSK) >> AR_WSIZ_SHFT)) * 16 * 1024; - hc->mem_end = (caddr_t)(mem_addr + hc->winsize); - hc->winmsk = hc->winsize - 1; - hc->numports = hc->orbase[AR_PNUM * 4]; - hc->handshake = hc->orbase[AR_HNDSH * 4]; + if(ar_allocate_irq(device, 0, 1)) + return (ENXIO); - for(i = 1; i < hc->numports; i++) - hc->interface[i] = hc->interface[0]; + if(bus_get_resource(device, SYS_RES_IRQ, 0, &irq, &junk)) { + ar_deallocate_resources(device); + return (ENXIO); + } + hc->isa_irq = irq; - TRC(printf("arp%d: bus %x, rev %d, memstart %p, winsize %d, " - "winmsk %x, interface %x\n", - unit, hc->bustype, hc->revision, hc->mem_start, hc->winsize, - hc->winmsk, hc->interface[0])); + if(ar_attach(device)) { + ar_deallocate_resources(device); + return (ENXIO); + } - arattach(hc); - return hc; + return (0); } -static int -arattach(struct ar_hardc *hc) +int +ar_attach(device_t device) { + struct ar_hardc *hc; struct ar_softc *sc; #ifndef NETGRAPH struct ifnet *ifp; @@ -441,6 +420,8 @@ arattach(struct ar_hardc *hc) #endif /* NETGRAPH */ int unit; + hc = (struct ar_hardc *)device_get_softc(device); + printf("arc%d: %uK RAM, %u ports, rev %u.\n", hc->cunit, hc->memsize/1024, @@ -449,6 +430,10 @@ arattach(struct ar_hardc *hc) arc_init(hc); + if(BUS_SETUP_INTR(device_get_parent(device), device, hc->res_irq, + INTR_TYPE_NET, arintr, hc, &hc->intr_cookie) != 0) + return (1); + sc = hc->sc; for(unit=0;unit<hc->numports;unit+=NCHAN) @@ -508,11 +493,11 @@ arattach(struct ar_hardc *hc) */ if (ngar_done_init == 0) ngar_init(NULL); if (ng_make_node_common(&typestruct, &sc->node) != 0) - return (0); + return (1); sprintf(sc->nodename, "%s%d", NG_AR_NODE_TYPE, sc->unit); if (ng_name_node(sc->node, sc->nodename)) { NG_NODE_UNREF(sc->node); /* drop it again */ - return (0); + return (1); } NG_NODE_SET_PRIVATE(sc->node, sc); callout_handle_init(&sc->handle); @@ -527,7 +512,139 @@ arattach(struct ar_hardc *hc) if(hc->bustype == AR_BUS_ISA) ARC_SET_OFF(hc->iobase); - return 1; + return (0); +} + +int +ar_detach(device_t device) +{ + device_t parent = device_get_parent(device); + struct ar_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; + } + + /* + * 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 (ar_deallocate_resources(device)); +} + +int +ar_allocate_ioport(device_t device, int rid, u_long size) +{ + struct ar_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: + ar_deallocate_resources(device); + return (ENXIO); +} + +int +ar_allocate_irq(device_t device, int rid, u_long size) +{ + struct ar_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: + ar_deallocate_resources(device); + return (ENXIO); +} + +int +ar_allocate_memory(device_t device, int rid, u_long size) +{ + struct ar_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: + ar_deallocate_resources(device); + return (ENXIO); +} + +int +ar_allocate_plx_memory(device_t device, int rid, u_long size) +{ + struct ar_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: + ar_deallocate_resources(device); + return (ENXIO); +} + +int +ar_deallocate_resources(device_t device) +{ + struct ar_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); } /* @@ -537,18 +654,9 @@ arattach(struct ar_hardc *hc) * Repeat until there is no more interrupts. */ static void -arintr(int unit) -{ - struct ar_hardc *hc; - - hc = &ar_hardc[unit]; - arintr_hc(hc); - return; -} - -void -arintr_hc(struct ar_hardc *hc) +arintr(void *arg) { + struct ar_hardc *hc = (struct ar_hardc *)arg; sca_regs *sca; u_char isr0, isr1, isr2, arisr; int scano; @@ -838,10 +946,10 @@ arioctl(struct ifnet *ifp, u_long cmd, caddr_t data) TRC(printf("ar%d: ioctl: ifsppp.pp_flags = %x, if_flags %x.\n", ifp->if_unit, ((struct sppp *)ifp)->pp_flags, ifp->if_flags);) if(error) - return error; + return (error); if((cmd != SIOCSIFFLAGS) && cmd != (SIOCSIFADDR)) - return 0; + return (0); TRC(printf("ar%d: arioctl %s.\n", ifp->if_unit, (cmd == SIOCSIFFLAGS) ? "SIOCSIFFLAGS" : "SIOCSIFADDR");) @@ -862,7 +970,7 @@ arioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sppp_flush(ifp); } splx(s); - return 0; + return (0); } #endif /* NETGRAPH */ @@ -1051,7 +1159,7 @@ ar_read_pim_iface(volatile struct ar_hardc *hc, int channel) TRC(printf("x = %x", x)); if(x & AR_PIM_DATA) { printf("No PIM installed\n"); - return(AR_IFACE_UNKNOWN); + return (AR_IFACE_UNKNOWN); } x = (x >> 1) & 0x01; @@ -1105,20 +1213,20 @@ ar_read_pim_iface(volatile struct ar_hardc *hc, int channel) *pimctrl = AR_PIM_MODEG; *pimctrl = AR_PIM_MODEG | AR_PIM_AUTO_LED; if(ctype > 255) - return(AR_IFACE_UNKNOWN); + return (AR_IFACE_UNKNOWN); if(ctype > 239) - return(AR_IFACE_V_35); + return (AR_IFACE_V_35); if(ctype > 207) - return(AR_IFACE_EIA_232); + return (AR_IFACE_EIA_232); if(ctype > 178) - return(AR_IFACE_X_21); + return (AR_IFACE_X_21); if(ctype > 150) - return(AR_IFACE_EIA_530); + return (AR_IFACE_EIA_530); if(ctype > 25) - return(AR_IFACE_UNKNOWN); + return (AR_IFACE_UNKNOWN); if(ctype > 7) - return(AR_IFACE_LOOPBACK); - return(AR_IFACE_UNKNOWN); + return (AR_IFACE_LOOPBACK); + return (AR_IFACE_UNKNOWN); } /* @@ -1173,10 +1281,10 @@ arc_init(struct ar_hardc *hc) * Mem address, irq, */ mar = kvtop(hc->mem_start) >> 16; - isr = irqtable[ffs(hc->isa_irq) - 1] << 1; + isr = irqtable[hc->isa_irq] << 1; if(isr == 0) printf("ar%d: Warning illegal interrupt %d\n", - hc->cunit, ffs(hc->isa_irq) - 1); + hc->cunit, hc->isa_irq); isr = isr | ((kvtop(hc->mem_start) & 0xc000) >> 10); hc->sca[0] = (sca_regs *)hc->mem_start; @@ -1577,7 +1685,7 @@ ar_packet_avail(struct ar_softc *sc, *rxstat = rxdesc->stat; TRC(printf("ar%d: PKT AVAIL len %d, %x.\n", sc->unit, *len, *rxstat)); - return 1; + return (1); } rxdesc++; @@ -1588,7 +1696,7 @@ ar_packet_avail(struct ar_softc *sc, *len = 0; *rxstat = 0; - return 0; + return (0); } @@ -2276,7 +2384,7 @@ ngar_rcvmsg(node_p node, item_p item, hook_p lasthook) /* * get data from another node and transmit it to the correct channel */ -static int +static int ngar_rcvdata(hook_p hook, item_p item) { int s; diff --git a/sys/dev/ar/if_ar_pci.c b/sys/dev/ar/if_ar_pci.c index 45482eb..ad2bfa0 100644 --- a/sys/dev/ar/if_ar_pci.c +++ b/sys/dev/ar/if_ar_pci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 John Hay. + * Copyright (c) 1999 - 2001 John Hay. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,58 +29,67 @@ * $FreeBSD$ */ -#ifdef COMPILING_LINT -#warning "The ar pci driver is broken and is not compiled with LINT" -#else - -#include "ar.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/pcireg.h> #include <pci/pcivar.h> -#ifndef COMPAT_OLDPCI -#error "The ar device requires the old pci compatibility shims" +#include <i386/isa/ic/hd64570.h> +#include <i386/isa/if_arregs.h> + +#ifdef TRACE +#define TRC(x) x +#else +#define TRC(x) #endif -/* - * The must match with the real functions in if_ar.c - */ -extern void *arattach_pci(int unit, vm_offset_t mem_vaddr); -extern void arintr_hc(void *hc); +#define TRCL(x) x -static const char *ar_pci_probe(pcici_t tag, pcidi_t type); -static void ar_pci_attach(pcici_t config_id, int unit); +static int ar_pci_probe(device_t); +static int ar_pci_attach(device_t); -static u_long arc_count = NAR; +static device_method_t ar_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ar_pci_probe), + DEVMETHOD(device_attach, ar_pci_attach), + DEVMETHOD(device_detach, ar_detach), + { 0, 0 } +}; -static struct pci_device ar_pci_driver = -{ +static driver_t ar_pci_driver = { "ar", - ar_pci_probe, - ar_pci_attach, - &arc_count, - NULL + ar_pci_methods, + sizeof(struct ar_hardc), }; -COMPAT_PCI_DRIVER (ar_pci, ar_pci_driver); +DRIVER_MODULE(if_ar, pci, ar_pci_driver, ar_devclass, 0, 0); -static const char * -ar_pci_probe(pcici_t tag, pcidi_t type) +static int +ar_pci_probe(device_t device) { + u_int32_t type = pci_get_devid(device); + switch(type) { case 0x5012114f: - return ("Digi SYNC/570i-PCI 2 port"); + device_set_desc(device, "Digi SYNC/570i-PCI 2 port"); + return (0); break; case 0x5010114f: printf("Digi SYNC/570i-PCI 2 port (mapped below 1M)\n"); printf("Please change the jumper to select linear mode.\n"); break; case 0x5013114f: - return ("Digi SYNC/570i-PCI 4 port"); + device_set_desc(device, "Digi SYNC/570i-PCI 4 port"); + return (0); break; case 0x5011114f: printf("Digi SYNC/570i-PCI 4 port (mapped below 1M)\n"); @@ -89,38 +98,73 @@ ar_pci_probe(pcici_t tag, pcidi_t type) default: break; } - return (0); + return (ENXIO); } -static void -ar_pci_attach(pcici_t config_id, int unit) +static int +ar_pci_attach(device_t device) { + int error; + u_int i, tmp; u_char *inten; - void *hc; - vm_offset_t mem_vaddr, mem_paddr; - vm_offset_t plx_vaddr, plx_paddr; - - if(!pci_map_mem(config_id, 0x10, &plx_vaddr, &plx_paddr)) { - printf("arp: map failed.\n"); - return; - } - - if(!pci_map_mem(config_id, 0x18, &mem_vaddr, &mem_paddr)) { - printf("arp: map failed.\n"); - return; - } - - hc = arattach_pci(unit, mem_vaddr); - if(!hc) - return; + struct ar_hardc *hc; + + hc = (struct ar_hardc *)device_get_softc(device); + bzero(hc, sizeof(struct ar_hardc)); + + error = ar_allocate_plx_memory(device, 0x10, 1); + if(error) + goto errexit; + + error = ar_allocate_memory(device, 0x18, 1); + if(error) + goto errexit; + + error = ar_allocate_irq(device, 0, 1); + if(error) + goto errexit; + + hc->plx_mem = rman_get_virtual(hc->res_plx_memory); + hc->mem_start = rman_get_virtual(hc->res_memory); + + hc->cunit = device_get_unit(device); + hc->sca[0] = (sca_regs *)(hc->mem_start + AR_PCI_SCA_1_OFFSET); + hc->sca[1] = (sca_regs *)(hc->mem_start + AR_PCI_SCA_2_OFFSET); + hc->iobase = 0; + hc->orbase = (u_char *)(hc->mem_start + AR_PCI_ORBASE_OFFSET); + + tmp = hc->orbase[AR_BMI * 4]; + hc->bustype = tmp & AR_BUS_MSK; + hc->memsize = (tmp & AR_MEM_MSK) >> AR_MEM_SHFT; + hc->memsize = 1 << hc->memsize; + hc->memsize <<= 16; + hc->interface[0] = (tmp & AR_IFACE_MSK); + tmp = hc->orbase[AR_REV * 4]; + hc->revision = tmp & AR_REV_MSK; + hc->winsize = (1 << ((tmp & AR_WSIZ_MSK) >> AR_WSIZ_SHFT)) * 16 * 1024; + hc->mem_end = (caddr_t)(hc->mem_start + hc->winsize); + hc->winmsk = hc->winsize - 1; + hc->numports = hc->orbase[AR_PNUM * 4]; + hc->handshake = hc->orbase[AR_HNDSH * 4]; + + for(i = 1; i < hc->numports; i++) + hc->interface[i] = hc->interface[0]; + + TRC(printf("arp%d: bus %x, rev %d, memstart %p, winsize %d, " + "winmsk %x, interface %x\n", + unit, hc->bustype, hc->revision, hc->mem_start, hc->winsize, + hc->winmsk, hc->interface[0])); + + ar_attach(device); /* Magic to enable the card to generate interrupts. */ - inten = (u_char *)plx_vaddr; + inten = (u_char *)hc->plx_mem; inten[0x69] = 0x09; - if(!pci_map_int(config_id, arintr_hc, (void *)hc, &net_imask)) { - free(hc, M_DEVBUF); - return; - } + return (0); + +errexit: + ar_deallocate_resources(device); + return (ENXIO); } -#endif + diff --git a/sys/dev/ar/if_arregs.h b/sys/dev/ar/if_arregs.h index 32e3b0d..552d20e 100644 --- a/sys/dev/ar/if_arregs.h +++ b/sys/dev/ar/if_arregs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1999 John Hay. All rights reserved. + * Copyright (c) 1995 - 2001 John Hay. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -167,4 +167,61 @@ #define AR_PIM_READ AR_PIM_MODEG #define AR_PIM_WRITE AR_PIM_MODEY +#define ARC_GET_WIN(addr) ((addr >> ARC_WIN_SHFT) & AR_WIN_MSK) + +#define ARC_SET_MEM(iobase,win) outb(iobase+AR_MSCA_EN, AR_ENA_MEM | \ + ARC_GET_WIN(win)) +#define ARC_SET_SCA(iobase,ch) outb(iobase+AR_MSCA_EN, AR_ENA_MEM | \ + AR_ENA_SCA | (ch ? AR_SEL_SCA_1:AR_SEL_SCA_0)) +#define ARC_SET_OFF(iobase) outb(iobase+AR_MSCA_EN, 0) + +struct ar_hardc { + int cunit; + struct ar_softc *sc; + u_short iobase; + int isa_irq; + int numports; + caddr_t mem_start; + caddr_t mem_end; + caddr_t plx_mem; + u_char *orbase; + + u_int memsize; /* in bytes */ + u_int winsize; /* in bytes */ + u_int winmsk; + u_char bustype; /* ISA, MCA, PCI.... */ + u_char interface[NPORT];/* X21, V.35, EIA-530.... */ + u_char revision; + u_char handshake; /* handshake lines supported by card. */ + + u_char txc_dtr[NPORT/NCHAN]; /* the register is write only */ + u_int txc_dtr_off[NPORT/NCHAN]; + + sca_regs *sca[NPORT/NCHAN]; + + bus_space_tag_t bt; + bus_space_handle_t bh; + int rid_ioport; + int rid_memory; + int rid_plx_memory; + int rid_irq; + int rid_drq; + struct resource* res_ioport; /* resource for port range */ + struct resource* res_memory; /* resource for mem range */ + struct resource* res_plx_memory; + struct resource* res_irq; /* resource for irq range */ + struct resource* res_drq; /* resource for dma channel */ + void *intr_cookie; +}; + +extern devclass_t ar_devclass; + +int ar_allocate_ioport(device_t device, int rid, u_long size); +int ar_allocate_irq(device_t device, int rid, u_long size); +int ar_allocate_memory(device_t device, int rid, u_long size); +int ar_allocate_plx_memory(device_t device, int rid, u_long size); +int ar_deallocate_resources(device_t device); +int ar_attach(device_t device); +int ar_detach (device_t); + #endif /* _IF_ARREGS_H_ */ |