Exemple #1
0
static int
cy_isa_probe(device_t dev)
{
	struct resource *mem_res;
	cy_addr iobase;
	int mem_rid;

	if (isa_get_logicalid(dev) != 0)	/* skip PnP probes */
		return (ENXIO);

	mem_rid = 0;
	mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &mem_rid,
	    0ul, ~0ul, 0ul, RF_ACTIVE);
	if (mem_res == NULL) {
		device_printf(dev, "ioport resource allocation failed\n");
		return (ENXIO);
	}
	iobase = rman_get_virtual(mem_res);

	/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
	cy_inb(iobase, CY16_RESET, 0);	/* XXX? */
	DELAY(500);		/* wait for the board to get its act together */

	/* this is needed to get the board out of reset */
	cy_outb(iobase, CY_CLEAR_INTR, 0, 0);
	DELAY(500);

	bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res);
	return (cy_units(iobase, 0) == 0 ? ENXIO : 0);
}
Exemple #2
0
static int
uart_isa_probe(device_t dev)
{
	struct uart_softc *sc;
	device_t parent;

	parent = device_get_parent(dev);
	sc = device_get_softc(dev);

	/* Check PnP IDs */
	if (ISA_PNP_PROBE(parent, dev, isa_ns8250_ids) == ENXIO)
		return (ENXIO);

	/* Probe PnP _and_ non-PnP ns8250 here. */
#ifdef PC98
	if (isa_get_logicalid(dev))
		sc->sc_class = &uart_ns8250_class;
	else
		sc->sc_class = uart_pc98_getdev(bus_get_resource_start(dev,
		    SYS_RES_IOPORT, 0));
#else
	sc->sc_class = &uart_ns8250_class;
#endif
	return (uart_bus_probe(dev, 0, 0, 0, 0));
}
Exemple #3
0
static int
sbc_probe(device_t dev)
{
	char *s = NULL;
	u_int32_t lid, vid;

	lid = isa_get_logicalid(dev);
	vid = isa_get_vendorid(dev);
	if (lid) {
		if (lid == 0x01000000 && vid != 0x01009305) /* ALS0001 */
			return ENXIO;
		/* Check pnp ids */
		return ISA_PNP_PROBE(device_get_parent(dev), dev, sbc_ids);
	} else {
		int rid = 0, ver;
	    	struct resource *io;

#ifdef PC98
		io = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
					 pcm_iat, 16, RF_ACTIVE);
#else
		io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
		  		    	0, ~0, 16, RF_ACTIVE);
#endif
		if (!io) goto bad;
#ifdef PC98
		isa_load_resourcev(io, pcm_iat, 16);
#endif
    		if (sb_reset_dsp(io)) goto bad2;
		ver = sb_identify_board(io);
		if (ver == 0) goto bad2;
		switch ((ver & 0x00000f00) >> 8) {
		case 1:
			device_set_desc(dev, "SoundBlaster 1.0 (not supported)");
			s = NULL;
			break;

		case 2:
			s = "SoundBlaster 2.0";
			break;

		case 3:
			s = (ver & 0x0000f000)? "ESS 488" : "SoundBlaster Pro";
			break;

		case 4:
			s = "SoundBlaster 16";
			break;

		case 5:
			s = (ver & 0x00000008)? "ESS 688" : "ESS 1688";
			break;
	     	}
		if (s) device_set_desc(dev, s);
