コード例 #1
0
ファイル: xlp_pci.c プロジェクト: wulf7/freebsd
static int
xlp_pci_attach(device_t dev)
{
	device_t pcib = device_get_parent(dev);
	int maxslots, s, f, pcifunchigh;
	int busno;
	uint8_t hdrtype;

	/*
	 * The on-chip devices are on a bus that is almost, but not
	 * quite, completely like PCI. Add those things by hand.
	 */
	busno = pcib_get_bus(dev);
	maxslots = PCIB_MAXSLOTS(pcib);
	for (s = 0; s <= maxslots; s++) {
		pcifunchigh = 0;
		f = 0;
		hdrtype = PCIB_READ_CONFIG(pcib, busno, s, f, PCIR_HDRTYPE, 1);
		if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
			continue;
		if (hdrtype & PCIM_MFDEV)
			pcifunchigh = PCI_FUNCMAX;
		for (f = 0; f <= pcifunchigh; f++)
			xlp_add_soc_child(pcib, dev, busno, s, f);
	}
	return (bus_generic_attach(dev));
}
コード例 #2
0
ファイル: xlp_pci.c プロジェクト: drpnd/freebsd
static int
xlp_pci_attach(device_t dev)
{
    struct pci_devinfo *dinfo;
    device_t pcib;
    int maxslots, s, f, pcifunchigh, irq;
    int busno, node, devoffset;
    uint16_t devid;
    uint8_t hdrtype;

    /*
     * The on-chip devices are on a bus that is almost, but not
     * quite, completely like PCI. Add those things by hand.
     */
    pcib = device_get_parent(dev);
    busno = pcib_get_bus(dev);
    maxslots = PCIB_MAXSLOTS(pcib);
    for (s = 0; s <= maxslots; s++) {
        pcifunchigh = 0;
        f = 0;
        hdrtype = PCIB_READ_CONFIG(pcib, busno, s, f, PCIR_HDRTYPE, 1);
        if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
            continue;
        if (hdrtype & PCIM_MFDEV)
            pcifunchigh = PCI_FUNCMAX;
        node = s / 8;
        for (f = 0; f <= pcifunchigh; f++) {
            devoffset = XLP_HDR_OFFSET(node, 0, s % 8, f);
            if (!nlm_dev_exists(devoffset))
                continue;

            /* Find if there is a desc for the SoC device */
            devid = PCIB_READ_CONFIG(pcib, busno, s, f, PCIR_DEVICE, 2);

            /* Skip devices that don't have a proper PCI header */
            switch (devid) {
            case PCI_DEVICE_ID_NLM_ICI:
            case PCI_DEVICE_ID_NLM_PIC:
            case PCI_DEVICE_ID_NLM_FMN:
            case PCI_DEVICE_ID_NLM_UART:
            case PCI_DEVICE_ID_NLM_I2C:
            case PCI_DEVICE_ID_NLM_NOR:
            case PCI_DEVICE_ID_NLM_MMC:
                continue;
            case PCI_DEVICE_ID_NLM_EHCI:
                irq = PIC_USB_IRQ(f);
                PCIB_WRITE_CONFIG(pcib, busno, s, f,
                                  XLP_PCI_DEVSCRATCH_REG0 << 2,
                                  (1 << 8) | irq, 4);
            }
            dinfo = pci_read_device(pcib, dev, pcib_get_domain(dev),
                                    busno, s, f);
            pci_add_child(dev, dinfo);
        }
    }
    return (bus_generic_attach(dev));
}
コード例 #3
0
ファイル: ofw_pcibus.c プロジェクト: fengsi/freebsd
static void
ofw_pcibus_enum_bus(device_t dev, u_int domain, u_int busno)
{
	device_t pcib;
	struct ofw_pcibus_devinfo *dinfo;
	int maxslots;
	int s, f, pcifunchigh;
	uint8_t hdrtype;

	pcib = device_get_parent(dev);

	maxslots = PCIB_MAXSLOTS(pcib);
	for (s = 0; s <= maxslots; s++) {
		pcifunchigh = 0;
		f = 0;
		DELAY(1);
		hdrtype = PCIB_READ_CONFIG(pcib, busno, s, f, PCIR_HDRTYPE, 1);
		if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
			continue;
		if (hdrtype & PCIM_MFDEV)
			pcifunchigh = PCI_FUNCMAX;
		for (f = 0; f <= pcifunchigh; f++) {
			/* Filter devices we have already added */
			if (pci_find_dbsf(domain, busno, s, f) != NULL)
				continue;

			dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(
			    pcib, domain, busno, s, f, sizeof(*dinfo));
			if (dinfo == NULL)
				continue;

			dinfo->opd_dma_tag = NULL;
			dinfo->opd_obdinfo.obd_node = -1;

			dinfo->opd_obdinfo.obd_name = NULL;
			dinfo->opd_obdinfo.obd_compat = NULL;
			dinfo->opd_obdinfo.obd_type = NULL;
			dinfo->opd_obdinfo.obd_model = NULL;

			/*
			 * For non OFW-devices, don't believe 0 
			 * for an interrupt.
			 */
			if (dinfo->opd_dinfo.cfg.intline == 0) {
				dinfo->opd_dinfo.cfg.intline = PCI_INVALID_IRQ;
				PCIB_WRITE_CONFIG(pcib, busno, s, f, 
				    PCIR_INTLINE, PCI_INVALID_IRQ, 1);
			}

			pci_add_child(dev, (struct pci_devinfo *)dinfo);
		}
	}
}