File:  [DragonFly] / src / sys / net / i4b / capi / iavc / iavc_isa.c
Revision 1.5: download - view: text, annotated - select for diffs
Fri Apr 16 15:40:21 2004 UTC (10 years, 7 months ago) by joerg
Branches: MAIN
CVS tags: HEAD, DragonFly_Stable, DragonFly_Snap29Sep2004, DragonFly_Snap13Sep2004, DragonFly_RELEASE_1_2_Slip, DragonFly_RELEASE_1_2, DragonFly_1_0_REL, DragonFly_1_0_RC1, DragonFly_1_0A_REL
Merge changes from FreeBSD 5:
- remove dependency on device counting
- undo massive inlining on iavc

    1: /*
    2:  * Copyright (c) 2001 Hellmuth Michaelis. All rights reserved.
    3:  *
    4:  * Redistribution and use in source and binary forms, with or without
    5:  * modification, are permitted provided that the following conditions
    6:  * are met:
    7:  * 1. Redistributions of source code must retain the above copyright
    8:  *    notice, this list of conditions and the following disclaimer.
    9:  * 2. Redistributions in binary form must reproduce the above copyright
   10:  *    notice, this list of conditions and the following disclaimer in the
   11:  *    documentation and/or other materials provided with the distribution.
   12:  *
   13:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   14:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   17:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23:  * SUCH DAMAGE.
   24:  *
   25:  * $FreeBSD: src/sys/i4b/capi/iavc/iavc_isa.c,v 1.1.2.1 2001/08/10 14:08:34 obrien Exp $
   26:  * $DragonFly: src/sys/net/i4b/capi/iavc/iavc_isa.c,v 1.5 2004/04/16 15:40:21 joerg Exp $
   27:  */
   28: 
   29: #include <sys/param.h>
   30: #include <sys/kernel.h>
   31: #include <sys/systm.h>
   32: #include <sys/mbuf.h>
   33: #include <sys/socket.h>
   34: #include <net/if.h>
   35: 
   36: #include <machine/clock.h>
   37: 
   38: #include <machine/bus.h>
   39: #include <machine/resource.h>
   40: #include <sys/bus.h>
   41: #include <sys/rman.h>
   42: #include <vm/vm.h>
   43: #include <vm/pmap.h>
   44: #include <bus/isa/isavar.h>
   45: 
   46: #include <net/i4b/include/machine/i4b_debug.h>
   47: #include <net/i4b/include/machine/i4b_ioctl.h>
   48: #include <net/i4b/include/machine/i4b_trace.h>
   49: 
   50: #include "../../include/i4b_global.h"
   51: #include "../../include/i4b_l3l4.h"
   52: #include "../../include/i4b_mbuf.h"
   53: #include "../capi.h"
   54: 
   55: #include "iavc.h"
   56: 
   57: /* ISA driver linkage */
   58: 
   59: static void iavc_isa_intr(iavc_softc_t *sc);
   60: static int iavc_isa_probe(device_t dev);
   61: static int iavc_isa_attach(device_t dev);
   62: 
   63: static device_method_t iavc_isa_methods[] =
   64: {
   65:     DEVMETHOD(device_probe,	iavc_isa_probe),
   66:     DEVMETHOD(device_attach,	iavc_isa_attach),
   67:     { 0, 0 }
   68: };
   69: 
   70: static driver_t iavc_isa_driver =
   71: {
   72:     "iavc",
   73:     iavc_isa_methods,
   74:     0
   75: };
   76: 
   77: static devclass_t iavc_isa_devclass;
   78: 
   79: DRIVER_MODULE(iavc, isa, iavc_isa_driver, iavc_isa_devclass, 0, 0);
   80: 
   81: #define B1_IOLENGTH	0x20
   82: 
   83: static int b1_irq_table[] =
   84: {0, 0, 0, 192, 32, 160, 96, 224, 0, 64, 80, 208, 48, 0, 0, 112};
   85: /*        3    4   5    6   7       9   10  11   12        15 */
   86: 
   87: /*---------------------------------------------------------------------------*
   88:  *	device probe
   89:  *---------------------------------------------------------------------------*/
   90: 
   91: static int
   92: iavc_isa_probe(device_t dev)
   93: {
   94: 	struct iavc_softc *sc;
   95: 	int ret = ENXIO;
   96: 	int unit = device_get_unit(dev);
   97: 	
   98: 	if(isa_get_vendorid(dev))	/* no PnP probes here */
   99: 		return ENXIO;
  100: 
  101: 	/* check max unit range */
  102: 	
  103: 	if (unit >= IAVC_MAXUNIT)
  104: 	{
  105: 		printf("iavc%d: too many units\n", unit);
  106: 		return(ENXIO);	
  107: 	}
  108: 
  109: 	sc = iavc_find_sc(unit);	/* get softc */	
  110: 	
  111: 	sc->sc_unit = unit;
  112: 
  113: 	if (!(sc->sc_resources.io_base[0] =
  114: 		bus_alloc_resource(dev, SYS_RES_IOPORT,
  115: 			&sc->sc_resources.io_rid[0],
  116: 			0UL, ~0UL, B1_IOLENGTH, RF_ACTIVE)))
  117: 	{
  118: 		printf("iavc%d: can't allocate io region\n", unit);
  119: 		return(ENXIO);                                       
  120: 	}
  121: 
  122: 	sc->sc_iobase = rman_get_start(sc->sc_resources.io_base[0]);
  123: 
  124: 	switch(sc->sc_iobase)
  125: 	{
  126: 		case 0x150:
  127: 		case 0x250:
  128: 		case 0x300:
  129: 		case 0x340:
  130: 			break;
  131: 		default:
  132: 			printf("iavc%d: ERROR, invalid i/o base addr 0x%x configured!\n", sc->sc_unit, sc->sc_iobase);
  133: 			bus_release_resource(dev, SYS_RES_IOPORT,
  134: 					sc->sc_resources.io_rid[0],
  135: 		                        sc->sc_resources.io_base[0]);
  136: 		return(ENXIO);
  137: 	}	
  138: 	
  139: 	sc->sc_io_bt = rman_get_bustag(sc->sc_resources.io_base[0]);
  140: 	sc->sc_io_bh = rman_get_bushandle(sc->sc_resources.io_base[0]);
  141: 
  142: 	/* setup characteristics */
  143: 
  144: 	sc->sc_t1 = FALSE;
  145: 	sc->sc_dma = FALSE;
  146: 
  147: 	sc->sc_capi.card_type = CARD_TYPEC_AVM_B1_ISA;
  148: 	sc->sc_capi.sc_nbch = 2;
  149: 
  150: 	b1_reset(sc);
  151: 	DELAY(100);
  152: 
  153: 	ret = b1_detect(sc);
  154: 
  155: 	if(ret)
  156: 	{
  157: 		printf("iavc%d: no card ? b1_detect returns %0x02x\n", sc->sc_unit, ret);
  158: 		return(ENXIO);
  159: 	}
  160: 
  161: 	DELAY(100);
  162: 
  163: 	b1_reset(sc);
  164: 	
  165: 	DELAY(100);
  166: 
  167: 	if(bootverbose)
  168: 	{
  169: 		printf("iavc%d: class = 0x%02x, rev = 0x%02x\n", sc->sc_unit,
  170: 			iavc_read_port(sc, B1_ANALYSE),
  171: 			iavc_read_port(sc, B1_REVISION));
  172: 	}
  173: 
  174: 	device_set_desc(dev, "AVM B1 ISA");
  175: 	return(0);
  176: }
  177: 
  178: /*---------------------------------------------------------------------------*
  179:  *	attach
  180:  *---------------------------------------------------------------------------*/
  181: static int
  182: iavc_isa_attach(device_t dev)
  183: {
  184: 	struct iavc_softc *sc;
  185: 	void *ih = 0;
  186: 	int unit = device_get_unit(dev);
  187: 	int irq;
  188: 	
  189: 	sc = iavc_find_sc(unit);	/* get softc */	
  190: 	
  191: 	sc->sc_resources.irq_rid = 0;
  192: 	
  193: 	if(!(sc->sc_resources.irq =
  194: 		bus_alloc_resource(dev, SYS_RES_IRQ,
  195: 			&sc->sc_resources.irq_rid,
  196: 			0UL, ~0UL, 1, RF_ACTIVE)))
  197: 	{
  198: 		printf("iavc%d: can't allocate irq\n",unit);
  199: 		bus_release_resource(dev, SYS_RES_IOPORT,
  200: 				sc->sc_resources.io_rid[0],
  201: 	                        sc->sc_resources.io_base[0]);
  202: 		return(ENXIO);
  203: 	}
  204: 
  205: 	irq = rman_get_start(sc->sc_resources.irq);
  206: 
  207: 	if(b1_irq_table[irq] == 0)
  208: 	{
  209: 		printf("iavc%d: ERROR, illegal irq %d configured!\n",unit, irq);
  210: 		bus_release_resource(dev, SYS_RES_IOPORT,
  211: 				sc->sc_resources.io_rid[0],
  212: 	                        sc->sc_resources.io_base[0]);
  213: 		bus_release_resource(dev, SYS_RES_IRQ,
  214: 				sc->sc_resources.irq_rid,
  215: 				sc->sc_resources.irq);
  216: 		return(ENXIO);
  217: 	}
  218: 	
  219: 	memset(&sc->sc_txq, 0, sizeof(struct ifqueue));
  220: 	sc->sc_txq.ifq_maxlen = sc->sc_capi.sc_nbch * 4;
  221: 
  222: #if defined (__FreeBSD__) && __FreeBSD__ > 4
  223:         mtx_init(&sc->sc_txq.ifq_mtx, "i4b_ivac_isa", MTX_DEF);
  224: #endif
  225: 
  226: 	sc->sc_intr = FALSE;
  227: 	sc->sc_state = IAVC_DOWN;
  228: 	sc->sc_blocked = FALSE;
  229: 
  230: 	/* setup capi link */
  231: 	
  232: 	sc->sc_capi.load = iavc_load;
  233: 	sc->sc_capi.reg_appl = iavc_register;
  234: 	sc->sc_capi.rel_appl = iavc_release;
  235: 	sc->sc_capi.send = iavc_send;
  236: 	sc->sc_capi.ctx = (void*) sc;
  237: 
  238: 	if (capi_ll_attach(&sc->sc_capi))
  239: 	{
  240: 		printf("iavc%d: capi attach failed\n", unit);
  241: 		return(ENXIO);
  242: 	}
  243: 
  244: 	/* setup the interrupt */
  245: 
  246: 	if(bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET,
  247: 		      (void(*)(void*))iavc_isa_intr,
  248: 		      sc, &ih))
  249: 	{
  250: 		printf("iavc%d: irq setup failed\n", unit);
  251: 		bus_release_resource(dev, SYS_RES_IOPORT,
  252: 				sc->sc_resources.io_rid[0],
  253: 	                        sc->sc_resources.io_base[0]);
  254: 		bus_release_resource(dev, SYS_RES_IRQ,
  255: 				sc->sc_resources.irq_rid,
  256: 				sc->sc_resources.irq);
  257: 		return(ENXIO);
  258: 	}
  259: 
  260: 	/* the board is now ready to be loaded */
  261: 
  262: 	return(0);
  263: }
  264: 
  265: /*---------------------------------------------------------------------------*
  266:  *	setup interrupt
  267:  *---------------------------------------------------------------------------*/
  268: void
  269: b1isa_setup_irq(struct iavc_softc *sc)
  270: {
  271: 	int irq = rman_get_start(sc->sc_resources.irq);
  272: 	
  273: 	if(bootverbose)
  274: 		printf("iavc%d: using irq %d\n", sc->sc_unit, irq);
  275: 
  276: 	/* enable the interrupt */
  277: 
  278: 	b1io_outp(sc, B1_INSTAT, 0x00);
  279: 	b1io_outp(sc, B1_RESET, b1_irq_table[irq]);
  280: 	b1io_outp(sc, B1_INSTAT, 0x02);
  281: }	
  282: 
  283: /*---------------------------------------------------------------------------*
  284:  *	IRQ handler
  285:  *---------------------------------------------------------------------------*/
  286: static void
  287: iavc_isa_intr(struct iavc_softc *sc)
  288: {
  289: 	iavc_handle_intr(sc);
  290: }