bad2:		bus_release_resource(dev, SYS_RES_IOPORT, rid, io);
bad:		return s? 0 : ENXIO;
	}
}
Exemple #4
0
static int
gusc_probe(device_t dev)
{
	device_t child;
	u_int32_t logical_id;
	char *s;
	struct sndcard_func *func;
	int ret;

	logical_id = isa_get_logicalid(dev);
	s = NULL;

	/* Check isapnp ids */
	if (logical_id != 0 && (ret = ISA_PNP_PROBE(device_get_parent(dev), dev, gusc_ids)) != 0)
		return (ret);
	else {
		if (logical_id == 0)
			return gusisa_probe(dev);
	}

	switch (logical_id) {
	case LOGICALID_PCM:
		s = "Gravis UltraSound Plug & Play PCM";
		func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO);
		if (func == NULL)
			return (ENOMEM);
		func->func = SCF_PCM;
		child = device_add_child(dev, "pcm", -1);
		device_set_ivars(child, func);
		break;
	case LOGICALID_OPL:
		s = "Gravis UltraSound Plug & Play OPL";
		func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO);
		if (func == NULL)
			return (ENOMEM);
		func->func = SCF_SYNTH;
		child = device_add_child(dev, "midi", -1);
		device_set_ivars(child, func);
		break;
	case LOGICALID_MIDI:
		s = "Gravis UltraSound Plug & Play MIDI";
		func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO);
		if (func == NULL)
			return (ENOMEM);
		func->func = SCF_MIDI;
		child = device_add_child(dev, "midi", -1);
		device_set_ivars(child, func);
		break;
	}

	if (s != NULL) {
		device_set_desc(dev, s);
		return (0);
	}

	return (ENXIO);
}
Exemple #5
0
static int
sn_isa_probe (device_t dev)
{
	if (isa_get_logicalid(dev))		/* skip PnP probes */
		return (ENXIO);
	if (sn_probe(dev) != 0)
		return (ENXIO);
	return (0);
}
Exemple #6
0
static int
ichwd_probe(device_t dev)
{

    /* Do not claim some ISA PnP device by accident. */
    if (isa_get_logicalid(dev) != 0)
        return (ENXIO);
    return (0);
}
Exemple #7
0
static int
release_resource(sc_p scp)
{
	int i, lid, flags;
	device_t dev;

	flags = 0;
	if (isa_get_vendorid(scp->dev))
		lid = isa_get_logicalid(scp->dev);
	else {
		lid = LOGICALID_NOPNP;
		flags = device_get_flags(scp->dev);
	}
	switch(lid) {
	case LOGICALID_PCM:
	case LOGICALID_NOPNP:		/* XXX Non-PnP */
		for (i = 0 ; i < NELEM(scp->io) ; i++) {
			if (scp->io[i] != NULL) {
				bus_release_resource(scp->dev, SYS_RES_IOPORT, scp->io_rid[i], scp->io[i]);
				scp->io[i] = NULL;
			}
		}
		if (scp->irq != NULL) {
			bus_release_resource(scp->dev, SYS_RES_IRQ, scp->irq_rid, scp->irq);
			scp->irq = NULL;
		}
		for (i = 0 ; i < NELEM(scp->drq) ; i++) {
			if (scp->drq[i] != NULL) {
				bus_release_resource(scp->dev, SYS_RES_DRQ, scp->drq_rid[i], scp->drq[i]);
				scp->drq[i] = NULL;
			}
		}
		break;
	case LOGICALID_OPL:
		if (scp->io[0] != NULL) {
			bus_release_resource(scp->dev, SYS_RES_IOPORT, scp->io_rid[0], scp->io[0]);
			scp->io[0] = NULL;
		}
		break;
	case LOGICALID_MIDI:
		if (scp->io[0] != NULL) {
			bus_release_resource(scp->dev, SYS_RES_IOPORT, scp->io_rid[0], scp->io[0]);
			scp->io[0] = NULL;
		}
		if (scp->irq != NULL) {
			/* The irq is shared with pcm audio. */
			dev = find_masterdev(scp);
			if (dev == NULL)
				return (1);
			BUS_RELEASE_RESOURCE(dev, NULL, SYS_RES_IOPORT, scp->irq_rid, scp->irq);
			scp->irq = NULL;
		}
		break;
	}
	return (0);
}
Exemple #8
0
static int
ct_isa_match(device_t dev)
{
	struct bshw *hw;
	struct resource *port_res, *mem_res;
	struct ct_bus_access_handle ch;
	int rv;

	if (ISA_PNP_PROBE(device_get_parent(dev), dev, ct_pnp_ids) == ENXIO)
		return ENXIO;

	switch (isa_get_logicalid(dev)) {
	case 0x0100e7b1:	/* LHA-301 */
	case 0x110154dc:	/* SC-98III */
	case 0x4120acb4:	/* IFC-NN */
		/* XXX - force to SMIT mode */
		device_set_flags(dev, device_get_flags(dev) | 0x40000);
		break;
	}

	if (isa_get_port(dev) == -1)
		bus_set_resource(dev, SYS_RES_IOPORT, 0,
				 BSHW_IOBASE, BSHW_IOSZ);

	if ((hw = ct_find_hw(dev)) == NULL)
		return ENXIO;
	if (ct_space_map(dev, hw, &port_res, &mem_res) != 0)
		return ENXIO;

	bzero(&ch, sizeof(ch));
	ch.ch_iot = rman_get_bustag(port_res);
	ch.ch_ioh = rman_get_bushandle(port_res),
	ch.ch_bus_weight = ct_isa_bus_access_weight;

	rv = ctprobesubr(&ch, 0, BSHW_DEFAULT_HOSTID,
			 BSHW_DEFAULT_CHIPCLK, NULL);
	if (rv != 0)
	{
		struct bshw_softc bshw_tab;
		struct bshw_softc *bs = &bshw_tab;

		memset(bs, 0, sizeof(*bs));
		bshw_read_settings(&ch, bs);
		bus_set_resource(dev, SYS_RES_IRQ, 0, bs->sc_irq, 1);
		bus_set_resource(dev, SYS_RES_DRQ, 0, bs->sc_drq, 1);
	}

	bus_release_resource(dev, SYS_RES_IOPORT, 0, port_res);
	if (mem_res != NULL)
		bus_release_resource(dev, SYS_RES_MEMORY, 0, mem_res);

	if (rv != 0)
		return 0;
	return ENXIO;
}
Exemple #9
0
static int
amdsbwd_probe(device_t dev)
{
	struct resource		*res;
	device_t		smb_dev;
	uint32_t		addr;
	int			rid;
	int			rc;

	/* Do not claim some ISA PnP device by accident. */
	if (isa_get_logicalid(dev) != 0)
		return (ENXIO);

	rc = bus_set_resource(dev, SYS_RES_IOPORT, 0, AMDSB_PMIO_INDEX,
	    AMDSB_PMIO_WIDTH);
	if (rc != 0) {
		device_printf(dev, "bus_set_resource for IO failed\n");
		return (ENXIO);
	}
	rid = 0;
	res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0ul, ~0ul,
	    AMDSB_PMIO_WIDTH, RF_ACTIVE | RF_SHAREABLE);
	if (res == NULL) {
		device_printf(dev, "bus_alloc_resource for IO failed\n");
		return (ENXIO);
	}

	smb_dev = pci_find_bsf(0, 20, 0);
	KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n"));
	if (pci_get_revid(smb_dev) < AMDSB8_SMBUS_REVID)
		amdsbwd_probe_sb7xx(dev, res, &addr);
	else
		amdsbwd_probe_sb8xx(dev, res, &addr);

	bus_release_resource(dev, SYS_RES_IOPORT, rid, res);
	bus_delete_resource(dev, SYS_RES_IOPORT, rid);

	amdsbwd_verbose_printf(dev, "memory base address = %#010x\n", addr);
	rc = bus_set_resource(dev, SYS_RES_MEMORY, 0, addr + AMDSB_WD_CTRL,
	    AMDSB_WDIO_REG_WIDTH);
	if (rc != 0) {
		device_printf(dev, "bus_set_resource for control failed\n");
		return (ENXIO);
	}
	rc = bus_set_resource(dev, SYS_RES_MEMORY, 1, addr + AMDSB_WD_COUNT,
	    AMDSB_WDIO_REG_WIDTH);
	if (rc != 0) {
		device_printf(dev, "bus_set_resource for count failed\n");
		return (ENXIO);
	}

	return (0);
}
Exemple #10
0
static int
aic_isa_alloc_resources(device_t dev)
{
	struct aic_isa_softc *sc = device_get_softc(dev);
	int rid;
	bus_addr_t *bs_iat;

	if ((isa_get_logicalid(dev) == 0xa180a3b8) ||
	    (AIC_TYPE98(device_get_flags(dev)) == AIC98_NEC100))
		bs_iat = aicport_100;
	else
		bs_iat = aicport_generic;

	sc->sc_port = sc->sc_irq = sc->sc_drq = NULL;

	rid = 0;
	sc->sc_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
					  bs_iat, AIC_ISA_PORTSIZE, RF_ACTIVE);
	if (!sc->sc_port) {
		device_printf(dev, "I/O port allocation failed\n");
		return (ENOMEM);
	}
	isa_load_resourcev(sc->sc_port, bs_iat, AIC_ISA_PORTSIZE);
	mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF);

	if (isa_get_irq(dev) != -1) {
		rid = 0;
		sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
						    RF_ACTIVE);
		if (!sc->sc_irq) {
			device_printf(dev, "IRQ allocation failed\n");
			aic_isa_release_resources(dev);
			return (ENOMEM);
		}
	}

	if (isa_get_drq(dev) != -1) {
		rid = 0;
		sc->sc_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &rid,
						    RF_ACTIVE);
		if (!sc->sc_drq) {
			device_printf(dev, "DRQ allocation failed\n");
			aic_isa_release_resources(dev);
			return (ENOMEM);
		}
	}

	sc->sc_aic.dev = dev;
	sc->sc_aic.res = sc->sc_port;
	return (0);
}
Exemple #11
0
static int
mecia_probe(device_t dev)
{
	int		validslots = 0;

	/* Check isapnp ids */
	if (isa_get_logicalid(dev))		/* skip PnP probes */
		return (ENXIO);

	if (inb(MECIA_REG0) != 0xff) {
		validslots++;
		/* XXX need to allocated the port resources */
		device_set_desc(dev, "MECIA PC98 Original PCMCIA Controller");
	}
	return (validslots ? 0 : ENXIO);
}
Exemple #12
0
static device_t
find_masterdev(sc_p scp)
{
	int i, units;
	devclass_t devclass;
	device_t dev;

	devclass = device_get_devclass(scp->dev);
	units = devclass_get_maxunit(devclass);
	dev = NULL;
	for (i = 0 ; i < units ; i++) {
		dev = devclass_get_device(devclass, i);
		if (isa_get_vendorid(dev) == isa_get_vendorid(scp->dev)
		    && isa_get_logicalid(dev) == LOGICALID_PCM
		    && isa_get_serial(dev) == isa_get_serial(scp->dev))
			break;
	}
	if (i == units)
		return (NULL);

	return (dev);
}
Exemple #13
0
static int
pcf_isa_probe(device_t dev)
{
	u_long		start, count;
	u_int		rid = 0, port, error;

	/* skip PnP probes */
	if (isa_get_logicalid(dev))
		return (ENXIO);

	/* The port address must be explicitly specified */
	bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count);
	if ((error = resource_int_value(PCF_NAME, 0, "port", &port) != 0))
		return (error);

	/* Probe is only successfull for the specified base io */
	if (port != (u_int)start)
		return (ENXIO);

	device_set_desc(dev, "PCF8584 I2C bus controller");

	return (0);
}
Exemple #14
0
void
pnp_parse_resources(device_t dev, u_char *resources, int len, int ldn)
{
	struct isa_config *configs;
	struct isa_config *config;
	device_t parent;
	int priorities[1 + MAXDEP];
	u_char *start;
	u_char *p;
	u_char tag;
	u_int32_t id;
	int ncfgs;
	int l;
	int i;

	parent = device_get_parent(dev);
	id = isa_get_logicalid(dev);

	configs = (struct isa_config *)malloc(sizeof(*configs)*(1 + MAXDEP),
					      M_DEVBUF, M_NOWAIT | M_ZERO);
	if (configs == NULL) {
		device_printf(parent, "No memory to parse PNP data\n");
		return;
	}
	config = &configs[0];
	priorities[0] = 0;
	ncfgs = 1;

	p = resources;
	start = NULL;
	while (len > 0) {
		tag = *p++;
		len--;
		if (PNP_RES_TYPE(tag) == 0) {
			/* Small resource */
			l = PNP_SRES_LEN(tag);
			if (len < l) {
				len = 0;
				continue;
			}
			len -= l;

			switch (PNP_SRES_NUM(tag)) {

			case PNP_TAG_START_DEPENDANT:
				if (start != NULL) {
					/*
					 * Copy the common resources first,
					 * then parse the "dependent" resources.
					 */
					pnp_merge_resources(dev, &configs[0],
							    config);
					pnp_parse_dependant(dev, start,
							    p - start - 1,
							    config, ldn);
				}
				start = p + l;
				if (ncfgs > MAXDEP) {
					device_printf(parent, "too many dependant configs (%d)\n", MAXDEP);
					len = 0;
					break;
				}
				config = &configs[ncfgs];
				/*
				 * If the priority is not specified,
				 * then use the default of 'acceptable'
				 */
				if (l > 0)
					priorities[ncfgs] = p[0];
				else
					priorities[ncfgs] = 1;
				if (bootverbose)
					pnp_printf(id, "start dependent (%d)\n",
						   priorities[ncfgs]);
				ncfgs++;
				break;

			case PNP_TAG_END_DEPENDANT:
				if (start == NULL) {
					device_printf(parent,
						      "malformed resources\n");
					len = 0;
					break;
				}
				/*
				 * Copy the common resources first,
				 * then parse the "dependent" resources.
				 */
				pnp_merge_resources(dev, &configs[0], config);
				pnp_parse_dependant(dev, start, p - start - 1,
						    config, ldn);
				start = NULL;
				if (bootverbose)
					pnp_printf(id, "end dependent\n");
				/*
				 * Back to the common part; clear it
				 * as its contents has already been copied
				 * to each dependant.
				 */
				config = &configs[0];
				bzero(config, sizeof(*config));
				break;

			case PNP_TAG_END:
				if (start != NULL) {
					device_printf(parent,
						      "malformed resources\n");
				}
				len = 0;
				break;

			default:
				if (start != NULL)
					/* defer parsing a dependent section */
					break;
				if (pnp_parse_desc(dev, tag, p, l, config, ldn))
					len = 0;
				break;
			}
			p += l;
		} else {
			/* Large resource */
			if (len < 2) {
				len = 0;
				break;
			}
			l = I16(p);
			p += 2;
			len -= 2;
			if (len < l) {
				len = 0;
				break;
			}
			len -= l;
			if (start == NULL &&
			    pnp_parse_desc(dev, tag, p, l, config, ldn)) {
				len = 0;
				break;
			}
			p += l;
		}
	}

	if (ncfgs == 1) {
		/* Single config without dependants */
		ISA_ADD_CONFIG(parent, dev, priorities[0], &configs[0]);
		free(configs, M_DEVBUF);
		return;
	}

	for (i = 1; i < ncfgs; i++) {
		/*
		 * Merge the remaining part of the common resources,
		 * if any. Strictly speaking, there shouldn't be common/main
		 * resources after the END_DEPENDENT tag.
		 */
		pnp_merge_resources(dev, &configs[0], &configs[i]);
		ISA_ADD_CONFIG(parent, dev, priorities[i], &configs[i]);
	}

	free(configs, M_DEVBUF);
}
Exemple #15
0
static int
adv_isa_probe(device_t dev)
{
	int	port_index;
	int	max_port_index;
	u_long	iobase, iocount, irq;
	int	user_iobase = 0;
	int	rid = 0;
	void	*ih;
	struct resource	*iores, *irqres;

	/*
	 * We don't know of any PnP ID's for these cards.
	 */
	if (isa_get_logicalid(dev) != 0)
		return (ENXIO);

	/*
	 * Default to scanning all possible device locations.
	 */
	port_index = 0;
	max_port_index = MAX_ISA_IOPORT_INDEX;

	if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, &iocount) == 0) {
		user_iobase = 1;
		for (;port_index <= max_port_index; port_index++)
			if (iobase <= adv_isa_ioports[port_index])
				break;
		if ((port_index > max_port_index)
		 || (iobase != adv_isa_ioports[port_index])) {
			if (bootverbose)
			    printf("adv%d: Invalid baseport of 0x%lx specified. "
				"Nearest valid baseport is 0x%x.  Failing "
				"probe.\n", device_get_unit(dev), iobase,
				(port_index <= max_port_index) ?
					adv_isa_ioports[port_index] :
					adv_isa_ioports[max_port_index]);
			return ENXIO;
		}
		max_port_index = port_index;
	}

	/* Perform the actual probing */
	adv_set_isapnp_wait_for_key();
	for (;port_index <= max_port_index; port_index++) {
		u_int16_t port_addr = adv_isa_ioports[port_index];
		bus_size_t maxsegsz;
		bus_size_t maxsize;
		bus_addr_t lowaddr;
		int error;
		struct adv_softc *adv;

		if (port_addr == 0)
			/* Already been attached */
			continue;
		
		if (bus_set_resource(dev, SYS_RES_IOPORT, 0, port_addr, 1))
			continue;

		/* XXX what is the real portsize? */
		iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
					       RF_ACTIVE);
		if (iores == NULL)
			continue;

		if (adv_find_signature(rman_get_bustag(iores),
				       rman_get_bushandle(iores)) == 0) {
			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
			continue;
		}

		/*
		 * Got one.  Now allocate our softc
		 * and see if we can initialize the card.
		 */
		adv = adv_alloc(dev, rman_get_bustag(iores),
				rman_get_bushandle(iores));
		if (adv == NULL) {
			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
			break;
		}

		/*
		 * Stop the chip.
		 */
		ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
		ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
		/*
		 * Determine the chip version.
		 */
		adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION);
		if ((adv->chip_version >= ADV_CHIP_MIN_VER_VL)
		    && (adv->chip_version <= ADV_CHIP_MAX_VER_VL)) {
			adv->type = ADV_VL;
			maxsegsz = ADV_VL_MAX_DMA_COUNT;
			maxsize = BUS_SPACE_MAXSIZE_32BIT;
			lowaddr = ADV_VL_MAX_DMA_ADDR;
			bus_delete_resource(dev, SYS_RES_DRQ, 0);
		} else if ((adv->chip_version >= ADV_CHIP_MIN_VER_ISA)
			   && (adv->chip_version <= ADV_CHIP_MAX_VER_ISA)) {
			if (adv->chip_version >= ADV_CHIP_MIN_VER_ISA_PNP) {
				adv->type = ADV_ISAPNP;
				ADV_OUTB(adv, ADV_REG_IFC,
					 ADV_IFC_INIT_DEFAULT);
			} else {
				adv->type = ADV_ISA;
			}
			maxsegsz = ADV_ISA_MAX_DMA_COUNT;
			maxsize = BUS_SPACE_MAXSIZE_24BIT;
			lowaddr = ADV_ISA_MAX_DMA_ADDR;
			adv->isa_dma_speed = ADV_DEF_ISA_DMA_SPEED;
			adv->isa_dma_channel = adv_get_isa_dma_channel(adv);
			bus_set_resource(dev, SYS_RES_DRQ, 0,
					 adv->isa_dma_channel, 1);
		} else {
			panic("advisaprobe: Unknown card revision\n");
		}

		/*
		 * Allocate a parent dmatag for all tags created
		 * by the MI portions of the advansys driver
		 */
		error = bus_dma_tag_create(
				/* parent	*/ bus_get_dma_tag(dev),
				/* alignemnt	*/ 1,
				/* boundary	*/ 0,
				/* lowaddr	*/ lowaddr,
				/* highaddr	*/ BUS_SPACE_MAXADDR,
				/* filter	*/ NULL,
				/* filterarg	*/ NULL,
				/* maxsize	*/ maxsize,
				/* nsegments	*/ ~0,
				/* maxsegsz	*/ maxsegsz,
				/* flags	*/ 0,
				/* lockfunc	*/ busdma_lock_mutex,
				/* lockarg	*/ &Giant,
				&adv->parent_dmat); 

		if (error != 0) {
			printf("%s: Could not allocate DMA tag - error %d\n",
			       adv_name(adv), error); 
			adv_free(adv); 
			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
			break;
		}

		adv->init_level += 2;

		if (overrun_buf == NULL) {
			/* Need to allocate our overrun buffer */
			if (bus_dma_tag_create(
				/* parent	*/ adv->parent_dmat,
				/* alignment	*/ 8,
				/* boundary	*/ 0,
				/* lowaddr	*/ ADV_ISA_MAX_DMA_ADDR,
				/* highaddr	*/ BUS_SPACE_MAXADDR,
				/* filter	*/ NULL,
				/* filterarg	*/ NULL,
				/* maxsize	*/ ADV_OVERRUN_BSIZE,
				/* nsegments	*/ 1,
				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_32BIT,
				/* flags	*/ 0,
				/* lockfunc	*/ NULL,
				/* lockarg	*/ NULL,
				&overrun_dmat) != 0) {
				adv_free(adv);
				bus_release_resource(dev, SYS_RES_IOPORT, 0,
						     iores);
				break;
			}
			if (bus_dmamem_alloc(overrun_dmat,
					     (void **)&overrun_buf,
					     BUS_DMA_NOWAIT,
					     &overrun_dmamap) != 0) {
				bus_dma_tag_destroy(overrun_dmat);
				adv_free(adv);
				bus_release_resource(dev, SYS_RES_IOPORT, 0,
						     iores);
				break;
			}
			/* And permanently map it in */  
			bus_dmamap_load(overrun_dmat, overrun_dmamap,
					overrun_buf, ADV_OVERRUN_BSIZE,
					adv_map, &overrun_physbase,
					/*flags*/0);
		}

		adv->overrun_physbase = overrun_physbase;

		if (adv_init(adv) != 0) {
			bus_dmamap_unload(overrun_dmat, overrun_dmamap);
			bus_dmamem_free(overrun_dmat, overrun_buf,
			    overrun_dmamap);
			bus_dma_tag_destroy(overrun_dmat);
			adv_free(adv);
			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
			break;
		}

		switch (adv->type) {
		case ADV_ISAPNP:
			if (adv->chip_version == ADV_CHIP_VER_ASYN_BUG) {
				adv->bug_fix_control
				    |= ADV_BUG_FIX_ASYN_USE_SYN;
				adv->fix_asyn_xfer = ~0;
			}
			/* Fall Through */
		case ADV_ISA:
			adv->max_dma_count = ADV_ISA_MAX_DMA_COUNT;
			adv->max_dma_addr = ADV_ISA_MAX_DMA_ADDR;
			adv_set_isa_dma_settings(adv);
			break;

		case ADV_VL:
			adv->max_dma_count = ADV_VL_MAX_DMA_COUNT;
			adv->max_dma_addr = ADV_VL_MAX_DMA_ADDR;
			break;
		default:
			panic("advisaprobe: Invalid card type\n");
		}
			
		/* Determine our IRQ */
		if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL))
			bus_set_resource(dev, SYS_RES_IRQ, 0,
					 adv_get_chip_irq(adv), 1);
		else
			adv_set_chip_irq(adv, irq);

		irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
						RF_ACTIVE);
		if (irqres == NULL ||
		    bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY,
		        NULL, adv_intr, adv, &ih)) {
			bus_dmamap_unload(overrun_dmat, overrun_dmamap);
			bus_dmamem_free(overrun_dmat, overrun_buf,
			    overrun_dmamap);
			bus_dma_tag_destroy(overrun_dmat);
			adv_free(adv);
			bus_release_resource(dev, SYS_RES_IOPORT, 0, iores);
			break;
		}

		/* Mark as probed */
		adv_isa_ioports[port_index] = 0;
		return 0;
	}

	if (user_iobase)
		bus_set_resource(dev, SYS_RES_IOPORT, 0, iobase, iocount);
	else
		bus_delete_resource(dev, SYS_RES_IOPORT, 0);

	return ENXIO;
}
Exemple #16
0
/*
 * On standard ISA, we don't just use an 8 port range
 * (e.g. 0x3f0-0x3f7) since that covers an IDE control register at
 * 0x3f6.  So, on older hardware, we use 0x3f0-0x3f5 and 0x3f7.
 * However, some BIOSs omit the control port, while others start at
 * 0x3f2.  Of the latter, sometimes we have two resources, other times
 * we have one.  We have to deal with the following cases:
 *
 * 1:	0x3f0-0x3f5			# very rare
 * 2:	0x3f0				# hints -> 0x3f0-0x3f5,0x3f7
 * 3:	0x3f0-0x3f5,0x3f7		# Most common
 * 4:	0x3f2-0x3f5,0x3f7		# Second most common
 * 5:	0x3f2-0x3f5			# implies 0x3f7 too.
 * 6:	0x3f2-0x3f3,0x3f4-0x3f5,0x3f7	# becoming common
 * 7:	0x3f2-0x3f3,0x3f4-0x3f5		# rare
 * 8:	0x3f0-0x3f1,0x3f2-0x3f3,0x3f4-0x3f5,0x3f7
 * 9:	0x3f0-0x3f3,0x3f4-0x3f5,0x3f7
 *
 * The following code is generic for any value of 0x3fx.  It is also
 * generic for all the above cases, as well as cases where things are
 * even weirder.
 */
