예제 #1
0
static int
ichsmb_pci_attach(device_t dev)
{
	const sc_p sc = device_get_softc(dev);
	int error;

	/* Initialize private state */
	bzero(sc, sizeof(*sc));
	sc->ich_cmd = -1;
	sc->dev = dev;

	/* Allocate an I/O range */
	sc->io_rid = ICH_SMB_BASE;
	sc->io_res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT,
	    &sc->io_rid, 16, RF_ACTIVE);
	if (sc->io_res == NULL)
		sc->io_res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT,
		    &sc->io_rid, 32, RF_ACTIVE);
	if (sc->io_res == NULL) {
		device_printf(dev, "can't map I/O\n");
		error = ENXIO;
		goto fail;
	}

	/* Allocate interrupt */
	sc->irq_rid = 0;
	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &sc->irq_rid, RF_ACTIVE | RF_SHAREABLE);
	if (sc->irq_res == NULL) {
		device_printf(dev, "can't get IRQ\n");
		error = ENXIO;
		goto fail;
	}

	/* Enable device */
	pci_write_config(dev, ICH_HOSTC, ICH_HOSTC_HST_EN, 1);

	/* Done */
	error = ichsmb_attach(dev);
	if (error)
		goto fail;
	return (0);

fail:
	/* Attach failed, release resources */
	ichsmb_release_resources(sc);
	return (error);
}
예제 #2
0
static int
ichsmb_pci_attach(device_t dev)
{
	const sc_p sc = device_get_softc(dev);
	u_int32_t cmd;
	int error;

	/* Initialize private state */
	bzero(sc, sizeof(*sc));
	sc->ich_cmd = -1;
	sc->dev = dev;

	/* Allocate an I/O range */
	sc->io_rid = ICH_SMB_BASE;
	sc->io_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
	    &sc->io_rid, 0, ~0, 16, RF_ACTIVE);
	if (sc->io_res == NULL) {
		log(LOG_ERR, "%s: can't map I/O\n", device_get_nameunit(dev));
		error = ENXIO;
		goto fail;
	}
	sc->io_bst = rman_get_bustag(sc->io_res);
	sc->io_bsh = rman_get_bushandle(sc->io_res);

	/* Allocate interrupt */
	sc->irq_rid = 0;
	sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ,
	    &sc->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
	if (sc->irq_res == NULL) {
		log(LOG_ERR, "%s: can't get IRQ\n", device_get_nameunit(dev));
		error = ENXIO;
		goto fail;
	}

	/* Set up interrupt handler */
	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC,
	    ichsmb_device_intr, sc, &sc->irq_handle);
	if (error != 0) {
		log(LOG_ERR, "%s: can't setup irq\n", device_get_nameunit(dev));
		goto fail;
	}

	/* Enable I/O mapping */
	cmd = pci_read_config(dev, PCIR_COMMAND, 4);
	cmd |= PCIM_CMD_PORTEN;
	pci_write_config(dev, PCIR_COMMAND, cmd, 4);
	cmd = pci_read_config(dev, PCIR_COMMAND, 4);
	if ((cmd & PCIM_CMD_PORTEN) == 0) {
		log(LOG_ERR, "%s: can't enable memory map\n",
		    device_get_nameunit(dev));
		error = ENXIO;
		goto fail;
	}

	/* Enable device */
	pci_write_config(dev, ICH_HOSTC, ICH_HOSTC_HST_EN, 1);

	/* Done */
	return (ichsmb_attach(dev));

fail:
	/* Attach failed, release resources */
	ichsmb_release_resources(sc);
	return (error);
}