예제 #1
0
파일: if_gem_pci.c 프로젝트: 2asoft/freebsd
static int
gem_pci_attach(device_t dev)
{
	struct gem_softc *sc;
	int i;
#if defined(__powerpc__) || defined(__sparc64__)
	char buf[sizeof(GEM_SHARED_PINS)];
#else
	int j;
#endif

	sc = device_get_softc(dev);
	sc->sc_variant = GEM_UNKNOWN;
	for (i = 0; gem_pci_devlist[i].gpd_desc != NULL; i++) {
		if (pci_get_devid(dev) == gem_pci_devlist[i].gpd_devid) {
			sc->sc_variant = gem_pci_devlist[i].gpd_variant;
			break;
		}
	}
	if (sc->sc_variant == GEM_UNKNOWN) {
		device_printf(dev, "unknown adaptor\n");
		return (ENXIO);
	}

	pci_enable_busmaster(dev);

	/*
	 * Some Sun GEMs/ERIs do have their intpin register bogusly set to 0,
	 * although it should be 1.  Correct that.
	 */
	if (pci_get_intpin(dev) == 0)
		pci_set_intpin(dev, 1);

	/* Set the PCI latency timer for Sun ERIs. */
	if (sc->sc_variant == GEM_SUN_ERI)
		pci_write_config(dev, PCIR_LATTIMER, GEM_ERI_LATENCY_TIMER, 1);

	sc->sc_dev = dev;
	sc->sc_flags |= GEM_PCI;

	if (bus_alloc_resources(dev, gem_pci_res_spec, sc->sc_res)) {
		device_printf(dev, "failed to allocate resources\n");
		bus_release_resources(dev, gem_pci_res_spec, sc->sc_res);
		return (ENXIO);
	}

	GEM_LOCK_INIT(sc, device_get_nameunit(dev));

	/*
	 * Derive GEM_RES_BANK2 from GEM_RES_BANK1.  This seemed cleaner
	 * with the old way of using copies of the bus tag and handle in
	 * the softc along with bus_space_*()...
	 */
	sc->sc_res[GEM_RES_BANK2] = malloc(sizeof(*sc->sc_res[GEM_RES_BANK2]),
	    M_DEVBUF, M_NOWAIT | M_ZERO);
	if (sc->sc_res[GEM_RES_BANK2] == NULL) {
		device_printf(dev, "failed to allocate bank2 resource\n");
		goto fail;
	}
	rman_set_bustag(sc->sc_res[GEM_RES_BANK2],
	    rman_get_bustag(sc->sc_res[GEM_RES_BANK1]));
	bus_space_subregion(rman_get_bustag(sc->sc_res[GEM_RES_BANK1]),
	    rman_get_bushandle(sc->sc_res[GEM_RES_BANK1]),
	    GEM_PCI_BANK2_OFFSET, GEM_PCI_BANK2_SIZE,
	    &sc->sc_res[GEM_RES_BANK2]->r_bushandle);

	/* Determine whether we're running at 66MHz. */
	if ((GEM_BANK2_READ_4(sc, GEM_PCI_BIF_CONFIG) &
	   GEM_PCI_BIF_CNF_M66EN) != 0)
		sc->sc_flags |= GEM_PCI66;

#if defined(__powerpc__) || defined(__sparc64__)
	OF_getetheraddr(dev, sc->sc_enaddr);
	if (OF_getprop(ofw_bus_get_node(dev), GEM_SHARED_PINS, buf,
	    sizeof(buf)) > 0) {
		buf[sizeof(buf) - 1] = '\0';
		if (strcmp(buf, GEM_SHARED_PINS_SERDES) == 0)
			sc->sc_flags |= GEM_SERDES;
	}
#else
	/*
	 * Dig out VPD (vital product data) and read NA (network address).
	 * The VPD resides in the PCI Expansion ROM (PCI FCode) and can't
	 * be accessed via the PCI capability pointer.
	 * ``Writing FCode 3.x Programs'' (newer ones, dated 1997 and later)
	 * chapter 2 describes the data structure.
	 */

#define	PCI_ROMHDR_SIZE			0x1c
#define	PCI_ROMHDR_SIG			0x00
#define	PCI_ROMHDR_SIG_MAGIC		0xaa55		/* little endian */
#define	PCI_ROMHDR_PTR_DATA		0x18
#define	PCI_ROM_SIZE			0x18
#define	PCI_ROM_SIG			0x00
#define	PCI_ROM_SIG_MAGIC		0x52494350	/* "PCIR", endian */
							/* reversed */
#define	PCI_ROM_VENDOR			0x04
#define	PCI_ROM_DEVICE			0x06
#define	PCI_ROM_PTR_VPD			0x08
#define	PCI_VPDRES_BYTE0		0x00
#define	PCI_VPDRES_ISLARGE(x)		((x) & 0x80)
#define	PCI_VPDRES_LARGE_NAME(x)	((x) & 0x7f)
#define	PCI_VPDRES_LARGE_LEN_LSB	0x01
#define	PCI_VPDRES_LARGE_LEN_MSB	0x02
#define	PCI_VPDRES_LARGE_SIZE		0x03
#define	PCI_VPDRES_TYPE_VPD		0x10		/* large */
#define	PCI_VPD_KEY0			0x00
#define	PCI_VPD_KEY1			0x01
#define	PCI_VPD_LEN			0x02
#define	PCI_VPD_SIZE			0x03

#define	GEM_ROM_READ_1(sc, offs)					\
	GEM_BANK1_READ_1((sc), GEM_PCI_ROM_OFFSET + (offs))
#define	GEM_ROM_READ_2(sc, offs)					\
	GEM_BANK1_READ_2((sc), GEM_PCI_ROM_OFFSET + (offs))
#define	GEM_ROM_READ_4(sc, offs)					\
	GEM_BANK1_READ_4((sc), GEM_PCI_ROM_OFFSET + (offs))

	/* Read PCI Expansion ROM header. */
	if (GEM_ROM_READ_2(sc, PCI_ROMHDR_SIG) != PCI_ROMHDR_SIG_MAGIC ||
	    (i = GEM_ROM_READ_2(sc, PCI_ROMHDR_PTR_DATA)) <
	    PCI_ROMHDR_SIZE) {
		device_printf(dev, "unexpected PCI Expansion ROM header\n");
		goto fail;
	}

	/* Read PCI Expansion ROM data. */
	if (GEM_ROM_READ_4(sc, i + PCI_ROM_SIG) != PCI_ROM_SIG_MAGIC ||
	    GEM_ROM_READ_2(sc, i + PCI_ROM_VENDOR) != pci_get_vendor(dev) ||
	    GEM_ROM_READ_2(sc, i + PCI_ROM_DEVICE) != pci_get_device(dev) ||
	    (j = GEM_ROM_READ_2(sc, i + PCI_ROM_PTR_VPD)) <
	    i + PCI_ROM_SIZE) {
		device_printf(dev, "unexpected PCI Expansion ROM data\n");
		goto fail;
	}

	/*
	 * Read PCI VPD.
	 * SUNW,pci-gem cards have a single large resource VPD-R tag
	 * containing one NA.  The VPD used is not in PCI 2.2 standard
	 * format however.  The length in the resource header is in big
	 * endian and the end tag is non-standard (0x79) and followed
	 * by an all-zero "checksum" byte.  Sun calls this a "Fresh
	 * Choice Ethernet" VPD...
	 */
	if (PCI_VPDRES_ISLARGE(GEM_ROM_READ_1(sc,
	    j + PCI_VPDRES_BYTE0)) == 0 ||
	    PCI_VPDRES_LARGE_NAME(GEM_ROM_READ_1(sc,
	    j + PCI_VPDRES_BYTE0)) != PCI_VPDRES_TYPE_VPD ||
	    ((GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_LSB) << 8) |
	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_MSB)) !=
	    PCI_VPD_SIZE + ETHER_ADDR_LEN ||
	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_KEY0) !=
	    0x4e /* N */ ||
	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_KEY1) !=
	    0x41 /* A */ ||
	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_LEN) !=
	    ETHER_ADDR_LEN ||
	    GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_SIZE +
	    ETHER_ADDR_LEN) != 0x79) {
		device_printf(dev, "unexpected PCI VPD\n");
		goto fail;
	}
	bus_read_region_1(sc->sc_res[GEM_RES_BANK1],
	    GEM_PCI_ROM_OFFSET + j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_SIZE,
	    sc->sc_enaddr, ETHER_ADDR_LEN);
#endif
	/*
	 * The Xserve G5 has a fake GMAC with an all-zero MAC address.
	 * Check for this, and don't attach in this case.
	 */

	for (i = 0; i < ETHER_ADDR_LEN && sc->sc_enaddr[i] == 0; i++) {}
	if (i == ETHER_ADDR_LEN) {
		device_printf(dev, "invalid MAC address\n");
		goto fail;
	}

	if (gem_attach(sc) != 0) {
		device_printf(dev, "could not be attached\n");
		goto fail;
	}

	if (bus_setup_intr(dev, sc->sc_res[GEM_RES_INTR], INTR_TYPE_NET |
	    INTR_MPSAFE, NULL, gem_intr, sc, &sc->sc_ih) != 0) {
		device_printf(dev, "failed to set up interrupt\n");
		gem_detach(sc);
		goto fail;
	}
	return (0);

 fail:
	if (sc->sc_res[GEM_RES_BANK2] != NULL)
		free(sc->sc_res[GEM_RES_BANK2], M_DEVBUF);
	GEM_LOCK_DESTROY(sc);
	bus_release_resources(dev, gem_pci_res_spec, sc->sc_res);
	return (ENXIO);
}
예제 #2
0
파일: mpt_pci.c 프로젝트: wulf7/freebsd
static int
mpt_pci_probe(device_t dev)
{
	const char *desc;

	if (pci_get_vendor(dev) != MPI_MANUFACTPAGE_VENDORID_LSILOGIC)
		return (ENXIO);

	switch (pci_get_device(dev)) {
	case MPI_MANUFACTPAGE_DEVICEID_FC909_FB:
		desc = "LSILogic FC909 FC Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC909:
		desc = "LSILogic FC909A FC Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC919:
		desc = "LSILogic FC919 FC Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC919_LAN_FB:
		desc = "LSILogic FC919 LAN Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC929:
		desc = "Dual LSILogic FC929 FC Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB:
		desc = "Dual LSILogic FC929 LAN Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC919X:
		desc = "LSILogic FC919 FC PCI-X Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC919X_LAN_FB:
		desc = "LSILogic FC919 LAN PCI-X Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC929X:
		desc = "Dual LSILogic FC929X 2Gb/s FC PCI-X Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC929X_LAN_FB:
		desc = "Dual LSILogic FC929X LAN PCI-X Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC949E:
		desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-Express Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC949X:
		desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-X Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVID_53C1030:
	case MPI_MANUFACTPAGE_DEVID_53C1030ZC:
		desc = "LSILogic 1030 Ultra4 Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVID_SAS1064:
	case MPI_MANUFACTPAGE_DEVID_SAS1064A:
	case MPI_MANUFACTPAGE_DEVID_SAS1064E:
	case MPI_MANUFACTPAGE_DEVID_SAS1066:
	case MPI_MANUFACTPAGE_DEVID_SAS1066E:
	case MPI_MANUFACTPAGE_DEVID_SAS1068:
	case MPI_MANUFACTPAGE_DEVID_SAS1068A_FB:
	case MPI_MANUFACTPAGE_DEVID_SAS1068E:
	case MPI_MANUFACTPAGE_DEVID_SAS1078:
	case MPI_MANUFACTPAGE_DEVID_SAS1078DE_FB:
		desc = "LSILogic SAS/SATA Adapter";
		break;
	default:
		return (ENXIO);
	}

	device_set_desc(dev, desc);
	return (0);
}
예제 #3
0
static int
iir_pci_attach(device_t dev)
{
    struct gdt_softc    *gdt;
    struct resource     *io = NULL, *irq = NULL;
    int                 retries, rid, error = 0;
    void                *ih;
    u_int8_t            protocol;

    /* map DPMEM */
    rid = PCI_DPMEM;
    io = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
    if (io == NULL) {
        device_printf(dev, "can't allocate register resources\n");
        error = ENOMEM;
        goto err;
    }

    /* get IRQ */
    rid = 0;
    irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
                                 RF_ACTIVE | RF_SHAREABLE);
    if (irq == NULL) {
        device_printf(dev, "can't find IRQ value\n");
        error = ENOMEM;
        goto err;
    }

    gdt = device_get_softc(dev);
    gdt->sc_init_level = 0;
    gdt->sc_dpmemt = rman_get_bustag(io);
    gdt->sc_dpmemh = rman_get_bushandle(io);
    gdt->sc_dpmembase = rman_get_start(io);
    gdt->sc_hanum = device_get_unit(dev);
    gdt->sc_bus = pci_get_bus(dev);
    gdt->sc_slot = pci_get_slot(dev);
    gdt->sc_vendor = pci_get_vendor(dev);
    gdt->sc_device = pci_get_device(dev);
    gdt->sc_subdevice = pci_get_subdevice(dev);
    gdt->sc_class = GDT_MPR;
/* no FC ctr.
    if (gdt->sc_device >= GDT_PCI_PRODUCT_FC)
        gdt->sc_class |= GDT_FC;
*/

    /* initialize RP controller */
    /* check and reset interface area */
    bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC,
                      htole32(GDT_MPR_MAGIC));
    if (bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC) !=
        htole32(GDT_MPR_MAGIC)) {
        kprintf("cannot access DPMEM at 0x%jx (shadowed?)\n",
               (uintmax_t)gdt->sc_dpmembase);
        error = ENXIO;
        goto err;
    }
    bus_space_set_region_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_I960_SZ, htole32(0),
                           GDT_MPR_SZ >> 2);

    /* Disable everything */
    bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_EDOOR_EN,
                      bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
                                       GDT_EDOOR_EN) | 4);
    bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR, 0xff);
    bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS,
                      0);
    bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_CMD_INDEX,
                      0);

    bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO,
                      htole32(gdt->sc_dpmembase));
    bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX,
                      0xff);
    bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1);

    DELAY(20);
    retries = GDT_RETRIES;
    while (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
                            GDT_MPR_IC + GDT_S_STATUS) != 0xff) {
        if (--retries == 0) {
            kprintf("DEINIT failed\n");
            error = ENXIO;
            goto err;
        }
        DELAY(1);
    }

    protocol = (uint8_t)le32toh(bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
                                                  GDT_MPR_IC + GDT_S_INFO));
    bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS,
                      0);
    if (protocol != GDT_PROTOCOL_VERSION) {
        kprintf("unsupported protocol %d\n", protocol);
        error = ENXIO;
        goto err;
    }

    /* special commnd to controller BIOS */
    bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO,
                      htole32(0));
    bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
                      GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), htole32(0));
    bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
                      GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t),
                      htole32(1));
    bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
                      GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t),
                      htole32(0));
    bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX,
                      0xfe);
    bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1);

    DELAY(20);
    retries = GDT_RETRIES;
    while (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
                            GDT_MPR_IC + GDT_S_STATUS) != 0xfe) {
        if (--retries == 0) {
            kprintf("initialization error\n");
            error = ENXIO;
            goto err;
        }
        DELAY(1);
    }

    bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS,
                      0);

    gdt->sc_ic_all_size = GDT_MPR_SZ;

    gdt->sc_copy_cmd = gdt_mpr_copy_cmd;
    gdt->sc_get_status = gdt_mpr_get_status;
    gdt->sc_intr = gdt_mpr_intr;
    gdt->sc_release_event = gdt_mpr_release_event;
    gdt->sc_set_sema0 = gdt_mpr_set_sema0;
    gdt->sc_test_busy = gdt_mpr_test_busy;

    /* Allocate a dmatag representing the capabilities of this attachment */
    /* XXX Should be a child of the PCI bus dma tag */
    if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/1, /*boundary*/0,
                           /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
                           /*highaddr*/BUS_SPACE_MAXADDR,
                           /*filter*/NULL, /*filterarg*/NULL,
                           /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
                           /*nsegments*/GDT_MAXSG,
                           /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
                           /*flags*/0, &gdt->sc_parent_dmat) != 0) {
        error = ENXIO;
        goto err;
    }
    gdt->sc_init_level++;

    if (iir_init(gdt) != 0) {
        iir_free(gdt);
        error = ENXIO;
        goto err;
    }

    /* Register with the XPT */
    iir_attach(gdt);

    /* associate interrupt handler */
    error = bus_setup_intr(dev, irq, 0, iir_intr, gdt, &ih, NULL);
    if (error) {
        device_printf(dev, "Unable to register interrupt handler\n");
        error = ENXIO;
        goto err;
    }

    gdt_pci_enable_intr(gdt);
    return (0);

err:
    if (irq)
        bus_release_resource( dev, SYS_RES_IRQ, 0, irq );