int
fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc)
{
	struct resource *res;
	int i, j, rid, newrid, nport;
	u_long port;

	fdc->fdc_dev = dev;
	rid = 0;
	for (i = 0; i < FDC_MAXREG; i++)
		fdc->resio[i] = NULL;

	nport = isa_get_logicalid(dev) ? 1 : 6;
	for (rid = 0; ; rid++) {
		newrid = rid;
		res = bus_alloc_resource(dev, SYS_RES_IOPORT, &newrid,
		    0ul, ~0ul, rid == 0 ? nport : 1, RF_ACTIVE);
		if (res == NULL)
			break;
		/*
		 * Mask off the upper bits of the register, and sanity
		 * check resource ranges.
		 */
		i = rman_get_start(res) & 0x7;
		if (i + rman_get_size(res) - 1 > FDC_MAXREG) {
			bus_release_resource(dev, SYS_RES_IOPORT, newrid, res);
			return (ENXIO);
		}
		for (j = 0; j < rman_get_size(res); j++) {
			fdc->resio[i + j] = res;
			fdc->ridio[i + j] = newrid;
			fdc->ioff[i + j] = j;
			fdc->ioh[i + j] = rman_get_bushandle(res);
		}
	}
	if (fdc->resio[2] == NULL) {
		device_printf(dev, "No FDOUT register!\n");
		return (ENXIO);
	}
	fdc->iot = rman_get_bustag(fdc->resio[2]);
	if (fdc->resio[7] == NULL) {
		port = (rman_get_start(fdc->resio[2]) & ~0x7) + 7;
		newrid = rid;
		res = bus_alloc_resource(dev, SYS_RES_IOPORT, &newrid, port,
		    port, 1, RF_ACTIVE);
		if (res == NULL) {
			device_printf(dev, "Faking up FDCTL\n");
			fdc->resio[7] = fdc->resio[2];
			fdc->ridio[7] = fdc->ridio[2];
			fdc->ioff[7] = fdc->ioff[2] + 5;
			fdc->ioh[7] = fdc->ioh[2];
		} else {
			fdc->resio[7] = res;
			fdc->ridio[7] = newrid;
			fdc->ioff[7] = rman_get_start(res) & 7;
			fdc->ioh[7] = rman_get_bushandle(res);
		}
	}

	fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq,
	    RF_ACTIVE | RF_SHAREABLE);
	if (fdc->res_irq == NULL) {
		device_printf(dev, "cannot reserve interrupt line\n");
		return (ENXIO);
	}

	if ((fdc->flags & FDC_NODMA) == 0) {
		fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
		    &fdc->rid_drq, RF_ACTIVE | RF_SHAREABLE);
		if (fdc->res_drq == NULL) {
			device_printf(dev, "cannot reserve DMA request line\n");
			/* This is broken and doesn't work for ISA case */
			fdc->flags |= FDC_NODMA;
		} else
			fdc->dmachan = rman_get_start(fdc->res_drq);
	}

	return (0);
}
Exemple #17
0
static int
alloc_resource(sc_p scp)
{
	int i, base, lid, flags;
	device_t dev;

	flags = 0;
	if (isa_get_vendorid(scp->dev))
		lid = isa_get_logicalid(scp->dev);
	else {
		lid = LOGICALID_NOPNP;
		flags = device_get_flags(scp->dev);
	}
	switch(lid) {
	case LOGICALID_PCM:
	case LOGICALID_NOPNP:		/* XXX Non-PnP */
		if (lid == LOGICALID_NOPNP)
			base = isa_get_port(scp->dev);
		else
			base = 0;
		for (i = 0 ; i < sizeof(scp->io) / sizeof(*scp->io) ; i++) {
			if (scp->io[i] == NULL) {
				scp->io_rid[i] = i;
				if (base == 0)
					scp->io[i] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[i],
									0, ~0, io_range[i], RF_ACTIVE);
				else
					scp->io[i] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[i],
									base + io_offset[i],
									base + io_offset[i] + io_range[i] - 1
									, io_range[i], RF_ACTIVE);
				if (scp->io[i] == NULL)
					return (1);
				scp->io_alloced[i] = 0;
			}
		}
		if (scp->irq == NULL) {
			scp->irq_rid = 0;
			scp->irq = 
				bus_alloc_resource_any(scp->dev, SYS_RES_IRQ, 
						       &scp->irq_rid,
						       RF_ACTIVE|RF_SHAREABLE);
			if (scp->irq == NULL)
				return (1);
			scp->irq_alloced = 0;
		}
		for (i = 0 ; i < sizeof(scp->drq) / sizeof(*scp->drq) ; i++) {
			if (scp->drq[i] == NULL) {
				scp->drq_rid[i] = i;
				if (base == 0 || i == 0)
					scp->drq[i] = 
						bus_alloc_resource_any(
							scp->dev, SYS_RES_DRQ,
							&scp->drq_rid[i],
							RF_ACTIVE);
				else if ((flags & DV_F_DUAL_DMA) != 0)
					/* XXX The secondary drq is specified in the flag. */
					scp->drq[i] = bus_alloc_resource(scp->dev, SYS_RES_DRQ, &scp->drq_rid[i],
									 flags & DV_F_DRQ_MASK,
									 flags & DV_F_DRQ_MASK, 1, RF_ACTIVE);
				if (scp->drq[i] == NULL)
					return (1);
				scp->drq_alloced[i] = 0;
			}
		}
		break;
	case LOGICALID_OPL:
		if (scp->io[0] == NULL) {
			scp->io_rid[0] = 0;
			scp->io[0] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[0],
							0, ~0, io_range[0], RF_ACTIVE);
			if (scp->io[0] == NULL)
				return (1);
			scp->io_alloced[0] = 0;
		}
		break;
	case LOGICALID_MIDI:
		if (scp->io[0] == NULL) {
			scp->io_rid[0] = 0;
			scp->io[0] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[0],
							0, ~0, io_range[0], RF_ACTIVE);
			if (scp->io[0] == NULL)
				return (1);
			scp->io_alloced[0] = 0;
		}
		if (scp->irq == NULL) {
			/* The irq is shared with pcm audio. */
			dev = find_masterdev(scp);
			if (dev == NULL)
				return (1);
			scp->irq_rid = 0;
			scp->irq = BUS_ALLOC_RESOURCE(dev, NULL, SYS_RES_IRQ, &scp->irq_rid,
						      0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
			if (scp->irq == NULL)
				return (1);
			scp->irq_alloced = 0;
		}
		break;
	}
	return (0);
}
Exemple #18
0
static int
sbc_attach(device_t dev)
{
	char *err = NULL;
	struct sbc_softc *scp;
	struct sndcard_func *func;
	u_int32_t logical_id = isa_get_logicalid(dev);
    	int flags = device_get_flags(dev);
	int f, dh, dl, x, irq, i;

    	if (!logical_id && (flags & DV_F_DUAL_DMA)) {
        	bus_set_resource(dev, SYS_RES_DRQ, 1,
				 flags & DV_F_DRQ_MASK, 1);
    	}

	scp = device_get_softc(dev);
	bzero(scp, sizeof(*scp));
	scp->dev = dev;
	sbc_lockinit(scp);
	err = "alloc_resource";
	if (alloc_resource(scp)) goto bad;

	err = "sb_reset_dsp";
	if (sb_reset_dsp(scp->io[0])) goto bad;
	err = "sb_identify_board";
	scp->bd_ver = sb_identify_board(scp->io[0]) & 0x00000fff;
	if (scp->bd_ver == 0) goto bad;
	f = 0;
	if (logical_id == 0x01200000 && scp->bd_ver < 0x0400) scp->bd_ver = 0x0499;
	switch ((scp->bd_ver & 0x0f00) >> 8) {
    	case 1: /* old sound blaster has nothing... */
		break;

    	case 2:
		f |= BD_F_DUP_MIDI;
		if (scp->bd_ver > 0x200) f |= BD_F_MIX_CT1335;
		break;

	case 5:
		f |= BD_F_ESS;
		scp->bd_ver = 0x0301;
    	case 3:
		f |= BD_F_DUP_MIDI | BD_F_MIX_CT1345;
		break;

    	case 4:
    		f |= BD_F_SB16 | BD_F_MIX_CT1745;
		if (scp->drq[0]) dl = rman_get_start(scp->drq[0]); else dl = -1;
		if (scp->drq[1]) dh = rman_get_start(scp->drq[1]); else dh = dl;
		if (!logical_id && (dh < dl)) {
			struct resource *r;
			r = scp->drq[0];
			scp->drq[0] = scp->drq[1];
			scp->drq[1] = r;
			dl = rman_get_start(scp->drq[0]);
			dh = rman_get_start(scp->drq[1]);
		}
		/* soft irq/dma configuration */
		x = -1;
		irq = rman_get_start(scp->irq[0]);
#ifdef PC98
		/* SB16 in PC98 use different IRQ table */
		if	(irq == 3) x = 1;
		else if (irq == 5) x = 8;
		else if (irq == 10) x = 2;
		else if (irq == 12) x = 4;
		if (x == -1) {
			err = "bad irq (3/5/10/12 valid)";
			goto bad;
		}
		else sb_setmixer(scp->io[0], IRQ_NR, x);
		/* SB16 in PC98 use different dma setting */
		sb_setmixer(scp->io[0], DMA_NR, dh == 0 ? 1 : 2);
#else
		if      (irq == 5) x = 2;
		else if (irq == 7) x = 4;
		else if (irq == 9) x = 1;
		else if (irq == 10) x = 8;
		if (x == -1) {
			err = "bad irq (5/7/9/10 valid)";
			goto bad;
		}
		else sb_setmixer(scp->io[0], IRQ_NR, x);
		sb_setmixer(scp->io[0], DMA_NR, (1 << dh) | (1 << dl));
#endif
		if (bootverbose) {
			device_printf(dev, "setting card to irq %d, drq %d", irq, dl);
			if (dl != dh) printf(", %d", dh);
			printf("\n");
    		}
		break;
    	}

	switch (logical_id) {
    	case 0x43008c0e:	/* CTL0043 */
	case 0x01200000:
	case 0x01000000:
		f |= BD_F_SB16X;
		break;
	}
	scp->bd_ver |= f << 16;

	err = "setup_intr";
	for (i = 0; i < IRQ_MAX; i++) {
		scp->ihl[i].parent = scp;
		if (snd_setup_intr(dev, scp->irq[i], 0, sbc_intr, &scp->ihl[i], &scp->ih[i]))
			goto bad;
	}

	/* PCM Audio */
	func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO);
	if (func == NULL) goto bad;
	func->func = SCF_PCM;
	scp->child_pcm = device_add_child(dev, "pcm", -1);
	device_set_ivars(scp->child_pcm, func);

	/* Midi Interface */
	func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO);
	if (func == NULL) goto bad;
	func->func = SCF_MIDI;
	scp->child_midi1 = device_add_child(dev, "midi", -1);
	device_set_ivars(scp->child_midi1, func);

	/* OPL FM Synthesizer */
	func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO);
	if (func == NULL) goto bad;
	func->func = SCF_SYNTH;
	scp->child_midi2 = device_add_child(dev, "midi", -1);
	device_set_ivars(scp->child_midi2, func);

	/* probe/attach kids */
	bus_generic_attach(dev);

	return (0);

