Пример #1
0
static int
bt_isa_alloc_resources(device_t dev, u_long portstart, u_long portend)
{
	int rid;
	struct resource *port;
	struct resource *irq;
	struct resource *drq;

	rid = 0;
	port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
				  portstart, portend, BT_NREGS, RF_ACTIVE);
	if (!port)
		return (ENOMEM);

	if (isa_get_irq(dev) != -1) {
		rid = 0;
		irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
		if (!irq) {
			if (port)
				bus_release_resource(dev, SYS_RES_IOPORT,
						     0, port);
			return (ENOMEM);
		}
	} else
		irq = NULL;

	if (isa_get_drq(dev) != -1) {
		rid = 0;
		drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, &rid, RF_ACTIVE);
		if (!drq) {
			if (port)
				bus_release_resource(dev, SYS_RES_IOPORT,
						     0, port);
			if (irq)
				bus_release_resource(dev, SYS_RES_IRQ,
						     0, irq);
			return (ENOMEM);
		}
	} else
		drq = NULL;

	bt_init_softc(dev, port, irq, drq);

	return (0);
}
Пример #2
0
static int
aic_isa_probe(device_t dev)
{
	struct aic_isa_softc *sc = device_get_softc(dev);
	struct aic_softc *aic = &sc->sc_aic;
	int numports, i;
	u_int port, *ports;
	u_int8_t porta;

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

	port = isa_get_port(dev);
	if (port != -1) {
		ports = &port;
		numports = 1;
	} else {
		ports = aic_isa_ports;
		numports = AIC_ISA_NUMPORTS;
	}

	for (i = 0; i < numports; i++) {
		if (bus_set_resource(dev, SYS_RES_IOPORT, 0, ports[i],
				     AIC_ISA_PORTSIZE))
			continue;
		if (aic_isa_alloc_resources(dev))
			continue;
		if (!aic_probe(aic)) {
			aic_isa_release_resources(dev);
			break;
		}
		aic_isa_release_resources(dev);
	}

	if (i == numports)
		return (ENXIO);

	porta = aic_inb(aic, PORTA);
	if (isa_get_irq(dev) == -1)
		bus_set_resource(dev, SYS_RES_IRQ, 0, PORTA_IRQ(porta), 1);
	if ((aic->flags & AIC_DMA_ENABLE) && isa_get_drq(dev) == -1)
		bus_set_resource(dev, SYS_RES_DRQ, 0, PORTA_DRQ(porta), 1);
	device_set_desc(dev, "Adaptec 6260/6360 SCSI controller");
	return (0);
}
Пример #3
0
static int
aic_isa_alloc_resources(device_t dev)
{
	struct aic_isa_softc *sc = device_get_softc(dev);
	int rid;

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

	rid = 0;
	sc->sc_port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
					0ul, ~0ul, AIC_ISA_PORTSIZE, RF_ACTIVE);
	if (!sc->sc_port) {
		device_printf(dev, "I/O port allocation failed\n");
		return (ENOMEM);
	}

	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.unit = device_get_unit(dev);
	sc->sc_aic.tag = rman_get_bustag(sc->sc_port);
	sc->sc_aic.bsh = rman_get_bushandle(sc->sc_port);
	return (0);
}
Пример #4
0
static int
aic_isa_alloc_resources(device_t dev)
{
	struct aic_isa_softc *sc = device_get_softc(dev);
	int rid;

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

	rid = 0;
	sc->sc_port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid,
						AIC_ISA_PORTSIZE, RF_ACTIVE);
	if (!sc->sc_port) {
		device_printf(dev, "I/O port allocation failed\n");
		return (ENOMEM);
	}

	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;
	mtx_init(&sc->sc_aic.lock, "aic", NULL, MTX_DEF);
	return (0);
}
Пример #5
0
/*
 * Attach all the sub-devices we can find
 */
static int
bt_isa_attach(device_t dev)
{
	struct	bt_softc *bt = device_get_softc(dev);
	bus_dma_filter_t *filter;
	void		 *filter_arg;
	bus_addr_t	 lowaddr;
	int		 error, drq;

	/* Initialise softc */
	error = bt_isa_alloc_resources(dev, 0, ~0);
	if (error) {
		device_printf(dev, "can't allocate resources in bt_isa_attach\n");
		return error;
	}

	/* Program the DMA channel for external control */
	if ((drq = isa_get_drq(dev)) != -1)
		isa_dmacascade(drq);

	/* Allocate our parent dmatag */
	filter = NULL;
	filter_arg = NULL;
	lowaddr = BUS_SPACE_MAXADDR_24BIT;

	/* XXX Should be a child of the ISA bus dma tag */
	if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/1, /*boundary*/0,
                               lowaddr, /*highaddr*/BUS_SPACE_MAXADDR,
                               filter, filter_arg,
                               /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
                               /*nsegments*/BUS_SPACE_UNRESTRICTED,
                               /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
                               /*flags*/0, &bt->parent_dmat) != 0) {
		bt_isa_release_resources(dev);
                return (ENOMEM);
        }                              

        error = bt_init(dev);
        if (error) {
		bt_isa_release_resources(dev);
                return (ENOMEM);
        }

	if (lowaddr != BUS_SPACE_MAXADDR_32BIT) {
		/* DMA tag for our sense buffers */
		if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/1,
				       /*boundary*/0,
				       /*lowaddr*/BUS_SPACE_MAXADDR,
				       /*highaddr*/BUS_SPACE_MAXADDR,
				       /*filter*/NULL, /*filterarg*/NULL,
				       bt->max_ccbs
					   * sizeof(struct scsi_sense_data),
				       /*nsegments*/1,
				       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
				       /*flags*/0, &bt->sense_dmat) != 0) {
			bt_isa_release_resources(dev);
			return (ENOMEM);
		}

		bt->init_level++;

		/* Allocation of sense buffers */
		if (bus_dmamem_alloc(bt->sense_dmat,
				     (void *)&bt->sense_buffers,
				     BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) {
			bt_isa_release_resources(dev);
			return (ENOMEM);
		}

		bt->init_level++;

		/* And permanently map them */
		bus_dmamap_load(bt->sense_dmat, bt->sense_dmamap,
       				bt->sense_buffers,
				bt->max_ccbs * sizeof(*bt->sense_buffers),
				btmapsensebuffers, bt, /*flags*/0);

		bt->init_level++;
	}

	error = bt_attach(dev);
	if (error) {
		bt_isa_release_resources(dev);
		return (error);
	}

	return (0);
}
Пример #6
0
/*
 * Attach all the sub-devices we can find
 */