/*
    if (io)
        bus_release_resource( dev, SYS_RES_MEMORY, rid, io );
*/
    return (error);
}
예제 #4
0
파일: sfxge.c 프로젝트: AhmadTux/freebsd
static int
sfxge_create(struct sfxge_softc *sc)
{
	device_t dev;
	efx_nic_t *enp;
	int error;

	dev = sc->dev;

	sx_init(&sc->softc_lock, "sfxge_softc");

	sc->stats_node = SYSCTL_ADD_NODE(
		device_get_sysctl_ctx(dev),
		SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
		OID_AUTO, "stats", CTLFLAG_RD, NULL, "Statistics");
	if (!sc->stats_node) {
		error = ENOMEM;
		goto fail;
	}

	TASK_INIT(&sc->task_reset, 0, sfxge_reset, sc);

	(void) pci_enable_busmaster(dev);

	/* Initialize DMA mappings. */
	if ((error = sfxge_dma_init(sc)) != 0)
		goto fail;

	/* Map the device registers. */
	if ((error = sfxge_bar_init(sc)) != 0)
		goto fail;

	error = efx_family(pci_get_vendor(dev), pci_get_device(dev),
	    &sc->family);
	KASSERT(error == 0, ("Family should be filtered by sfxge_probe()"));

	/* Create the common code nic object. */
	mtx_init(&sc->enp_lock, "sfxge_nic", NULL, MTX_DEF);
	if ((error = efx_nic_create(sc->family, (efsys_identifier_t *)sc,
	    &sc->bar, &sc->enp_lock, &enp)) != 0)
		goto fail3;
	sc->enp = enp;

	/* Initialize MCDI to talk to the microcontroller. */
	if ((error = sfxge_mcdi_init(sc)) != 0)
		goto fail4;

	/* Probe the NIC and build the configuration data area. */
	if ((error = efx_nic_probe(enp)) != 0)
		goto fail5;

	/* Initialize the NVRAM. */
	if ((error = efx_nvram_init(enp)) != 0)
		goto fail6;

	/* Initialize the VPD. */
	if ((error = efx_vpd_init(enp)) != 0)
		goto fail7;

	/* Reset the NIC. */
	if ((error = efx_nic_reset(enp)) != 0)
		goto fail8;

	/* Initialize buffer table allocation. */
	sc->buffer_table_next = 0;

	/* Set up interrupts. */
	if ((error = sfxge_intr_init(sc)) != 0)
		goto fail8;

	/* Initialize event processing state. */
	if ((error = sfxge_ev_init(sc)) != 0)
		goto fail11;

	/* Initialize receive state. */
	if ((error = sfxge_rx_init(sc)) != 0)
		goto fail12;

	/* Initialize transmit state. */
	if ((error = sfxge_tx_init(sc)) != 0)
		goto fail13;

	/* Initialize port state. */
	if ((error = sfxge_port_init(sc)) != 0)
		goto fail14;

	sc->init_state = SFXGE_INITIALIZED;

	return (0);

fail14:
	sfxge_tx_fini(sc);

fail13:
	sfxge_rx_fini(sc);

fail12:
	sfxge_ev_fini(sc);

fail11:
	sfxge_intr_fini(sc);

fail8:
	efx_vpd_fini(enp);

fail7:
	efx_nvram_fini(enp);

fail6:
	efx_nic_unprobe(enp);

fail5:
	sfxge_mcdi_fini(sc);

fail4:
	sc->enp = NULL;
	efx_nic_destroy(enp);
	mtx_destroy(&sc->enp_lock);

fail3:
	sfxge_bar_fini(sc);
	(void) pci_disable_busmaster(sc->dev);

fail:
	sc->dev = NULL;
	sx_destroy(&sc->softc_lock);
	return (error);
}
예제 #5
0
/*
 * Silicon Integrated Systems Corp. (SiS) chipset support functions
 */
static int
ata_sis_probe(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);
    const struct ata_chip_id *idx;
    static const struct ata_chip_id ids[] =
    {   { ATA_SIS182,  0x00, SIS_SATA,   0, ATA_SA150, "182" }, /* south */
        { ATA_SIS181,  0x00, SIS_SATA,   0, ATA_SA150, "181" }, /* south */
        { ATA_SIS180,  0x00, SIS_SATA,   0, ATA_SA150, "180" }, /* south */
        { ATA_SIS965,  0x00, SIS_133NEW, 0, ATA_UDMA6, "965" }, /* south */
        { ATA_SIS964,  0x00, SIS_133NEW, 0, ATA_UDMA6, "964" }, /* south */
        { ATA_SIS963,  0x00, SIS_133NEW, 0, ATA_UDMA6, "963" }, /* south */
        { ATA_SIS962,  0x00, SIS_133NEW, 0, ATA_UDMA6, "962" }, /* south */

        { ATA_SIS745,  0x00, SIS_100NEW, 0, ATA_UDMA5, "745" }, /* 1chip */
        { ATA_SIS735,  0x00, SIS_100NEW, 0, ATA_UDMA5, "735" }, /* 1chip */
        { ATA_SIS733,  0x00, SIS_100NEW, 0, ATA_UDMA5, "733" }, /* 1chip */
        { ATA_SIS730,  0x00, SIS_100OLD, 0, ATA_UDMA5, "730" }, /* 1chip */

        { ATA_SIS635,  0x00, SIS_100NEW, 0, ATA_UDMA5, "635" }, /* 1chip */
        { ATA_SIS633,  0x00, SIS_100NEW, 0, ATA_UDMA5, "633" }, /* unknown */
        { ATA_SIS630,  0x30, SIS_100OLD, 0, ATA_UDMA5, "630S"}, /* 1chip */
        { ATA_SIS630,  0x00, SIS_66,     0, ATA_UDMA4, "630" }, /* 1chip */
        { ATA_SIS620,  0x00, SIS_66,     0, ATA_UDMA4, "620" }, /* 1chip */

        { ATA_SIS550,  0x00, SIS_66,     0, ATA_UDMA5, "550" },
        { ATA_SIS540,  0x00, SIS_66,     0, ATA_UDMA4, "540" },
        { ATA_SIS530,  0x00, SIS_66,     0, ATA_UDMA4, "530" },

        { ATA_SIS5513, 0xc2, SIS_33,     1, ATA_UDMA2, "5513" },
        { ATA_SIS5513, 0x00, SIS_33,     1, ATA_WDMA2, "5513" },
        { 0, 0, 0, 0, 0, 0 }
    };
    static struct ata_chip_id id[] =
    {{ ATA_SISSOUTH, 0x10, 0, 0, 0, "" }, { 0, 0, 0, 0, 0, 0 }};
    char buffer[64];
    int found = 0;

    if (pci_get_class(dev) != PCIC_STORAGE)
        return (ENXIO);

    if (pci_get_vendor(dev) != ATA_SIS_ID)
        return ENXIO;

    if (!(idx = ata_find_chip(dev, ids, -pci_get_slot(dev))))
        return ENXIO;

    if (idx->cfg2) {
        u_int8_t reg57 = pci_read_config(dev, 0x57, 1);

        pci_write_config(dev, 0x57, (reg57 & 0x7f), 1);
        if (pci_read_config(dev, PCIR_DEVVENDOR, 4) == ATA_SIS5518) {
            found = 1;
            memcpy(&id[0], idx, sizeof(id[0]));
            id[0].cfg1 = SIS_133NEW;
            id[0].max_dma = ATA_UDMA6;
            sprintf(buffer, "SiS 962/963 %s controller",
                    ata_mode2str(idx->max_dma));
        }
        pci_write_config(dev, 0x57, reg57, 1);
    }
    if (idx->cfg2 && !found) {
        u_int8_t reg4a = pci_read_config(dev, 0x4a, 1);

        pci_write_config(dev, 0x4a, (reg4a | 0x10), 1);
        if (pci_read_config(dev, PCIR_DEVVENDOR, 4) == ATA_SIS5517) {
            found = 1;
            if (ata_find_chip(dev, id, pci_get_slot(dev))) {
                id[0].cfg1 = SIS_133OLD;
                id[0].max_dma = ATA_UDMA6;
            } else {
                id[0].cfg1 = SIS_100NEW;
                id[0].max_dma = ATA_UDMA5;
            }
            sprintf(buffer, "SiS 961 %s controller",ata_mode2str(idx->max_dma));
        }
        pci_write_config(dev, 0x4a, reg4a, 1);
    }
    if (!found)
        sprintf(buffer,"SiS %s %s controller",
                idx->text, ata_mode2str(idx->max_dma));
    else
        idx = &id[0];

    device_set_desc_copy(dev, buffer);
    ctlr->chip = idx;
    ctlr->chipinit = ata_sis_chipinit;
    return (BUS_PROBE_DEFAULT);
}
예제 #6
0
파일: xhci_pci.c 프로젝트: ornarium/freebsd
static int
xhci_pci_attach(device_t self)
{
	struct xhci_softc *sc = device_get_softc(self);
	int err;
	int rid;

	/* XXX check for 64-bit capability */

	if (xhci_init(sc, self)) {
		device_printf(self, "Could not initialize softc\n");
		goto error;
	}

	pci_enable_busmaster(self);

	rid = PCI_XHCI_CBMEM;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map memory\n");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(self, "Could not allocate IRQ\n");
		goto error;
	}
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (sc->sc_bus.bdev == NULL) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	sprintf(sc->sc_vendor, "0x%04x", pci_get_vendor(self));

#if (__FreeBSD_version >= 700031)
	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl);
#else
	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl);
#endif
	if (err) {
		device_printf(self, "Could not setup IRQ, err=%d\n", err);
		sc->sc_intr_hdl = NULL;
		goto error;
	}
	xhci_pci_take_controller(self);

	err = xhci_halt_controller(sc);

	if (err == 0)
		err = xhci_start_controller(sc);

	if (err == 0)
		err = device_probe_and_attach(sc->sc_bus.bdev);

	if (err) {
		device_printf(self, "XHCI halt/start/probe failed err=%d\n", err);
		goto error;
	}
	return (0);

error:
	xhci_pci_detach(self);
	return (ENXIO);
}
예제 #7
0
/*
 * The probe routine.
 */
static int
fwohci_pci_probe( device_t dev )
{
#if 1
	uint32_t id;

	id = pci_get_devid(dev);
	if (id == (FW_VENDORID_NATSEMI | FW_DEVICE_CS4210)) {
		device_set_desc(dev, "National Semiconductor CS4210");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_NEC | FW_DEVICE_UPD861)) {
		device_set_desc(dev, "NEC uPD72861");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_NEC | FW_DEVICE_UPD871)) {
		device_set_desc(dev, "NEC uPD72871/2");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_NEC | FW_DEVICE_UPD72870)) {
		device_set_desc(dev, "NEC uPD72870");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_NEC | FW_DEVICE_UPD72873)) {
		device_set_desc(dev, "NEC uPD72873");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_NEC | FW_DEVICE_UPD72874)) {
		device_set_desc(dev, "NEC uPD72874");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_SIS | FW_DEVICE_7007)) {
		/* It has no real identifier, using device id. */
		device_set_desc(dev, "SiS 7007");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB22)) {
		device_set_desc(dev, "Texas Instruments TSB12LV22");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB23)) {
		device_set_desc(dev, "Texas Instruments TSB12LV23");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB26)) {
		device_set_desc(dev, "Texas Instruments TSB12LV26");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB43)) {
		device_set_desc(dev, "Texas Instruments TSB43AA22");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB43A)) {
		device_set_desc(dev, "Texas Instruments TSB43AB22/A");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB43AB21)) {
		device_set_desc(dev, "Texas Instruments TSB43AB21/A/AI/A-EP");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB43AB23)) {
		device_set_desc(dev, "Texas Instruments TSB43AB23");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB82AA2)) {
		device_set_desc(dev, "Texas Instruments TSB82AA2");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TIPCI4450)) {
		device_set_desc(dev, "Texas Instruments PCI4450");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TIPCI4410A)) {
		device_set_desc(dev, "Texas Instruments PCI4410A");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_TI | FW_DEVICE_TIPCI4451)) {
		device_set_desc(dev, "Texas Instruments PCI4451");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_SONY | FW_DEVICE_CXD1947)) {
		device_printf(dev, "Sony i.LINK (CXD1947) not supported\n");
		return ENXIO;
	}
	if (id == (FW_VENDORID_SONY | FW_DEVICE_CXD3222)) {
		device_set_desc(dev, "Sony i.LINK (CXD3222)");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_VIA | FW_DEVICE_VT6306)) {
		device_set_desc(dev, "VIA Fire II (VT6306)");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_RICOH | FW_DEVICE_R5C551)) {
		device_set_desc(dev, "Ricoh R5C551");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_RICOH | FW_DEVICE_R5C552)) {
		device_set_desc(dev, "Ricoh R5C552");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_APPLE | FW_DEVICE_PANGEA)) {
		device_set_desc(dev, "Apple Pangea");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_APPLE | FW_DEVICE_UNINORTH)) {
		device_set_desc(dev, "Apple UniNorth");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_LUCENT | FW_DEVICE_FW322)) {
		device_set_desc(dev, "Lucent FW322/323");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_INTEL | FW_DEVICE_82372FB)) {
		device_set_desc(dev, "Intel 82372FB");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_ADAPTEC | FW_DEVICE_AIC5800)) {
		device_set_desc(dev, "Adaptec AHA-894x/AIC-5800");
		return BUS_PROBE_DEFAULT;
	}
	if (id == (FW_VENDORID_SUN | FW_DEVICE_PCIO2FW)) {
		device_set_desc(dev, "Sun PCIO-2");
		return BUS_PROBE_DEFAULT;
	}
#endif
	if (pci_get_class(dev) == PCIC_SERIALBUS
			&& pci_get_subclass(dev) == PCIS_SERIALBUS_FW
			&& pci_get_progif(dev) == PCI_INTERFACE_OHCI) {
		if (bootverbose)
			device_printf(dev, "vendor=%x, dev=%x\n",
			    pci_get_vendor(dev), pci_get_device(dev));
		device_set_desc(dev, "1394 Open Host Controller Interface");
		return BUS_PROBE_DEFAULT;
	}

	return ENXIO;
}
예제 #8
0
파일: xhci_pci.c 프로젝트: ralphost/NextBSD
static int
xhci_pci_attach(device_t self)
{
	struct xhci_softc *sc = device_get_softc(self);
	int count, err, rid;
	uint8_t usedma32;

	rid = PCI_XHCI_CBMEM;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map memory\n");
		return (ENOMEM);
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	switch (pci_get_devid(self)) {
	case 0x01941033:	/* NEC uPD720200 USB 3.0 controller */
		/* Don't use 64-bit DMA on these controllers. */
		usedma32 = 1;
		break;
	case 0x0f358086:	/* BayTrail */
	case 0x9c318086:	/* Panther Point */
	case 0x1e318086:	/* Panther Point */
	case 0x8c318086:	/* Lynx Point */
	case 0x8cb18086:	/* Wildcat Point */
		/*
		 * On Intel chipsets, reroute ports from EHCI to XHCI
		 * controller and use a different IMOD value.
		 */
		sc->sc_port_route = &xhci_pci_port_route;
		sc->sc_imod_default = XHCI_IMOD_DEFAULT_LP;
		/* FALLTHROUGH */
	default:
		usedma32 = 0;
		break;
	}

	if (xhci_init(sc, self, usedma32)) {
		device_printf(self, "Could not initialize softc\n");
		bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM,
		    sc->sc_io_res);
		return (ENXIO);
	}

	pci_enable_busmaster(self);

	usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_mtx, 0);

	rid = 0;
	if (xhci_use_msi) {
		count = 1;
		if (pci_alloc_msi(self, &count) == 0) {
			if (bootverbose)
				device_printf(self, "MSI enabled\n");
			rid = 1;
		}
	}
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_ACTIVE | (rid != 0 ? 0 : RF_SHAREABLE));
	if (sc->sc_irq_res == NULL) {
		pci_release_msi(self);
		device_printf(self, "Could not allocate IRQ\n");
		/* goto error; FALLTHROUGH - use polling */
	}
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (sc->sc_bus.bdev == NULL) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	sprintf(sc->sc_vendor, "0x%04x", pci_get_vendor(self));

	if (sc->sc_irq_res != NULL) {
		err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
		    NULL, (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl);
		if (err != 0) {
			bus_release_resource(self, SYS_RES_IRQ,
			    rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
			sc->sc_irq_res = NULL;
			pci_release_msi(self);
			device_printf(self, "Could not setup IRQ, err=%d\n", err);
			sc->sc_intr_hdl = NULL;
		}
	}
	if (sc->sc_irq_res == NULL || sc->sc_intr_hdl == NULL) {
		if (xhci_use_polling() != 0) {
			device_printf(self, "Interrupt polling at %dHz\n", hz);
			USB_BUS_LOCK(&sc->sc_bus);
			xhci_interrupt_poll(sc);
			USB_BUS_UNLOCK(&sc->sc_bus);
		} else
			goto error;
	}

	xhci_pci_take_controller(self);

	err = xhci_halt_controller(sc);

	if (err == 0)
		err = xhci_start_controller(sc);

	if (err == 0)
		err = device_probe_and_attach(sc->sc_bus.bdev);

	if (err) {
		device_printf(self, "XHCI halt/start/probe failed err=%d\n", err);
		goto error;
	}
	return (0);

error:
	xhci_pci_detach(self);
	return (ENXIO);
}
예제 #9
0
/*
 * nVidia chipset support functions
 */