bad:	if (err) device_printf(dev, "%s\n", err);
	release_resource(scp);
	return (ENXIO);
}
Exemple #19
0
static int
pnp_parse_desc(device_t dev, u_char tag, u_char *res, int len,
	       struct isa_config *config, int ldn)
{
	char buf[100];
	u_int32_t id;
	u_int32_t compat_id;
	int temp;

	id = isa_get_logicalid(dev);

	if (PNP_RES_TYPE(tag) == 0) {

		/* Small resource */
		switch (PNP_SRES_NUM(tag)) {

		case PNP_TAG_VERSION:
		case PNP_TAG_VENDOR:
			/* these descriptors are quietly ignored */
			break;

		case PNP_TAG_LOGICAL_DEVICE:
		case PNP_TAG_START_DEPENDANT:
		case PNP_TAG_END_DEPENDANT:
			if (bootverbose)
				pnp_printf(id, "unexpected small tag %d\n",
					   PNP_SRES_NUM(tag));
			/* shouldn't happen; quit now */
			return (1);

		case PNP_TAG_COMPAT_DEVICE:
			/*
			 * Got a compatible device id resource.
			 * Should keep a list of compat ids in the device.
			 */
			bcopy(res, &compat_id, 4);
			if (isa_get_compatid(dev) == 0)
				isa_set_compatid(dev, compat_id);
			break;
	    
		case PNP_TAG_IRQ_FORMAT:
			if (config->ic_nirq == ISA_NIRQ) {
				pnp_printf(id, "too many irqs\n");
				return (1);
			}
			if (I16(res) == 0) {
				/* a null descriptor */
				config->ic_irqmask[config->ic_nirq] = 0;
				config->ic_nirq++;
				break;
			}
			if (bootverbose)
				pnp_printf(id, "adding irq mask %#02x\n",
					   I16(res));
			config->ic_irqmask[config->ic_nirq] = I16(res);
			config->ic_nirq++;
			break;

		case PNP_TAG_DMA_FORMAT:
			if (config->ic_ndrq == ISA_NDRQ) {
				pnp_printf(id, "too many drqs\n");
				return (1);
			}
			if (res[0] == 0) {
				/* a null descriptor */
				config->ic_drqmask[config->ic_ndrq] = 0;
				config->ic_ndrq++;
				break;
			}
			if (bootverbose)
				pnp_printf(id, "adding dma mask %#02x\n",
					   res[0]);
			config->ic_drqmask[config->ic_ndrq] = res[0];
			config->ic_ndrq++;
			break;

		case PNP_TAG_IO_RANGE:
			if (config->ic_nport == ISA_NPORT) {
				pnp_printf(id, "too many ports\n");
				return (1);
			}
			if (res[6] == 0) {
				/* a null descriptor */
				config->ic_port[config->ic_nport].ir_start = 0;
				config->ic_port[config->ic_nport].ir_end = 0;
				config->ic_port[config->ic_nport].ir_size = 0;
				config->ic_port[config->ic_nport].ir_align = 0;
				config->ic_nport++;
				break;
			}
			if (bootverbose) {
				pnp_printf(id, "adding io range "
					   "%#x-%#x, size=%#x, "
					   "align=%#x\n",
					   I16(res + 1),
					   I16(res + 3) + res[6]-1,
					   res[6], res[5]);
			}
			config->ic_port[config->ic_nport].ir_start =
			    I16(res + 1);
			config->ic_port[config->ic_nport].ir_end =
			    I16(res + 3) + res[6] - 1;
			config->ic_port[config->ic_nport].ir_size = res[6];
			if (res[5] == 0) {
			    /* Make sure align is at least one */
			    res[5] = 1;
			}
			config->ic_port[config->ic_nport].ir_align = res[5];
			config->ic_nport++;
			pnp_check_quirks(isa_get_vendorid(dev),
					 isa_get_logicalid(dev), ldn, config);
			break;

		case PNP_TAG_IO_FIXED:
			if (config->ic_nport == ISA_NPORT) {
				pnp_printf(id, "too many ports\n");
				return (1);
			}
			if (res[2] == 0) {
				/* a null descriptor */
				config->ic_port[config->ic_nport].ir_start = 0;
				config->ic_port[config->ic_nport].ir_end = 0;
				config->ic_port[config->ic_nport].ir_size = 0;
				config->ic_port[config->ic_nport].ir_align = 0;
				config->ic_nport++;
				break;
			}
			if (bootverbose) {
				pnp_printf(id, "adding fixed io range "
					   "%#x-%#x, size=%#x, "
					   "align=%#x\n",
					   I16(res),
					   I16(res) + res[2] - 1,
					   res[2], 1);
			}
			config->ic_port[config->ic_nport].ir_start = I16(res);
			config->ic_port[config->ic_nport].ir_end =
			    I16(res) + res[2] - 1;
			config->ic_port[config->ic_nport].ir_size = res[2];
			config->ic_port[config->ic_nport].ir_align = 1;
			config->ic_nport++;
			break;

		case PNP_TAG_END:
			if (bootverbose)
				pnp_printf(id, "end config\n");
			return (1);

		default:
			/* Skip this resource */
			pnp_printf(id, "unexpected small tag %d\n",
				      PNP_SRES_NUM(tag));
			break;
		}
	} else {
		/* Large resource */
		switch (PNP_LRES_NUM(tag)) {

		case PNP_TAG_ID_UNICODE:
		case PNP_TAG_LARGE_VENDOR:
			/* these descriptors are quietly ignored */
			break;

		case PNP_TAG_ID_ANSI:
			if (len > sizeof(buf) - 1)
				len = sizeof(buf) - 1;
			bcopy(res, buf, len);

			/*
			 * Trim trailing spaces and garbage.
			 */
			while (len > 0 && buf[len - 1] <= ' ')
				len--;
			buf[len] = '\0';
			device_set_desc_copy(dev, buf);
			break;
			
		case PNP_TAG_MEMORY_RANGE:
			if (config->ic_nmem == ISA_NMEM) {
				pnp_printf(id, "too many memory ranges\n");
				return (1);
			}
			if (I16(res + 7) == 0) {
				/* a null descriptor */
				config->ic_mem[config->ic_nmem].ir_start = 0;
				config->ic_mem[config->ic_nmem].ir_end = 0;
				config->ic_mem[config->ic_nmem].ir_size = 0;
				config->ic_mem[config->ic_nmem].ir_align = 0;
				config->ic_nmem++;
				break;
			}
			if (bootverbose) {
				temp = I16(res + 7) << 8;
				pnp_printf(id, "adding memory range "
					   "%#x-%#x, size=%#x, "
					   "align=%#x\n",
					   I16(res + 1) << 8,
					   (I16(res + 3) << 8) + temp - 1,
					   temp, I16(res + 5));
			}
			config->ic_mem[config->ic_nmem].ir_start =
			    I16(res + 1) << 8;
			config->ic_mem[config->ic_nmem].ir_end =
			    (I16(res + 3) << 8) + (I16(res + 7) << 8) - 1;
			config->ic_mem[config->ic_nmem].ir_size =
			    I16(res + 7) << 8;
			config->ic_mem[config->ic_nmem].ir_align = I16(res + 5);
			if (!config->ic_mem[config->ic_nmem].ir_align)
				config->ic_mem[config->ic_nmem].ir_align =
				    0x10000;
			config->ic_nmem++;
			break;

		case PNP_TAG_MEMORY32_RANGE:
			if (config->ic_nmem == ISA_NMEM) {
				pnp_printf(id, "too many memory ranges\n");
				return (1);
			}
			if (I32(res + 13) == 0) {
				/* a null descriptor */
				config->ic_mem[config->ic_nmem].ir_start = 0;
				config->ic_mem[config->ic_nmem].ir_end = 0;
				config->ic_mem[config->ic_nmem].ir_size = 0;
				config->ic_mem[config->ic_nmem].ir_align = 0;
				config->ic_nmem++;
				break;
			}
			if (bootverbose) {
				pnp_printf(id, "adding memory32 range "
					   "%#x-%#x, size=%#x, "
					   "align=%#x\n",
					   I32(res + 1),
					   I32(res + 5) + I32(res + 13) - 1,
					   I32(res + 13), I32(res + 9));
			}
			config->ic_mem[config->ic_nmem].ir_start = I32(res + 1);
			config->ic_mem[config->ic_nmem].ir_end =
			    I32(res + 5) + I32(res + 13) - 1;
			config->ic_mem[config->ic_nmem].ir_size = I32(res + 13);
			config->ic_mem[config->ic_nmem].ir_align = I32(res + 9);
			config->ic_nmem++;
			break;

		case PNP_TAG_MEMORY32_FIXED:
			if (config->ic_nmem == ISA_NMEM) {
				pnp_printf(id, "too many memory ranges\n");
				return (1);
			}
			if (I32(res + 5) == 0) {
				/* a null descriptor */
				config->ic_mem[config->ic_nmem].ir_start = 0;
				config->ic_mem[config->ic_nmem].ir_end = 0;
				config->ic_mem[config->ic_nmem].ir_size = 0;
				config->ic_mem[config->ic_nmem].ir_align = 0;
				break;
			}
			if (bootverbose) {
				pnp_printf(id, "adding fixed memory32 range "
					   "%#x-%#x, size=%#x\n",
					   I32(res + 1),
					   I32(res + 1) + I32(res + 5) - 1,
					   I32(res + 5));
			}
			config->ic_mem[config->ic_nmem].ir_start = I32(res + 1);
			config->ic_mem[config->ic_nmem].ir_end =
			    I32(res + 1) + I32(res + 5) - 1;
			config->ic_mem[config->ic_nmem].ir_size = I32(res + 5);
			config->ic_mem[config->ic_nmem].ir_align = 1;
			config->ic_nmem++;
			break;

		default:
			/* Skip this resource */
			pnp_printf(id, "unexpected large tag %d\n",
				   PNP_SRES_NUM(tag));
			break;
		}
	}

