summaryrefslogtreecommitdiffstats
path: root/sys/dev/ar
diff options
context:
space:
mode:
authorjhay <jhay@FreeBSD.org>2001-01-24 18:45:29 +0000
committerjhay <jhay@FreeBSD.org>2001-01-24 18:45:29 +0000
commit1acb4466b06b7dde27e22ccf97f77182199cd3b0 (patch)
tree4106297a7393c56a7e57c90646ff94da95b89e9d /sys/dev/ar
parent4c773ee5aad277b37efa1e792875eebd015806f2 (diff)
downloadFreeBSD-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.c460
-rw-r--r--sys/dev/ar/if_ar_isa.c460
-rw-r--r--sys/dev/ar/if_ar_pci.c154
-rw-r--r--sys/dev/ar/if_arregs.h59
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_ */
OpenPOWER on IntegriCloud