static int
ata_nvidia_probe(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);
    static const struct ata_chip_id ids[] =
    {{ ATA_NFORCE1,         0, 0,       0, ATA_UDMA5, "nForce" },
     { ATA_NFORCE2,         0, 0,       0, ATA_UDMA6, "nForce2" },
     { ATA_NFORCE2_PRO,     0, 0,       0, ATA_UDMA6, "nForce2 Pro" },
     { ATA_NFORCE2_PRO_S1,  0, 0,       0, ATA_SA150, "nForce2 Pro" },
     { ATA_NFORCE3,         0, 0,       0, ATA_UDMA6, "nForce3" },
     { ATA_NFORCE3_PRO,     0, 0,       0, ATA_UDMA6, "nForce3 Pro" },
     { ATA_NFORCE3_PRO_S1,  0, 0,       0, ATA_SA150, "nForce3 Pro" },
     { ATA_NFORCE3_PRO_S2,  0, 0,       0, ATA_SA150, "nForce3 Pro" },
     { ATA_NFORCE_MCP04,    0, 0,       0, ATA_UDMA6, "nForce MCP" },
     { ATA_NFORCE_MCP04_S1, 0, NV4,     0, ATA_SA150, "nForce MCP" },
     { ATA_NFORCE_MCP04_S2, 0, NV4,     0, ATA_SA150, "nForce MCP" },
     { ATA_NFORCE_CK804,    0, 0,       0, ATA_UDMA6, "nForce CK804" },
     { ATA_NFORCE_CK804_S1, 0, NV4,     0, ATA_SA300, "nForce CK804" },
     { ATA_NFORCE_CK804_S2, 0, NV4,     0, ATA_SA300, "nForce CK804" },
     { ATA_NFORCE_MCP51,    0, 0,       0, ATA_UDMA6, "nForce MCP51" },
     { ATA_NFORCE_MCP51_S1, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP51" },
     { ATA_NFORCE_MCP51_S2, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP51" },
     { ATA_NFORCE_MCP55,    0, 0,       0, ATA_UDMA6, "nForce MCP55" },
     { ATA_NFORCE_MCP55_S1, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP55" },
     { ATA_NFORCE_MCP55_S2, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP55" },
     { ATA_NFORCE_MCP61,    0, 0,       0, ATA_UDMA6, "nForce MCP61" },
     { ATA_NFORCE_MCP61_S1, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP61" },
     { ATA_NFORCE_MCP61_S2, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP61" },
     { ATA_NFORCE_MCP61_S3, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP61" },
     { ATA_NFORCE_MCP65,    0, 0,       0, ATA_UDMA6, "nForce MCP65" },
     { ATA_NFORCE_MCP65_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
     { ATA_NFORCE_MCP65_A1, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
     { ATA_NFORCE_MCP65_A2, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
     { ATA_NFORCE_MCP65_A3, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
     { ATA_NFORCE_MCP65_A4, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
     { ATA_NFORCE_MCP65_A5, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
     { ATA_NFORCE_MCP65_A6, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
     { ATA_NFORCE_MCP65_A7, 0, NVAHCI,  0, ATA_SA300, "nForce MCP65" },
     { ATA_NFORCE_MCP67,    0, 0,       0, ATA_UDMA6, "nForce MCP67" },
     { ATA_NFORCE_MCP67_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_A1, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_A2, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_A3, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_A4, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_A5, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_A6, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_A7, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_A8, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_A9, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_AA, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_AB, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP67_AC, 0, NVAHCI,  0, ATA_SA300, "nForce MCP67" },
     { ATA_NFORCE_MCP73,    0, 0,       0, ATA_UDMA6, "nForce MCP73" },
     { ATA_NFORCE_MCP73_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_A1, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_A2, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_A3, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_A4, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_A5, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_A6, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_A7, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_A8, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_A9, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_AA, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP73_AB, 0, NVAHCI,  0, ATA_SA300, "nForce MCP73" },
     { ATA_NFORCE_MCP77,    0, 0,       0, ATA_UDMA6, "nForce MCP77" },
     { ATA_NFORCE_MCP77_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_A1, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_A2, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_A3, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_A4, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_A5, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_A6, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_A7, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_A8, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_A9, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_AA, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP77_AB, 0, NVAHCI,  0, ATA_SA300, "nForce MCP77" },
     { ATA_NFORCE_MCP79_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_A1, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_A2, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_A3, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_A4, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_A5, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_A6, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_A7, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_A8, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_A9, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_AA, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP79_AB, 0, NVAHCI,  0, ATA_SA300, "nForce MCP79" },
     { ATA_NFORCE_MCP89_A0, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_A1, 0, NVAHCI|NVNOFORCE, 0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_A2, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_A3, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_A4, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_A5, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_A6, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_A7, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_A8, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_A9, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_AA, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { ATA_NFORCE_MCP89_AB, 0, NVAHCI,  0, ATA_SA300, "nForce MCP89" },
     { 0, 0, 0, 0, 0, 0}} ;

    if (pci_get_vendor(dev) != ATA_NVIDIA_ID)
	return ENXIO;

    if (!(ctlr->chip = ata_match_chip(dev, ids)))
	return ENXIO;

    ata_set_desc(dev);
    if ((ctlr->chip->cfg1 & NVAHCI) &&
	((force_ahci == 1 && (ctlr->chip->cfg1 & NVNOFORCE) == 0) ||
	 pci_get_subclass(dev) != PCIS_STORAGE_IDE))
	ctlr->chipinit = ata_ahci_chipinit;
    else
	ctlr->chipinit = ata_nvidia_chipinit;
    return (BUS_PROBE_DEFAULT);
}
예제 #10
0
파일: ql_ioctl.c 프로젝트: Alkzndr/freebsd
static int
ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
	struct thread *td)
{
        qla_host_t *ha;
        int rval = 0;
	device_t pci_dev;
	struct ifnet *ifp;

	q80_offchip_mem_val_t val;
	qla_rd_pci_ids_t *pci_ids;
	qla_rd_fw_dump_t *fw_dump;
        union {
		qla_reg_val_t *rv;
	        qla_rd_flash_t *rdf;
		qla_wr_flash_t *wrf;
		qla_erase_flash_t *erf;
		qla_offchip_mem_val_t *mem;
	} u;


        if ((ha = (qla_host_t *)dev->si_drv1) == NULL)
                return ENXIO;

	pci_dev= ha->pci_dev;

        switch(cmd) {

        case QLA_RDWR_REG:

                u.rv = (qla_reg_val_t *)data;

                if (u.rv->direct) {
                        if (u.rv->rd) {
                                u.rv->val = READ_REG32(ha, u.rv->reg);
                        } else {
                                WRITE_REG32(ha, u.rv->reg, u.rv->val);
                        }
                } else {
                        if ((rval = ql_rdwr_indreg32(ha, u.rv->reg, &u.rv->val,
                                u.rv->rd)))
                                rval = ENXIO;
                }
                break;

        case QLA_RD_FLASH:

		if (!ha->hw.flags.fdt_valid) {
			rval = EIO;
			break;
		}	

                u.rdf = (qla_rd_flash_t *)data;
                if ((rval = ql_rd_flash32(ha, u.rdf->off, &u.rdf->data)))
                        rval = ENXIO;
                break;

	case QLA_WR_FLASH:

		ifp = ha->ifp;

		if (ifp == NULL) {
			rval = ENXIO;
			break;
		}

		if (ifp->if_drv_flags & (IFF_DRV_OACTIVE | IFF_DRV_RUNNING)) {
			rval = ENXIO;
			break;
		}

		if (!ha->hw.flags.fdt_valid) {
			rval = EIO;
			break;
		}	

		u.wrf = (qla_wr_flash_t *)data;
		if ((rval = ql_wr_flash_buffer(ha, u.wrf->off, u.wrf->size,
			u.wrf->buffer))) {
			printf("flash write failed[%d]\n", rval);
			rval = ENXIO;
		}
		break;

	case QLA_ERASE_FLASH:

		ifp = ha->ifp;

		if (ifp == NULL) {
			rval = ENXIO;
			break;
		}

		if (ifp->if_drv_flags & (IFF_DRV_OACTIVE | IFF_DRV_RUNNING)) {
			rval = ENXIO;
			break;
		}

		if (!ha->hw.flags.fdt_valid) {
			rval = EIO;
			break;
		}	
		
		u.erf = (qla_erase_flash_t *)data;
		if ((rval = ql_erase_flash(ha, u.erf->off, 
			u.erf->size))) {
			printf("flash erase failed[%d]\n", rval);
			rval = ENXIO;
		}
		break;

	case QLA_RDWR_MS_MEM:
		u.mem = (qla_offchip_mem_val_t *)data;

		if ((rval = ql_rdwr_offchip_mem(ha, u.mem->off, &val, 
			u.mem->rd)))
			rval = ENXIO;
		else {
			u.mem->data_lo = val.data_lo;
			u.mem->data_hi = val.data_hi;
			u.mem->data_ulo = val.data_ulo;
			u.mem->data_uhi = val.data_uhi;
		}

		break;

	case QLA_RD_FW_DUMP_SIZE:

		if (ha->hw.mdump_init == 0) {
			rval = EINVAL;
			break;
		}
		
		fw_dump = (qla_rd_fw_dump_t *)data;
		fw_dump->template_size = ha->hw.dma_buf.minidump.size;
		fw_dump->pci_func = ha->pci_func;

		break;

	case QLA_RD_FW_DUMP:

		if (ha->hw.mdump_init == 0) {
			rval = EINVAL;
			break;
		}
		
		fw_dump = (qla_rd_fw_dump_t *)data;

		if ((fw_dump->md_template == NULL) ||
			(fw_dump->template_size != ha->hw.dma_buf.minidump.size)) {
			rval = EINVAL;
			break;
		}

		if ((rval = copyout(ha->hw.dma_buf.minidump.dma_b,
			fw_dump->md_template, fw_dump->template_size)))
			rval = ENXIO;
		break;

	case QLA_RD_PCI_IDS:
		pci_ids = (qla_rd_pci_ids_t *)data;
		pci_ids->ven_id = pci_get_vendor(pci_dev);
		pci_ids->dev_id = pci_get_device(pci_dev);
		pci_ids->subsys_ven_id = pci_get_subvendor(pci_dev);
		pci_ids->subsys_dev_id = pci_get_subdevice(pci_dev);
		pci_ids->rev_id = pci_read_config(pci_dev, PCIR_REVID, 1);
		break;

        default:
                break;
        }

        return rval;
}
예제 #11
0
static void
ichss_identify(driver_t *driver, device_t parent)
{
	device_t child;
	uint32_t pmbase;

	if (resource_disabled("ichss", 0))
		return;

	/*
	 * It appears that ICH SpeedStep only requires a single CPU to
	 * set the value (since the chipset is shared by all CPUs.)
	 * Thus, we only add a child to cpu 0.
	 */
	if (device_get_unit(parent) != 0)
		return;

	/* Avoid duplicates. */
	if (device_find_child(parent, "ichss", -1))
		return;

	/*
	 * ICH2/3/4-M I/O Controller Hub is at bus 0, slot 1F, function 0.
	 * E.g. see Section 6.1 "PCI Devices and Functions" and table 6.1 of
	 * Intel(r) 82801BA I/O Controller Hub 2 (ICH2) and Intel(r) 82801BAM
	 * I/O Controller Hub 2 Mobile (ICH2-M).
	 */
	ich_device = pci_find_bsf(0, 0x1f, 0);
	if (ich_device == NULL ||
	    pci_get_vendor(ich_device) != PCI_VENDOR_INTEL ||
	    (pci_get_device(ich_device) != PCI_DEV_82801BA &&
	    pci_get_device(ich_device) != PCI_DEV_82801CA &&
	    pci_get_device(ich_device) != PCI_DEV_82801DB))
		return;

	/*
	 * Certain systems with ICH2 and an Intel 82815_MC host bridge
	 * where the host bridge's revision is < 5 lockup if SpeedStep
	 * is used.
	 */
	if (pci_get_device(ich_device) == PCI_DEV_82801BA) {
		device_t hostb;

		hostb = pci_find_bsf(0, 0, 0);
		if (hostb != NULL &&
		    pci_get_vendor(hostb) == PCI_VENDOR_INTEL &&
		    pci_get_device(hostb) == PCI_DEV_82815_MC &&
		    pci_get_revid(hostb) < 5)
			return;
	}

	/* Find the PMBASE register from our PCI config header. */
	pmbase = pci_read_config(ich_device, ICHSS_PMBASE_OFFSET,
	    sizeof(pmbase));
	if ((pmbase & ICHSS_IO_REG) == 0) {
		printf("ichss: invalid PMBASE memory type\n");
		return;
	}
	pmbase &= ICHSS_PMBASE_MASK;
	if (pmbase == 0) {
		printf("ichss: invalid zero PMBASE address\n");
		return;
	}
	DPRINT("ichss: PMBASE is %#x\n", pmbase);

	child = BUS_ADD_CHILD(parent, 20, "ichss", 0);
	if (child == NULL) {
		device_printf(parent, "add SpeedStep child failed\n");
		return;
	}

	/* Add the bus master arbitration and control registers. */
	bus_set_resource(child, SYS_RES_IOPORT, 0, pmbase + ICHSS_BM_OFFSET,
	    1);
	bus_set_resource(child, SYS_RES_IOPORT, 1, pmbase + ICHSS_CTRL_OFFSET,
	    1);
}
예제 #12
0
static int
ad_attach(device_t dev)
{
    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
    struct ata_device *atadev = device_get_softc(dev);
    struct ad_softc *adp;
    device_t parent;

    /* check that we have a virgin disk to attach */
    if (device_get_ivars(dev))
	return EEXIST;

    if (!(adp = malloc(sizeof(struct ad_softc), M_AD, M_NOWAIT | M_ZERO))) {
	device_printf(dev, "out of memory\n");
	return ENOMEM;
    }
    device_set_ivars(dev, adp);

    /* get device geometry into internal structs */
    if (ad_get_geometry(dev))
	return ENXIO;

    /* set the max size if configured */
    if (ata_setmax)
	ad_set_geometry(dev);

    /* init device parameters */
    ad_init(dev);

    /* announce we are here */
    ad_describe(dev);

    /* create the disk device */
    adp->disk = disk_alloc();
    adp->disk->d_strategy = ad_strategy;
    adp->disk->d_ioctl = ad_ioctl;
    adp->disk->d_dump = ad_dump;
    adp->disk->d_name = "ad";
    adp->disk->d_drv1 = dev;
    adp->disk->d_maxsize = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS;
    if (atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48)
	adp->disk->d_maxsize = min(adp->disk->d_maxsize, 65536 * DEV_BSIZE);
    else					/* 28bit ATA command limit */
	adp->disk->d_maxsize = min(adp->disk->d_maxsize, 256 * DEV_BSIZE);
    adp->disk->d_sectorsize = DEV_BSIZE;
    adp->disk->d_mediasize = DEV_BSIZE * (off_t)adp->total_secs;
    adp->disk->d_fwsectors = adp->sectors;
    adp->disk->d_fwheads = adp->heads;
    adp->disk->d_unit = device_get_unit(dev);
    if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE)
	adp->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
    if ((atadev->param.support.command2 & ATA_SUPPORT_CFA) ||
	atadev->param.config == ATA_PROTO_CFA)
	adp->disk->d_flags |= DISKFLAG_CANDELETE;
    strlcpy(adp->disk->d_ident, atadev->param.serial,
	sizeof(adp->disk->d_ident));
    strlcpy(adp->disk->d_descr, atadev->param.model,
	sizeof(adp->disk->d_descr));
    parent = device_get_parent(ch->dev);
    if (parent != NULL && device_get_parent(parent) != NULL &&
	    (device_get_devclass(parent) ==
	     devclass_find("atapci") ||
	     device_get_devclass(device_get_parent(parent)) ==
	     devclass_find("pci"))) {
	adp->disk->d_hba_vendor = pci_get_vendor(parent);
	adp->disk->d_hba_device = pci_get_device(parent);
	adp->disk->d_hba_subvendor = pci_get_subvendor(parent);
	adp->disk->d_hba_subdevice = pci_get_subdevice(parent);
    }
    ata_disk_firmware_geom_adjust(adp->disk);
    disk_create(adp->disk, DISK_VERSION);
    device_add_child(dev, "subdisk", device_get_unit(dev));
    bus_generic_attach(dev);

    callout_init(&atadev->spindown_timer, 1);
    return 0;
}
예제 #13
0
static int
ehci_pci_attach(device_t self)
{
	ehci_softc_t *sc = device_get_softc(self);
	devclass_t dc;
	device_t parent;
	device_t *neighbors;
	device_t *nbus;
	struct usbd_bus *bsc;
	int err;
	int rid;
	int ncomp;
	int count, buscount;
	int slot, function;
	int res;
	int i;

	switch(pci_read_config(self, PCI_USBREV, 1) & PCI_USBREV_MASK) {
	case PCI_USBREV_PRE_1_0:
	case PCI_USBREV_1_0:
	case PCI_USBREV_1_1:
		device_printf(self, "pre-2.0 USB rev\n");
		if (pci_get_devid(self) == PCI_EHCI_DEVICEID_CS5536) {
			sc->sc_bus.usbrev = USBREV_2_0;
			device_printf(self, "Quirk for CS5536 USB 2.0 enabled\n");
			break;
		}
		sc->sc_bus.usbrev = USBREV_UNKNOWN;
		return ENXIO;
	case PCI_USBREV_2_0:
		sc->sc_bus.usbrev = USBREV_2_0;
		break;
	default:
		sc->sc_bus.usbrev = USBREV_UNKNOWN;
		break;
	}

	pci_enable_busmaster(self);

	rid = PCI_CBMEM;
	sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->io_res) {
		device_printf(self, "Could not map memory\n");
		return ENXIO;
	}
	sc->iot = rman_get_bustag(sc->io_res);
	sc->ioh = rman_get_bushandle(sc->io_res);

	rid = 0;
	sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		ehci_pci_detach(self);
		return ENXIO;
	}
	sc->sc_bus.bdev = device_add_child(self, "usb", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		ehci_pci_detach(self);
		return ENOMEM;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	/* ehci_pci_match will never return NULL if ehci_pci_probe succeeded */
	device_set_desc(sc->sc_bus.bdev, ehci_pci_match(self));
	switch (pci_get_vendor(self)) {
	case PCI_EHCI_VENDORID_ACERLABS:
		sprintf(sc->sc_vendor, "AcerLabs");
		break;
	case PCI_EHCI_VENDORID_AMD:
		sprintf(sc->sc_vendor, "AMD");
		break;
	case PCI_EHCI_VENDORID_APPLE:
		sprintf(sc->sc_vendor, "Apple");
		break;
	case PCI_EHCI_VENDORID_ATI:
		sprintf(sc->sc_vendor, "ATI");
		break;
	case PCI_EHCI_VENDORID_CMDTECH:
		sprintf(sc->sc_vendor, "CMDTECH");
		break;
	case PCI_EHCI_VENDORID_INTEL:
		sprintf(sc->sc_vendor, "Intel");
		break;
	case PCI_EHCI_VENDORID_NEC:
		sprintf(sc->sc_vendor, "NEC");
		break;
	case PCI_EHCI_VENDORID_OPTI:
		sprintf(sc->sc_vendor, "OPTi");
		break;
	case PCI_EHCI_VENDORID_SIS:
		sprintf(sc->sc_vendor, "SiS");
		break;
	case PCI_EHCI_VENDORID_NVIDIA:
	case PCI_EHCI_VENDORID_NVIDIA2:
		sprintf(sc->sc_vendor, "nVidia");
		break;
	case PCI_EHCI_VENDORID_VIA:
		sprintf(sc->sc_vendor, "VIA");
		break;
	default:
		if (bootverbose)
			device_printf(self, "(New EHCI DeviceId=0x%08x)\n",
			    pci_get_devid(self));
		sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
	}

	err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
	    NULL, (driver_intr_t *)ehci_intr, sc, &sc->ih);
	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->ih = NULL;
		ehci_pci_detach(self);
		return ENXIO;
	}

	/* Enable workaround for dropped interrupts as required */
	switch (pci_get_vendor(self)) {
	case PCI_EHCI_VENDORID_ATI:
	case PCI_EHCI_VENDORID_VIA:
		sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG;
		if (bootverbose)
			device_printf(self,
			    "Dropped interrupts workaround enabled\n");
		break;
	default:
		break;
	}

	/*
	 * Find companion controllers.  According to the spec they always
	 * have lower function numbers so they should be enumerated already.
	 */
	parent = device_get_parent(self);
	res = device_get_children(parent, &neighbors, &count);
	if (res != 0) {
		device_printf(self, "Error finding companion busses\n");
		ehci_pci_detach(self);
		return ENXIO;
	}
	ncomp = 0;
	dc = devclass_find("usb");
	slot = pci_get_slot(self);
	function = pci_get_function(self);
	for (i = 0; i < count; i++) {
		if (pci_get_slot(neighbors[i]) == slot && \
			pci_get_function(neighbors[i]) < function) {
			res = device_get_children(neighbors[i],
				&nbus, &buscount);
			if (res != 0)
				continue;
			if (buscount != 1) {
				free(nbus, M_TEMP);
				continue;
			}
			if (device_get_devclass(nbus[0]) != dc) {
				free(nbus, M_TEMP);
				continue;
			}
			bsc = device_get_softc(nbus[0]);
			free(nbus, M_TEMP);
			DPRINTF(("ehci_pci_attach: companion %s\n",
			    device_get_nameunit(bsc->bdev)));
			sc->sc_comps[ncomp++] = bsc;
			if (ncomp >= EHCI_COMPANION_MAX)
				break;
		}
	}
	sc->sc_ncomp = ncomp;

	/* Allocate a parent dma tag for DMA maps */
	err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
	    BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
	    NULL, NULL, &sc->sc_bus.parent_dmatag);
	if (err) {
		device_printf(self, "Could not allocate parent DMA tag (%d)\n",
		    err);
		ehci_pci_detach(self);
		return ENXIO;
	}

	/* Allocate a dma tag for transfer buffers */
	err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
	    BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
	    busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
	if (err) {
		device_printf(self, "Could not allocate buffer DMA tag (%d)\n",
		    err);
		ehci_pci_detach(self);
		return ENXIO;
	}

	ehci_pci_takecontroller(self);
	err = ehci_init(sc);
	if (!err) {
		sc->sc_flags |= EHCI_SCFLG_DONEINIT;
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}

	if (err) {
		device_printf(self, "USB init failed err=%d\n", err);
		ehci_pci_detach(self);
		return EIO;
	}
	return 0;
}
예제 #14
0
static int
mlx_pci_attach(device_t dev)
{
    struct mlx_softc	*sc;
    int			i, error;
    u_int32_t		command;

    debug_called(1);

    /*
     * Make sure we are going to be able to talk to this board.
     */
    command = pci_read_config(dev, PCIR_COMMAND, 2);
    if ((command & PCIM_CMD_MEMEN) == 0) {
	device_printf(dev, "memory window not available\n");
	return(ENXIO);
    }
    /* force the busmaster enable bit on */
    command |= PCIM_CMD_BUSMASTEREN;
    pci_write_config(dev, PCIR_COMMAND, command, 2);

    /*
     * Initialise softc.
     */
    sc = device_get_softc(dev);
    bzero(sc, sizeof(*sc));
    sc->mlx_dev = dev;

    /*
     * Work out what sort of adapter this is (we need to know this in order
     * to map the appropriate interface resources).
     */
    sc->mlx_iftype = 0;
    for (i = 0; mlx_identifiers[i].vendor != 0; i++) {
	if ((mlx_identifiers[i].vendor == pci_get_vendor(dev)) &&
	    (mlx_identifiers[i].device == pci_get_device(dev))) {
	    sc->mlx_iftype = mlx_identifiers[i].iftype;
	    break;
	}
    }
    if (sc->mlx_iftype == 0)		/* shouldn't happen */
	return(ENXIO);
    
    /*
     * Allocate the PCI register window.
     */
    
    /* type 2/3 adapters have an I/O region we don't prefer at base 0 */
    switch(sc->mlx_iftype) {
    case MLX_IFTYPE_2:
    case MLX_IFTYPE_3:
	sc->mlx_mem_type = SYS_RES_MEMORY;
	sc->mlx_mem_rid = MLX_CFG_BASE1;
	sc->mlx_mem = bus_alloc_resource_any(dev, sc->mlx_mem_type,
		&sc->mlx_mem_rid, RF_ACTIVE);
	if (sc->mlx_mem == NULL) {
	    sc->mlx_mem_type = SYS_RES_IOPORT;
	    sc->mlx_mem_rid = MLX_CFG_BASE0;
	    sc->mlx_mem = bus_alloc_resource_any(dev, sc->mlx_mem_type,
		&sc->mlx_mem_rid, RF_ACTIVE);
	}
	break;
    case MLX_IFTYPE_4:
    case MLX_IFTYPE_5:
	sc->mlx_mem_type = SYS_RES_MEMORY;
	sc->mlx_mem_rid = MLX_CFG_BASE0;
	sc->mlx_mem = bus_alloc_resource_any(dev, sc->mlx_mem_type,
		&sc->mlx_mem_rid, RF_ACTIVE);
	break;
    }
    if (sc->mlx_mem == NULL) {
	device_printf(sc->mlx_dev, "couldn't allocate mailbox window\n");
	mlx_free(sc);
	return(ENXIO);
    }
    sc->mlx_btag = rman_get_bustag(sc->mlx_mem);
    sc->mlx_bhandle = rman_get_bushandle(sc->mlx_mem);

    /*
     * Allocate the parent bus DMA tag appropriate for PCI.
     */
    error = bus_dma_tag_create(NULL, 			/* parent */
			       1, 0, 			/* alignment, boundary */
			       BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
			       BUS_SPACE_MAXADDR, 	/* highaddr */
			       NULL, NULL, 		/* filter, filterarg */
			       MAXBSIZE, MLX_NSEG,	/* maxsize, nsegments */
			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
			       BUS_DMA_ALLOCNOW,	/* flags */
			       NULL,			/* lockfunc */
			       NULL,			/* lockarg */
			       &sc->mlx_parent_dmat);
    if (error != 0) {
	device_printf(dev, "can't allocate parent DMA tag\n");
	mlx_free(sc);
	return(ENOMEM);
    }

    /*
     * Do bus-independant initialisation.
     */
    error = mlx_attach(sc);
    if (error != 0) {
	mlx_free(sc);
	return(error);
    }
    
    /*
     * Start the controller.
     */
    mlx_startup(sc);
    return(0);
}
예제 #15
0
static int
tdfx_attach(device_t dev) { 
	/*
	 * The attach routine is called after the probe routine successfully says it
	 * supports a given card. We now proceed to initialize this card for use with
	 * the system. I want to map the device memory for userland allocation and
	 * fill an information structure with information on this card. I'd also like
	 * to set Write Combining with the MTRR code so that we can hopefully speed
	 * up memory writes. The last thing is to register the character device
	 * interface to the card, so we can open it from /dev/3dfxN, where N is a
	 * small, whole number.
	 */
	struct tdfx_softc *tdfx_info;
	u_long	val;
	/* rid value tells bus_alloc_resource where to find the addresses of ports or
	 * of memory ranges in the PCI config space*/
	int rid = PCIR_BAR(0);

	/* Increment the card counter (for the ioctl code) */
	tdfx_count++;

 	/* Enable MemMap on Voodoo */
	val = pci_read_config(dev, PCIR_COMMAND, 2);
	val |= (PCIM_CMD_MEMEN);
	pci_write_config(dev, PCIR_COMMAND, val, 2);
	val = pci_read_config(dev, PCIR_COMMAND, 2);
	
	/* Fill the soft config struct with info about this device*/
	tdfx_info = device_get_softc(dev);
	tdfx_info->dev = dev;
	tdfx_info->vendor = pci_get_vendor(dev);
	tdfx_info->type = pci_get_devid(dev) >> 16;
	tdfx_info->bus = pci_get_bus(dev);
	tdfx_info->dv = pci_get_slot(dev);
	tdfx_info->curFile = NULL;

	/* 
	 *	Get the Memory Location from the PCI Config, mask out lower word, since
	 * the config space register is only one word long (this is nicer than a
	 * bitshift).
	 */
	tdfx_info->addr0 = (pci_read_config(dev, 0x10, 4) & 0xffff0000);
#ifdef DEBUG
	device_printf(dev, "Base0 @ 0x%x\n", tdfx_info->addr0);
#endif
	/* Notify the VM that we will be mapping some memory later */
	tdfx_info->memrange = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
		&rid, RF_ACTIVE | RF_SHAREABLE);
	if(tdfx_info->memrange == NULL) {
#ifdef DEBUG
		device_printf(dev, "Error mapping mem, won't be able to use mmap()\n");
#endif
		tdfx_info->memrid = 0;
	}
	else {
		tdfx_info->memrid = rid;
#ifdef DEBUG
		device_printf(dev, "Mapped to: 0x%x\n", 
				(unsigned int)rman_get_start(tdfx_info->memrange));
#endif
	}

	/* Setup for Voodoo3 and Banshee, PIO and an extram Memrange */
	if(pci_get_devid(dev) == PCI_DEVICE_3DFX_VOODOO3 ||
		pci_get_devid(dev) == PCI_DEVICE_3DFX_BANSHEE) {
		rid = 0x14;	/* 2nd mem map */
		tdfx_info->addr1 = (pci_read_config(dev, 0x14, 4) & 0xffff0000);
#ifdef DEBUG
		device_printf(dev, "Base1 @ 0x%x\n", tdfx_info->addr1);
#endif
		tdfx_info->memrange2 = bus_alloc_resource_any(dev,
			SYS_RES_MEMORY, &rid, RF_ACTIVE | RF_SHAREABLE);
		if(tdfx_info->memrange2 == NULL) {
#ifdef DEBUG
			device_printf(dev, "Mem1 couldn't be allocated, glide may not work.");
#endif
			tdfx_info->memrid2 = 0;
		}
		else {
			tdfx_info->memrid2 = rid;
		}
		/* Now to map the PIO stuff */
		rid = PCIR_IOBASE0_2;
		tdfx_info->pio0 = pci_read_config(dev, 0x2c, 2);
		tdfx_info->pio0max = pci_read_config(dev, 0x30, 2) + tdfx_info->pio0;
		tdfx_info->piorange = bus_alloc_resource_any(dev,
			SYS_RES_IOPORT, &rid, RF_ACTIVE | RF_SHAREABLE);
		if(tdfx_info->piorange == NULL) {
#ifdef DEBUG
			device_printf(dev, "Couldn't map PIO range.");
#endif
			tdfx_info->piorid = 0;
		}
		else {
			tdfx_info->piorid = rid;
		}
	} else {
	  tdfx_info->addr1 = 0;
	  tdfx_info->memrange2 = NULL;
	  tdfx_info->piorange = NULL;
	}

	/* 
	 *	Set Writecombining, or at least Uncacheable for the memory region, if we
	 * are able to
	 */

	if(tdfx_setmtrr(dev) != 0) {
#ifdef DEBUG
		device_printf(dev, "Some weird error setting MTRRs");
#endif
		return -1;
	}

	/* 
	 * make_dev registers the cdev to access the 3dfx card from /dev
	 *	use hex here for the dev num, simply to provide better support if > 10
	 * voodoo cards, for the mad. The user must set the link, or use MAKEDEV.
	 * Why would we want that many voodoo cards anyhow? 
	 */
	tdfx_info->devt = make_dev(&tdfx_cdev, device_get_unit(dev),
		UID_ROOT, GID_WHEEL, 0600, "3dfx%x", device_get_unit(dev));
	tdfx_info->devt->si_drv1 = tdfx_info;
	
	return 0;
}
예제 #16
0
static int
xhci_pci_attach(device_t self)
{
	struct xhci_softc *sc = device_get_softc(self);
	int count, err, rid;

	/* XXX check for 64-bit capability */

	if (xhci_init(sc, self)) {
		device_printf(self, "Could not initialize softc\n");
		goto error;
	}

	pci_enable_busmaster(self);

	rid = PCI_XHCI_CBMEM;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map memory\n");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_mtx, 0);

	sc->sc_irq_rid = 0;
	if (xhci_use_msi) {
		count = pci_msi_count(self);
		if (count >= 1) {
			count = 1;
			if (pci_alloc_msi(self, &count) == 0) {
				if (bootverbose)
					device_printf(self, "MSI enabled\n");
				sc->sc_irq_rid = 1;
			}
		}
	}
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ,
	    &sc->sc_irq_rid, RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(self, "Could not allocate IRQ\n");
		/* goto error; FALLTHROUGH - use polling */
	}
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (sc->sc_bus.bdev == NULL) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	sprintf(sc->sc_vendor, "0x%04x", pci_get_vendor(self));

	if (sc->sc_irq_res != NULL) {
		err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
		    NULL, (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl);
		if (err != 0) {
			device_printf(self, "Could not setup IRQ, err=%d\n", err);
			sc->sc_intr_hdl = NULL;
		}
	}
	if (sc->sc_irq_res == NULL || sc->sc_intr_hdl == NULL ||
	    xhci_use_polling() != 0) {
		device_printf(self, "Interrupt polling at %dHz\n", hz);
		USB_BUS_LOCK(&sc->sc_bus);
		xhci_interrupt_poll(sc);
		USB_BUS_UNLOCK(&sc->sc_bus);
	}

	/* On Intel chipsets reroute ports from EHCI to XHCI controller. */
	switch (pci_get_devid(self)) {
	case 0x9c318086:	/* Panther Point */
	case 0x1e318086:	/* Panther Point */
	case 0x8c318086:	/* Lynx Point */
		sc->sc_port_route = &xhci_pci_port_route;
		sc->sc_imod_default = XHCI_IMOD_DEFAULT_LP;
		break;
	default:
		break;
	}

	xhci_pci_take_controller(self);

	err = xhci_halt_controller(sc);

	if (err == 0)
		err = xhci_start_controller(sc);

	if (err == 0)
		err = device_probe_and_attach(sc->sc_bus.bdev);

	if (err) {
		device_printf(self, "XHCI halt/start/probe failed err=%d\n", err);
		goto error;
	}
	return (0);

error:
	xhci_pci_detach(self);
	return (ENXIO);
}
예제 #17
0
/*main(int argc, char *argv[])*/
int pci_scan(pciinfo_t *pci_list,unsigned *num_pci)
{
    unsigned int idx = 0;
    struct pci_config_reg pcr;
    int do_mode1_scan = 0;
#if !defined(__alpha__) && !defined(__powerpc__)
    int do_mode2_scan = 0;
#endif
    int func, hostbridges=0;
    int ret = -1;

    pci_lst = pci_list;
    *num_pci = 0;

    ret = enable_os_io();
    if (ret != 0)
        return ret;

    if((pcr._configtype = pci_config_type()) == 0xFFFF) return ENODEV;

    /* Try pci config 1 probe first */

    if ((pcr._configtype == 1) || do_mode1_scan) {
        /*printf("\nPCI probing configuration type 1\n");*/

        pcr._ioaddr = 0xFFFF;

        pcr._pcibuses[0] = 0;
        pcr._pcinumbus = 1;
        pcr._pcibusidx = 0;

        do {
            /*printf("Probing for devices on PCI bus %d:\n\n", pcr._pcibusidx);*/

            for (pcr._cardnum = 0x0; pcr._cardnum < MAX_PCI_DEVICES_PER_BUS;
                    pcr._cardnum += 0x1) {
                func = 0;
                do { /* loop over the different functions, if present */
                    pcr._device_vendor = pci_get_vendor(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,
                                                        func);
                    if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF))
                        break;   /* nothing there */

                    /*printf("\npci bus 0x%x cardnum 0x%02x function 0x%04x: vendor 0x%04x device 0x%04x\n",
                        pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, func,
                    pcr._vendor, pcr._device);*/
                    pcibus = pcr._pcibuses[pcr._pcibusidx];
                    pcicard = pcr._cardnum;
                    pcifunc = func;

                    pcr._status_command = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                          pcr._cardnum,func,PCI_CMD_STAT_REG);
                    pcr._class_revision = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                          pcr._cardnum,func,PCI_CLASS_REG);
                    pcr._bist_header_latency_cache = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                                     pcr._cardnum,func,PCI_HEADER_MISC);
                    pcr._base0 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                                      pcr._cardnum,func,PCI_MAP_REG_START);
                    pcr._base1 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                                      pcr._cardnum,func,PCI_MAP_REG_START+4);
                    pcr._base2 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                                      pcr._cardnum,func,PCI_MAP_REG_START+8);
                    pcr._base3 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                                      pcr._cardnum,func,PCI_MAP_REG_START+0x0C);
                    pcr._base4 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                                      pcr._cardnum,func,PCI_MAP_REG_START+0x10);
                    pcr._base5 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                                      pcr._cardnum,func,PCI_MAP_REG_START+0x14);
                    pcr._baserom = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                                        pcr._cardnum,func,PCI_MAP_ROM_REG);
                    pcr._max_min_ipin_iline = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                              pcr._cardnum,func,PCI_INTERRUPT_REG);
                    pcr._user_config = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx],
                                                            pcr._cardnum,func,PCI_REG_USERCONFIG);
                    /* check for pci-pci bridges */