	return (0);
}
Exemple #20
0
static int
ahc_isa_probe(device_t dev)
{
	struct	  aic7770_identity *entry;
	bus_space_tag_t	    tag;
	bus_space_handle_t  bsh;
	struct	  resource *regs;
	struct	  resource *irq;
	uint32_t  iobase;
	u_int	  intdef;
	u_int	  hcntrl;
	int	  irq_num;
	int	  error;
	int	  zero;

	error = ENXIO;
	zero = 0;
	regs = NULL;
	irq = NULL;

	/* Skip probes for ISA PnP devices */
	if (isa_get_logicalid(dev) != 0)
		return (error);

	regs = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &zero, RF_ACTIVE);
	if (regs == NULL) {
		device_printf(dev, "No resources allocated.\n");
		return (ENOMEM);
	}

	iobase = rman_get_start(regs);
	tag = rman_get_bustag(regs);
	bsh = rman_get_bushandle(regs);

	entry = ahc_isa_find_device(tag, bsh);
	if (entry == NULL)
		goto cleanup;

	/* Pause the card preseving the IRQ type */
	hcntrl = bus_space_read_1(tag, bsh, HCNTRL) & IRQMS;
	bus_space_write_1(tag, bsh, HCNTRL, hcntrl | PAUSE);
	while ((bus_space_read_1(tag, bsh, HCNTRL) & PAUSE) == 0)
		;

	/* Make sure we have a valid interrupt vector */
	intdef = bus_space_read_1(tag, bsh, INTDEF);
	irq_num = intdef & VECTOR;
	switch (irq_num) {
	case 9: 
	case 10:
	case 11:
	case 12:
	case 14:
	case 15:
		break;
	default:
		device_printf(dev, "@0x%x: illegal irq setting %d\n",
			      iobase, irq_num);
		goto cleanup;
	}

	if (bus_set_resource(dev, SYS_RES_IRQ, zero, irq_num, 1) != 0)
		goto cleanup;

	/*
	 * The 284X only supports edge triggered interrupts,
	 * so do not claim RF_SHAREABLE.
	 */
	irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &zero,
				     0 /*!(RF_ACTIVE|RF_SHAREABLE)*/);
	if (irq != NULL) {
		error = 0;
		device_set_desc(dev, entry->name);
	} else 
		device_printf(dev, "@0x%x: irq %d allocation failed\n",
			      iobase, irq_num);

