diff options
author | wpaul <wpaul@FreeBSD.org> | 1999-07-20 21:23:17 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 1999-07-20 21:23:17 +0000 |
commit | 636feedd28b9d8d576a4624516dbcd34d7598dae (patch) | |
tree | d0364f774de340b9d6450379c5e5c1180fe54d2d /sys/pci | |
parent | ab3ab1d2c07331358b51abfe403df7a9113aca45 (diff) | |
download | FreeBSD-src-636feedd28b9d8d576a4624516dbcd34d7598dae.zip FreeBSD-src-636feedd28b9d8d576a4624516dbcd34d7598dae.tar.gz |
Convert the xl driver to newbus. It is now possible to make this driver
into a loadable module, and all of the platform dependencies are gone
(except for the alpha_XXX_dmamap() thing, which is another issue -- I
still don't know how to use the busdma stuff with a network driver).
Also increase the delay in xl_reset(); testing on a 486/66 with a 3c905C
shows that reading the EEPROM fails immediately after a reset. Waiting
a little longer after the reset completes seems to fix it.
Diffstat (limited to 'sys/pci')
-rw-r--r-- | sys/pci/if_xl.c | 210 | ||||
-rw-r--r-- | sys/pci/if_xlreg.h | 5 |
2 files changed, 127 insertions, 88 deletions
diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c index 868a179..fbe1e5c 100644 --- a/sys/pci/if_xl.c +++ b/sys/pci/if_xl.c @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_xl.c,v 1.43 1999/07/07 21:49:14 wpaul Exp $ + * $Id: if_xl.c,v 1.44 1999/07/08 00:42:02 wpaul Exp $ */ /* @@ -120,6 +120,9 @@ #include <machine/bus_memio.h> #include <machine/bus_pio.h> #include <machine/bus.h> +#include <machine/resource.h> +#include <sys/bus.h> +#include <sys/rman.h> #include <pci/pcireg.h> #include <pci/pcivar.h> @@ -160,7 +163,7 @@ #if !defined(lint) static const char rcsid[] = - "$Id: if_xl.c,v 1.43 1999/07/07 21:49:14 wpaul Exp $"; + "$Id: if_xl.c,v 1.44 1999/07/08 00:42:02 wpaul Exp $"; #endif /* @@ -216,9 +219,9 @@ static struct xl_type xl_phys[] = { { 0, 0, "<MII-compliant physical interface>" } }; -static unsigned long xl_count = 0; -static const char *xl_probe __P((pcici_t, pcidi_t)); -static void xl_attach __P((pcici_t, int)); +static int xl_probe __P((device_t)); +static int xl_attach __P((device_t)); +static int xl_detach __P((device_t)); static int xl_newbuf __P((struct xl_softc *, struct xl_chain_onefrag *)); @@ -235,7 +238,7 @@ static int xl_ioctl __P((struct ifnet *, u_long, caddr_t)); static void xl_init __P((void *)); static void xl_stop __P((struct xl_softc *)); static void xl_watchdog __P((struct ifnet *)); -static void xl_shutdown __P((int, void *)); +static void xl_shutdown __P((device_t)); static int xl_ifmedia_upd __P((struct ifnet *)); static void xl_ifmedia_sts __P((struct ifnet *, struct ifmediareq *)); @@ -266,6 +269,25 @@ static void xl_mediacheck __P((struct xl_softc *)); static void xl_testpacket __P((struct xl_softc *)); #endif +static device_method_t xl_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, xl_probe), + DEVMETHOD(device_attach, xl_attach), + DEVMETHOD(device_detach, xl_detach), + DEVMETHOD(device_shutdown, xl_shutdown), + { 0, 0 } +}; + +static driver_t xl_driver = { + "xl", + xl_methods, + sizeof(struct xl_softc) +}; + +static devclass_t xl_devclass; + +DRIVER_MODULE(xl, pci, xl_driver, xl_devclass, 0, 0); + /* * Murphy's law says that it's possible the chip can wedge and * the 'command in progress' bit may never clear. Hence, we wait @@ -1232,7 +1254,7 @@ static void xl_reset(sc) printf("xl%d: reset didn't complete\n", sc->xl_unit); /* Wait a little while for the chip to get its brains in order. */ - DELAY(1000); + DELAY(100000); return; } @@ -1240,24 +1262,23 @@ static void xl_reset(sc) * Probe for a 3Com Etherlink XL chip. Check the PCI vendor and device * IDs against our list and return a device name if we find a match. */ -static const char * -xl_probe(config_id, device_id) - pcici_t config_id; - pcidi_t device_id; +static int xl_probe(dev) + device_t dev; { struct xl_type *t; t = xl_devs; while(t->xl_name != NULL) { - if ((device_id & 0xFFFF) == t->xl_vid && - ((device_id >> 16) & 0xFFFF) == t->xl_did) { - return(t->xl_name); + if ((pci_get_vendor(dev) == t->xl_vid) && + (pci_get_device(dev) == t->xl_did)) { + device_set_desc(dev, t->xl_name); + return(0); } t++; } - return(NULL); + return(ENXIO); } /* @@ -1377,15 +1398,11 @@ static void xl_mediacheck(sc) * Attach the interface. Allocate softc structures, do ifmedia * setup and ethernet/BPF attach. */ -static void -xl_attach(config_id, unit) - pcici_t config_id; - int unit; +static int +xl_attach(dev) + device_t dev; { int s, i; -#ifndef XL_USEIOSPACE - vm_offset_t pbase, vbase; -#endif u_char eaddr[ETHER_ADDR_LEN]; u_int32_t command; struct xl_softc *sc; @@ -1395,14 +1412,12 @@ xl_attach(config_id, unit) caddr_t roundptr; struct xl_type *p; u_int16_t phy_vid, phy_did, phy_sts; + int unit, error, rid; s = splimp(); - sc = malloc(sizeof(struct xl_softc), M_DEVBUF, M_NOWAIT); - if (sc == NULL) { - printf("xl%d: no memory for softc struct!\n", unit); - goto fail; - } + sc = device_get_softc(dev); + unit = device_get_unit(dev); bzero(sc, sizeof(struct xl_softc)); /* @@ -1423,85 +1438,85 @@ xl_attach(config_id, unit) * back in the D0 state, then restore the PCI config ourselves. */ - command = pci_conf_read(config_id, XL_PCI_CAPID) & 0x000000FF; + command = pci_read_config(dev, XL_PCI_CAPID, 4) & 0x000000FF; if (command == 0x01) { - command = pci_conf_read(config_id, XL_PCI_PWRMGMTCTRL); + command = pci_read_config(dev, XL_PCI_PWRMGMTCTRL, 4); if (command & XL_PSTATE_MASK) { u_int32_t iobase, membase, irq; /* Save important PCI config data. */ - iobase = pci_conf_read(config_id, XL_PCI_LOIO); - membase = pci_conf_read(config_id, XL_PCI_LOMEM); - irq = pci_conf_read(config_id, XL_PCI_INTLINE); + iobase = pci_read_config(dev, XL_PCI_LOIO, 4); + membase = pci_read_config(dev, XL_PCI_LOMEM, 4); + irq = pci_read_config(dev, XL_PCI_INTLINE, 4); /* Reset the power state. */ printf("xl%d: chip is in D%d power mode " "-- setting to D0\n", unit, command & XL_PSTATE_MASK); command &= 0xFFFFFFFC; - pci_conf_write(config_id, XL_PCI_PWRMGMTCTRL, command); + pci_write_config(dev, XL_PCI_PWRMGMTCTRL, command, 4); /* Restore PCI config data. */ - pci_conf_write(config_id, XL_PCI_LOIO, iobase); - pci_conf_write(config_id, XL_PCI_LOMEM, membase); - pci_conf_write(config_id, XL_PCI_INTLINE, irq); + pci_write_config(dev, XL_PCI_LOIO, iobase, 4); + pci_write_config(dev, XL_PCI_LOMEM, membase, 4); + pci_write_config(dev, XL_PCI_INTLINE, irq, 4); } } /* * Map control/status registers. */ - command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG); + command = pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4); command |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); - pci_conf_write(config_id, PCI_COMMAND_STATUS_REG, command); - command = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG); + pci_write_config(dev, PCI_COMMAND_STATUS_REG, command, 4); + command = pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4); #ifdef XL_USEIOSPACE if (!(command & PCIM_CMD_PORTEN)) { printf("xl%d: failed to enable I/O ports!\n", unit); - free(sc, M_DEVBUF); + error = ENXIO; goto fail; } - if (!pci_map_port(config_id, XL_PCI_LOIO, - (pci_port_t *)&(sc->xl_bhandle))) { - printf ("xl%d: couldn't map port\n", unit); - printf ("xl%d: WARNING: check your BIOS and " - "set 'Plug & Play OS' to 'no'\n", unit); - printf ("xl%d: attempting to map iobase manually\n", unit); - sc->xl_bhandle = - pci_conf_read(config_id, XL_PCI_LOIO) & 0xFFFFFFE0; - /*goto fail;*/ - } - -#ifdef __i386__ - sc->xl_btag = I386_BUS_SPACE_IO; -#endif -#ifdef __alpha__ - sc->xl_btag = ALPHA_BUS_SPACE_IO; -#endif + rid = XL_PCI_LOIO; + sc->xl_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, + 0, ~0, 1, RF_ACTIVE); #else if (!(command & PCIM_CMD_MEMEN)) { printf("xl%d: failed to enable memory mapping!\n", unit); + error = ENXIO; goto fail; } - if (!pci_map_mem(config_id, XL_PCI_LOMEM, &vbase, &pbase)) { - printf ("xl%d: couldn't map memory\n", unit); + rid = XL_PCI_LOMEM; + sc->xl_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, + 0, ~0, 1, RF_ACTIVE); +#endif + + if (sc->xl_res == NULL) { + printf ("xl%d: couldn't map ports\n", unit); + error = ENXIO; goto fail; } - sc->xl_bhandle = vbase; -#ifdef __i386__ - sc->xl_btag = I386_BUS_SPACE_MEM; -#endif -#ifdef __alpha__ - sc->xl_btag = ALPHA_BUS_SPACE_MEM; -#endif -#endif - /* Allocate interrupt */ - if (!pci_map_int(config_id, xl_intr, sc, &net_imask)) { + sc->xl_btag = rman_get_bustag(sc->xl_res); + sc->xl_bhandle = rman_get_bushandle(sc->xl_res); + + rid = 0; + sc->xl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, + RF_SHAREABLE | RF_ACTIVE); + + if (sc->xl_irq == NULL) { printf("xl%d: couldn't map interrupt\n", unit); + error = ENXIO; + goto fail; + } + + error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET, + xl_intr, sc, &sc->xl_intrhand); + + if (error) { + printf("xl%d: couldn't set up irq\n", unit); goto fail; } @@ -1513,7 +1528,7 @@ xl_attach(config_id, unit) */ if (xl_read_eeprom(sc, (caddr_t)&eaddr, XL_EE_OEM_ADR0, 3, 1)) { printf("xl%d: failed to read station address\n", sc->xl_unit); - free(sc, M_DEVBUF); + error = ENXIO; goto fail; } @@ -1529,8 +1544,8 @@ xl_attach(config_id, unit) sc->xl_ldata_ptr = malloc(sizeof(struct xl_list_data) + 8, M_DEVBUF, M_NOWAIT); if (sc->xl_ldata_ptr == NULL) { - free(sc, M_DEVBUF); printf("xl%d: no memory for list buffers!\n", unit); + error = ENXIO; goto fail; } @@ -1794,11 +1809,41 @@ xl_attach(config_id, unit) #if NBPF > 0 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); #endif - at_shutdown(xl_shutdown, sc, SHUTDOWN_POST_SYNC); fail: splx(s); - return; + return(0); +} + +static int xl_detach(dev) + device_t dev; +{ + struct xl_softc *sc; + struct ifnet *ifp; + int s; + + s = splimp(); + + sc = device_get_softc(dev); + ifp = &sc->arpcom.ac_if; + + xl_stop(sc); + if_detach(ifp); + + bus_teardown_intr(dev, sc->xl_irq, sc->xl_intrhand); + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->xl_irq); +#ifdef XL_USEIOSPACE + bus_release_resource(dev, SYS_RES_IOPORT, XL_PCI_LOIO, sc->xl_res); +#else + bus_release_resource(dev, SYS_RES_MEMORY, XL_PCI_LOMEM, sc->xl_res); +#endif + + free(sc->xl_ldata_ptr, M_DEVBUF); + ifmedia_removeall(&sc->ifmedia); + + splx(s); + + return(0); } /* @@ -2917,23 +2962,14 @@ static void xl_stop(sc) * Stop all chip I/O so that the kernel's probe routines don't * get confused by errant DMAs when rebooting. */ -static void xl_shutdown(howto, arg) - int howto; - void *arg; +static void xl_shutdown(dev) + device_t dev; { - struct xl_softc *sc = (struct xl_softc *)arg; + struct xl_softc *sc; + + sc = device_get_softc(dev); xl_stop(sc); return; } - - -static struct pci_device xl_device = { - "xl", - xl_probe, - xl_attach, - &xl_count, - NULL -}; -COMPAT_PCI_DRIVER(xl, xl_device); diff --git a/sys/pci/if_xlreg.h b/sys/pci/if_xlreg.h index 49f95a4..c748246 100644 --- a/sys/pci/if_xlreg.h +++ b/sys/pci/if_xlreg.h @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_xlreg.h,v 1.16 1999/05/26 23:01:52 gallatin Exp $ + * $Id: if_xlreg.h,v 1.17 1999/05/30 18:09:17 wpaul Exp $ */ #define XL_EE_READ 0x0080 /* read, 5 bit address */ @@ -541,6 +541,9 @@ struct xl_softc { struct ifmedia ifmedia; /* media info */ bus_space_handle_t xl_bhandle; bus_space_tag_t xl_btag; + void *xl_intrhand; + struct resource *xl_irq; + struct resource *xl_res; struct xl_type *xl_info; /* 3Com adapter info */ struct xl_type *xl_pinfo; /* phy info */ u_int8_t xl_unit; /* interface number */ |