#define PCI_CLASS_MASK 		0xff000000
#define PCI_SUBCLASS_MASK 	0x00ff0000
#define PCI_CLASS_BRIDGE 	0x06000000
#define PCI_SUBCLASS_BRIDGE_PCI	0x00040000
                    switch(pcr._class_revision & (PCI_CLASS_MASK|PCI_SUBCLASS_MASK)) {
                    case PCI_CLASS_BRIDGE|PCI_SUBCLASS_BRIDGE_PCI:
                        if (pcr._secondary_bus_number > 0) {
                            pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number;
                        }
                        break;
                    case PCI_CLASS_BRIDGE:
                        if ( ++hostbridges > 1) {
                            pcr._pcibuses[pcr._pcinumbus] = pcr._pcinumbus;
                            pcr._pcinumbus++;
                        }
                        break;
                    default:
                        break;
                    }
                    if((func==0) && ((pcr._header_type & PCI_MULTIFUNC_DEV) == 0)) {
                        /* not a multi function device */
                        func = 8;
                    } else {
                        func++;
                    }

                    if (idx++ >= MAX_PCI_DEVICES)
                        continue;

                    identify_card(&pcr, (*num_pci)++);
                } while( func < 8 );
            }
        } while (++pcr._pcibusidx < pcr._pcinumbus);
    }