cleanup:
	if (regs != NULL) {
		bus_release_resource(dev, SYS_RES_IOPORT, zero, regs);
		regs = NULL;
	}

	if (irq != NULL) {
		bus_release_resource(dev, SYS_RES_IRQ, zero, irq);
		irq = NULL;
	}

	return (error);
}
Exemple #21
0
static int
rp_probe(device_t dev)
{
	int unit;
	CONTROLLER_t *controller;
	int num_aiops;
	CONTROLLER_t *ctlp;
	int retval;

	/*
	 * We have no PnP RocketPort cards.
	 * (At least according to LINT)
	 */
	if (isa_get_logicalid(dev) != 0)
		return (ENXIO);

	/* We need IO port resource to configure an ISA device. */
	if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 0)
		return (ENXIO);

	unit = device_get_unit(dev);
	if (unit >= 4) {
		device_printf(dev, "rpprobe: unit number %d invalid.\n", unit);
		return (ENXIO);
	}
	device_printf(dev, "probing for RocketPort(ISA) unit %d.\n", unit);

	ctlp = device_get_softc(dev);
	bzero(ctlp, sizeof(*ctlp));
	ctlp->dev = dev;
	ctlp->aiop2rid = rp_isa_aiop2rid;
	ctlp->aiop2off = rp_isa_aiop2off;
	ctlp->ctlmask = rp_isa_ctlmask;

	/* The IO ports of AIOPs for an ISA controller are discrete. */
	ctlp->io_num = 1;
	ctlp->io_rid = malloc(sizeof(*(ctlp->io_rid)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO);
	ctlp->io = malloc(sizeof(*(ctlp->io)) * MAX_AIOPS_PER_BOARD, M_DEVBUF, M_NOWAIT | M_ZERO);
	if (ctlp->io_rid == NULL || ctlp->io == NULL) {
		device_printf(dev, "rp_attach: Out of memory.\n");
		retval = ENOMEM;
		goto nogo;
	}

	ctlp->bus_ctlp = malloc(sizeof(ISACONTROLLER_t) * 1, M_DEVBUF, M_NOWAIT | M_ZERO);
	if (ctlp->bus_ctlp == NULL) {
		device_printf(dev, "rp_attach: Out of memory.\n");
		retval = ENOMEM;
		goto nogo;
	}

	ctlp->io_rid[0] = 0;
	if (rp_controller != NULL) {
		controller = rp_controller;
		ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x40, RF_ACTIVE);
	} else {
		controller = rp_controller = ctlp;
		ctlp->io[0] = bus_alloc_resource(dev, SYS_RES_IOPORT, &ctlp->io_rid[0], 0, ~0, 0x44, RF_ACTIVE);
	}
	if (ctlp->io[0] == NULL) {
		device_printf(dev, "rp_attach: Resource not available.\n");
		retval = ENXIO;
		goto nogo;
	}

	num_aiops = sInitController(ctlp,
				controller,
				MAX_AIOPS_PER_BOARD, 0,
				FREQ_DIS, 0);
	if (num_aiops <= 0) {
		device_printf(dev, "board%d init failed.\n", unit);
		retval = ENXIO;
		goto nogo;
	}

	if (rp_controller == NULL)
		rp_controller = controller;
	rp_nisadevs++;

	device_set_desc(dev, "RocketPort ISA");

	return (0);

