File:  [DragonFly] / src / sys / contrib / dev / oltr / Attic / if_oltr.c
Revision 1.9: download - view: text, annotated - select for diffs
Thu Feb 12 22:38:59 2004 UTC (10 years, 6 months ago) by joerg
Branches: MAIN
CVS tags: HEAD
Add __DragonFly__

    1: /*
    2:  * Copyright (c) 1998, Larry Lile
    3:  * All rights reserved.
    4:  *
    5:  * For latest sources and information on this driver, please
    6:  * go to http://anarchy.stdio.com.
    7:  *
    8:  * Questions, comments or suggestions should be directed to
    9:  * Larry Lile <lile@stdio.com>.
   10:  *
   11:  * Redistribution and use in source and binary forms, with or without
   12:  * modification, are permitted provided that the following conditions
   13:  * are met:
   14:  * 1. Redistributions of source code must retain the above copyright
   15:  *    notice unmodified, this list of conditions, and the following
   16:  *    disclaimer.
   17:  * 2. Redistributions in binary form must reproduce the above copyright
   18:  *    notice, this list of conditions and the following disclaimer in the
   19:  *    documentation and/or other materials provided with the distribution.
   20:  *
   21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31:  * SUCH DAMAGE.
   32:  *
   33:  * $FreeBSD: src/sys/contrib/dev/oltr/if_oltr.c,v 1.11.2.5 2001/10/20 04:15:21 mdodd Exp $
   34:  * $DragonFly: src/sys/contrib/dev/oltr/if_oltr.c,v 1.9 2004/02/12 22:38:59 joerg Exp $
   35:  */
   36: 
   37: #include <sys/param.h>
   38: #include <sys/systm.h>
   39: #include <sys/sockio.h>
   40: #include <sys/mbuf.h>
   41: #include <sys/malloc.h>
   42: #include <sys/kernel.h>
   43: #include <sys/socket.h>
   44: #include <sys/param.h>
   45: 
   46: #include <net/if.h>
   47: #include <net/if_arp.h>
   48: #include <net/iso88025.h>
   49: #include <net/ethernet.h>
   50: #include <net/if_dl.h>
   51: #include <net/if_media.h>
   52: #include <net/iso88025.h>
   53: 
   54: #if (NBPFILTER > 0)
   55: #include <net/bpf.h>
   56: #endif
   57: 
   58: #include <vm/vm.h>              /* for vtophys */
   59: #include <vm/pmap.h>            /* for vtophys */
   60: #include <machine/bus_memio.h>
   61: #include <machine/bus_pio.h>
   62: #include <machine/bus.h>
   63: #include <machine/resource.h>
   64: #include <machine/clock.h>
   65: #include <sys/bus.h>
   66: #include <sys/rman.h>
   67: 
   68: #include <bus/pci/pcireg.h>
   69: #include <bus/pci/pcivar.h>
   70: 
   71: #include "contrib/dev/oltr/trlld.h"
   72: 
   73: /*#define DEBUG_MASK DEBUG_POLL*/
   74: 
   75: #ifndef DEBUG_MASK
   76: #define DEBUG_MASK 0x0000
   77: #endif
   78: 
   79: #define DEBUG_POLL	0x0001
   80: #define DEBUG_INT	0x0002
   81: #define DEBUG_INIT	0x0004
   82: #define DEBUG_FN_ENT	0x8000
   83: 
   84: #define PCI_VENDOR_OLICOM 0x108D
   85: 
   86: #define MIN3(A,B,C) (MIN(A, (MIN(B, C))))
   87: 
   88: char *AdapterName[] = {
   89: 	/*  0 */ "Olicom XT Adapter [unsupported]",
   90: 	/*  1 */ "Olicom OC-3115",
   91: 	/*  2 */ "Olicom ISA 16/4 Adapter (OC-3117)",
   92: 	/*  3 */ "Olicom ISA 16/4 Adapter (OC-3118)",
   93: 	/*  4 */ "Olicom MCA 16/4 Adapter (OC-3129) [unsupported]",
   94: 	/*  5 */ "Olicom MCA 16/4 Adapter (OC-3129) [unsupported]",
   95: 	/*  6 */ "Olicom MCA 16/4 Adapter (OC-3129) [unsupported]",
   96: 	/*  7 */ "Olicom EISA 16/4 Adapter (OC-3133)",
   97: 	/*  8 */ "Olicom EISA 16/4 Adapter (OC-3133)",
   98: 	/*  9 */ "Olicom EISA 16/4 Server Adapter (OC-3135)",
   99: 	/* 10 */ "Olicom PCI 16/4 Adapter (OC-3136)",
  100: 	/* 11 */ "Olicom PCI 16/4 Adapter (OC-3136)",
  101: 	/* 12 */ "Olicom PCI/II 16/4 Adapter (OC-3137)",
  102: 	/* 13 */ "Olicom PCI 16/4 Adapter (OC-3139)",
  103: 	/* 14 */ "Olicom RapidFire 3140 16/4 PCI Adapter (OC-3140)",
  104: 	/* 15 */ "Olicom RapidFire 3141 Fiber Adapter (OC-3141)",
  105: 	/* 16 */ "Olicom PCMCIA 16/4 Adapter (OC-3220) [unsupported]",
  106: 	/* 17 */ "Olicom PCMCIA 16/4 Adapter (OC-3121, OC-3230, OC-3232) [unsupported]",
  107: 	/* 18 */ "Olicom PCMCIA 16/4 Adapter (OC-3250)",
  108: 	/* 19 */ "Olicom RapidFire 3540 100/16/4 Adapter (OC-3540)"
  109: };
  110: 
  111: /*
  112:  * Glue function prototypes for PMW kit IO
  113:  */
  114: 
  115: #ifndef TRlldInlineIO
  116: static void DriverOutByte	(unsigned short, unsigned char);
  117: static void DriverOutWord	(unsigned short, unsigned short);
  118: static void DriverOutDword	(unsigned short, unsigned long);
  119: static void DriverRepOutByte	(unsigned short, unsigned char  *, int);
  120: static void DriverRepOutWord	(unsigned short, unsigned short *, int);
  121: static void DriverRepOutDword	(unsigned short, unsigned long  *, int);
  122: static unsigned char  DriverInByte (unsigned short);
  123: static unsigned short DriverInWord (unsigned short);
  124: static unsigned long  DriverInDword (unsigned short);
  125: static void DriverRepInByte	(unsigned short, unsigned char  *, int);
  126: static void DriverRepInWord	(unsigned short, unsigned short *, int);
  127: static void DriverRepInDword	(unsigned short, unsigned long  *, int);
  128: #endif /*TRlldInlineIO*/
  129: static void DriverSuspend	(unsigned short);
  130: static void DriverStatus	(void *, TRlldStatus_t *);
  131: static void DriverCloseCompleted (void *);
  132: static void DriverStatistics	(void *, TRlldStatistics_t *);
  133: static void DriverTransmitFrameCompleted (void *, void *, int);
  134: static void DriverReceiveFrameCompleted	(void *, int, int, void *, int);
  135: 
  136: static TRlldDriver_t LldDriver = {
  137: 	TRLLD_VERSION,
  138: #ifndef TRlldInlineIO
  139: 	DriverOutByte,
  140: 	DriverOutWord,
  141: 	DriverOutDword,
  142: 	DriverRepOutByte,
  143: 	DriverRepOutWord,
  144: 	DriverRepOutDword,
  145: 	DriverInByte,
  146: 	DriverInWord,
  147: 	DriverInDword,
  148: 	DriverRepInByte,
  149: 	DriverRepInWord,
  150: 	DriverRepInDword,
  151: #endif /*TRlldInlineIO*/
  152: 	DriverSuspend,
  153: 	DriverStatus,
  154: 	DriverCloseCompleted,
  155: 	DriverStatistics,
  156: 	DriverTransmitFrameCompleted,
  157: 	DriverReceiveFrameCompleted,
  158: };
  159: 
  160: struct oltr_rx_buf {
  161: 	int			index;
  162: 	char			*data;
  163: 	u_long			address;
  164: };
  165: 
  166: struct oltr_tx_buf {
  167: 	int			index;
  168: 	char 			*data;
  169: 	u_long			address;
  170: };
  171: 
  172: #define RING_BUFFER_LEN		16
  173: #define RING_BUFFER(x)		((RING_BUFFER_LEN - 1) & x)
  174: #define RX_BUFFER_LEN		2048
  175: #define TX_BUFFER_LEN		2048
  176: 
  177: struct oltr_softc {
  178: 	struct arpcom		arpcom;
  179: 	struct ifmedia		ifmedia;
  180: 	bus_space_handle_t	oltr_bhandle;
  181: 	bus_space_tag_t		oltr_btag;
  182: 	void			*oltr_intrhand;
  183: 	struct resource		*oltr_irq;
  184: 	struct resource		*oltr_res;
  185: 	int			unit;
  186: 	int 			state;
  187: #define OL_UNKNOWN	0
  188: #define OL_INIT		1
  189: #define OL_READY	2
  190: #define OL_CLOSING	3
  191: #define OL_CLOSED	4
  192: #define OL_OPENING	5
  193: #define OL_OPEN		6
  194: #define OL_PROMISC	7
  195: #define OL_DEAD		8
  196: 	struct oltr_rx_buf	rx_ring[RING_BUFFER_LEN];
  197: 	int			tx_head, tx_avail, tx_frame;
  198: 	struct oltr_tx_buf	tx_ring[RING_BUFFER_LEN];
  199: 	TRlldTransmit_t		frame_ring[RING_BUFFER_LEN];
  200: 	struct mbuf		*restart;
  201: 	TRlldAdapter_t		TRlldAdapter;
  202: 	TRlldStatistics_t	statistics;
  203: 	TRlldStatistics_t	current;
  204:         TRlldAdapterConfig_t    config;
  205: 	u_short			AdapterMode;
  206: 	u_long			GroupAddress;
  207: 	u_long			FunctionalAddress;
  208: 	struct callout_handle	oltr_poll_ch;
  209: 	/*struct callout_handle	oltr_stat_ch;*/
  210: 	void			*work_memory;
  211: };
  212: 
  213: #define SELF_TEST_POLLS	32
  214: 
  215: void oltr_poll 			(void *);
  216: /*void oltr_stat 			(void *);*/
  217: 
  218: static void oltr_start		(struct ifnet *);
  219: static void oltr_stop		(struct oltr_softc *);
  220: static void oltr_close		(struct oltr_softc *);
  221: static void oltr_init		(void *);
  222: static int oltr_ioctl		(struct ifnet *, u_long, caddr_t);
  223: static void oltr_intr		(void *);
  224: static int oltr_ifmedia_upd	(struct ifnet *);
  225: static void oltr_ifmedia_sts	(struct ifnet *, struct ifmediareq *);
  226: 
  227: #if defined(__DragonFly__) || __FreeBSD_version > 400000
  228: 
  229: static int oltr_pci_probe		(device_t);
  230: static int oltr_pci_attach	(device_t);
  231: static int oltr_pci_detach	(device_t);
  232: static void oltr_pci_shutdown	(device_t);
  233: 
  234: static device_method_t oltr_methods[] = {
  235: 	DEVMETHOD(device_probe,		oltr_pci_probe),
  236: 	DEVMETHOD(device_attach,	oltr_pci_attach),
  237: 	DEVMETHOD(device_detach,	oltr_pci_detach),
  238: 	DEVMETHOD(device_shutdown,	oltr_pci_shutdown),
  239:         { 0, 0 }
  240: };
  241: 
  242: static driver_t oltr_driver = {
  243: 	"oltr",
  244: 	oltr_methods,
  245: 	sizeof(struct oltr_softc)
  246: };
  247: 
  248: static devclass_t oltr_devclass;
  249: 
  250: DRIVER_MODULE(oltr, pci, oltr_driver, oltr_devclass, 0, 0);
  251: 
  252: static int
  253: oltr_pci_probe(device_t dev)
  254: {
  255:         int                     i, rc;
  256:         char                    PCIConfigHeader[64];
  257:         TRlldAdapterConfig_t    config;
  258: 
  259:         if ((pci_get_vendor(dev) == PCI_VENDOR_OLICOM) &&
  260:            ((pci_get_device(dev) == 0x0001) ||
  261: 	    (pci_get_device(dev) == 0x0004) ||
  262:             (pci_get_device(dev) == 0x0005) ||
  263: 	    (pci_get_device(dev) == 0x0007) ||
  264:             (pci_get_device(dev) == 0x0008))) {
  265: 
  266:                 for (i = 0; i < sizeof(PCIConfigHeader); i++)
  267:                         PCIConfigHeader[i] = pci_read_config(dev, i, 1);
  268: 
  269:                 rc = TRlldPCIConfig(&LldDriver, &config, PCIConfigHeader);
  270:                 if (rc == TRLLD_PCICONFIG_FAIL) {
  271:                         device_printf(dev, "TRlldPciConfig failed!\n");
  272:                         return(ENXIO);
  273:                 }
  274:                 if (rc == TRLLD_PCICONFIG_VERSION) {
  275:                         device_printf(dev, "wrong LLD version\n");
  276:                         return(ENXIO);
  277:                 }
  278:                 device_set_desc(dev, AdapterName[config.type]);
  279:                 return(0);
  280:         }
  281:         return(ENXIO);
  282: }
  283: 
  284: static int
  285: oltr_pci_attach(device_t dev)
  286: {
  287:         int 			i, s, rc = 0, rid,
  288: 				scratch_size;
  289: 	int			media = IFM_TOKEN|IFM_TOK_UTP16;
  290: 	u_long 			command;
  291: 	char 			PCIConfigHeader[64];
  292: 	struct oltr_softc		*sc = device_get_softc(dev);
  293: 	struct ifnet		*ifp = &sc->arpcom.ac_if;
  294: 
  295:         s = splimp();
  296: 
  297:        	bzero(sc, sizeof(struct oltr_softc));
  298: 	sc->unit = device_get_unit(dev);
  299: 	sc->state = OL_UNKNOWN;
  300: 
  301: 	for (i = 0; i < sizeof(PCIConfigHeader); i++)
  302: 		PCIConfigHeader[i] = pci_read_config(dev, i, 1);
  303: 
  304: 	switch(TRlldPCIConfig(&LldDriver, &sc->config, PCIConfigHeader)) {
  305: 	case TRLLD_PCICONFIG_OK:
  306: 		break;
  307: 	case TRLLD_PCICONFIG_SET_COMMAND:
  308: 		device_printf(dev, "enabling bus master mode\n");
  309: 		command = pci_read_config(dev, PCIR_COMMAND, 4);
  310: 		pci_write_config(dev, PCIR_COMMAND,
  311: 			(command | PCIM_CMD_BUSMASTEREN), 4);
  312: 		command = pci_read_config(dev, PCIR_COMMAND, 4);
  313: 		if (!(command & PCIM_CMD_BUSMASTEREN)) {
  314: 			device_printf(dev, "failed to enable bus master mode\n");
  315: 			goto config_failed;
  316: 		}
  317: 		break;
  318: 	case TRLLD_PCICONFIG_FAIL:
  319: 		device_printf(dev, "TRlldPciConfig failed!\n");
  320: 		goto config_failed;
  321: 		break;
  322: 	case TRLLD_PCICONFIG_VERSION:
  323: 		device_printf(dev, "wrong LLD version\n");
  324: 		goto config_failed;
  325: 		break;
  326: 	}
  327: 	device_printf(dev, "MAC address %6D\n", sc->config.macaddress, ":");
  328: 
  329: 	scratch_size = TRlldAdapterSize();
  330: 	if (bootverbose)
  331: 		device_printf(dev, "adapter memory block size %d bytes\n", scratch_size);
  332: 	sc->TRlldAdapter = (TRlldAdapter_t)malloc(scratch_size, M_DEVBUF, M_NOWAIT);
  333: 	if (sc->TRlldAdapter == NULL) {
  334: 		device_printf(dev, "couldn't allocate scratch buffer (%d bytes)\n", scratch_size);
  335: 		goto config_failed;
  336: 	}
  337: 
  338: 	/*
  339: 	 * Allocate RX/TX Pools
  340: 	 */
  341: 	for (i = 0; i < RING_BUFFER_LEN; i++) {
  342: 		sc->rx_ring[i].index = i;
  343: 		sc->rx_ring[i].data = (char *)malloc(RX_BUFFER_LEN, M_DEVBUF, M_NOWAIT);
  344: 		sc->rx_ring[i].address = vtophys(sc->rx_ring[i].data);
  345: 		sc->tx_ring[i].index = i;
  346: 		sc->tx_ring[i].data = (char *)malloc(TX_BUFFER_LEN, M_DEVBUF, M_NOWAIT);
  347: 		sc->tx_ring[i].address = vtophys(sc->tx_ring[i].data);
  348: 		if ((!sc->rx_ring[i].data) || (!sc->tx_ring[i].data)) {
  349: 			device_printf(dev, "unable to allocate ring buffers\n");
  350: 			while (i > 0) {
  351: 				if (sc->rx_ring[i].data)
  352: 					free(sc->rx_ring[i].data, M_DEVBUF);
  353: 				if (sc->tx_ring[i].data)
  354: 					free(sc->tx_ring[i].data, M_DEVBUF);
  355: 				i--;
  356: 			}
  357: 			goto config_failed;
  358: 		}
  359: 	}
  360: 	
  361: 	/*
  362: 	 * Allocate interrupt and DMA channel
  363: 	 */
  364: 	rid = 0;
  365: 	sc->oltr_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
  366: 		(sc->config.mode & TRLLD_MODE_SHARE_INTERRUPT ? RF_ACTIVE | RF_SHAREABLE : RF_ACTIVE));
  367: 	if (sc->oltr_irq == NULL) {
  368: 		device_printf(dev, "couldn't map interrupt\n");
  369: 		goto config_failed;
  370: 	}
  371: 	if (bus_setup_intr(dev, sc->oltr_irq, INTR_TYPE_NET, oltr_intr, sc, &sc->oltr_intrhand)) {
  372: 		device_printf(dev, "couldn't setup interrupt\n");
  373: 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->oltr_irq);
  374: 		goto config_failed;
  375: 	}
  376: 
  377: 	/*
  378: 	 * Do the ifnet initialization
  379: 	 */
  380: 	ifp->if_softc	= sc;
  381: 	if_initname(ifp, "oltr", device_get_unit(dev));
  382: 	ifp->if_output	= iso88025_output;
  383: 	ifp->if_init	= oltr_init;
  384: 	ifp->if_start	= oltr_start;
  385: 	ifp->if_ioctl	= oltr_ioctl;
  386: 	ifp->if_flags	= IFF_BROADCAST;
  387: 	bcopy(sc->config.macaddress, sc->arpcom.ac_enaddr, sizeof(sc->config.macaddress));
  388: 
  389: 	/*
  390: 	 * Do ifmedia setup.
  391: 	 */
  392: 	ifmedia_init(&sc->ifmedia, 0, oltr_ifmedia_upd, oltr_ifmedia_sts);
  393: 	rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
  394: 	switch(sc->config.type) {
  395: 	case TRLLD_ADAPTER_PCI7:	/* OC-3540 */
  396: 		ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP100, 0, NULL);
  397: 		/* FALL THROUGH */
  398: 	case TRLLD_ADAPTER_PCI4:	/* OC-3139 */
  399: 	case TRLLD_ADAPTER_PCI5:	/* OC-3140 */
  400: 	case TRLLD_ADAPTER_PCI6:	/* OC-3141 */
  401: 		ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_AUTO, 0, NULL);
  402: 		media = IFM_TOKEN|IFM_AUTO;
  403: 		rc = TRlldSetSpeed(sc->TRlldAdapter, 0);
  404: 		/* FALL THROUGH */
  405: 	default:
  406: 		ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP4, 0, NULL);
  407: 		ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP16, 0, NULL);
  408: 		break;
  409: 	}
  410: 	sc->ifmedia.ifm_media = media;
  411: 	ifmedia_set(&sc->ifmedia, media);
  412: 
  413: 	/*
  414: 	 * Attach the interface
  415: 	 */
  416: 	if_attach(ifp);
  417: 	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
  418: 	iso88025_ifattach(ifp);
  419: 
  420: #if (NBPFILTER > 0) || defined(__DragonFly__) || (__FreeBSD_version > 400000)
  421: 	bpfattach(ifp, DLT_IEEE802, sizeof(struct iso88025_header));
  422: #endif
  423: 
  424: 	splx(s);
  425: 	return(0);
  426: 
  427: config_failed:
  428: 
  429: 	splx(s);
  430: 	return(ENXIO);
  431: }
  432: 
  433: static int
  434: oltr_pci_detach(device_t dev)
  435: {
  436: 	struct oltr_softc	*sc = device_get_softc(dev);
  437: 	struct ifnet		*ifp = &sc->arpcom.ac_if;
  438: 	int s, i;
  439: 
  440: 	device_printf(dev, "driver unloading\n");
  441: 
  442: 	s = splimp();
  443: 
  444: 	if_detach(ifp);
  445: 	if (sc->state > OL_CLOSED)
  446: 		oltr_stop(sc);
  447: 
  448: 	untimeout(oltr_poll, (void *)sc, sc->oltr_poll_ch);
  449: 	/*untimeout(oltr_stat, (void *)sc, sc->oltr_stat_ch);*/
  450: 
  451: 	bus_teardown_intr(dev, sc->oltr_irq, sc->oltr_intrhand);
  452: 	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->oltr_irq);
  453: 
  454: 	/* Deallocate all dynamic memory regions */
  455: 	for (i = 0; i < RING_BUFFER_LEN; i++) {
  456: 		free(sc->rx_ring[i].data, M_DEVBUF);
  457: 		free(sc->tx_ring[i].data, M_DEVBUF);
  458: 	}
  459: 	if (sc->work_memory)
  460: 		free(sc->work_memory, M_DEVBUF);
  461: 	free(sc->TRlldAdapter, M_DEVBUF);
  462: 
  463: 	(void)splx(s);
  464: 
  465: 	return(0);
  466: }
  467: 
  468: static void
  469: oltr_pci_shutdown(device_t dev)
  470: {
  471: 	struct oltr_softc		*sc = device_get_softc(dev);
  472: 
  473: 	device_printf(dev, "oltr_pci_shutdown called\n");
  474: 
  475: 	if (sc->state > OL_CLOSED)
  476: 		oltr_stop(sc);
  477: 
  478: 	return;
  479: }
  480: 
  481: #else
  482: 
  483: static const char *oltr_pci_probe	(pcici_t, pcidi_t);
  484: static void oltr_pci_attach		(pcici_t, int);
  485: 
  486: static unsigned long oltr_count = 0;
  487: 
  488: static struct pci_device oltr_device = {
  489: 	"oltr",
  490: 	oltr_pci_probe,
  491: 	oltr_pci_attach,
  492: 	&oltr_count,
  493: 	NULL
  494: };
  495: 
  496: DATA_SET(pcidevice_set, oltr_device);
  497: 
  498: static const char *
  499: oltr_pci_probe(pcici_t config_id, pcidi_t device_id)
  500: {
  501:         int                     i, rc;
  502:         char                    PCIConfigHeader[64];
  503:         TRlldAdapterConfig_t    config;
  504: 	
  505: 	if (((device_id & 0xffff) == PCI_VENDOR_OLICOM) && (
  506: 	    (((device_id >> 16) & 0xffff) == 0x0001) ||
  507: 	    (((device_id >> 16) & 0xffff) == 0x0004) ||
  508: 	    (((device_id >> 16) & 0xffff) == 0x0005) ||
  509: 	    (((device_id >> 16) & 0xffff) == 0x0007) ||
  510: 	    (((device_id >> 16) & 0xffff) == 0x0008))) {
  511: 	
  512: 		for (i = 0; i < 64; i++)
  513: 			PCIConfigHeader[i] = pci_cfgread(config_id, i, /* bytes */ 1);
  514: 
  515: 		rc = TRlldPCIConfig(&LldDriver, &config, PCIConfigHeader);
  516: 
  517: 		if (rc == TRLLD_PCICONFIG_FAIL) {
  518: 			printf("oltr: TRlldPciConfig failed!\n");
  519: 			return(NULL);
  520: 		}
  521: 		if (rc == TRLLD_PCICONFIG_VERSION) {
  522: 			printf("oltr: wrong LLD version.\n");
  523: 			return(NULL);
  524: 		}
  525: 		return(AdapterName[config.type]);
  526: 	}
  527: 
  528: 	return(NULL);
  529: }
  530: 
  531: static void
  532: oltr_pci_attach(pcici_t config_id, int unit)
  533: {
  534:         int 			i, s, rc = 0, scratch_size;
  535: 	int			media = IFM_TOKEN|IFM_TOK_UTP16;
  536: 	u_long 			command;
  537: 	char 			PCIConfigHeader[64];
  538: 	struct oltr_softc		*sc;
  539: 	struct ifnet		*ifp; /* = &sc->arpcom.ac_if; */
  540: 
  541:         s = splimp();
  542: 
  543: 	sc = malloc(sizeof(struct oltr_softc), M_DEVBUF, M_NOWAIT | M_ZERO);
  544: 	if (sc == NULL) {
  545: 		printf("oltr%d: no memory for softc struct!\n", unit);
  546: 		goto config_failed;
  547: 	}
  548: 	sc->unit = unit;
  549: 	sc->state = OL_UNKNOWN;
  550: 	ifp = &sc->arpcom.ac_if;
  551: 
  552: 	for (i = 0; i < sizeof(PCIConfigHeader); i++)
  553: 		PCIConfigHeader[i] = pci_cfgread(config_id, i, 1);
  554: 
  555: 	switch(TRlldPCIConfig(&LldDriver, &sc->config, PCIConfigHeader)) {
  556: 	case TRLLD_PCICONFIG_OK:
  557: 		break;
  558: 	case TRLLD_PCICONFIG_SET_COMMAND:
  559: 		printf("oltr%d: enabling bus master mode\n", unit);
  560: 		command = pci_conf_read(config_id, PCIR_COMMAND);
  561: 		pci_conf_write(config_id, PCIR_COMMAND, (command | PCIM_CMD_BUSMASTEREN));
  562: 		command = pci_conf_read(config_id, PCIR_COMMAND);
  563: 		if (!(command & PCIM_CMD_BUSMASTEREN)) {
  564: 			printf("oltr%d: failed to enable bus master mode\n", unit);
  565: 			goto config_failed;
  566: 		}
  567: 		break;
  568: 	case TRLLD_PCICONFIG_FAIL:
  569: 		printf("oltr%d: TRlldPciConfig failed!\n", unit);
  570: 		goto config_failed;
  571: 		break;
  572: 	case TRLLD_PCICONFIG_VERSION:
  573: 		printf("oltr%d: wrong LLD version\n", unit);
  574: 		goto config_failed;
  575: 		break;
  576: 	}
  577: 	printf("oltr%d: MAC address %6D\n", unit, sc->config.macaddress, ":");
  578: 
  579: 	scratch_size = TRlldAdapterSize();
  580: 	if (bootverbose)
  581: 		printf("oltr%d: adapter memory block size %d bytes\n", unit, scratch_size);
  582: 	sc->TRlldAdapter = (TRlldAdapter_t)malloc(scratch_size, M_DEVBUF, M_NOWAIT);
  583: 	if (sc->TRlldAdapter == NULL) {
  584: 		printf("oltr%d: couldn't allocate scratch buffer (%d bytes)\n",unit, scratch_size);
  585: 		goto config_failed;
  586: 	}
  587: 
  588: 	/*
  589: 	 * Allocate RX/TX Pools
  590: 	 */
  591: 	for (i = 0; i < RING_BUFFER_LEN; i++) {
  592: 		sc->rx_ring[i].index = i;
  593: 		sc->rx_ring[i].data = (char *)malloc(RX_BUFFER_LEN, M_DEVBUF, M_NOWAIT);
  594: 		sc->rx_ring[i].address = vtophys(sc->rx_ring[i].data);
  595: 		sc->tx_ring[i].index = i;
  596: 		sc->tx_ring[i].data = (char *)malloc(TX_BUFFER_LEN, M_DEVBUF, M_NOWAIT);
  597: 		sc->tx_ring[i].address = vtophys(sc->tx_ring[i].data);
  598: 		if ((!sc->rx_ring[i].data) || (!sc->tx_ring[i].data)) {
  599: 			printf("oltr%d: unable to allocate ring buffers\n", unit);
  600: 			while (i > 0) {
  601: 				if (sc->rx_ring[i].data)
  602: 					free(sc->rx_ring[i].data, M_DEVBUF);
  603: 				if (sc->tx_ring[i].data)
  604: 					free(sc->tx_ring[i].data, M_DEVBUF);
  605: 				i--;
  606: 			}
  607: 			goto config_failed;
  608: 		}
  609: 	}
  610: 	
  611: 	/*
  612: 	 * Allocate interrupt and DMA channel
  613: 	 */
  614: 	if (!pci_map_int(config_id, oltr_intr, sc, &net_imask)) {
  615: 		printf("oltr%d: couldn't setup interrupt\n", unit);
  616: 		goto config_failed;
  617: 	}
  618: 
  619: 	/*
  620: 	 * Do the ifnet initialization
  621: 	 */
  622: 	ifp->if_softc	= sc;
  623: 	if_initname(ifp, "oltr", unit);
  624: 	ifp->if_output	= iso88025_output;
  625: 	ifp->if_init	= oltr_init;
  626: 	ifp->if_start	= oltr_start;
  627: 	ifp->if_ioctl	= oltr_ioctl;
  628: 	ifp->if_flags	= IFF_BROADCAST;
  629: 	bcopy(sc->config.macaddress, sc->arpcom.ac_enaddr, sizeof(sc->config.macaddress));
  630: 
  631: 	/*
  632: 	 * Do ifmedia setup.
  633: 	 */
  634: 	ifmedia_init(&sc->ifmedia, 0, oltr_ifmedia_upd, oltr_ifmedia_sts);
  635: 	rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
  636: 	switch(sc->config.type) {
  637: 	case TRLLD_ADAPTER_PCI7:	/* OC-3540 */
  638: 		ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP100, 0, NULL);
  639: 		/* FALL THROUGH */
  640: 	case TRLLD_ADAPTER_PCI4:	/* OC-3139 */
  641: 	case TRLLD_ADAPTER_PCI5:	/* OC-3140 */
  642: 	case TRLLD_ADAPTER_PCI6:	/* OC-3141 */
  643: 		ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_AUTO, 0, NULL);
  644: 		media = IFM_TOKEN|IFM_AUTO;
  645: 		rc = TRlldSetSpeed(sc->TRlldAdapter, 0);
  646: 		/* FALL THROUGH */
  647: 	default:
  648: 		ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP4, 0, NULL);
  649: 		ifmedia_add(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP16, 0, NULL);
  650: 		break;
  651: 	}
  652: 	sc->ifmedia.ifm_media = media;
  653: 	ifmedia_set(&sc->ifmedia, media);
  654: 
  655: 	/*
  656: 	 * Attach the interface
  657: 	 */
  658: 	if_attach(ifp);
  659: 	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
  660: 	iso88025_ifattach(ifp);
  661: 
  662: #if (NBPFILTER > 0) || defined(__DragonFly__) || (__FreeBSD_version > 400000)
  663: 	bpfattach(ifp, DLT_IEEE802, sizeof(struct iso88025_header));
  664: #endif
  665: 
  666: 	splx(s);
  667: 	return;
  668: 
  669: config_failed:
  670:         (void)splx(s);
  671: 
  672: 	return;
  673: }
  674: 
  675: #endif
  676: 
  677: static void
  678: oltr_intr(void *xsc)
  679: {
  680: 	struct oltr_softc		*sc = (struct oltr_softc *)xsc;
  681: 
  682: 	if (DEBUG_MASK & DEBUG_INT)
  683: 		printf("I");
  684: 
  685: 	TRlldInterruptService(sc->TRlldAdapter);
  686: 
  687: 	return;
  688: }
  689: 
  690: static void
  691: oltr_start(struct ifnet *ifp)
  692: {
  693: 	struct oltr_softc 	*sc = ifp->if_softc;
  694: 	struct mbuf		*m0, *m;
  695: 	int			copy_len, buffer, frame, fragment, rc, s;
  696: 	
  697: 	/*
  698: 	 * Check to see if output is already active
  699: 	 */
  700: 	if (ifp->if_flags & IFF_OACTIVE)
  701: 		return;
  702: 
  703: outloop:
  704: 
  705: 	/*
  706: 	 * Make sure we have buffers to transmit with
  707: 	 */
  708: 	if (sc->tx_avail <= 0) {
  709: 		printf("oltr%d: tx queue full\n", sc->unit);
  710: 		ifp->if_flags |= IFF_OACTIVE;
  711: 		return;
  712: 	}
  713: 
  714: 	if (sc->restart == NULL) {
  715: 		IF_DEQUEUE(&ifp->if_snd, m);
  716: 		if (m == NULL)
  717: 			return;
  718: 	} else {
  719: 		m = sc->restart;
  720: 		sc->restart = NULL;
  721: 	}
  722: 
  723: 	m0 = m;
  724: 	frame = RING_BUFFER(sc->tx_frame);
  725: 	buffer = RING_BUFFER(sc->tx_head);
  726: 	fragment = 0;
  727: 	copy_len = 0;
  728: 	sc->frame_ring[frame].FragmentCount = 0;
  729: 	
  730: 	while (copy_len < m0->m_pkthdr.len) {
  731: 		sc->frame_ring[frame].FragmentCount++;
  732: 		if (sc->frame_ring[frame].FragmentCount > sc->tx_avail)
  733: 			goto nobuffers;
  734: 		sc->frame_ring[frame].TransmitFragment[fragment].VirtualAddress = sc->tx_ring[buffer].data;
  735: 		sc->frame_ring[frame].TransmitFragment[fragment].PhysicalAddress = sc->tx_ring[buffer].address;
  736: 		sc->frame_ring[frame].TransmitFragment[fragment].count = MIN(m0->m_pkthdr.len - copy_len, TX_BUFFER_LEN);
  737: 		m_copydata(m0, copy_len, MIN(m0->m_pkthdr.len - copy_len, TX_BUFFER_LEN), sc->tx_ring[buffer].data);
  738: 		copy_len += MIN(m0->m_pkthdr.len - copy_len, TX_BUFFER_LEN);
  739: 		fragment++;
  740: 		buffer = RING_BUFFER((buffer + 1));
  741: 	}
  742: 
  743: 	s = splimp();
  744: 	rc = TRlldTransmitFrame(sc->TRlldAdapter, &sc->frame_ring[frame], (void *)&sc->frame_ring[frame]);
  745: 	(void)splx(s);
  746: 
  747: 	if (rc != TRLLD_TRANSMIT_OK) {
  748: 		printf("oltr%d: TRlldTransmitFrame returned %d\n", sc->unit, rc);
  749: 		ifp->if_oerrors++;
  750: 		goto bad;
  751: 	}
  752: 
  753: 	sc->tx_avail -= sc->frame_ring[frame].FragmentCount;
  754: 	sc->tx_head = RING_BUFFER((sc->tx_head + sc->frame_ring[frame].FragmentCount));
  755: 	sc->tx_frame++;
  756: 
  757: #if (NBPFILTER > 0) || defined(__DragonFly__) || (__FreeBSD_version > 400000)
  758: 	if (ifp->if_bpf)
  759: 		bpf_mtap(ifp, m0);
  760: #endif
  761: 	/*ifp->if_opackets++;*/
  762: 
  763: bad:
  764: 	m_freem(m0);
  765: 
  766: 	goto outloop;
  767: 
  768: nobuffers:
  769: 
  770: 	printf("oltr%d: queue full\n", sc->unit);
  771: 	ifp->if_flags |= IFF_OACTIVE;
  772: 	ifp->if_oerrors++;
  773: 	/*m_freem(m0);*/
  774: 	sc->restart = m0;
  775: 
  776: 	return;
  777: }
  778: 
  779: static void
  780: oltr_close(struct oltr_softc *sc)
  781: {
  782: 	/*printf("oltr%d: oltr_close\n", sc->unit);*/
  783: 
  784: 	oltr_stop(sc);
  785: 
  786: 	tsleep(sc, 0, "oltrclose", 30*hz);
  787: }
  788: 
  789: static void
  790: oltr_stop(struct oltr_softc *sc)
  791: {
  792: 	struct ifnet 		*ifp = &sc->arpcom.ac_if;
  793: 
  794: 	/*printf("oltr%d: oltr_stop\n", sc->unit);*/
  795: 
  796: 	ifp->if_flags &= ~(IFF_UP | IFF_RUNNING | IFF_OACTIVE);
  797: 	TRlldClose(sc->TRlldAdapter, 0);
  798: 	sc->state = OL_CLOSING;
  799: }
  800: 
  801: static void
  802: oltr_init(void * xsc)
  803: {
  804: 	struct oltr_softc 	*sc = (struct oltr_softc *)xsc;
  805: 	struct ifnet		*ifp = &sc->arpcom.ac_if;
  806: 	struct ifmedia		*ifm = &sc->ifmedia;
  807: 	int			poll = 0, i, rc = 0, s;
  808: 	int			work_size;
  809: 
  810: 	/*
  811: 	 * Check adapter state, don't allow multiple inits
  812: 	 */
  813: 	if (sc->state > OL_CLOSED) {
  814: 		printf("oltr%d: adapter not ready\n", sc->unit);
  815: 		return;
  816: 	}
  817: 
  818: 	s = splimp();
  819: 
  820: 	/*
  821: 	 * Initialize Adapter
  822: 	 */
  823: 	if ((rc = TRlldAdapterInit(&LldDriver, sc->TRlldAdapter, vtophys(sc->TRlldAdapter),
  824: 	    (void *)sc, &sc->config)) != TRLLD_INIT_OK) {
  825: 		switch(rc) {
  826: 		case TRLLD_INIT_NOT_FOUND:
  827: 			printf("oltr%d: adapter not found\n", sc->unit);
  828: 			break;
  829: 		case TRLLD_INIT_UNSUPPORTED:
  830: 			printf("oltr%d: adapter not supported by low level driver\n", sc->unit);
  831: 			break;
  832: 		case TRLLD_INIT_PHYS16:
  833: 			printf("oltr%d: adapter memory block above 16M cannot DMA\n", sc->unit);
  834: 			break;
  835: 		case TRLLD_INIT_VERSION:
  836: 			printf("oltr%d: low level driver version mismatch\n", sc->unit);
  837: 			break;
  838: 		default:
  839: 			printf("oltr%d: unknown init error %d\n", sc->unit, rc);
  840: 			break;
  841: 		}
  842: 		goto init_failed;
  843: 	}
  844: 	sc->state = OL_INIT;
  845: 
  846: 	switch(sc->config.type) {
  847: 	case TRLLD_ADAPTER_PCI4:        /* OC-3139 */
  848: 		work_size = 32 * 1024;
  849: 		break;
  850: 	case TRLLD_ADAPTER_PCI7:        /* OC-3540 */
  851: 		work_size = 256;
  852: 		break;
  853: 	default:
  854: 		work_size = 0;
  855: 	}
  856: 
  857: 	if (work_size) {
  858: 		if ((sc->work_memory = malloc(work_size, M_DEVBUF, M_NOWAIT)) == NULL) {
  859: 			printf("oltr%d: failed to allocate work memory (%d octets).\n", sc->unit, work_size);
  860: 		} else {
  861: 		TRlldAddMemory(sc->TRlldAdapter, sc->work_memory,
  862: 		    vtophys(sc->work_memory), work_size);
  863: 		}
  864: 	}
  865: 
  866: 	switch(IFM_SUBTYPE(ifm->ifm_media)) {
  867: 	case IFM_AUTO:
  868: 		rc = TRlldSetSpeed(sc->TRlldAdapter, 0); /* TRLLD_SPEED_AUTO */
  869: 		break;
  870: 	case IFM_TOK_UTP4:
  871: 		rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_4MBPS);
  872: 		break;
  873: 	case IFM_TOK_UTP16:
  874: 		rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
  875: 		break;
  876: 	case IFM_TOK_UTP100:
  877: 		rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_100MBPS);
  878: 		break;
  879: 	}
  880: 
  881: 	/*
  882: 	 * Download adapter micro-code
  883: 	 */
  884: 	if (bootverbose)
  885: 		printf("oltr%d: Downloading adapter microcode: ", sc->unit);
  886: 
  887: 	switch(sc->config.mactype) {
  888: 	case TRLLD_MAC_TMS:
  889: 		rc = TRlldDownload(sc->TRlldAdapter, TRlldMacCode);
  890: 		if (bootverbose)
  891: 			printf("TMS-380");
  892: 		break;
  893: 	case TRLLD_MAC_HAWKEYE:
  894: 		rc = TRlldDownload(sc->TRlldAdapter, TRlldHawkeyeMac);
  895: 		if (bootverbose)
  896: 			printf("Hawkeye");
  897: 		break;
  898: 	case TRLLD_MAC_BULLSEYE:
  899: 		rc = TRlldDownload(sc->TRlldAdapter, TRlldBullseyeMac);
  900: 		if (bootverbose)
  901: 			printf("Bullseye");
  902: 		break;
  903: 	default:
  904: 		if (bootverbose)
  905: 			printf("unknown - failed!\n");
  906: 		goto init_failed;
  907: 		break;
  908: 	}
  909: 
  910: 	/*
  911: 	 * Check download status
  912: 	 */
  913: 	switch(rc) {
  914: 	case TRLLD_DOWNLOAD_OK:
  915: 		if (bootverbose)
  916: 			printf(" - ok\n");
  917: 		break;
  918: 	case TRLLD_DOWNLOAD_ERROR:
  919: 		if (bootverbose)
  920: 			printf(" - failed\n");
  921: 		else
  922: 			printf("oltr%d: adapter microcode download failed\n", sc->unit);
  923: 		goto init_failed;
  924: 		break;
  925: 	case TRLLD_STATE:
  926: 		if (bootverbose)
  927: 			printf(" - not ready\n");
  928: 		goto init_failed;
  929: 		break;
  930: 	}
  931: 
  932: 	/*
  933: 	 * Wait for self-test to complete
  934: 	 */
  935: 	i = 0;
  936: 	while ((poll++ < SELF_TEST_POLLS) && (sc->state < OL_READY)) {
  937: 		if (DEBUG_MASK & DEBUG_INIT)
  938: 			printf("p");
  939: 		DELAY(TRlldPoll(sc->TRlldAdapter) * 1000);
  940: 		if (TRlldInterruptService(sc->TRlldAdapter) != 0)
  941: 			if (DEBUG_MASK & DEBUG_INIT) printf("i");
  942: 	}
  943: 
  944: 	if (sc->state != OL_CLOSED) {
  945: 		printf("oltr%d: self-test failed\n", sc->unit);
  946: 		goto init_failed;
  947: 	}
  948: 
  949: 	/*
  950: 	 * Set up adapter poll
  951: 	 */
  952: 	callout_handle_init(&sc->oltr_poll_ch);
  953: 	sc->oltr_poll_ch = timeout(oltr_poll, (void *)sc, 1);
  954: 
  955: 	sc->state = OL_OPENING;
  956: 
  957: 	/*
  958: 	 * Open the adapter
  959: 	 */
  960: 	rc = TRlldOpen(sc->TRlldAdapter, sc->arpcom.ac_enaddr, sc->GroupAddress,
  961: 		sc->FunctionalAddress, 1552, sc->AdapterMode);
  962: 	switch(rc) {
  963: 		case TRLLD_OPEN_OK:
  964: 			break;
  965: 		case TRLLD_OPEN_STATE:
  966: 			printf("oltr%d: adapter not ready for open\n", sc->unit);
  967: 			(void)splx(s);
  968: 			return;
  969: 		case TRLLD_OPEN_ADDRESS_ERROR:
  970: 			printf("oltr%d: illegal MAC address\n", sc->unit);
  971: 			(void)splx(s);
  972: 			return;
  973: 		case TRLLD_OPEN_MODE_ERROR:
  974: 			printf("oltr%d: illegal open mode\n", sc->unit);
  975: 			(void)splx(s);
  976: 			return;
  977: 		default:
  978: 			printf("oltr%d: unknown open error (%d)\n", sc->unit, rc);
  979: 			(void)splx(s);
  980: 			return;
  981: 	}
  982: 
  983: 	/*
  984: 	 * Set promiscious mode for now...
  985: 	 */
  986: 	TRlldSetPromiscuousMode(sc->TRlldAdapter, TRLLD_PROM_LLC);
  987: 	ifp->if_flags |= IFF_PROMISC;
  988: 
  989: 	/*
  990: 	 * Block on the ring insert and set a timeout
  991: 	 */
  992: 	tsleep(sc, 0, "oltropen", 30*hz);
  993: 
  994: 	/*
  995: 	 * Set up receive buffer ring
  996: 	 */
  997: 	for (i = 0; i < RING_BUFFER_LEN; i++) {
  998: 		rc = TRlldReceiveFragment(sc->TRlldAdapter, (void *)sc->rx_ring[i].data,
  999: 			sc->rx_ring[i].address, RX_BUFFER_LEN, (void *)sc->rx_ring[i].index);
 1000: 		if (rc != TRLLD_RECEIVE_OK) {
 1001: 			printf("oltr%d: adapter refused receive fragment %d (rc = %d)\n", sc->unit, i, rc);
 1002: 			break;
 1003: 		}	
 1004: 	}
 1005: 
 1006: 	sc->tx_avail = RING_BUFFER_LEN;
 1007: 	sc->tx_head = 0;
 1008: 	sc->tx_frame = 0;
 1009: 
 1010: 	sc->restart = NULL;
 1011: 
 1012: 	ifp->if_flags |= IFF_RUNNING;
 1013: 	ifp->if_flags &= ~IFF_OACTIVE;
 1014: 
 1015: 	/*
 1016: 	 * Set up adapter statistics poll
 1017: 	 */
 1018: 	/*callout_handle_init(&sc->oltr_stat_ch);*/
 1019: 	/*sc->oltr_stat_ch = timeout(oltr_stat, (void *)sc, 1*hz);*/
 1020: 
 1021: 	(void)splx(s);
 1022: 	return;
 1023: 
 1024: init_failed:
 1025: 	sc->state = OL_DEAD;
 1026: 	(void)splx(s);
 1027: 	return;
 1028: }
 1029: 
 1030: static int
 1031: oltr_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 1032: {
 1033: 	struct oltr_softc 	*sc = ifp->if_softc;
 1034: 	struct ifreq		*ifr = (struct ifreq *)data;
 1035: 	int 			error = 0, s;
 1036: 
 1037: 	s = splimp();
 1038: 
 1039: 	switch(command) {
 1040: 	case SIOCSIFADDR:
 1041: 	case SIOCGIFADDR:
 1042: 	case SIOCSIFMTU:
 1043: 		error = iso88025_ioctl(ifp, command, data);
 1044: 		break;
 1045: 
 1046: 	case SIOCSIFFLAGS:
 1047: 		if (ifp->if_flags & IFF_UP) {
 1048: 			oltr_init(sc);
 1049: 		} else {
 1050: 			if (ifp->if_flags & IFF_RUNNING) {
 1051: 				oltr_close(sc);
 1052: 			}
 1053: 		}
 1054: 		break;
 1055: 	case SIOCGIFMEDIA:
 1056: 	case SIOCSIFMEDIA:
 1057: 		error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
 1058: 		break;
 1059: 	default:
 1060: 		error = EINVAL;
 1061: 		break;
 1062: 	}
 1063: 
 1064: 	(void)splx(s);	
 1065: 
 1066: 	return(error);
 1067: }
 1068: 
 1069: 
 1070: void
 1071: oltr_poll(void *arg)
 1072: {
 1073: 	struct oltr_softc *sc = (struct oltr_softc *)arg;
 1074: 	int s;
 1075: 
 1076: 	s = splimp();
 1077: 
 1078: 	if (DEBUG_MASK & DEBUG_POLL) printf("P");
 1079: 
 1080: 	/* Set up next adapter poll */
 1081: 	sc->oltr_poll_ch = timeout(oltr_poll, (void *)sc, (TRlldPoll(sc->TRlldAdapter) * hz / 1000));
 1082: 
 1083: 	(void)splx(s);
 1084: }
 1085: 
 1086: #ifdef NOTYET
 1087: void
 1088: oltr_stat(void *arg)
 1089: {
 1090: 	struct oltr_softc	*sc = (struct oltr_softc *)arg;
 1091: 	int			s;
 1092: 
 1093: 	s = splimp();
 1094: 
 1095: 	/* Set up next adapter poll */
 1096: 	sc->oltr_stat_ch = timeout(oltr_stat, (void *)sc, 1*hz);
 1097: 	if (TRlldGetStatistics(sc->TRlldAdapter, &sc->current, 0) != 0) {
 1098: 		/*printf("oltr%d: statistics available immediately...\n", sc->unit);*/
 1099: 		DriverStatistics((void *)sc, &sc->current);
 1100: 	}
 1101: 
 1102: 	(void)splx(s);
 1103: }
 1104: #endif
 1105: static int
 1106: oltr_ifmedia_upd(struct ifnet *ifp)
 1107: {
 1108: 	struct oltr_softc 	*sc = ifp->if_softc;
 1109: 	struct ifmedia		*ifm = &sc->ifmedia;
 1110: 	int			rc;
 1111: 
 1112: 	if (IFM_TYPE(ifm->ifm_media) != IFM_TOKEN)
 1113: 		return(EINVAL);
 1114: 
 1115: 	switch(IFM_SUBTYPE(ifm->ifm_media)) {
 1116: 	case IFM_AUTO:
 1117: 		rc = TRlldSetSpeed(sc->TRlldAdapter, 0); /* TRLLD_SPEED_AUTO */
 1118: 		break;
 1119: 	case IFM_TOK_UTP4:
 1120: 		rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_4MBPS);
 1121: 		break;
 1122: 	case IFM_TOK_UTP16:
 1123: 		rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
 1124: 		break;
 1125: 	case IFM_TOK_UTP100:
 1126: 		rc = TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_100MBPS);
 1127: 		break;
 1128: 	default:
 1129: 		return(EINVAL);
 1130: 		break;
 1131: 	}
 1132: 
 1133: 	return(0);
 1134: 
 1135: }
 1136: 
 1137: static void
 1138: oltr_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 1139: {
 1140: 	struct oltr_softc	*sc = ifp->if_softc;
 1141: 	struct ifmedia		*ifm = &sc->ifmedia;
 1142: 
 1143: 	/*printf("oltr%d: oltr_ifmedia_sts\n", sc->unit);*/
 1144: 
 1145: 	ifmr->ifm_active = IFM_TYPE(ifm->ifm_media)|IFM_SUBTYPE(ifm->ifm_media);
 1146: 
 1147: }
 1148: 
 1149: /*
 1150:  * ---------------------- PMW Callback Functions -----------------------
 1151:  */
 1152: 
 1153: void
 1154: DriverStatistics(void *DriverHandle, TRlldStatistics_t *statistics)
 1155: {
 1156: #ifdef NOTYET
 1157: 	struct oltr_softc		*sc = (struct oltr_softc *)DriverHandle;
 1158: 
 1159: 	if (sc->statistics.LineErrors != statistics->LineErrors)
 1160: 		printf("oltr%d: Line Errors %lu\n", sc->unit,
 1161: 		    statistics->LineErrors);
 1162: 	if (sc->statistics.InternalErrors != statistics->InternalErrors)
 1163: 		printf("oltr%d: Internal Errors %lu\n", sc->unit,
 1164: 		    statistics->InternalErrors);
 1165: 	if (sc->statistics.BurstErrors != statistics->BurstErrors)
 1166: 		printf("oltr%d: Burst Errors %lu\n", sc->unit,
 1167: 		    statistics->BurstErrors);
 1168: 	if (sc->statistics.AbortDelimiters != statistics->AbortDelimiters)
 1169: 		printf("oltr%d: Abort Delimiters %lu\n", sc->unit,
 1170: 		    statistics->AbortDelimiters);
 1171: 	if (sc->statistics.ARIFCIErrors != statistics->ARIFCIErrors)
 1172: 		printf("oltr%d: ARIFCI Errors %lu\n", sc->unit,
 1173: 		    statistics->ARIFCIErrors);
 1174: 	if (sc->statistics.LostFrames != statistics->LostFrames)
 1175: 		printf("oltr%d: Lost Frames %lu\n", sc->unit,
 1176: 		    statistics->LostFrames);
 1177: 	if (sc->statistics.CongestionErrors != statistics->CongestionErrors)
 1178: 		printf("oltr%d: Congestion Errors %lu\n", sc->unit,
 1179: 		    statistics->CongestionErrors);
 1180: 	if (sc->statistics.FrequencyErrors != statistics->FrequencyErrors)
 1181: 		printf("oltr%d: Frequency Errors %lu\n", sc->unit,
 1182: 		    statistics->FrequencyErrors);
 1183: 	if (sc->statistics.TokenErrors != statistics->TokenErrors)
 1184: 		printf("oltr%d: Token Errors %lu\n", sc->unit,
 1185: 		    statistics->TokenErrors);
 1186: 	if (sc->statistics.DMABusErrors != statistics->DMABusErrors)
 1187: 		printf("oltr%d: DMA Bus Errors %lu\n", sc->unit,
 1188: 		    statistics->DMABusErrors);
 1189: 	if (sc->statistics.DMAParityErrors != statistics->DMAParityErrors)
 1190: 		printf("oltr%d: DMA Parity Errors %lu\n", sc->unit,
 1191: 		    statistics->DMAParityErrors);
 1192: 	if (sc->statistics.ReceiveLongFrame != statistics->ReceiveLongFrame)
 1193: 		printf("oltr%d: Long frames received %lu\n", sc->unit,
 1194: 		    statistics->ReceiveLongFrame);
 1195: 	if (sc->statistics.ReceiveCRCErrors != statistics->ReceiveCRCErrors)
 1196: 		printf("oltr%d: Receive CRC Errors %lu\n", sc->unit,
 1197: 		    statistics->ReceiveCRCErrors);
 1198: 	if (sc->statistics.ReceiveOverflow != statistics->ReceiveOverflow)
 1199: 		printf("oltr%d: Recieve overflows %lu\n", sc->unit,
 1200: 		    statistics->ReceiveOverflow);
 1201: 	if (sc->statistics.TransmitUnderrun != statistics->TransmitUnderrun)
 1202: 		printf("oltr%d: Frequency Errors %lu\n", sc->unit,
 1203: 		    statistics->TransmitUnderrun);
 1204: 	bcopy(statistics, &sc->statistics, sizeof(TRlldStatistics_t));
 1205: #endif
 1206: }
 1207: 
 1208: static void
 1209: DriverSuspend(unsigned short MicroSeconds)
 1210: {
 1211:     DELAY(MicroSeconds);
 1212: }
 1213: 
 1214: 
 1215: static void
 1216: DriverStatus(void *DriverHandle, TRlldStatus_t *Status)
 1217: {
 1218: 	struct oltr_softc	*sc = (struct oltr_softc *)DriverHandle;
 1219: 	struct ifnet		*ifp = &sc->arpcom.ac_if;
 1220: 
 1221: 	char *Protocol[] = { /* 0 */ "Unknown",
 1222: 			     /* 1 */ "TKP",
 1223: 			     /* 2 */ "TXI" };
 1224: 	char *Timeout[]  = { /* 0 */ "command",
 1225: 			     /* 1 */ "transmit",
 1226: 			     /* 2 */ "interrupt" };
 1227: 	
 1228: 	switch (Status->Type) {
 1229: 
 1230: 	case TRLLD_STS_ON_WIRE:
 1231: 		printf("oltr%d: ring insert (%d Mbps - %s)\n", sc->unit,
 1232: 		    Status->Specification.OnWireInformation.Speed,
 1233: 		    Protocol[Status->Specification.OnWireInformation.AccessProtocol]);
 1234: 		sc->state = OL_OPEN;
 1235: 		wakeup(sc);
 1236: 		break;
 1237: 	case TRLLD_STS_SELFTEST_STATUS:
 1238: 		if (Status->Specification.SelftestStatus == TRLLD_ST_OK) {
 1239: 			sc->state = OL_CLOSED;
 1240: 			if (bootverbose)
 1241: 				printf("oltr%d: self test complete\n", sc->unit);
 1242: 		}
 1243: 		if (Status->Specification.SelftestStatus & TRLLD_ST_ERROR) {
 1244: 			printf("oltr%d: Adapter self test error %d", sc->unit,
 1245: 			Status->Specification.SelftestStatus & ~TRLLD_ST_ERROR);
 1246: 			sc->state = OL_DEAD;
 1247: 		}
 1248: 		if (Status->Specification.SelftestStatus & TRLLD_ST_TIMEOUT) {
 1249: 			printf("oltr%d: Adapter self test timed out.\n", sc->unit);
 1250: 			sc->state = OL_DEAD;
 1251: 		}
 1252: 		break;
 1253: 	case TRLLD_STS_INIT_STATUS:
 1254: 		if (Status->Specification.InitStatus == 0x800) {
 1255: 			oltr_stop(sc);
 1256: 			ifmedia_set(&sc->ifmedia, IFM_TOKEN|IFM_TOK_UTP16);
 1257: 			TRlldSetSpeed(sc->TRlldAdapter, TRLLD_SPEED_16MBPS);
 1258: 			oltr_init(sc);
 1259: 			break;
 1260: 		}
 1261: 		printf("oltr%d: adapter init failure 0x%03x\n", sc->unit,
 1262: 		    Status->Specification.InitStatus);
 1263: 		oltr_stop(sc);
 1264: 		break;
 1265: 	case TRLLD_STS_RING_STATUS:
 1266: 		if (Status->Specification.RingStatus) {
 1267: 			printf("oltr%d: Ring status change: ", sc->unit);
 1268: 			if (Status->Specification.RingStatus &
 1269: 			    TRLLD_RS_SIGNAL_LOSS)
 1270: 				printf(" [Signal Loss]");
 1271: 			if (Status->Specification.RingStatus &
 1272: 			    TRLLD_RS_HARD_ERROR)
 1273: 				printf(" [Hard Error]");
 1274: 			if (Status->Specification.RingStatus &
 1275: 			    TRLLD_RS_SOFT_ERROR)
 1276: 				printf(" [Soft Error]");
 1277: 			if (Status->Specification.RingStatus &
 1278: 			    TRLLD_RS_TRANSMIT_BEACON)
 1279: 				printf(" [Beacon]");
 1280: 			if (Status->Specification.RingStatus &
 1281: 			    TRLLD_RS_LOBE_WIRE_FAULT)
 1282: 				printf(" [Wire Fault]");
 1283: 			if (Status->Specification.RingStatus &
 1284: 			    TRLLD_RS_AUTO_REMOVAL_ERROR)
 1285: 				printf(" [Auto Removal]");
 1286: 			if (Status->Specification.RingStatus &
 1287: 			    TRLLD_RS_REMOVE_RECEIVED)
 1288: 				printf(" [Remove Received]");
 1289: 			if (Status->Specification.RingStatus &
 1290: 			    TRLLD_RS_COUNTER_OVERFLOW)
 1291: 				printf(" [Counter Overflow]");
 1292: 			if (Status->Specification.RingStatus &
 1293: 			    TRLLD_RS_SINGLE_STATION)
 1294: 				printf(" [Single Station]");
 1295: 			if (Status->Specification.RingStatus &
 1296: 				TRLLD_RS_RING_RECOVERY)
 1297: 				printf(" [Ring Recovery]");
 1298: 			printf("\n");	
 1299: 		}
 1300: 		break;
 1301: 	case TRLLD_STS_ADAPTER_CHECK:
 1302: 		printf("oltr%d: adapter check (%04x %04x %04x %04x)\n", sc->unit,
 1303: 		    Status->Specification.AdapterCheck[0],
 1304: 		    Status->Specification.AdapterCheck[1],
 1305: 		    Status->Specification.AdapterCheck[2],
 1306: 		    Status->Specification.AdapterCheck[3]);
 1307: 		sc->state = OL_DEAD;
 1308: 		oltr_stop(sc);
 1309: 		break;
 1310: 	case TRLLD_STS_PROMISCUOUS_STOPPED:
 1311: 		printf("oltr%d: promiscuous mode ", sc->unit);
 1312: 		if (Status->Specification.PromRemovedCause == 1)
 1313: 			printf("remove received.");
 1314: 		if (Status->Specification.PromRemovedCause == 2)
 1315: 			printf("poll failure.");
 1316: 		if (Status->Specification.PromRemovedCause == 2)
 1317: 			printf("buffer size failure.");
 1318: 		printf("\n");
 1319: 		ifp->if_flags &= ~IFF_PROMISC;
 1320: 		break;
 1321: 	case TRLLD_STS_LLD_ERROR:
 1322: 		printf("oltr%d: low level driver internal error ", sc->unit);
 1323: 		printf("(%04x %04x %04x %04x).\n",
 1324: 		    Status->Specification.InternalError[0],
 1325: 		    Status->Specification.InternalError[1],
 1326: 		    Status->Specification.InternalError[2],
 1327: 		    Status->Specification.InternalError[3]);
 1328: 		sc->state = OL_DEAD;
 1329: 		oltr_stop(sc);
 1330: 		break;
 1331: 	case TRLLD_STS_ADAPTER_TIMEOUT:
 1332: 		printf("oltr%d: adapter %s timeout.\n", sc->unit,
 1333: 		    Timeout[Status->Specification.AdapterTimeout]);
 1334: 		break;
 1335: 	default:
 1336: 		printf("oltr%d: driver status Type = %d\n", sc->unit, Status->Type);
 1337: 		break;
 1338: 
 1339: 	}
 1340: 	if (Status->Closed) {
 1341: 		sc->state = OL_CLOSING;
 1342: 		oltr_stop(sc);
 1343: 	}
 1344: 
 1345: }
 1346: 
 1347: static void
 1348: DriverCloseCompleted(void *DriverHandle)
 1349: {
 1350: 	struct oltr_softc		*sc = (struct oltr_softc *)DriverHandle;
 1351: 	
 1352: 	printf("oltr%d: adapter closed\n", sc->unit);
 1353: 	wakeup(sc);
 1354: 	sc->state = OL_CLOSED;
 1355: }
 1356: 
 1357: static void
 1358: DriverTransmitFrameCompleted(void *DriverHandle, void *FrameHandle, int TransmitStatus)
 1359: {
 1360: 	struct oltr_softc	*sc = (struct oltr_softc *)DriverHandle;
 1361: 	struct ifnet		*ifp = &sc->arpcom.ac_if;
 1362: 	TRlldTransmit_t		*frame = (TRlldTransmit_t *)FrameHandle;
 1363: 	
 1364: 	/*printf("oltr%d: DriverTransmitFrameCompleted\n", sc->unit);*/
 1365: 
 1366: 	if (TransmitStatus != TRLLD_TRANSMIT_OK) {
 1367: 		ifp->if_oerrors++;
 1368: 		printf("oltr%d: transmit error %d\n", sc->unit, TransmitStatus);
 1369: 	} else {
 1370: 		ifp->if_opackets++;
 1371: 	}
 1372: 	
 1373: 	sc->tx_avail += frame->FragmentCount;
 1374: 
 1375: 	if (ifp->if_flags & IFF_OACTIVE) {
 1376: 		printf("oltr%d: queue restart\n", sc->unit);
 1377: 		ifp->if_flags &= ~IFF_OACTIVE;
 1378: 		oltr_start(ifp);
 1379: 	}
 1380: 
 1381: 
 1382: }
 1383: 
 1384: static void
 1385: DriverReceiveFrameCompleted(void *DriverHandle, int ByteCount, int FragmentCount, void *FragmentHandle, int ReceiveStatus)
 1386: {
 1387: 	struct oltr_softc 	*sc = (struct oltr_softc *)DriverHandle;
 1388: 	struct ifnet		*ifp = (struct ifnet *)&sc->arpcom.ac_if;
 1389: 	struct mbuf		*m0, *m1, *m;
 1390: 	struct iso88025_header	*th;
 1391: 	int			frame_len = ByteCount, hdr_len, i = (int)FragmentHandle, rc, s;
 1392: 	int			mbuf_offset, mbuf_size, frag_offset, copy_length;
 1393: 	char			*fragment = sc->rx_ring[RING_BUFFER(i)].data;
 1394: 	
 1395: 	if (sc->state > OL_CLOSED) {
 1396: 		if (ReceiveStatus == TRLLD_RCV_OK) {
 1397: 			MGETHDR(m0, M_DONTWAIT, MT_DATA);
 1398: 			mbuf_size = MHLEN - 2;
 1399: 			if (!m0) {
 1400: 				ifp->if_ierrors++;
 1401: 				goto dropped;
 1402: 			}
 1403: 			if (ByteCount + 2 > MHLEN) {
 1404: 				MCLGET(m0, M_DONTWAIT);
 1405: 				mbuf_size = MCLBYTES - 2;
 1406: 				if (!(m0->m_flags & M_EXT)) {
 1407: 					m_freem(m0);
 1408: 					ifp->if_ierrors++;
 1409: 					goto dropped;
 1410: 				}
 1411: 			}
 1412: 			m0->m_pkthdr.rcvif = ifp;
 1413: 			m0->m_pkthdr.len = ByteCount;
 1414: 			m0->m_len = 0;
 1415: 			m0->m_data += 2;
 1416: 			th = mtod(m0, struct iso88025_header *);
 1417: 			m0->m_pkthdr.header = (void *)th;
 1418: 
 1419: 			m = m0;
 1420: 			mbuf_offset = 0;
 1421: 			frag_offset = 0;
 1422: 			while (frame_len) {
 1423: 				copy_length = MIN3(frame_len,
 1424: 				    (RX_BUFFER_LEN - frag_offset),
 1425: 				    (mbuf_size - mbuf_offset));
 1426: 				bcopy(fragment + frag_offset, mtod(m, char *) +
 1427: 				    mbuf_offset, copy_length);
 1428: 				m->m_len += copy_length;
 1429: 				mbuf_offset += copy_length;
 1430: 				frag_offset += copy_length;
 1431: 				frame_len -= copy_length;
 1432: 			
 1433: 				if (frag_offset == RX_BUFFER_LEN) {
 1434: 					fragment =
 1435: 					    sc->rx_ring[RING_BUFFER(++i)].data;
 1436: 					frag_offset = 0;
 1437: 				}
 1438: 				if ((mbuf_offset == mbuf_size) && (frame_len > 0)) {
 1439: 					MGET(m1, M_DONTWAIT, MT_DATA);
 1440: 					mbuf_size = MHLEN;
 1441: 					if (!m1) {
 1442: 						ifp->if_ierrors++;
 1443: 						m_freem(m0);
 1444: 						goto dropped;
 1445: 					}
 1446: 					if (frame_len > MHLEN) {
 1447: 						MCLGET(m1, M_DONTWAIT);
 1448: 						mbuf_size = MCLBYTES;
 1449: 						if (!(m1->m_flags & M_EXT)) {
 1450: 							m_freem(m0);
 1451: 							m_freem(m1);
 1452: 							ifp->if_ierrors++;
 1453: 							goto dropped;
 1454: 						}
 1455: 					}
 1456: 					m->m_next = m1;
 1457: 					m = m1;
 1458: 					mbuf_offset = 0;
 1459: 					m->m_len = 0;
 1460: 				}
 1461: 			}
 1462: #if (NBPFILTER > 0) || defined(__DragonFly__) || (__FreeBSD_version > 400000)
 1463: 			if (ifp->if_bpf)
 1464: 				bpf_mtap(ifp, m0);
 1465: #endif
 1466: 
 1467: 			/*if (ifp->if_flags & IFF_PROMISC) {*/
 1468: 				if (bcmp(th->iso88025_dhost, etherbroadcastaddr
 1469: 				    , sizeof(th->iso88025_dhost))) {
 1470: 					if ((bcmp(th->iso88025_dhost + 1, sc->arpcom.ac_enaddr + 1, ISO88025_ADDR_LEN - 1)) ||
 1471: 					    ((th->iso88025_dhost[0] & 0x7f) != sc->arpcom.ac_enaddr[0])) {
 1472: 						m_freem(m0);
 1473: 						goto dropped;
 1474: 					}
 1475: 				}
 1476: 			/*}*/
 1477: 			ifp->if_ipackets++;
 1478: 
 1479: 			hdr_len = ISO88025_HDR_LEN;
 1480: 			if (th->iso88025_shost[0] & 0x80)
 1481: 				hdr_len += (ntohs(th->rcf) & 0x1f00) >> 8;
 1482: 
 1483: 			m0->m_pkthdr.len -= hdr_len;
 1484: 			m0->m_len -= hdr_len;
 1485: 			m0->m_data += hdr_len;
 1486: 
 1487: 			iso88025_input(ifp, th, m0);
 1488: 
 1489: 		} else {	/* Receiver error */
 1490: 			if (ReceiveStatus != TRLLD_RCV_NO_DATA) {
 1491: 				printf("oltr%d: receive error %d\n", sc->unit,
 1492: 				    ReceiveStatus);
 1493: 				ifp->if_ierrors++;
 1494: 			}
 1495: 		}
 1496: 
 1497: dropped:
 1498: 		s = splimp();
 1499: 		i = (int)FragmentHandle;
 1500: 		while (FragmentCount--) {
 1501: 			rc = TRlldReceiveFragment(sc->TRlldAdapter,
 1502: 			    (void *)sc->rx_ring[RING_BUFFER(i)].data,
 1503: 			    sc->rx_ring[RING_BUFFER(i)].address,
 1504: 			    RX_BUFFER_LEN, (void *)sc->rx_ring[RING_BUFFER(i)].index);
 1505: 			if (rc != TRLLD_RECEIVE_OK) {
 1506: 				printf("oltr%d: adapter refused receive fragment %d (rc = %d)\n", sc->unit, i, rc);
 1507: 				break;
 1508: 			}
 1509: 			i++;
 1510: 		}
 1511: 		(void)splx(s);
 1512: 	}
 1513: }
 1514: 
 1515: 
 1516: /*
 1517:  * ---------------------------- PMW Glue -------------------------------
 1518:  */
 1519: 
 1520: #ifndef TRlldInlineIO
 1521: 
 1522: static void
 1523: DriverOutByte(unsigned short IOAddress, unsigned char value)
 1524: {
 1525: 	outb(IOAddress, value);
 1526: }
 1527: 
 1528: static void
 1529: DriverOutWord(unsigned short IOAddress, unsigned short value)
 1530: {
 1531: 	outw(IOAddress, value);
 1532: }
 1533: 
 1534: static void
 1535: DriverOutDword(unsigned short IOAddress, unsigned long value)
 1536: {
 1537: 	outl(IOAddress, value);
 1538: }
 1539: 
 1540: static void
 1541: DriverRepOutByte(unsigned short IOAddress, unsigned char *DataPointer, int ByteCount)
 1542: {
 1543: 	outsb(IOAddress, (void *)DataPointer, ByteCount);
 1544: }
 1545: 
 1546: static void
 1547: DriverRepOutWord(unsigned short IOAddress, unsigned short *DataPointer, int WordCount)
 1548: {
 1549: 	outsw(IOAddress, (void *)DataPointer, WordCount);
 1550: }
 1551: 
 1552: static void
 1553: DriverRepOutDword(unsigned short IOAddress, unsigned long *DataPointer, int DWordCount)
 1554: {
 1555: 	outsl(IOAddress, (void *)DataPointer, DWordCount);
 1556: }
 1557: 
 1558: static unsigned char
 1559: DriverInByte(unsigned short IOAddress)
 1560: {
 1561: 	return(inb(IOAddress));
 1562: }
 1563: 
 1564: static unsigned short
 1565: DriverInWord(unsigned short IOAddress)
 1566: {
 1567: 	return(inw(IOAddress));
 1568: }
 1569: 
 1570: static unsigned long
 1571: DriverInDword(unsigned short IOAddress)
 1572: {
 1573: 	return(inl(IOAddress));
 1574: }
 1575: 
 1576: static void
 1577: DriverRepInByte(unsigned short IOAddress, unsigned char *DataPointer, int ByteCount)
 1578: {
 1579: 	insb(IOAddress, (void *)DataPointer, ByteCount);
 1580: }
 1581: 
 1582: static void
 1583: DriverRepInWord(unsigned short IOAddress, unsigned short *DataPointer, int WordCount)
 1584: {
 1585: 	insw(IOAddress, (void *)DataPointer, WordCount);
 1586: }
 1587: static void
 1588: DriverRepInDword( unsigned short IOAddress, unsigned long *DataPointer, int DWordCount)
 1589: {
 1590: 	insl(IOAddress, (void *)DataPointer, DWordCount);
 1591: }
 1592: #endif /* TRlldInlineIO */