#if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sh__)
    /* Now try pci config 2 probe (deprecated) */

    if ((pcr._configtype == 2) || do_mode2_scan) {
        outb(PCI_MODE2_ENABLE_REG, 0xF1);
        outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */

        /*printf("\nPCI probing configuration type 2\n");*/

        pcr._pcibuses[0] = 0;
        pcr._pcinumbus = 1;
        pcr._pcibusidx = 0;
        idx = 0;

        do {
            for (pcr._ioaddr = 0xC000; pcr._ioaddr < 0xD000; pcr._ioaddr += 0x0100) {
                outb(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */
                pcr._device_vendor = inl(pcr._ioaddr);
                outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */

                if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF))
                    continue;
                if ((pcr._vendor == 0xF0F0) || (pcr._device == 0xF0F0))
                    continue;  /* catch ASUS P55TP4XE motherboards */

                /*printf("\npci bus 0x%x slot at 0x%04x, vendor 0x%04x device 0x%04x\n",
                    pcr._pcibuses[pcr._pcibusidx], pcr._ioaddr, pcr._vendor,
                        pcr._device);*/
                pcibus = pcr._pcibuses[pcr._pcibusidx] ;
                pcicard = pcr._ioaddr ;
                pcifunc = 0 ;

                outb(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */
                pcr._status_command = inl(pcr._ioaddr + 0x04);
                pcr._class_revision = inl(pcr._ioaddr + 0x08);
                pcr._bist_header_latency_cache = inl(pcr._ioaddr + 0x0C);
                pcr._base0 = inl(pcr._ioaddr + 0x10);
                pcr._base1 = inl(pcr._ioaddr + 0x14);
                pcr._base2 = inl(pcr._ioaddr + 0x18);
                pcr._base3 = inl(pcr._ioaddr + 0x1C);
                pcr._base4 = inl(pcr._ioaddr + 0x20);
                pcr._base5 = inl(pcr._ioaddr + 0x24);
                pcr._baserom = inl(pcr._ioaddr + 0x30);
                pcr._max_min_ipin_iline = inl(pcr._ioaddr + 0x3C);
                pcr._user_config = inl(pcr._ioaddr + 0x40);
                outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */

                /* check for pci-pci bridges (currently we only know Digital) */
                if ((pcr._vendor == 0x1011) && (pcr._device == 0x0001))
                    if (pcr._secondary_bus_number > 0)
                        pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number;

                if (idx++ >= MAX_PCI_DEVICES)
                    continue;

                identify_card(&pcr, (*num_pci)++);
            }
        } while (++pcr._pcibusidx < pcr._pcinumbus);

        outb(PCI_MODE2_ENABLE_REG, 0x00);
    }

#endif /* !__alpha__ && !__powerpc__ && !__sh__ */

    disable_os_io();

    return 0 ;

}
예제 #18
0
static int
uhci_pci_attach(device_t self)
{
	uhci_softc_t *sc = device_get_softc(self);
	int rid;
	int err;

	/* initialise some bus fields */
	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = UHCI_MAX_DEVICES;
	sc->sc_bus.dma_bits = 32;

	/* get all DMA memory */
	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self),
	    &uhci_iterate_hw_softc)) {
		return ENOMEM;
	}
	sc->sc_dev = self;

	pci_enable_busmaster(self);

	rid = PCI_UHCI_BASE_REG;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_IOPORT, &rid,
	    RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map ports\n");
		goto error;
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	/* disable interrupts */
	bus_space_write_2(sc->sc_io_tag, sc->sc_io_hdl, UHCI_INTR, 0);

	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		goto error;
	}
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	/*
	 * uhci_pci_match must never return NULL if uhci_pci_probe
	 * succeeded
	 */
	device_set_desc(sc->sc_bus.bdev, uhci_pci_match(self));
	switch (pci_get_vendor(self)) {
	case PCI_UHCI_VENDORID_INTEL:
		sprintf(sc->sc_vendor, "Intel");
		break;
	case PCI_UHCI_VENDORID_HP:
		sprintf(sc->sc_vendor, "HP");
		break;
	case PCI_UHCI_VENDORID_VIA:
		sprintf(sc->sc_vendor, "VIA");
		break;
	default:
		if (bootverbose) {
			device_printf(self, "(New UHCI DeviceId=0x%08x)\n",
			    pci_get_devid(self));
		}
		sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
	}

	switch (pci_read_config(self, PCI_USBREV, 1) & PCI_USB_REV_MASK) {
	case PCI_USB_REV_PRE_1_0:
		sc->sc_bus.usbrev = USB_REV_PRE_1_0;
		break;
	case PCI_USB_REV_1_0:
		sc->sc_bus.usbrev = USB_REV_1_0;
		break;
	default:
		/* Quirk for Parallels Desktop 4.0 */
		device_printf(self, "USB revision is unknown. Assuming v1.1.\n");
		sc->sc_bus.usbrev = USB_REV_1_1;
		break;
	}

#if (__FreeBSD_version >= 700031)
	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)uhci_interrupt, sc, &sc->sc_intr_hdl);
#else
	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    (driver_intr_t *)uhci_interrupt, sc, &sc->sc_intr_hdl);
#endif

	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->sc_intr_hdl = NULL;
		goto error;
	}
	/*
	 * Set the PIRQD enable bit and switch off all the others. We don't
	 * want legacy support to interfere with us XXX Does this also mean
	 * that the BIOS won't touch the keyboard anymore if it is connected
	 * to the ports of the root hub?
	 */
#ifdef USB_DEBUG
	if (pci_read_config(self, PCI_LEGSUP, 2) != PCI_LEGSUP_USBPIRQDEN) {
		device_printf(self, "LegSup = 0x%04x\n",
		    pci_read_config(self, PCI_LEGSUP, 2));
	}
#endif
	pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);

	err = uhci_init(sc);
	if (!err) {
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}
	if (err) {
		device_printf(self, "USB init failed\n");
		goto error;
	}
	return (0);

error:
	uhci_pci_detach(self);
	return (ENXIO);
}
예제 #19
0
파일: qla_ioctl.c 프로젝트: 2asoft/freebsd
int
qla_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
        struct thread *td)
{
        qla_host_t *ha;
        int rval = 0;
        qla_reg_val_t *rv;
        qla_rd_flash_t *rdf;
	qla_wr_flash_t *wrf;
	qla_rd_pci_ids_t *pci_ids;
	device_t pci_dev;

        if ((ha = (qla_host_t *)dev->si_drv1) == NULL)
                return ENXIO;

	pci_dev= ha->pci_dev;

        switch(cmd) {

        case QLA_RDWR_REG:

                rv = (qla_reg_val_t *)data;

                if (rv->direct) {
                        if (rv->rd) {
                                rv->val = READ_OFFSET32(ha, rv->reg);
                        } else {
                                WRITE_OFFSET32(ha, rv->reg, rv->val);
                        }
                } else {
                        if ((rval = qla_rdwr_indreg32(ha, rv->reg, &rv->val,
                                rv->rd)))
                                rval = ENXIO;
                }
                break;

        case QLA_RD_FLASH:
                rdf = (qla_rd_flash_t *)data;
                if ((rval = qla_rd_flash32(ha, rdf->off, &rdf->data)))
                        rval = ENXIO;
                break;

        case QLA_WR_FLASH:
                wrf = (qla_wr_flash_t *)data;
                if ((rval = qla_wr_flash_buffer(ha, wrf->off, wrf->size,
					wrf->buffer, wrf->pattern)))
                        rval = ENXIO;
                break;


	case QLA_ERASE_FLASH:
		if (qla_erase_flash(ha, ((qla_erase_flash_t *)data)->off,
			((qla_erase_flash_t *)data)->size))
			rval = ENXIO;
		break;

	case QLA_RD_PCI_IDS:
		pci_ids = (qla_rd_pci_ids_t *)data;
		pci_ids->ven_id = pci_get_vendor(pci_dev);
		pci_ids->dev_id = pci_get_device(pci_dev);
		pci_ids->subsys_ven_id = pci_get_subvendor(pci_dev);
		pci_ids->subsys_dev_id = pci_get_subdevice(pci_dev);
		pci_ids->rev_id = pci_read_config(pci_dev, PCIR_REVID, 1);
		break;
		
        default:
                break;
        }

        return rval;
}
예제 #20
0
static int
uhci_pci_attach(device_t self)
{
	uhci_softc_t *sc = device_get_softc(self);
	int rid;
	int err;

	pci_enable_busmaster(self);

	rid = PCI_UHCI_BASE_REG;
	sc->io_res = bus_alloc_resource(self, SYS_RES_IOPORT, &rid,
	    0, ~0, 1, RF_ACTIVE);
	if (!sc->io_res) {
		device_printf(self, "Could not map ports\n");
		return ENXIO;
	}
	sc->iot = rman_get_bustag(sc->io_res);
	sc->ioh = rman_get_bushandle(sc->io_res);

	/* disable interrupts */
	bus_space_write_2(sc->iot, sc->ioh, UHCI_INTR, 0);

	rid = 0;
	sc->irq_res = bus_alloc_resource(self, SYS_RES_IRQ, &rid,
	    0, ~0, 1,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		uhci_pci_detach(self);
		return ENXIO;
	}
	sc->sc_bus.bdev = device_add_child(self, "usb", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		uhci_pci_detach(self);
		return ENOMEM;
	}
	device_set_ivars(sc->sc_bus.bdev, sc);

	/* uhci_pci_match must never return NULL if uhci_pci_probe succeeded */
	device_set_desc(sc->sc_bus.bdev, uhci_pci_match(self));
	switch (pci_get_vendor(self)) {
	case PCI_UHCI_VENDORID_INTEL:
		sprintf(sc->sc_vendor, "Intel");
		break;
	case PCI_UHCI_VENDORID_VIA:
		sprintf(sc->sc_vendor, "VIA");
		break;
	default:
		if (bootverbose)
			device_printf(self, "(New UHCI DeviceId=0x%08x)\n",
			    pci_get_devid(self));
		sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
	}

	switch (pci_read_config(self, PCI_USBREV, 1) & PCI_USBREV_MASK) {
	case PCI_USBREV_PRE_1_0:
		sc->sc_bus.usbrev = USBREV_PRE_1_0;
		break;
	case PCI_USBREV_1_0:
		sc->sc_bus.usbrev = USBREV_1_0;
		break;
	default:
		sc->sc_bus.usbrev = USBREV_UNKNOWN;
		break;
	}

	err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
	    (driver_intr_t *) uhci_intr, sc, &sc->ih);
	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->ih = NULL;
		uhci_pci_detach(self);
		return ENXIO;
	}
	/*
	 * Set the PIRQD enable bit and switch off all the others. We don't
	 * want legacy support to interfere with us XXX Does this also mean
	 * that the BIOS won't touch the keyboard anymore if it is connected
	 * to the ports of the root hub?
	 */
#ifdef USB_DEBUG
	if (pci_read_config(self, PCI_LEGSUP, 2) != PCI_LEGSUP_USBPIRQDEN)
		device_printf(self, "LegSup = 0x%04x\n",
		    pci_read_config(self, PCI_LEGSUP, 2));
#endif
	pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);

	err = uhci_init(sc);
	if (!err)
		err = device_probe_and_attach(sc->sc_bus.bdev);

	if (err) {
		device_printf(self, "USB init failed\n");
		uhci_pci_detach(self);
		return EIO;
	}
	return 0;		/* success */
}
예제 #21
0
static int hpt_attach(device_t dev)
{
	PHBA hba = (PHBA)device_get_softc(dev);
	HIM *him = hba->ldm_adapter.him;
	PCI_ID pci_id;
	HPT_UINT size;
	PVBUS vbus;
	PVBUS_EXT vbus_ext;
	
	KdPrint(("hpt_attach(%d/%d/%d)", pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev)));
	
#if __FreeBSD_version >=440000
	pci_enable_busmaster(dev);