nogo:
	rp_isareleaseresource(ctlp);

	return (retval);
}
Exemple #22
0
/* Probe routine.  See if the card is there and at the right place. */
static int
el_probe(device_t dev)
{
	struct el_softc *sc;
	u_short base; /* Just for convenience */
	u_char station_addr[ETHER_ADDR_LEN];
	int i, rid;

	/* Grab some info for our structure */
	sc = device_get_softc(dev);

	if (isa_get_logicalid(dev))		/* skip PnP probes */
		return (ENXIO);

	if ((base = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0)
		return (ENXIO);

	/* First check the base */
	if((base < 0x280) || (base > 0x3f0)) {
		device_printf(dev,
		    "ioaddr must be between 0x280 and 0x3f0\n");
		return(ENXIO);
	}

	/* Temporarily map the resources. */
	rid = 0;
	sc->el_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
	    0, ~0, EL_IOSIZ, RF_ACTIVE);

	if (sc->el_res == NULL)
		return(ENXIO);

	sc->el_btag = rman_get_bustag(sc->el_res);
	sc->el_bhandle = rman_get_bushandle(sc->el_res);
	mtx_init(&sc->el_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
	    MTX_DEF | MTX_RECURSE);
	EL_LOCK(sc);

	/* Now attempt to grab the station address from the PROM
	 * and see if it contains the 3com vendor code.
	 */
	dprintf(("Probing 3c501 at 0x%x...\n",base));

	/* Reset the board */
	dprintf(("Resetting board...\n"));
	CSR_WRITE_1(sc,EL_AC,EL_AC_RESET);
	DELAY(5);
	CSR_WRITE_1(sc,EL_AC,0);
	dprintf(("Reading station address...\n"));
	/* Now read the address */
	for(i=0;i<ETHER_ADDR_LEN;i++) {
		CSR_WRITE_1(sc,EL_GPBL,i);
		station_addr[i] = CSR_READ_1(sc,EL_EAW);
	}

	/* Now release resources */
	bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->el_res);
	EL_UNLOCK(sc);
	mtx_destroy(&sc->el_mtx);

	dprintf(("Address is %6D\n",station_addr, ":"));

	/* If the vendor code is ok, return a 1.  We'll assume that
	 * whoever configured this system is right about the IRQ.
	 */
	if((station_addr[0] != 0x02) || (station_addr[1] != 0x60)
	   || (station_addr[2] != 0x8c)) {
		dprintf(("Bad vendor code.\n"));
		return(ENXIO);
	} else {
		dprintf(("Vendor code ok.\n"));
		/* Copy the station address into the arpcom structure */
		bcopy(station_addr,sc->arpcom.ac_enaddr,ETHER_ADDR_LEN);
	}

	device_set_desc(dev, "3Com 3c501 Ethernet");

	return(0);
}