コード例 #1
0
ファイル: i4b_avm_a1.c プロジェクト: MarginC/kame
/*---------------------------------------------------------------------------*
 *	allocate an io port
 *---------------------------------------------------------------------------*/
static int
isic_alloc_port(device_t dev, int rid, u_int base, u_int len)
{ 
	size_t unit = device_get_unit(dev);
	struct l1_softc *sc = &l1_sc[unit];

	sc->sc_resources.io_rid[rid] = rid;

	bus_set_resource(dev, SYS_RES_IOPORT, rid, base, len);

	if(!(sc->sc_resources.io_base[rid] =
		bus_alloc_resource(dev, SYS_RES_IOPORT,
				   &sc->sc_resources.io_rid[rid],
				   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		printf("isic%d: Error, failed to reserve io #%d!\n", unit, rid);
		isic_detach_common(dev);
		return(ENXIO);
	}
	return(0);
}
コード例 #2
0
ファイル: i4b_isic_pnp.c プロジェクト: MarginC/kame
/*---------------------------------------------------------------------------*
 *      attach for ISA PnP cards
 *---------------------------------------------------------------------------*/
static int
isic_pnp_attach(device_t dev)
{
	u_int32_t vend_id = isa_get_vendorid(dev);	/* vendor id */
	unsigned int unit = device_get_unit(dev);	/* get unit */
	const char *name = device_get_desc(dev);	/* get description */
	struct l1_softc *sc = 0;			/* softc */
	void *ih = 0;					/* a dummy */
	int ret;
 
	/* see if we are out of bounds */
	
	if(unit >= ISIC_MAXUNIT)
	{
		printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for %s\n", unit, unit, name);
		return ENXIO;
	}

	/* get information structure for this unit */

	sc = &l1_sc[unit];

	/* get io_base */
	if(!(sc->sc_resources.io_base[0] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
						&sc->sc_resources.io_rid[0],
						0UL, ~0UL, 1, RF_ACTIVE ) ))
	{
		printf("isic_pnp_attach: Couldn't get my io_base.\n");
		return ENXIO;                                       
	}
	
	/* will not be used for pnp devices */

	sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]);

	/* get irq, release io_base if we don't get it */

	if(!(sc->sc_resources.irq =
			bus_alloc_resource(dev, SYS_RES_IRQ,
					   &sc->sc_resources.irq_rid,
					   0UL, ~0UL, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not get irq.\n",unit);
		isic_detach_common(dev);
		return ENXIO;                                       
	}
	
	/* not needed */
	sc->sc_irq = rman_get_start(sc->sc_resources.irq);


	/* set flag so we know what this card is */

	ret = ENXIO;
	
	switch(vend_id)
	{
#if defined(TEL_S0_16_3_P) || defined(CRTX_S0_P) || defined(COMPAQ_M610)
		case VID_TEL163PNP:
			sc->sc_cardtyp = CARD_TYPEP_163P;
			ret = isic_attach_Cs0P(dev);
			break;

		case VID_CREATIXPP:
			sc->sc_cardtyp = CARD_TYPEP_CS0P;
			ret = isic_attach_Cs0P(dev);
			break;

		case VID_COMPAQ_M610:
			sc->sc_cardtyp = CARD_TYPEP_COMPAQ_M610;
			ret = isic_attach_Cs0P(dev);
			break;
#endif
#ifdef DYNALINK
		case VID_DYNALINK:
			sc->sc_cardtyp = CARD_TYPEP_DYNALINK;
			ret = isic_attach_Dyn(dev);
			break;
#endif
#ifdef SEDLBAUER
		case VID_SEDLBAUER:
			sc->sc_cardtyp = CARD_TYPEP_SWS;
			ret = isic_attach_sws(dev);
			break;
#endif
#ifdef DRN_NGO
		case VID_NICCYGO:
			sc->sc_cardtyp = CARD_TYPEP_DRNNGO;
			ret = isic_attach_drnngo(dev);
			break;
#endif
#ifdef ELSA_QS1ISA
		case VID_ELSAQS1P:
			sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA;
			ret = isic_attach_Eqs1pi(dev);
			break;
#endif
#ifdef ITKIX1
		case VID_ITK0025:
			sc->sc_cardtyp = CARD_TYPEP_ITKIX1;
			ret = isic_attach_itkix1(dev);
			break;
#endif			
#ifdef SIEMENS_ISURF2
		case VID_SIESURF2:
			sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2;
			ret = isic_attach_siemens_isurf(dev);
			break;
#endif
#ifdef ASUSCOM_IPAC
		case VID_ASUSCOM_IPAC:
			sc->sc_cardtyp = CARD_TYPEP_ASUSCOMIPAC;
			ret = isic_attach_asi(dev);
			break;
#endif
#ifdef EICON_DIVA
		case VID_EICON_DIVA_20:
			sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA;
			ret = isic_attach_diva(dev);
			break;
		
		case VID_EICON_DIVA_202:
			sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA;
			ret = isic_attach_diva_ipac(dev);
			break;
#endif
		default:
			printf("isic%d: Error, no driver for %s\n", unit, name);
			ret = ENXIO;
			break;		
	}

	if(ret)
	{
		isic_detach_common(dev);
		return ENXIO;                                       
	}		
		
	if(isic_attach_common(dev))
	{
		/* unset flag */
		sc->sc_cardtyp = CARD_TYPEP_UNK;

		/* free irq here, it hasn't been attached yet */
		bus_release_resource(dev,SYS_RES_IRQ,sc->sc_resources.irq_rid,
					sc->sc_resources.irq);
		sc->sc_resources.irq = 0;
		isic_detach_common(dev);
		return ENXIO;
	}
	else
	{
		/* setup intr routine */
		bus_setup_intr(dev,sc->sc_resources.irq,INTR_TYPE_NET,
				(void(*)(void*))isicintr,
				sc,&ih);
		return 0;
	}
}
コード例 #3
0
/*---------------------------------------------------------------------------*
 *	isic_probe_usrtai - probe for USR
 *---------------------------------------------------------------------------*/
int
isic_probe_usrtai(device_t dev)
{
	size_t unit = device_get_unit(dev);	/* get unit */
	struct l1_softc *sc = 0;	/* pointer to softc */
	void *ih = 0;			/* dummy */

	/* check max unit range */

	if(unit >= ISIC_MAXUNIT)
	{
		kprintf("isic%d: Error, unit %d >= ISIC_MAXUNIT for USR Sportster TA!\n",
				unit, unit);
		return(ENXIO);	
	}

	sc = &l1_sc[unit];			/* get pointer to softc */
	sc->sc_unit = unit;			/* set unit */

	/* see if an io base was supplied */
	
	if(!(sc->sc_resources.io_base[0] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
	                                   &sc->sc_resources.io_rid[0],
	                                   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		kprintf("isic%d: Could not get iobase for USR Sportster TA!\n",
				unit);
		return(ENXIO);
	}

	/* set io base */

	sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]);
	
	/* release io base */
	
	bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0],
		sc->sc_resources.io_base[0]);


	/* check if we got an iobase */

	switch(sc->sc_port)
	{
		case 0x200:
		case 0x208:
		case 0x210:
		case 0x218:
		case 0x220:
		case 0x228:
		case 0x230:
		case 0x238:
		case 0x240:
		case 0x248:
		case 0x250:
		case 0x258:
		case 0x260:
		case 0x268:
		case 0x270:
		case 0x278:
			break;
			
		default:
			kprintf("isic%d: Error, invalid iobase 0x%x specified for USR Sportster TA!\n",
				unit, sc->sc_port);
			return(0);
			break;
	}

	/* allocate all the ports needed */

	if(usrtai_alloc_port(dev))
	{
		kprintf("isic%d: Could not get the ports for USR Sportster TA!\n", unit);
		isic_detach_common(dev);
		return(ENXIO);
	}

	/* get our irq */

	if(!(sc->sc_resources.irq =
		bus_alloc_resource(dev, SYS_RES_IRQ,
				   &sc->sc_resources.irq_rid,
				   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		kprintf("isic%d: Could not get an irq for USR Sportster TA!\n",unit);
		isic_detach_common(dev);
		return ENXIO;
	}

	/* get the irq number */
	sc->sc_irq = rman_get_start(sc->sc_resources.irq);

	/* register interrupt routine */
	bus_setup_intr(dev, sc->sc_resources.irq, 0,
			(void(*)(void *))(isicintr), sc, &ih, NULL);

	/* check IRQ validity */

	if(intr_no[sc->sc_irq] == 0)
	{
		kprintf("isic%d: Error, invalid IRQ [%d] specified for USR Sportster TA!\n",
			unit, sc->sc_irq);
		return(1);
	}

	/* setup ISAC access routines */

	sc->clearirq = NULL;
	sc->readreg = usrtai_read_reg;
	sc->writereg = usrtai_write_reg;

	sc->readfifo = usrtai_read_fifo;
	sc->writefifo = usrtai_write_fifo;

	/* setup card type */

	sc->sc_cardtyp = CARD_TYPEP_USRTA;

	/* setup IOM bus type */
	
	sc->sc_bustyp = BUS_TYPE_IOM2;

	sc->sc_ipac = 0;
	sc->sc_bfifolen = HSCX_FIFO_LEN;
	
	/* setup ISAC and HSCX base addr */
	
	ISAC_BASE   = (caddr_t)sc->sc_port + USR_ISAC_OFF;
	HSCX_A_BASE = (caddr_t)sc->sc_port + USR_HSCXA_OFF;
	HSCX_B_BASE = (caddr_t)sc->sc_port + USR_HSCXB_OFF;

	/* 
	 * Read HSCX A/B VSTR.  Expected value for USR Sportster TA based
	 * boards is 0x05 in the least significant bits.
	 */

	if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
            ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
	{
		kprintf("isic%d: HSCX VSTR test failed for USR Sportster TA\n",
			unit);
		kprintf("isic%d: HSC0: VSTR: %#x\n",
			unit, HSCX_READ(0, H_VSTR));
		kprintf("isic%d: HSC1: VSTR: %#x\n",
			unit, HSCX_READ(1, H_VSTR));
		return (1);
	}                   
	
	return (0);
}
コード例 #4
0
/*---------------------------------------------------------------------------*
 *	allocate an io port - based on code in isa_isic.c
 *---------------------------------------------------------------------------*/
static int
usrtai_alloc_port(device_t dev)
{ 
	size_t unit = device_get_unit(dev);
	struct l1_softc *sc = &l1_sc[unit];
	int i, num = 0;
	bus_size_t base;

	/* 49 io mappings: 1 config and 48x8 registers */

	/* config at offset 0x8000 */
	base = sc->sc_port + 0x8000;
	if (base < 0 || base > 0x0ffff)
		return 1;
	sc->sc_resources.io_rid[num] = num;

	bus_set_resource(dev, SYS_RES_IOPORT, num, base, 1);

	if(!(sc->sc_resources.io_base[num] =
		bus_alloc_resource(dev, SYS_RES_IOPORT,
				   &sc->sc_resources.io_rid[num],
				   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		kprintf("isic%d: Error, failed to reserve io #%dport %#x!\n", unit, num, base);
		isic_detach_common(dev);
		return(ENXIO);
	}
	num++;

	/* HSCX A at offset 0 */
	base = sc->sc_port;
	for (i = 0; i < 16; i++) {
		if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
			return 1;
		sc->sc_resources.io_rid[num] = num;

		bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);

		if(!(sc->sc_resources.io_base[num] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
					   &sc->sc_resources.io_rid[num],
					   0ul, ~0ul, 1, RF_ACTIVE)))
		{
			kprintf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
			isic_detach_common(dev);
			return(ENXIO);
		}
		++num;
	}

	/* HSCX B at offset 0x4000 */
	base = sc->sc_port + 0x4000;
	for (i = 0; i < 16; i++) {
		if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
			return 1;
		sc->sc_resources.io_rid[num] = num;

		bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);

		if(!(sc->sc_resources.io_base[num] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
					   &sc->sc_resources.io_rid[num],
					   0ul, ~0ul, 1, RF_ACTIVE)))
		{
			kprintf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
			isic_detach_common(dev);
			return(ENXIO);
		}
		++num;
	}

	/* ISAC at offset 0xc000 */
	base = sc->sc_port + 0xc000;
	for (i = 0; i < 16; i++) {
		if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
			return 1;
		sc->sc_resources.io_rid[num] = num;

		bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);

		if(!(sc->sc_resources.io_base[num] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
					   &sc->sc_resources.io_rid[num],
					   0ul, ~0ul, 1, RF_ACTIVE)))
		{
			kprintf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
			isic_detach_common(dev);
			return(ENXIO);
		}
		++num;
	}

	return(0);
}
コード例 #5
0
ファイル: i4b_avm_a1.c プロジェクト: MarginC/kame
/*---------------------------------------------------------------------------*
 *	isic_probe_avma1 - probe for AVM A1 and compatibles
 *---------------------------------------------------------------------------*/