#endif

	pci_id.vid = pci_get_vendor(dev);
	pci_id.did = pci_get_device(dev);
	pci_id.rev = pci_get_revid(dev);
	pci_id.subsys = (HPT_U32)(pci_get_subdevice(dev)) << 16 | pci_get_subvendor(dev);

	size = him->get_adapter_size(&pci_id);
	hba->ldm_adapter.him_handle = malloc(size, M_DEVBUF, M_WAITOK);
	if (!hba->ldm_adapter.him_handle)
		return ENXIO;

	hba->pcidev = dev;
	hba->pciaddr.tree = 0;
	hba->pciaddr.bus = pci_get_bus(dev);
	hba->pciaddr.device = pci_get_slot(dev);
	hba->pciaddr.function = pci_get_function(dev);

	if (!him->create_adapter(&pci_id, hba->pciaddr, hba->ldm_adapter.him_handle, hba)) {
		free(hba->ldm_adapter.him_handle, M_DEVBUF);
		return -1;
	}

	os_printk("adapter at PCI %d:%d:%d, IRQ %d",
		hba->pciaddr.bus, hba->pciaddr.device, hba->pciaddr.function, pci_get_irq(dev));

	if (!ldm_register_adapter(&hba->ldm_adapter)) {
		size = ldm_get_vbus_size();
		vbus_ext = malloc(sizeof(VBUS_EXT) + size, M_DEVBUF, M_WAITOK);
		if (!vbus_ext) {
			free(hba->ldm_adapter.him_handle, M_DEVBUF);
			return -1;
		}
		memset(vbus_ext, 0, sizeof(VBUS_EXT));
		vbus_ext->ext_type = EXT_TYPE_VBUS;
		ldm_create_vbus((PVBUS)vbus_ext->vbus, vbus_ext);
		ldm_register_adapter(&hba->ldm_adapter);
	}

	ldm_for_each_vbus(vbus, vbus_ext) {
		if (hba->ldm_adapter.vbus==vbus) {
			hba->vbus_ext = vbus_ext;
			hba->next = vbus_ext->hba_list;
			vbus_ext->hba_list = hba;
			break;
		}
	}	
	return 0;
}
예제 #22
0
파일: ata-all.c 프로젝트: 2asoft/freebsd
static void
ataaction(struct cam_sim *sim, union ccb *ccb)
{
	device_t dev, parent;
	struct ata_channel *ch;

	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ataaction func_code=%x\n",
	    ccb->ccb_h.func_code));

	ch = (struct ata_channel *)cam_sim_softc(sim);
	dev = ch->dev;
	switch (ccb->ccb_h.func_code) {
	/* Common cases first */
	case XPT_ATA_IO:	/* Execute the requested I/O operation */
	case XPT_SCSI_IO:
		if (ata_check_ids(dev, ccb))
			return;
		if ((ch->devices & ((ATA_ATA_MASTER | ATA_ATAPI_MASTER)
		    << ccb->ccb_h.target_id)) == 0) {
			ccb->ccb_h.status = CAM_SEL_TIMEOUT;
			break;
		}
		if (ch->running)
			device_printf(dev, "already running!\n");
		if (ccb->ccb_h.func_code == XPT_ATA_IO &&
		    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
		    (ccb->ataio.cmd.control & ATA_A_RESET)) {
			struct ata_res *res = &ccb->ataio.res;
			
			bzero(res, sizeof(*res));
			if (ch->devices & (ATA_ATA_MASTER << ccb->ccb_h.target_id)) {
				res->lba_high = 0;
				res->lba_mid = 0;
			} else {
				res->lba_high = 0xeb;
				res->lba_mid = 0x14;
			}
			ccb->ccb_h.status = CAM_REQ_CMP;
			break;
		}
		ata_cam_begin_transaction(dev, ccb);
		return;
	case XPT_EN_LUN:		/* Enable LUN as a target */
	case XPT_TARGET_IO:		/* Execute target I/O request */
	case XPT_ACCEPT_TARGET_IO:	/* Accept Host Target Mode CDB */
	case XPT_CONT_TARGET_IO:	/* Continue Host Target I/O Connection*/
	case XPT_ABORT:			/* Abort the specified CCB */
		/* XXX Implement */
		ccb->ccb_h.status = CAM_REQ_INVALID;
		break;
	case XPT_SET_TRAN_SETTINGS:
	{
		struct	ccb_trans_settings *cts = &ccb->cts;
		struct	ata_cam_device *d; 

		if (ata_check_ids(dev, ccb))
			return;
		if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
			d = &ch->curr[ccb->ccb_h.target_id];
		else
			d = &ch->user[ccb->ccb_h.target_id];
		if (ch->flags & ATA_SATA) {
			if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION)
				d->revision = cts->xport_specific.sata.revision;
			if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE) {
				if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
					d->mode = ATA_SETMODE(ch->dev,
					    ccb->ccb_h.target_id,
					    cts->xport_specific.sata.mode);
				} else
					d->mode = cts->xport_specific.sata.mode;
			}
			if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
				d->bytecount = min(8192, cts->xport_specific.sata.bytecount);
			if (cts->xport_specific.sata.valid & CTS_SATA_VALID_ATAPI)
				d->atapi = cts->xport_specific.sata.atapi;
			if (cts->xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
				d->caps = cts->xport_specific.sata.caps;
		} else {
			if (cts->xport_specific.ata.valid & CTS_ATA_VALID_MODE) {
				if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
					d->mode = ATA_SETMODE(ch->dev,
					    ccb->ccb_h.target_id,
					    cts->xport_specific.ata.mode);
				} else
					d->mode = cts->xport_specific.ata.mode;
			}
			if (cts->xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)
				d->bytecount = cts->xport_specific.ata.bytecount;
			if (cts->xport_specific.ata.valid & CTS_ATA_VALID_ATAPI)
				d->atapi = cts->xport_specific.ata.atapi;
			if (cts->xport_specific.ata.valid & CTS_ATA_VALID_CAPS)
				d->caps = cts->xport_specific.ata.caps;
		}
		ccb->ccb_h.status = CAM_REQ_CMP;
		break;
	}
	case XPT_GET_TRAN_SETTINGS:
	{
		struct	ccb_trans_settings *cts = &ccb->cts;
		struct  ata_cam_device *d;

		if (ata_check_ids(dev, ccb))
			return;
		if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
			d = &ch->curr[ccb->ccb_h.target_id];
		else
			d = &ch->user[ccb->ccb_h.target_id];
		cts->protocol = PROTO_UNSPECIFIED;
		cts->protocol_version = PROTO_VERSION_UNSPECIFIED;
		if (ch->flags & ATA_SATA) {
			cts->transport = XPORT_SATA;
			cts->transport_version = XPORT_VERSION_UNSPECIFIED;
			cts->xport_specific.sata.valid = 0;
			cts->xport_specific.sata.mode = d->mode;
			cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE;
			cts->xport_specific.sata.bytecount = d->bytecount;
			cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT;
			if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
				cts->xport_specific.sata.revision =
				    ATA_GETREV(dev, ccb->ccb_h.target_id);
				if (cts->xport_specific.sata.revision != 0xff) {
					cts->xport_specific.sata.valid |=
					    CTS_SATA_VALID_REVISION;
				}
				cts->xport_specific.sata.caps =
				    d->caps & CTS_SATA_CAPS_D;
				if (ch->pm_level) {
					cts->xport_specific.sata.caps |=
					    CTS_SATA_CAPS_H_PMREQ;
				}
				cts->xport_specific.sata.caps &=
				    ch->user[ccb->ccb_h.target_id].caps;
			} else {
				cts->xport_specific.sata.revision = d->revision;
				cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION;
				cts->xport_specific.sata.caps = d->caps;
			}
			cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS;
			cts->xport_specific.sata.atapi = d->atapi;
			cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI;
		} else {
			cts->transport = XPORT_ATA;
			cts->transport_version = XPORT_VERSION_UNSPECIFIED;
			cts->xport_specific.ata.valid = 0;
			cts->xport_specific.ata.mode = d->mode;
			cts->xport_specific.ata.valid |= CTS_ATA_VALID_MODE;
			cts->xport_specific.ata.bytecount = d->bytecount;
			cts->xport_specific.ata.valid |= CTS_ATA_VALID_BYTECOUNT;
			if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
				cts->xport_specific.ata.caps =
				    d->caps & CTS_ATA_CAPS_D;
				if (!(ch->flags & ATA_NO_48BIT_DMA))
					cts->xport_specific.ata.caps |=
					    CTS_ATA_CAPS_H_DMA48;
				cts->xport_specific.ata.caps &=
				    ch->user[ccb->ccb_h.target_id].caps;
			} else
				cts->xport_specific.ata.caps = d->caps;
			cts->xport_specific.ata.valid |= CTS_ATA_VALID_CAPS;
			cts->xport_specific.ata.atapi = d->atapi;
			cts->xport_specific.ata.valid |= CTS_ATA_VALID_ATAPI;
		}
		ccb->ccb_h.status = CAM_REQ_CMP;
		break;
	}
	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
	case XPT_RESET_DEV:	/* Bus Device Reset the specified SCSI device */
		ata_reinit(dev);
		ccb->ccb_h.status = CAM_REQ_CMP;
		break;
	case XPT_TERM_IO:		/* Terminate the I/O process */
		/* XXX Implement */
		ccb->ccb_h.status = CAM_REQ_INVALID;
		break;
	case XPT_PATH_INQ:		/* Path routing inquiry */
	{
		struct ccb_pathinq *cpi = &ccb->cpi;

		parent = device_get_parent(dev);
		cpi->version_num = 1; /* XXX??? */
		cpi->hba_inquiry = PI_SDTR_ABLE;
		cpi->target_sprt = 0;
		cpi->hba_misc = PIM_SEQSCAN | PIM_UNMAPPED;
		cpi->hba_eng_cnt = 0;
		if (ch->flags & ATA_NO_SLAVE)
			cpi->max_target = 0;
		else
			cpi->max_target = 1;
		cpi->max_lun = 0;
		cpi->initiator_id = 0;
		cpi->bus_id = cam_sim_bus(sim);
		if (ch->flags & ATA_SATA)
			cpi->base_transfer_speed = 150000;
		else
			cpi->base_transfer_speed = 3300;
		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
		strncpy(cpi->hba_vid, "ATA", HBA_IDLEN);
		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
		cpi->unit_number = cam_sim_unit(sim);
		if (ch->flags & ATA_SATA)
			cpi->transport = XPORT_SATA;
		else
			cpi->transport = XPORT_ATA;
		cpi->transport_version = XPORT_VERSION_UNSPECIFIED;
		cpi->protocol = PROTO_ATA;
		cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
		cpi->maxio = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS;
		if (device_get_devclass(device_get_parent(parent)) ==
		    devclass_find("pci")) {
			cpi->hba_vendor = pci_get_vendor(parent);
			cpi->hba_device = pci_get_device(parent);
			cpi->hba_subvendor = pci_get_subvendor(parent);
			cpi->hba_subdevice = pci_get_subdevice(parent);
		}
		cpi->ccb_h.status = CAM_REQ_CMP;
		break;
	}
	default:
		ccb->ccb_h.status = CAM_REQ_INVALID;
		break;
	}
	xpt_done(ccb);
}
예제 #23
0
static int
xhci_pci_attach(device_t self)
{
	struct xhci_softc *sc = device_get_softc(self);
	int count, err, rid;
	uint8_t usedma32;

	rid = PCI_XHCI_CBMEM;
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->sc_io_res) {
		device_printf(self, "Could not map memory\n");
		return (ENOMEM);
	}
	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	/* check for USB 3.0 controllers which don't support 64-bit DMA */
	switch (pci_get_devid(self)) {
	case 0x01941033:	/* NEC uPD720200 USB 3.0 controller */
	case 0x00141912:        /* NEC uPD720201 USB 3.0 controller */
	case 0x78141022:	/* AMD A10-7300, tested does not work w/64-bit DMA */
		usedma32 = 1;
		break;
	default:
		usedma32 = 0;
		break;
	}

	if (xhci_init(sc, self, usedma32)) {
		device_printf(self, "Could not initialize softc\n");
		bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM,
		    sc->sc_io_res);
		return (ENXIO);
	}

	pci_enable_busmaster(self);

	usb_callout_init_mtx(&sc->sc_callout, &sc->sc_bus.bus_lock, 0);

	rid = 0;
	if (xhci_use_msi) {
		count = pci_msi_count(self);
		if (count >= 1) {
			count = 1;
			if (pci_alloc_msi(self, &rid, 1, count) == 0) {
				if (bootverbose)
					device_printf(self, "MSI enabled\n");
				sc->sc_irq_rid = 1;
			}
		}
	}

	/*
	 * hw.usb.xhci.use_polling=1 to force polling.
	 */
	if (xhci_use_polling() == 0) {
		sc->sc_irq_res = bus_alloc_resource_any(
					self, SYS_RES_IRQ,
					&sc->sc_irq_rid,
					RF_SHAREABLE | RF_ACTIVE);
		if (sc->sc_irq_res == NULL) {
			pci_release_msi(self);
			device_printf(self, "Could not allocate IRQ\n");
			/* goto error; FALLTHROUGH - use polling */
		}
	}
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (sc->sc_bus.bdev == NULL) {
		device_printf(self, "Could not add USB device\n");
		goto error;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	ksprintf(sc->sc_vendor, "0x%04x", pci_get_vendor(self));

	if (sc->sc_irq_res != NULL) {
		err = bus_setup_intr(self, sc->sc_irq_res, INTR_MPSAFE,
		    (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl, NULL);
		if (err != 0) {
			bus_release_resource(self, SYS_RES_IRQ,
			    rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
			sc->sc_irq_res = NULL;
			pci_release_msi(self);
			device_printf(self, "Could not setup IRQ, err=%d\n", err);
			sc->sc_intr_hdl = NULL;
		}
	}
	if (sc->sc_irq_res == NULL || sc->sc_intr_hdl == NULL) {
		if (xhci_use_polling() != 0) {
			device_printf(self, "Interrupt polling at %dHz\n", hz);
			USB_BUS_LOCK(&sc->sc_bus);
			xhci_interrupt_poll(sc);
			USB_BUS_UNLOCK(&sc->sc_bus);
		} else
			goto error;
	}

	/* On Intel chipsets reroute ports from EHCI to XHCI controller. */
	switch (pci_get_devid(self)) {
	case 0x0f358086:	/* BayTrail */
	case 0x9c318086:	/* Panther Point */
	case 0x1e318086:	/* Panther Point */
	case 0x8c318086:	/* Lynx Point */
	case 0x8cb18086:	/* Wildcat Point */
	case 0x9cb18086:	/* Wildcat Point-LP */
		sc->sc_port_route = &xhci_pci_port_route;
		sc->sc_imod_default = XHCI_IMOD_DEFAULT_LP;
		break;
	default:
		break;
	}

	xhci_pci_take_controller(self);

	err = xhci_halt_controller(sc);

	if (err == 0)
		err = xhci_start_controller(sc);

	if (err == 0)
		err = device_probe_and_attach(sc->sc_bus.bdev);

	if (err) {
		device_printf(self, "XHCI halt/start/probe failed err=%d\n", err);
		goto error;
	}
	return (0);

error:
	xhci_pci_detach(self);
	return (ENXIO);
}
예제 #24
0
void intel_detect_pch(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct device *pch = NULL;

	/* In all current cases, num_pipes is equivalent to the PCH_NOP setting
	 * (which really amounts to a PCH but no South Display).
	 */
	if (INTEL_INFO(dev)->num_pipes == 0) {
		dev_priv->pch_type = PCH_NOP;
		return;
	}

	/* XXX The ISA bridge probe causes some old Core2 machines to hang */
	if (INTEL_INFO(dev)->gen < 5)
		return;

	/*
	 * The reason to probe ISA bridge instead of Dev31:Fun0 is to
	 * make graphics device passthrough work easy for VMM, that only
	 * need to expose ISA bridge to let driver know the real hardware
	 * underneath. This is a requirement from virtualization team.
	 *
	 * In some virtualized environments (e.g. XEN), there is irrelevant
	 * ISA bridge in the system. To work reliably, we should scan trhough
	 * all the ISA bridge devices and check for the first match, instead
	 * of only checking the first one.
	 */
	while ((pch = pci_find_class(PCIC_BRIDGE, PCIS_BRIDGE_ISA))) {
		if (pci_get_vendor(pch) == PCI_VENDOR_INTEL) {
			unsigned short id = pci_get_device(pch) & INTEL_PCH_DEVICE_ID_MASK;
			dev_priv->pch_id = id;

			if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
				dev_priv->pch_type = PCH_IBX;
				DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
				WARN_ON(!IS_GEN5(dev));
			} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
				dev_priv->pch_type = PCH_CPT;
				DRM_DEBUG_KMS("Found CougarPoint PCH\n");
				WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
			} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
				/* PantherPoint is CPT compatible */
				dev_priv->pch_type = PCH_CPT;
				DRM_DEBUG_KMS("Found PantherPoint PCH\n");
				WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
			} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
				dev_priv->pch_type = PCH_LPT;
				DRM_DEBUG_KMS("Found LynxPoint PCH\n");
				WARN_ON(!IS_HASWELL(dev));
				WARN_ON(IS_ULT(dev));
			} else if (IS_BROADWELL(dev)) {
				dev_priv->pch_type = PCH_LPT;
				dev_priv->pch_id =
					INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
				DRM_DEBUG_KMS("This is Broadwell, assuming "
					      "LynxPoint LP PCH\n");
			} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
				dev_priv->pch_type = PCH_LPT;
				DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
				WARN_ON(!IS_HASWELL(dev));
				WARN_ON(!IS_ULT(dev));
			} else
				continue;

			break;
		}
	}
	if (!pch)
		DRM_DEBUG_KMS("No PCH found.\n");

