Exemplo n.º 1
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);
}
Exemplo n.º 2
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);
}