int
isic_probe_avma1(device_t dev)
{
	size_t unit = device_get_unit(dev);	/* get unit */
	struct l1_softc *sc = 0;	/* pointer to softc */
	void *ih = 0;			/* dummy */
	bus_space_tag_t    t;		/* bus things */
	bus_space_handle_t h;
	u_char savebyte;
	u_char byte;

	/* check max unit range */

	if(unit >= ISIC_MAXUNIT)
	{
		printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for AVM A1/Fritz!\n",
				unit, unit);
		return(ENXIO);	
	}

	sc = &l1_sc[unit];			/* get pointer to softc */
	sc->sc_unit = unit;			/* set unit */

	/* see if an io base was supplied */
	
	if(!(sc->sc_resources.io_base[0] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
	                                   &sc->sc_resources.io_rid[0],
	                                   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not get iobase for AVM A1/Fritz!\n",
				unit);
		return(ENXIO);
	}

	/* set io base */

	sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]);
	
	/* release io base */
	
        bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0],
			sc->sc_resources.io_base[0]);

	switch(sc->sc_port)
	{
		case 0x200:
		case 0x240:
		case 0x300:
		case 0x340:		
			break;
			
		default:
			printf("isic%d: Error, invalid iobase 0x%x specified for AVM A1/Fritz!\n",
				unit, sc->sc_port);
			return(ENXIO);
			break;
	}

	if(isic_alloc_port(dev, 0, sc->sc_port+AVM_CONF_REG, 0x20))
		return(ENXIO);

	if(isic_alloc_port(dev, 1, sc->sc_port+AVM_ISAC_R_OFFS, 0x20))
		return(ENXIO);

	if(isic_alloc_port(dev, 2, sc->sc_port+AVM_HSCXA_R_OFFS, 0x20))
		return(ENXIO);

	if(isic_alloc_port(dev, 3, sc->sc_port+AVM_HSCXB_R_OFFS, 0x20))
		return(ENXIO);

	if(isic_alloc_port(dev, 4, sc->sc_port+AVM_ISAC_F_OFFS, 0x20))
		return(ENXIO);

	if(isic_alloc_port(dev, 5, sc->sc_port+AVM_HSCXA_F_OFFS, 0x20))
		return(ENXIO);

	if(isic_alloc_port(dev, 6, sc->sc_port+AVM_HSCXB_F_OFFS, 0x20))
		return(ENXIO);

	/* get our irq */

	if(!(sc->sc_resources.irq =
		bus_alloc_resource(dev, SYS_RES_IRQ,
				   &sc->sc_resources.irq_rid,
				   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not get an irq for AVM A1/Fritz!\n",unit);
		isic_detach_common(dev);
		return ENXIO;
	}

	/* get the irq number */
	sc->sc_irq = rman_get_start(sc->sc_resources.irq);

	/* register interupt routine */
	bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET,
			(void(*)(void *))(isicintr),
			sc, &ih);

	/* check IRQ validity */

	switch(sc->sc_irq)
	{
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
		case 10:
		case 11:
		case 12:
		case 13:
		case 14:
		case 15:
			break;
			
		default:
			printf("isic%d: Error, invalid IRQ [%d] specified for AVM A1/Fritz!\n",
				unit, sc->sc_irq);
			isic_detach_common(dev);
			return(ENXIO);
			break;
	}		

	sc->clearirq = NULL;
	sc->readreg = avma1_read_reg;
	sc->writereg = avma1_write_reg;

	sc->readfifo = avma1_read_fifo;
	sc->writefifo = avma1_write_fifo;

	/* setup card type */

	sc->sc_cardtyp = CARD_TYPEP_AVMA1;

	/* setup IOM bus type */
	
	sc->sc_bustyp = BUS_TYPE_IOM2;

	sc->sc_ipac = 0;
	sc->sc_bfifolen = HSCX_FIFO_LEN;

	/* 
	 * Read HSCX A/B VSTR.
	 * Expected value for AVM A1 is 0x04 or 0x05 and for the
	 * AVM Fritz!Card is 0x05 in the least significant bits.
	 */

	if( (((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) &&
	     ((HSCX_READ(0, H_VSTR) & 0xf) != 0x4))	||
            (((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) &&
	     ((HSCX_READ(1, H_VSTR) & 0xf) != 0x4)) )  
	{
		printf("isic%d: HSCX VSTR test failed for AVM A1/Fritz\n",
			unit);
		printf("isic%d: HSC0: VSTR: %#x\n",
			unit, HSCX_READ(0, H_VSTR));
		printf("isic%d: HSC1: VSTR: %#x\n",
			unit, HSCX_READ(1, H_VSTR));
		return(ENXIO);
	}                   

	/* AVM A1 or Fritz! control register bits:	*/
	/*        read                write		*/
	/* 0x01  hscx irq*           RESET		*/
	/* 0x02  isac irq*           clear counter1	*/
	/* 0x04  counter irq*        clear counter2	*/
	/* 0x08  always 0            irq enable		*/
	/* 0x10  read test bit       set test bit	*/
	/* 0x20  always 0            unused		*/

	/*
	 * XXX the following test may be destructive, to prevent the
	 * worst case, we save the byte first, and in case the test
	 * fails, we write back the saved byte .....
	 */

	t = rman_get_bustag(sc->sc_resources.io_base[0]);
	h = rman_get_bushandle(sc->sc_resources.io_base[0]);

	savebyte = bus_space_read_1(t, h, 0);
	
	/* write low to test bit */

	bus_space_write_1(t, h, 0, 0x00);
	
	/* test bit and next higher and lower bit must be 0 */

	if((byte = bus_space_read_1(t, h, 0) & 0x38) != 0x00)
	{
		printf("isic%d: Error, probe-1 failed, 0x%02x should be 0x00 for AVM A1/Fritz!\n",
				unit, byte);
		bus_space_write_1(t, h, 0, savebyte);
		return(ENXIO);
	}

	/* write high to test bit */

	bus_space_write_1(t, h, 0, 0x10);
	
	/* test bit must be high, next higher and lower bit must be 0 */

	if((byte = bus_space_read_1(t, h, 0) & 0x38) != 0x10)
	{
		printf("isic%d: Error, probe-2 failed, 0x%02x should be 0x10 for AVM A1/Fritz!\n",
				unit, byte);
		bus_space_write_1(t, h, 0, savebyte);
		return(ENXIO);
	}
	return(0);
}
コード例 #6
0
ファイル: i4b_ctx_s0P.c プロジェクト: MarginC/kame
/*---------------------------------------------------------------------------*
 *	isic_attach_Cs0P - attach Creatix / Teles PnP
 *---------------------------------------------------------------------------*/
int
isic_attach_Cs0P(device_t dev)
{
	u_int32_t iobase1;
	u_int32_t iobase2;
	u_int32_t iocfg = 0;	/* quiet bogus gcc warning */
	int unit = device_get_unit(dev);
	struct l1_softc *sc = &l1_sc[unit];	
	bus_space_tag_t t;
	bus_space_handle_t h;

	/*
	 * this card needs a second io_base,
	 * free resources if we don't get it
	 */

	sc->sc_resources.io_rid[1] = 1;
	
	if(!(sc->sc_resources.io_base[1] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
					&sc->sc_resources.io_rid[1],
					0UL, ~0UL, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not get io area 1 for Creatix / Teles PnP!\n", unit);
		isic_detach_common(dev);
		return ENXIO;
	}

	/*
	 * Compaq M610 has a cfg io area,
	 * we need it
	 */

	if (sc->sc_cardtyp == CARD_TYPEP_COMPAQ_M610)
	{
		sc->sc_resources.io_rid[2] = 2;
	
		if(!(sc->sc_resources.io_base[2] =
				bus_alloc_resource(dev, SYS_RES_IOPORT,
						&sc->sc_resources.io_rid[2],
						0UL, ~0UL, 1, RF_ACTIVE)))
		{
			printf("isic%d: Could not get cfg io area for Compaq Microcom 610\n", unit);
			isic_detach_common(dev);
			return ENXIO;
		}

		iocfg = rman_get_start(sc->sc_resources.io_base[2]);

	        bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[2],
				sc->sc_resources.io_base[2]);
	}

	/* remember the io base addresses */
	
	if (sc->sc_cardtyp != CARD_TYPEP_COMPAQ_M610)
	{
		iobase1 = rman_get_start(sc->sc_resources.io_base[0]);
		iobase2 = rman_get_start(sc->sc_resources.io_base[1]);
	}
	else
	{
		iobase1 = rman_get_start(sc->sc_resources.io_base[1]);
		iobase2 = rman_get_start(sc->sc_resources.io_base[0]);
	}

	/*
	 * because overlapping resources are invalid,
	 * release the first and second io port resource
	 */
	
        bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0],
			sc->sc_resources.io_base[0]);
	
        bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[1],
			sc->sc_resources.io_base[1]);

	/* set and allocate a base io address for the ISAC chip */
	
	sc->sc_resources.io_rid[2] = 2;
	
	bus_set_resource(dev, SYS_RES_IOPORT, 2, iobase1-0x20, 0x40);

	if(!(sc->sc_resources.io_base[2] =
		bus_alloc_resource(dev, SYS_RES_IOPORT,
				   &sc->sc_resources.io_rid[2],
				   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not get io area 2 for Creatix / Teles PnP!\n", unit);
		isic_detach_common(dev);
		return ENXIO;
	}


	/* set and allocate a resource for the HSCX channel A */
	
	sc->sc_resources.io_rid[3] = 3;

/*XXX*/	/* FIXME !!!!
	 * the width of the resource is too small, there are accesses
	 * to it with an offset of 0x3e into the next resource. anyway,
         * it seems to work and i have no idea how to do 2 resources
	 * overlapping each other.
	 */

#if 0
	bus_set_resource(dev, SYS_RES_IOPORT, 3, iobase2-0x20, 0x20);
#else
	bus_set_resource(dev, SYS_RES_IOPORT, 3, iobase2-0x20, 0x10);
#endif

	if(!(sc->sc_resources.io_base[3] =
		bus_alloc_resource(dev,SYS_RES_IOPORT,
				   &sc->sc_resources.io_rid[3],
				   0ul,~0ul, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not get io area 3 for Creatix / Teles PnP!\n", unit);
		isic_detach_common(dev);
		return ENXIO;
	}

	/* set and allocate a resources for the HSCX channel B */
	
	sc->sc_resources.io_rid[4] = 4;
	
	bus_set_resource(dev, SYS_RES_IOPORT, 4, iobase2, 0x40);

	if(!(sc->sc_resources.io_base[4] =
		bus_alloc_resource(dev,SYS_RES_IOPORT,
				   &sc->sc_resources.io_rid[4],
				   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not get io area 4 for Creatix / Teles PnP!\n", unit);
		isic_detach_common(dev);
		return ENXIO;
	}

	/*
	 * set and allocate a resource for the cfg io
	 * for compaq m610
	 */

	if (sc->sc_cardtyp == CARD_TYPEP_COMPAQ_M610)
	{
		sc->sc_resources.io_rid[5] = 5;

		bus_set_resource(dev, SYS_RES_IOPORT, 5, iocfg, 0x01);

		if(!(sc->sc_resources.io_base[5] =
			bus_alloc_resource(dev,SYS_RES_IOPORT,
					   &sc->sc_resources.io_rid[5],
					   0ul, ~0ul, 1, RF_ACTIVE)))
		{
			printf("isic%d: Could not get cfg io area for Compaq Microcom 610!\n", unit);
			isic_detach_common(dev);
			return ENXIO;
		}
	}

	/* setup access routines */

	sc->clearirq = NULL;
	sc->readreg = ctxs0P_read_reg;
	sc->writereg = ctxs0P_write_reg;

	sc->readfifo = ctxs0P_read_fifo;
	sc->writefifo = ctxs0P_write_fifo;

	/* setup card type */

	if (sc->sc_cardtyp != CARD_TYPEP_COMPAQ_M610)
		sc->sc_cardtyp = CARD_TYPEP_CS0P;

	/* setup IOM bus type */
	
	sc->sc_bustyp = BUS_TYPE_IOM2;

	sc->sc_ipac = 0;
	sc->sc_bfifolen = HSCX_FIFO_LEN;

	/* enable the card */
	
	if (sc->sc_cardtyp != CARD_TYPEP_COMPAQ_M610)
	{
		t = rman_get_bustag(sc->sc_resources.io_base[2]);
		h = rman_get_bushandle(sc->sc_resources.io_base[2]);
	
		bus_space_write_1(t, h, 0x3c, 0);
		DELAY(SEC_DELAY / 10);

		bus_space_write_1(t, h, 0x3c, 1);
		DELAY(SEC_DELAY / 10);
	}
	else
	{
		t = rman_get_bustag(sc->sc_resources.io_base[5]);
		h = rman_get_bushandle(sc->sc_resources.io_base[5]);

		bus_space_write_1(t, h, 0xff, 0);
		DELAY(SEC_DELAY / 10);

		bus_space_write_1(t, h, 0x00, 1);
		DELAY(SEC_DELAY / 10);
	}

	return 0;
}
コード例 #7
0
ファイル: i4b_tel_s016.c プロジェクト: MarginC/kame
/*---------------------------------------------------------------------------*
 *	isic_probe_s016 - probe for Teles S0/16 and compatibles
 *---------------------------------------------------------------------------*/
int
isic_probe_s016(device_t dev)
{
	size_t unit = device_get_unit(dev);	/* get unit */
	struct l1_softc *sc = 0;		/* softc */
	void *ih = 0;				/* dummy */
	u_int8_t b0,b1,b2;			/* for signature */
	bus_space_tag_t    t;			/* bus things */
	bus_space_handle_t h;

	/* check max unit range */

	if(unit >= ISIC_MAXUNIT)
	{
		printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/16!\n",
				unit, unit);
		return(ENXIO);	
	}

	sc = &l1_sc[unit];			/* get pointer to softc */
	sc->sc_unit = unit;			/* set unit */

	/* see if an io base was supplied */

	if(!(sc->sc_resources.io_base[0] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
	                                   &sc->sc_resources.io_rid[0],
	                                   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not allocate i/o port for Teles S0/16.\n", unit);
		return(ENXIO);
	}

	sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]);

	/*
	 * check if the provided io port is valid
	 */

	switch(sc->sc_port)
	{
		case 0xd80:
		case 0xe80:
		case 0xf80:
			break;

		default:
			printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16!\n",
				unit, sc->sc_port);
			isic_detach_common(dev);
			return(ENXIO);
			break;
	}

	/* allocate memory resource */

	if(!(sc->sc_resources.mem =
			bus_alloc_resource(dev, SYS_RES_MEMORY,
					&sc->sc_resources.mem_rid,
					0ul, ~0ul, TELES_S016_MEMSIZE,
					RF_ACTIVE)))
	{
		printf("isic%d: Could not allocate memory for Teles S0/16.\n", unit);
		isic_detach_common(dev);
		return(ENXIO);
	}

	/* 
	 * get virtual addr.
	 */
	sc->sc_vmem_addr = rman_get_virtual(sc->sc_resources.mem);

	/*
	 * check for valid adresses
	 */
	switch(kvtop(sc->sc_vmem_addr))
	{
		case 0xc0000:
		case 0xc2000:
		case 0xc4000:
		case 0xc6000:
		case 0xc8000:
		case 0xca000:
		case 0xcc000:
		case 0xce000:
		case 0xd0000:
		case 0xd2000:
		case 0xd4000:
		case 0xd6000:
		case 0xd8000:
		case 0xda000:
		case 0xdc000:
		case 0xde000:
			break;

		default:
			printf("isic%d: Error, invalid memory address 0x%lx for Teles S0/16!\n",
				unit, kvtop(sc->sc_vmem_addr));
			isic_detach_common(dev);
			return(ENXIO);
			break;
	}		
	
	/* setup ISAC access routines */

	sc->clearirq = NULL;

	sc->readreg = tels016_read_reg;
	sc->writereg = tels016_write_reg;

	sc->readfifo = tels016_read_fifo;
	sc->writefifo = tels016_write_fifo;

	/* setup card type */
	sc->sc_cardtyp = CARD_TYPEP_16;

	/* setup IOM bus type */
	
	sc->sc_bustyp = BUS_TYPE_IOM1;

	sc->sc_ipac = 0;
	sc->sc_bfifolen = HSCX_FIFO_LEN;

	/* setup ISAC base addr, though we don't really need it */
	
	ISAC_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x100);

	/* setup HSCX base addr */
	
	HSCX_A_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x180);
	HSCX_B_BASE = (caddr_t)((sc->sc_vmem_addr) + 0x1c0);

	t = rman_get_bustag(sc->sc_resources.io_base[0]);
	h = rman_get_bushandle(sc->sc_resources.io_base[0]);

	/* get signature bytes */
	b0 = bus_space_read_1(t, h, 0);
	b1 = bus_space_read_1(t, h, 1);
	b2 = bus_space_read_1(t, h, 2);

	/* check signature bytes */
	if(b0 != 0x51)
	{
		printf("isic%d: Error, signature 1 0x%x != 0x51 for Teles S0/16!\n",
			unit, b0);
		isic_detach_common(dev);
		return(ENXIO);
	}
	
	if(b1 != 0x93)
	{
		printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16!\n",
			unit, b1);
		isic_detach_common(dev);
		return(ENXIO);
	}
	
	if((b2 != 0x1e) && (b2 != 0x1f))
	{
		printf("isic%d: Error, signature 3 0x%x != 0x1e or 0x1f for Teles S0/16!\n",
			unit, b2);
		isic_detach_common(dev);
		return(ENXIO);
	}

	/* get our irq */

	if(!(sc->sc_resources.irq =
			bus_alloc_resource(dev, SYS_RES_IRQ,
						&sc->sc_resources.irq_rid,
						0ul, ~0ul, 1, RF_ACTIVE)))
	{
		printf("isic%d: Could not allocate irq for Teles S0/16.\n", unit);
		isic_detach_common(dev);
		return ENXIO;
	}

	/* register interupt routine */

	bus_setup_intr(dev, sc->sc_resources.irq,
			INTR_TYPE_NET,
			(void(*)(void *))(isicintr),
			sc, &ih);

	/* get the irq number */
	
	sc->sc_irq = rman_get_start(sc->sc_resources.irq);

	/* check IRQ validity */

	if((intr_no[sc->sc_irq]) == 1)
	{
		printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/16!\n",
			unit, sc->sc_irq);
		isic_detach_common(dev);
		return(ENXIO);
	}
	
	return (0);
}
コード例 #8
0
/*---------------------------------------------------------------------------*
 *	isic_probe_s0163 - probe routine for Teles S0/16.3
 *---------------------------------------------------------------------------*/