#if 0
	pci_dev_put(pch);
#endif
}
예제 #25
0
static int
ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
	struct thread *td)
{
        qla_host_t *ha;
        int rval = 0;
	device_t pci_dev;
	struct ifnet *ifp;
	int count;

	q80_offchip_mem_val_t val;
	qla_rd_pci_ids_t *pci_ids;
	qla_rd_fw_dump_t *fw_dump;
        union {
		qla_reg_val_t *rv;
	        qla_rd_flash_t *rdf;
		qla_wr_flash_t *wrf;
		qla_erase_flash_t *erf;
		qla_offchip_mem_val_t *mem;
	} u;


        if ((ha = (qla_host_t *)dev->si_drv1) == NULL)
                return ENXIO;

	pci_dev= ha->pci_dev;

        switch(cmd) {

        case QLA_RDWR_REG:

                u.rv = (qla_reg_val_t *)data;

                if (u.rv->direct) {
                        if (u.rv->rd) {
                                u.rv->val = READ_REG32(ha, u.rv->reg);
                        } else {
                                WRITE_REG32(ha, u.rv->reg, u.rv->val);
                        }
                } else {
                        if ((rval = ql_rdwr_indreg32(ha, u.rv->reg, &u.rv->val,
                                u.rv->rd)))
                                rval = ENXIO;
                }
                break;

        case QLA_RD_FLASH:

		if (!ha->hw.flags.fdt_valid) {
			rval = EIO;
			break;
		}	

                u.rdf = (qla_rd_flash_t *)data;
                if ((rval = ql_rd_flash32(ha, u.rdf->off, &u.rdf->data)))
                        rval = ENXIO;
                break;

	case QLA_WR_FLASH:

		ifp = ha->ifp;

		if (ifp == NULL) {
			rval = ENXIO;
			break;
		}

		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
			rval = ENXIO;
			break;
		}

		if (!ha->hw.flags.fdt_valid) {
			rval = EIO;
			break;
		}	

		u.wrf = (qla_wr_flash_t *)data;
		if ((rval = ql_wr_flash_buffer(ha, u.wrf->off, u.wrf->size,
			u.wrf->buffer))) {
			printf("flash write failed[%d]\n", rval);
			rval = ENXIO;
		}
		break;

	case QLA_ERASE_FLASH:

		ifp = ha->ifp;

		if (ifp == NULL) {
			rval = ENXIO;
			break;
		}

		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
			rval = ENXIO;
			break;
		}

		if (!ha->hw.flags.fdt_valid) {
			rval = EIO;
			break;
		}	
		
		u.erf = (qla_erase_flash_t *)data;
		if ((rval = ql_erase_flash(ha, u.erf->off, 
			u.erf->size))) {
			printf("flash erase failed[%d]\n", rval);
			rval = ENXIO;
		}
		break;

	case QLA_RDWR_MS_MEM:
		u.mem = (qla_offchip_mem_val_t *)data;

		if ((rval = ql_rdwr_offchip_mem(ha, u.mem->off, &val, 
			u.mem->rd)))
			rval = ENXIO;
		else {
			u.mem->data_lo = val.data_lo;
			u.mem->data_hi = val.data_hi;
			u.mem->data_ulo = val.data_ulo;
			u.mem->data_uhi = val.data_uhi;
		}

		break;

	case QLA_RD_FW_DUMP_SIZE:

		if (ha->hw.mdump_init == 0) {
			rval = EINVAL;
			break;
		}
		
		fw_dump = (qla_rd_fw_dump_t *)data;
		fw_dump->minidump_size = ha->hw.mdump_buffer_size + 
						ha->hw.mdump_template_size;
		fw_dump->pci_func = ha->pci_func;

		break;

	case QLA_RD_FW_DUMP:

		if (ha->hw.mdump_init == 0) {
			device_printf(pci_dev, "%s: minidump not initialized\n", __func__);
			rval = EINVAL;
			break;
		}
		
		fw_dump = (qla_rd_fw_dump_t *)data;

		if ((fw_dump->minidump == NULL) ||
			(fw_dump->minidump_size != (ha->hw.mdump_buffer_size +
				ha->hw.mdump_template_size))) {
			device_printf(pci_dev,
				"%s: minidump buffer [%p] size = [%d, %d] invalid\n", __func__,
				fw_dump->minidump, fw_dump->minidump_size,
				(ha->hw.mdump_buffer_size + ha->hw.mdump_template_size));
			rval = EINVAL;
			break;
		}

		if ((ha->pci_func & 0x1)) {
			device_printf(pci_dev, "%s: mindump allowed only on Port0\n", __func__);
			rval = ENXIO;
			break;
		}

		fw_dump->saved = 1;

		if (ha->offline) {

			if (ha->enable_minidump)
				ql_minidump(ha);

			fw_dump->saved = 0;
			fw_dump->usec_ts = ha->hw.mdump_usec_ts;

			if (!ha->hw.mdump_done) {
				device_printf(pci_dev,
					"%s: port offline minidump failed\n", __func__);
				rval = ENXIO;
				break;
			}
		} else {

#define QLA_LOCK_MDUMP_MS_TIMEOUT (QLA_LOCK_DEFAULT_MS_TIMEOUT * 5)
			if (QLA_LOCK(ha, __func__, QLA_LOCK_MDUMP_MS_TIMEOUT, 0) == 0) {
				if (!ha->hw.mdump_done) {
					fw_dump->saved = 0;
					QL_INITIATE_RECOVERY(ha);
					device_printf(pci_dev, "%s: recovery initiated "
						" to trigger minidump\n",
						__func__);
				}
				QLA_UNLOCK(ha, __func__);
			} else {
				device_printf(pci_dev, "%s: QLA_LOCK() failed0\n", __func__);
				rval = ENXIO;
				break;
			}
	
#define QLNX_DUMP_WAIT_SECS	30

			count = QLNX_DUMP_WAIT_SECS * 1000;

			while (count) {
				if (ha->hw.mdump_done)
					break;
				qla_mdelay(__func__, 100);
				count -= 100;
			}

			if (!ha->hw.mdump_done) {
				device_printf(pci_dev,
					"%s: port not offline minidump failed\n", __func__);
				rval = ENXIO;
				break;
			}
			fw_dump->usec_ts = ha->hw.mdump_usec_ts;
			
			if (QLA_LOCK(ha, __func__, QLA_LOCK_MDUMP_MS_TIMEOUT, 0) == 0) {
				ha->hw.mdump_done = 0;
				QLA_UNLOCK(ha, __func__);
			} else {
				device_printf(pci_dev, "%s: QLA_LOCK() failed1\n", __func__);
				rval = ENXIO;
				break;
			}
		}

		if ((rval = copyout(ha->hw.mdump_template,
			fw_dump->minidump, ha->hw.mdump_template_size))) {
			device_printf(pci_dev, "%s: template copyout failed\n", __func__);
			rval = ENXIO;
			break;
		}

		if ((rval = copyout(ha->hw.mdump_buffer,
				((uint8_t *)fw_dump->minidump +
					ha->hw.mdump_template_size),
				ha->hw.mdump_buffer_size))) {
			device_printf(pci_dev, "%s: minidump copyout failed\n", __func__);
			rval = ENXIO;
		}
		break;

	case QLA_RD_DRVR_STATE:
		rval = ql_drvr_state(ha, (qla_driver_state_t *)data);
		break;

	case QLA_RD_SLOWPATH_LOG:
		rval = ql_slowpath_log(ha, (qla_sp_log_t *)data);
		break;

	case QLA_RD_PCI_IDS:
		pci_ids = (qla_rd_pci_ids_t *)data;
		pci_ids->ven_id = pci_get_vendor(pci_dev);
		pci_ids->dev_id = pci_get_device(pci_dev);
		pci_ids->subsys_ven_id = pci_get_subvendor(pci_dev);
		pci_ids->subsys_dev_id = pci_get_subdevice(pci_dev);
		pci_ids->rev_id = pci_read_config(pci_dev, PCIR_REVID, 1);
		break;

        default:
                break;
        }

        return rval;
}
예제 #26
0
static int
ohci_pci_attach(device_t self)
{
	ohci_softc_t *sc = device_get_softc(self);
	int err;
	int rid;

	/* XXX where does it say so in the spec? */
	sc->sc_bus.usbrev = USBREV_1_0;

	pci_enable_busmaster(self);

	/*
	 * Some Sun PCIO-2 USB controllers have their intpin register
	 * bogusly set to 0, although it should be 4. Correct that.
	 */
	if (pci_get_devid(self) == PCI_OHCI_DEVICEID_PCIO2USB &&
	    pci_get_intpin(self) == 0)
		pci_set_intpin(self, 4);

	rid = PCI_CBMEM;
	sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->io_res) {
		device_printf(self, "Could not map memory\n");
		return ENXIO;
	}
	sc->iot = rman_get_bustag(sc->io_res);
	sc->ioh = rman_get_bushandle(sc->io_res);

	rid = 0;
	sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		ohci_pci_detach(self);
		return ENXIO;
	}
	sc->sc_bus.bdev = device_add_child(self, "usb", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		ohci_pci_detach(self);
		return ENOMEM;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	/* ohci_pci_match will never return NULL if ohci_pci_probe succeeded */
	device_set_desc(sc->sc_bus.bdev, ohci_pci_match(self));
	switch (pci_get_vendor(self)) {
	case PCI_OHCI_VENDORID_ACERLABS:
		sprintf(sc->sc_vendor, "AcerLabs");
		break;
	case PCI_OHCI_VENDORID_AMD:
		sprintf(sc->sc_vendor, "AMD");
		break;
	case PCI_OHCI_VENDORID_APPLE:
		sprintf(sc->sc_vendor, "Apple");
		break;
	case PCI_OHCI_VENDORID_ATI:
		sprintf(sc->sc_vendor, "ATI");
		break;
	case PCI_OHCI_VENDORID_CMDTECH:
		sprintf(sc->sc_vendor, "CMDTECH");
		break;
	case PCI_OHCI_VENDORID_NEC:
		sprintf(sc->sc_vendor, "NEC");
		break;
	case PCI_OHCI_VENDORID_NVIDIA:
	case PCI_OHCI_VENDORID_NVIDIA2:
		sprintf(sc->sc_vendor, "nVidia");
		break;
	case PCI_OHCI_VENDORID_OPTI:
		sprintf(sc->sc_vendor, "OPTi");
		break;
	case PCI_OHCI_VENDORID_SIS:
		sprintf(sc->sc_vendor, "SiS");
		break;
	default:
		if (bootverbose)
			device_printf(self, "(New OHCI DeviceId=0x%08x)\n",
			    pci_get_devid(self));
		sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
	}

	err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO, NULL, ohci_intr, 
			     sc, &sc->ih);
	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->ih = NULL;
		ohci_pci_detach(self);
		return ENXIO;
	}

	/* Allocate a parent dma tag for DMA maps */
	err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
	    BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
	    NULL, NULL, &sc->sc_bus.parent_dmatag);
	if (err) {
		device_printf(self, "Could not allocate parent DMA tag (%d)\n",
		    err);
		ohci_pci_detach(self);
		return ENXIO;
	}
	/* Allocate a dma tag for transfer buffers */
	err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
	    BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
	    busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
	if (err) {
		device_printf(self, "Could not allocate transfer tag (%d)\n",
		    err);
		ohci_pci_detach(self);
		return ENXIO;
	}

	err = ohci_init(sc);
	if (!err) {
		sc->sc_flags |= OHCI_SCFLG_DONEINIT;
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}

	if (err) {
		device_printf(self, "USB init failed\n");
		ohci_pci_detach(self);
		return EIO;
	}
	return 0;
}
예제 #27
0
파일: mpt_pci.c 프로젝트: AhmadTux/freebsd
static int
mpt_pci_probe(device_t dev)
{
	const char *desc;
	int rval;

	if (pci_get_vendor(dev) != MPI_MANUFACTPAGE_VENDORID_LSILOGIC)
		return (ENXIO);

	rval = BUS_PROBE_DEFAULT;
	switch (pci_get_device(dev)) {
	case MPI_MANUFACTPAGE_DEVICEID_FC909_FB:
		desc = "LSILogic FC909 FC Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC909:
		desc = "LSILogic FC909A FC Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC919:
		desc = "LSILogic FC919 FC Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC919_LAN_FB:
		desc = "LSILogic FC919 LAN Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC929:
		desc = "Dual LSILogic FC929 FC Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB:
		desc = "Dual LSILogic FC929 LAN Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC919X:
		desc = "LSILogic FC919 FC PCI-X Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC919X_LAN_FB:
		desc = "LSILogic FC919 LAN PCI-X Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC929X:
		desc = "Dual LSILogic FC929X 2Gb/s FC PCI-X Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC929X_LAN_FB:
		desc = "Dual LSILogic FC929X LAN PCI-X Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC949E:
		desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-Express Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVICEID_FC949X:
		desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-X Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVID_53C1030:
	case MPI_MANUFACTPAGE_DEVID_53C1030ZC:
		desc = "LSILogic 1030 Ultra4 Adapter";
		break;
	case MPI_MANUFACTPAGE_DEVID_SAS1068E_FB:
		/*
		 * Allow mfi(4) to claim this device in case it's in MegaRAID
		 * mode.
		 */
		rval = BUS_PROBE_LOW_PRIORITY;
		/* FALLTHROUGH */
	case MPI_MANUFACTPAGE_DEVID_SAS1064:
	case MPI_MANUFACTPAGE_DEVID_SAS1064A:
	case MPI_MANUFACTPAGE_DEVID_SAS1064E:
	case MPI_MANUFACTPAGE_DEVID_SAS1066:
	case MPI_MANUFACTPAGE_DEVID_SAS1066E:
	case MPI_MANUFACTPAGE_DEVID_SAS1068:
	case MPI_MANUFACTPAGE_DEVID_SAS1068A_FB:
	case MPI_MANUFACTPAGE_DEVID_SAS1068E:
	case MPI_MANUFACTPAGE_DEVID_SAS1078:
	case MPI_MANUFACTPAGE_DEVID_SAS1078DE_FB:
		desc = "LSILogic SAS/SATA Adapter";
		break;
	default:
		return (ENXIO);
	}

	device_set_desc(dev, desc);
	return (rval);
}
예제 #28
0
static int
ohci_pci_attach(device_t self)
{
	ohci_softc_t *sc = device_get_softc(self);
	int err;
	int rid;

	/* XXX where does it say so in the spec? */
	sc->sc_bus.usbrev = USBREV_1_0;

	pci_enable_busmaster(self);

	/*
	 * Some Sun PCIO-2 USB controllers have their intpin register
	 * bogusly set to 0, although it should be 4. Correct that.
	 */
	if (pci_get_devid(self) == PCI_OHCI_DEVICEID_PCIO2USB &&
	    pci_get_intpin(self) == 0)
		pci_set_intpin(self, 4);

	rid = PCI_CBMEM;
	sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->io_res) {
		device_printf(self, "Could not map memory\n");
		return ENXIO;
	}
	sc->iot = rman_get_bustag(sc->io_res);
	sc->ioh = rman_get_bushandle(sc->io_res);

	rid = 0;
	sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->irq_res == NULL) {
		device_printf(self, "Could not allocate irq\n");
		ohci_pci_detach(self);
		return ENXIO;
	}
	sc->sc_bus.bdev = device_add_child(self, "usb", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		ohci_pci_detach(self);
		return ENOMEM;
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	/* ohci_pci_match will never return NULL if ohci_pci_probe succeeded */
	device_set_desc(sc->sc_bus.bdev, ohci_pci_match(self));
	switch (pci_get_vendor(self)) {
	case PCI_OHCI_VENDORID_ACERLABS:
		ksprintf(sc->sc_vendor, "AcerLabs");
		break;
	case PCI_OHCI_VENDORID_AMD:
		ksprintf(sc->sc_vendor, "AMD");
		break;
	case PCI_OHCI_VENDORID_APPLE:
		ksprintf(sc->sc_vendor, "Apple");
		break;
	case PCI_OHCI_VENDORID_ATI:
		ksprintf(sc->sc_vendor, "ATI");
		break;
	case PCI_OHCI_VENDORID_CMDTECH:
		ksprintf(sc->sc_vendor, "CMDTECH");
		break;
	case PCI_OHCI_VENDORID_NEC:
		ksprintf(sc->sc_vendor, "NEC");
		break;
	case PCI_OHCI_VENDORID_NVIDIA:
	case PCI_OHCI_VENDORID_NVIDIA2:
		ksprintf(sc->sc_vendor, "nVidia");
		break;
	case PCI_OHCI_VENDORID_OPTI:
		ksprintf(sc->sc_vendor, "OPTi");
		break;
	case PCI_OHCI_VENDORID_SIS:
		ksprintf(sc->sc_vendor, "SiS");
		break;
	default:
		if (bootverbose)
			device_printf(self, "(New OHCI DeviceId=0x%08x)\n",
			    pci_get_devid(self));
		ksprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
	}

	err = bus_setup_intr(self, sc->irq_res, 0,
	    (driver_intr_t *) ohci_intr, sc, &sc->ih, NULL);
	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->ih = NULL;
		ohci_pci_detach(self);
		return ENXIO;
	}

	/*
	 * OHCI interrupts which occur early will leave them disabled,
	 * so run the interrupt manually once we're done with the init.
	 */
	err = ohci_init(sc);
	if (err == 0)
		err = device_probe_and_attach(sc->sc_bus.bdev);

	if (err) {
		device_printf(self, "USB init failed\n");
		ohci_pci_detach(self);
		return EIO;
	}
	return 0;
}
예제 #29
0
int
hme_pci_attach(device_t dev)
{
	struct hme_pci_softc *hsc;
	struct hme_softc *sc;
	bus_space_tag_t	memt;
	bus_space_handle_t memh;
	int i, error = 0;
#if !(defined(__powerpc__) || defined(__sparc64__))
	device_t *children, ebus_dev;
	struct resource *ebus_rres;
	int j, slot;
#endif

	pci_enable_busmaster(dev);
	/*
	 * Some Sun HMEs do have their intpin register bogusly set to 0,
	 * although it should be 1.  Correct that.
	 */
	if (pci_get_intpin(dev) == 0)
		pci_set_intpin(dev, 1);

	hsc = device_get_softc(dev);
	sc = &hsc->hsc_hme;
	sc->sc_dev = dev;
	sc->sc_flags |= HME_PCI;
	mtx_init(&sc->sc_lock, device_get_nameunit(dev), MTX_NETWORK_LOCK,
	    MTX_DEF);

	/*
	 * Map five register banks:
	 *
	 *	bank 0: HME SEB registers:	+0x0000
	 *	bank 1: HME ETX registers:	+0x2000
	 *	bank 2: HME ERX registers:	+0x4000
	 *	bank 3: HME MAC registers:	+0x6000
	 *	bank 4: HME MIF registers:	+0x7000
	 *
	 */
	i = PCIR_BAR(0);
	hsc->hsc_sres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE);
	if (hsc->hsc_sres == NULL) {
		device_printf(dev, "could not map device registers\n");
		error = ENXIO;
		goto fail_mtx;
	}
	i = 0;
	hsc->hsc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &i, RF_SHAREABLE | RF_ACTIVE);
	if (hsc->hsc_ires == NULL) {
		device_printf(dev, "could not allocate interrupt\n");
		error = ENXIO;
		goto fail_sres;
	}
	memt = rman_get_bustag(hsc->hsc_sres);
	memh = rman_get_bushandle(hsc->hsc_sres);
	sc->sc_sebt = sc->sc_etxt = sc->sc_erxt = sc->sc_mact = sc->sc_mift =
	    memt;
	bus_space_subregion(memt, memh, 0x0000, 0x1000, &sc->sc_sebh);
	bus_space_subregion(memt, memh, 0x2000, 0x1000, &sc->sc_etxh);
	bus_space_subregion(memt, memh, 0x4000, 0x1000, &sc->sc_erxh);
	bus_space_subregion(memt, memh, 0x6000, 0x1000, &sc->sc_mach);
	bus_space_subregion(memt, memh, 0x7000, 0x1000, &sc->sc_mifh);