static int
bt_isa_attach(device_t dev)
{
	struct	bt_softc *bt = device_get_softc(dev);
	bus_dma_filter_t *filter;
	void		 *filter_arg;
	bus_addr_t	 lowaddr;
	int		 error, drq;

	/* Initialise softc */
	error = bt_isa_alloc_resources(dev, 0, ~0);
	if (error) {
		device_printf(dev, "can't allocate resources in bt_isa_attach\n");
		return error;
	}

	/* Program the DMA channel for external control */
	if ((drq = isa_get_drq(dev)) != -1)
		isa_dmacascade(drq);

	/* Allocate our parent dmatag */
	filter = NULL;
	filter_arg = NULL;
	lowaddr = BUS_SPACE_MAXADDR_24BIT;
	if (bt->model[0] == '4') {
		/*
		 * This is a VL adapter.  Typically, VL devices have access
		 * to the full 32bit address space.  On BT-445S adapters
		 * prior to revision E, there is a hardware bug that causes
		 * corruption of transfers to/from addresses in the range of
		 * the BIOS modulo 16MB.  The only properly functioning
		 * BT-445S Host Adapters have firmware version 3.37.
		 * If we encounter one of these adapters and the BIOS is
		 * installed, install a filter function for our bus_dma_map
		 * that will catch these accesses and bounce them to a safe
		 * region of memory.
		 */
		if (bt->bios_addr != 0
		 && strcmp(bt->model, "445S") == 0
		 && strcmp(bt->firmware_ver, "3.37") < 0) {
			filter = btvlbouncefilter;
			filter_arg = bt;
		} else {
			lowaddr = BUS_SPACE_MAXADDR_32BIT;
		}
	}
			
	/* XXX Should be a child of the ISA or VL bus dma tag */
	if (bus_dma_tag_create(	/* parent	*/ bus_get_dma_tag(dev),
				/* alignemnt	*/ 1,
				/* boundary	*/ 0,
				/* lowaddr	*/ lowaddr,
				/* highaddr	*/ BUS_SPACE_MAXADDR,
				/* filter	*/ filter,
				/* filterarg	*/ filter_arg,
				/* maxsize	*/ BUS_SPACE_MAXSIZE_32BIT,
				/* nsegments	*/ ~0,
				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_32BIT,
				/* flags	*/ 0,
				/* lockfunc	*/ NULL,
				/* lockarg	*/ NULL,
				&bt->parent_dmat) != 0) {
		bt_isa_release_resources(dev);
                return (ENOMEM);
        }                              

        error = bt_init(dev);
        if (error) {
		bt_isa_release_resources(dev);
                return (ENOMEM);
        }

	if (lowaddr != BUS_SPACE_MAXADDR_32BIT) {
		/* DMA tag for our sense buffers */
		if (bus_dma_tag_create(
				/* parent	*/ bt->parent_dmat,
				/* alignment	*/ 1,
				/* boundary	*/ 0,
				/* lowaddr	*/ BUS_SPACE_MAXADDR,
				/* highaddr	*/ BUS_SPACE_MAXADDR,
				/* filter	*/ NULL,
				/* filterarg	*/ NULL,
				/* maxsize	*/ bt->max_ccbs *
						   sizeof(struct scsi_sense_data),
				/* nsegments	*/ 1,
				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_32BIT,
				/* flags	*/ 0,
				/* lockfunc	*/ NULL,
				/* lockarg	*/ NULL,
				&bt->sense_dmat) != 0) {
			bt_isa_release_resources(dev);
			return (ENOMEM);
		}

		bt->init_level++;

		/* Allocation of sense buffers */
		if (bus_dmamem_alloc(bt->sense_dmat,
				     (void **)&bt->sense_buffers,
				     BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) {
			bt_isa_release_resources(dev);
			return (ENOMEM);
		}

		bt->init_level++;

		/* And permanently map them */
		bus_dmamap_load(bt->sense_dmat, bt->sense_dmamap,
       				bt->sense_buffers,
				bt->max_ccbs * sizeof(*bt->sense_buffers),
				btmapsensebuffers, bt, /*flags*/0);

		bt->init_level++;
	}

	error = bt_attach(dev);
	if (error) {
		bt_isa_release_resources(dev);
		return (error);
	}

	return (0);
}