int
isic_probe_s0163(device_t dev)
{
	size_t unit = device_get_unit(dev);	/* get unit */
	struct l1_softc *sc = 0;	/* pointer to softc */
	void *ih = 0;			/* dummy */
	bus_space_tag_t    t;		/* bus things */
	bus_space_handle_t h;
	u_int8_t b0,b1,b2;		/* signature */

	/* check max unit range */

	if(unit >= ISIC_MAXUNIT)
	{
		kprintf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles 16.3!\n",
				unit, unit);
		return(ENXIO);	
	}

	sc = &l1_sc[unit];			/* get pointer to softc */
	sc->sc_unit = unit;			/* set unit */

	/* see if an io base was supplied */
	
	if(!(sc->sc_resources.io_base[0] =
			bus_alloc_resource(dev, SYS_RES_IOPORT,
	                                   &sc->sc_resources.io_rid[0],
	                                   0ul, ~0ul, 1, RF_ACTIVE)))
	{
		kprintf("isic%d: Could not get iobase for Teles S0/16.3.\n",
				unit);
		return(ENXIO);
	}

	/* set io base */

	sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]);
	/* Release the resource -  re-allocate later with correct size	*/
        bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0],
			sc->sc_resources.io_base[0]);
	
	switch(sc->sc_port)
	{
		case 0xd80:
		case 0xe80:
		case 0xf80:
			break;
			
		case 0x180:
		case 0x280:
		case 0x380:
			kprintf("isic%d: Error, instead of using iobase 0x%x for your Teles S0/16.3,\n",
				unit, sc->sc_port);
			kprintf("isic%d:        please use 0x%x in the kernel configuration file!\n",
				unit, sc->sc_port+0xc00);			
			isic_detach_common(dev);
			return(ENXIO);
			break;
	
		default:
			kprintf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n",
				unit, sc->sc_port);
			isic_detach_common(dev);
			return(ENXIO);
			break;
	}
	
	/* set io port resources */

	sc->sc_resources.io_rid[0] = 0;	
	bus_set_resource(dev, SYS_RES_IOPORT, 0, sc->sc_port, 0x20);
	sc->sc_resources.io_base[0] =
		bus_alloc_resource(dev, SYS_RES_IOPORT,
				   &sc->sc_resources.io_rid[0],
				   0ul, ~0ul, 1, RF_ACTIVE);
	if(!sc->sc_resources.io_base[0])
	{
		kprintf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n",
			unit, sc->sc_port);
		isic_detach_common(dev);
		return ENXIO;
	}
	sc->sc_resources.io_rid[1] = 1;	
	bus_set_resource(dev, SYS_RES_IOPORT, 1,
		sc->sc_port-ISAC_OFFS, 0x20);
	sc->sc_resources.io_base[1] =
		bus_alloc_resource(dev, SYS_RES_IOPORT,
				   &sc->sc_resources.io_rid[1],
				   0ul, ~0ul, 1, RF_ACTIVE);
	if(!sc->sc_resources.io_base[1])
	{
		kprintf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n",
			unit, sc->sc_port-ISAC_OFFS);
		isic_detach_common(dev);
		return ENXIO;
	}
	
	sc->sc_resources.io_rid[2] = 2;
	bus_set_resource(dev, SYS_RES_IOPORT, 2,
		sc->sc_port-HSCXA_OFFS, 0x20);
	sc->sc_resources.io_base[2] =
		bus_alloc_resource(dev, SYS_RES_IOPORT,
				   &sc->sc_resources.io_rid[2],
				   0ul, ~0ul, 1, RF_ACTIVE);
	if(!sc->sc_resources.io_base[2])
	{
		kprintf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n",
			unit, sc->sc_port-HSCXA_OFFS);
		isic_detach_common(dev);
		return ENXIO;
	}

	sc->sc_resources.io_rid[3] = 3;
	bus_set_resource(dev, SYS_RES_IOPORT, 3,
		sc->sc_port-HSCXB_OFFS, 0x20);
	sc->sc_resources.io_base[3] =
		bus_alloc_resource(dev, SYS_RES_IOPORT,
				   &sc->sc_resources.io_rid[3],
				   0ul, ~0ul, 1, RF_ACTIVE);
	if(!sc->sc_resources.io_base[3])
	{
		kprintf("isic%d: Error allocating io at 0x%x for Teles S0/16.3!\n",
			unit, sc->sc_port-HSCXB_OFFS);
		isic_detach_common(dev);
		return ENXIO;
	}

	/* setup access routines */

	sc->clearirq = NULL;
	sc->readreg = tels0163_read_reg;
	sc->writereg = tels0163_write_reg;

	sc->readfifo = tels0163_read_fifo;
	sc->writefifo = tels0163_write_fifo;

	/* setup card type */
	
	sc->sc_cardtyp= CARD_TYPEP_16_3;

	/* setup IOM bus type */
	
	sc->sc_bustyp = BUS_TYPE_IOM2;

	sc->sc_ipac = 0;
	sc->sc_bfifolen = HSCX_FIFO_LEN;

	t = rman_get_bustag(sc->sc_resources.io_base[0]);
	h = rman_get_bushandle(sc->sc_resources.io_base[0]);

	b0 = bus_space_read_1(t, h, 0);
	b1 = bus_space_read_1(t, h, 1);
	b2 = bus_space_read_1(t, h, 2);
	
	if ( b0 != 0x51 && b0 != 0x10 ) {
		kprintf("isic%d: Error, signature 1 0x%x != 0x51 or 0x10 for Teles S0/16.3!\n",
			unit, b0);
		isic_detach_common(dev);
		return ENXIO;
	}
	
	if ( b1 != 0x93 ) {
		kprintf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!\n",
			unit, b1);
		isic_detach_common(dev);
		return ENXIO;
	}
	if (( b2 != 0x1c ) && ( b2 != 0x1f )) {
		kprintf("isic%d: Error, signature 3 0x%x != (0x1c || 0x1f) for Teles S0/16.3!\n",
			unit, b2);
		isic_detach_common(dev);
		return ENXIO;	
	}
	
	/* 
	 * Read HSCX A/B VSTR.  Expected value for the S0/16.3 card is
	 * 0x05 or 0x04 (for older 16.3's) in the least significant bits.
	 */
	 
	if( (((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) &&
	     ((HSCX_READ(0, H_VSTR) & 0xf) != 0x4))	||
            (((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) &&
	     ((HSCX_READ(1, H_VSTR) & 0xf) != 0x4)) )  
	{
		kprintf("isic%d: HSCX VSTR test failed for Teles S0/16.3\n",
			unit);
		kprintf("isic%d: HSC0: VSTR: %#x\n",
			unit, HSCX_READ(0, H_VSTR));
		kprintf("isic%d: HSC1: VSTR: %#x\n",
			unit, HSCX_READ(1, H_VSTR));
		isic_detach_common(dev);
		return (ENXIO);
	}                   

	/* get our irq */

	if(!(sc->sc_resources.irq =
		bus_alloc_resource(dev, SYS_RES_IRQ,
		&sc->sc_resources.irq_rid,
		0ul, ~0ul, 1, RF_ACTIVE)))
	{
		kprintf("isic%d: Could not get IRQ for Teles S0/16.3.\n",unit);
		isic_detach_common(dev);
		return ENXIO;
	}

	/* get the irq number */
	sc->sc_irq = rman_get_start(sc->sc_resources.irq);

	switch(sc->sc_irq)
	{
		case 2:
		case 9:
		case 5:
		case 10:
		case 12:
		case 15:
			break;

		default:
			kprintf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/16.3!\n",
				unit, sc->sc_irq);
			isic_detach_common(dev);
			return(ENXIO);
			break;
	}

	/* register interupt routine */
	bus_setup_intr(dev, sc->sc_resources.irq,
		       0, (void(*)(void *))(isicintr),
		       sc, &ih, NULL);

	return (0);
}