#if defined(__powerpc__) || defined(__sparc64__)
	OF_getetheraddr(dev, sc->sc_enaddr);
#else
	/*
	 * Dig out VPD (vital product data) and read NA (network address).
	 *
	 * The PCI HME is a PCIO chip, which is composed of two functions:
	 *	function 0: PCI-EBus2 bridge, and
	 *	function 1: HappyMeal Ethernet controller.
	 *
	 * The VPD of HME resides in the Boot PROM (PCI FCode) attached
	 * to the EBus bridge and can't be accessed via the PCI capability
	 * pointer.
	 * ``Writing FCode 3.x Programs'' (newer ones, dated 1997 and later)
	 * chapter 2 describes the data structure.
	 *
	 * We don't have a MI EBus driver since no EBus device exists
	 * (besides the FCode PROM) on add-on HME boards.  The ``no driver
	 * attached'' message for function 0 therefore is what is expected.
	 */

#define	PCI_ROMHDR_SIZE			0x1c
#define	PCI_ROMHDR_SIG			0x00
#define	PCI_ROMHDR_SIG_MAGIC		0xaa55		/* little endian */
#define	PCI_ROMHDR_PTR_DATA		0x18
#define	PCI_ROM_SIZE			0x18
#define	PCI_ROM_SIG			0x00
#define	PCI_ROM_SIG_MAGIC		0x52494350	/* "PCIR", endian */
							/* reversed */
#define	PCI_ROM_VENDOR			0x04
#define	PCI_ROM_DEVICE			0x06
#define	PCI_ROM_PTR_VPD			0x08
#define	PCI_VPDRES_BYTE0		0x00
#define	PCI_VPDRES_ISLARGE(x)		((x) & 0x80)
#define	PCI_VPDRES_LARGE_NAME(x)	((x) & 0x7f)
#define	PCI_VPDRES_TYPE_VPD		0x10		/* large */
#define	PCI_VPDRES_LARGE_LEN_LSB	0x01
#define	PCI_VPDRES_LARGE_LEN_MSB	0x02
#define	PCI_VPDRES_LARGE_DATA		0x03
#define	PCI_VPD_SIZE			0x03
#define	PCI_VPD_KEY0			0x00
#define	PCI_VPD_KEY1			0x01
#define	PCI_VPD_LEN			0x02
#define	PCI_VPD_DATA			0x03

#define	HME_ROM_READ_N(n, offs)	bus_space_read_ ## n (memt, memh, (offs))
#define	HME_ROM_READ_1(offs)	HME_ROM_READ_N(1, (offs))
#define	HME_ROM_READ_2(offs)	HME_ROM_READ_N(2, (offs))
#define	HME_ROM_READ_4(offs)	HME_ROM_READ_N(4, (offs))

	/* Search accompanying EBus bridge. */
	slot = pci_get_slot(dev);
	if (device_get_children(device_get_parent(dev), &children, &i) != 0) {
		device_printf(dev, "could not get children\n");
		error = ENXIO;
		goto fail_sres;
	}
	ebus_dev = NULL;
	for (j = 0; j < i; j++) {
		if (pci_get_class(children[j]) == PCIC_BRIDGE &&
		    pci_get_vendor(children[j]) == PCI_VENDOR_SUN &&
		    pci_get_device(children[j]) == PCI_PRODUCT_SUN_EBUS &&
		    pci_get_slot(children[j]) == slot) {
			ebus_dev = children[j];
			break;
		}
	}
	if (ebus_dev == NULL) {
		device_printf(dev, "could not find EBus bridge\n");
		error = ENXIO;
		goto fail_children;
	}

	/* Map EBus bridge PROM registers. */
	i = PCIR_BAR(0);
	if ((ebus_rres = bus_alloc_resource_any(ebus_dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE)) == NULL) {
		device_printf(dev, "could not map PROM registers\n");
		error = ENXIO;
		goto fail_children;
	}
	memt = rman_get_bustag(ebus_rres);
	memh = rman_get_bushandle(ebus_rres);

	/* Read PCI Expansion ROM header. */
	if (HME_ROM_READ_2(PCI_ROMHDR_SIG) != PCI_ROMHDR_SIG_MAGIC ||
	    (i = HME_ROM_READ_2(PCI_ROMHDR_PTR_DATA)) < PCI_ROMHDR_SIZE) {
		device_printf(dev, "unexpected PCI Expansion ROM header\n");
		error = ENXIO;
		goto fail_rres;
	}

	/* Read PCI Expansion ROM data. */
	if (HME_ROM_READ_4(i + PCI_ROM_SIG) != PCI_ROM_SIG_MAGIC ||
	    HME_ROM_READ_2(i + PCI_ROM_VENDOR) != pci_get_vendor(dev) ||
	    HME_ROM_READ_2(i + PCI_ROM_DEVICE) != pci_get_device(dev) ||
	    (j = HME_ROM_READ_2(i + PCI_ROM_PTR_VPD)) < i + PCI_ROM_SIZE) {
		device_printf(dev, "unexpected PCI Expansion ROM data\n");
		error = ENXIO;
		goto fail_rres;
	}

	/*
	 * Read PCI VPD.
	 * SUNW,hme cards have a single large resource VPD-R tag
	 * containing one NA.  SUNW,qfe cards have four large resource
	 * VPD-R tags containing one NA each (all four HME chips share
	 * the same PROM).
	 * The VPD used on both cards is not in PCI 2.2 standard format
	 * however.  The length in the resource header is in big endian
	 * and the end tag is non-standard (0x79) and followed by an
	 * all-zero "checksum" byte.  Sun calls this a "Fresh Choice
	 * Ethernet" VPD...
	 */
	/* Look at the end tag to determine whether this is a VPD with 4 NAs. */
	if (HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_SIZE +
	    ETHER_ADDR_LEN) != 0x79 &&
	    HME_ROM_READ_1(j + 4 * (PCI_VPDRES_LARGE_DATA + PCI_VPD_SIZE +
	    ETHER_ADDR_LEN)) == 0x79)
		/* Use the Nth NA for the Nth HME on this SUNW,qfe. */
		j += slot * (PCI_VPDRES_LARGE_DATA + PCI_VPD_SIZE +
		    ETHER_ADDR_LEN);
	if (PCI_VPDRES_ISLARGE(HME_ROM_READ_1(j + PCI_VPDRES_BYTE0)) == 0 ||
	    PCI_VPDRES_LARGE_NAME(HME_ROM_READ_1(j + PCI_VPDRES_BYTE0)) !=
	    PCI_VPDRES_TYPE_VPD ||
	    (HME_ROM_READ_1(j + PCI_VPDRES_LARGE_LEN_LSB) << 8 |
	    HME_ROM_READ_1(j + PCI_VPDRES_LARGE_LEN_MSB)) !=
	    PCI_VPD_SIZE + ETHER_ADDR_LEN ||
	    HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY0) !=
	    0x4e /* N */ ||
	    HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY1) !=
	    0x41 /* A */ ||
	    HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_LEN) !=
	    ETHER_ADDR_LEN) {
		device_printf(dev, "unexpected PCI VPD\n");
		error = ENXIO;
		goto fail_rres;
	}
	bus_space_read_region_1(memt, memh, j + PCI_VPDRES_LARGE_DATA +
	    PCI_VPD_DATA, sc->sc_enaddr, ETHER_ADDR_LEN);

fail_rres:
	bus_release_resource(ebus_dev, SYS_RES_MEMORY,
	    rman_get_rid(ebus_rres), ebus_rres);
fail_children:
	free(children, M_TEMP);
	if (error != 0)
		goto fail_sres;
#endif

	sc->sc_burst = 64;	/* XXX */

	/*
	 * call the main configure
	 */
	if ((error = hme_config(sc)) != 0) {
		device_printf(dev, "could not be configured\n");
		goto fail_ires;
	}

	if ((error = bus_setup_intr(dev, hsc->hsc_ires, INTR_TYPE_NET |
	    INTR_MPSAFE, NULL, hme_intr, sc, &hsc->hsc_ih)) != 0) {
		device_printf(dev, "couldn't establish interrupt\n");
		hme_detach(sc);
		goto fail_ires;
	}
	return (0);

fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ,
	    rman_get_rid(hsc->hsc_ires), hsc->hsc_ires);
fail_sres:
	bus_release_resource(dev, SYS_RES_MEMORY,
	    rman_get_rid(hsc->hsc_sres), hsc->hsc_sres);
fail_mtx:
	mtx_destroy(&sc->sc_lock);
	return (error);
}
예제 #30
0
/* Attach the PHY to the MII bus */
static int
brgphy_attach(device_t dev)
{
	struct brgphy_softc *bsc;
	struct bge_softc *bge_sc = NULL;
	struct bce_softc *bce_sc = NULL;
	struct mii_softc *sc;
	struct mii_attach_args *ma;
	struct mii_data *mii;
	struct ifnet *ifp;
	int fast_ether;

	bsc = device_get_softc(dev);
	sc = &bsc->mii_sc;
	ma = device_get_ivars(dev);
	sc->mii_dev = device_get_parent(dev);
	mii = device_get_softc(sc->mii_dev);
	LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);

	/* Initialize mii_softc structure */
	sc->mii_inst = mii->mii_instance;
	sc->mii_phy = ma->mii_phyno;
	sc->mii_service = brgphy_service;
	sc->mii_pdata = mii;
	sc->mii_anegticks = MII_ANEGTICKS_GIGE;
	sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP;
	mii->mii_instance++;

	/* Initialize brgphy_softc structure */
	bsc->mii_oui = MII_OUI(ma->mii_id1, ma->mii_id2);
	bsc->mii_model = MII_MODEL(ma->mii_id2);
	bsc->mii_rev = MII_REV(ma->mii_id2);
	bsc->serdes_flags = 0;

	fast_ether = 0;

	if (bootverbose)
		device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n",
		    bsc->mii_oui, bsc->mii_model, bsc->mii_rev);

	/* Handle any special cases based on the PHY ID */
	switch (bsc->mii_oui) {
	case MII_OUI_BROADCOM:
	case MII_OUI_BROADCOM2:
		break;
	case MII_OUI_xxBROADCOM:
		switch (bsc->mii_model) {
			case MII_MODEL_xxBROADCOM_BCM5706:
				/*
				 * The 5464 PHY used in the 5706 supports both copper
				 * and fiber interfaces over GMII.  Need to check the
				 * shadow registers to see which mode is actually
				 * in effect, and therefore whether we have 5706C or
				 * 5706S.
				 */
				PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C,
					BRGPHY_SHADOW_1C_MODE_CTRL);
				if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) &
					BRGPHY_SHADOW_1C_ENA_1000X) {
					bsc->serdes_flags |= BRGPHY_5706S;
					sc->mii_flags |= MIIF_HAVEFIBER;
				}
				break;
		} break;
	case MII_OUI_xxBROADCOM_ALT1:
		switch (bsc->mii_model) {
			case MII_MODEL_xxBROADCOM_ALT1_BCM5708S:
				bsc->serdes_flags |= BRGPHY_5708S;
				sc->mii_flags |= MIIF_HAVEFIBER;
				break;
		} break;
	default:
		device_printf(dev, "Unrecognized OUI for PHY!\n");
	}

	ifp = sc->mii_pdata->mii_ifp;

	/* Find the MAC driver associated with this PHY. */
	if (strcmp(ifp->if_dname, "bge") == 0)	{
		bge_sc = ifp->if_softc;
	} else if (strcmp(ifp->if_dname, "bce") == 0) {
		bce_sc = ifp->if_softc;
	}

	/* Todo: Need to add additional controllers such as 5906 & 5787F */
	/* The 590x chips are 10/100 only. */
	if (bge_sc &&
	    pci_get_vendor(bge_sc->bge_dev) == BCOM_VENDORID &&
	    (pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901 ||
	    pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901A2 ||
	    pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906 ||
	    pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906M)) {
		fast_ether = 1;
		sc->mii_anegticks = MII_ANEGTICKS;
	}

	brgphy_reset(sc);

	/* Read the PHY's capabilities. */
	sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
	if (sc->mii_capabilities & BMSR_EXTSTAT)
		sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
	device_printf(dev, " ");

#define	ADD(m, c)	ifmedia_add(&mii->mii_media, (m), (c), NULL)

	/* Create an instance of Ethernet media. */
	ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), BMCR_ISO);

	/* Add the supported media types */
	if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst),
			BRGPHY_S10);
		printf("10baseT, ");
		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst),
			BRGPHY_S10 | BRGPHY_BMCR_FDX);
		printf("10baseT-FDX, ");
		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst),
			BRGPHY_S100);
		printf("100baseTX, ");
		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst),
			BRGPHY_S100 | BRGPHY_BMCR_FDX);
		printf("100baseTX-FDX, ");
		if (fast_ether == 0) {
			ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst),
				BRGPHY_S1000);
			printf("1000baseT, ");
			ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst),
				BRGPHY_S1000 | BRGPHY_BMCR_FDX);
			printf("1000baseT-FDX, ");
		}
	} else {
		ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst),
			BRGPHY_S1000 | BRGPHY_BMCR_FDX);
		printf("1000baseSX-FDX, ");
		/* 2.5G support is a software enabled feature on the 5708S and 5709S. */
		if (bce_sc && (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)) {
			ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, sc->mii_inst), 0);
			printf("2500baseSX-FDX, ");
		}
	}

	ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0);
	printf("auto\n");

#undef ADD
	MIIBUS_MEDIAINIT(sc->mii_dev);
	return (0);
}