static void
jmahci_attach(device_t parent, device_t self, void *aux)
{
	struct jmahci_attach_args *jma = aux;
	const struct pci_attach_args *pa = jma->jma_pa;
	struct ahci_softc *sc = device_private(self);
	uint32_t ahci_cap;

	aprint_naive(": AHCI disk controller\n");
	aprint_normal("\n");

	sc->sc_atac.atac_dev = self;
	sc->sc_ahcit = jma->jma_ahcit;
	sc->sc_ahcih = jma->jma_ahcih;

	ahci_cap = AHCI_READ(sc, AHCI_CAP);

	if (pci_dma64_available(jma->jma_pa) && (ahci_cap & AHCI_CAP_64BIT))
		sc->sc_dmat = jma->jma_pa->pa_dmat64;
	else
		sc->sc_dmat = jma->jma_pa->pa_dmat;

	if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID)
		sc->sc_atac_capflags = ATAC_CAP_RAID;

	ahci_attach(sc);

	if (!pmf_device_register(self, NULL, jmahci_resume))
	    aprint_error_dev(self, "couldn't establish power handler\n");
}
static void
ahci_pci_attach(device_t parent, device_t self, void *aux)
{
	struct pci_attach_args *pa = aux;
	struct ahci_pci_softc *psc = device_private(self);
	struct ahci_softc *sc = &psc->ah_sc;
	const char *intrstr;
	bool ahci_cap_64bit;
	bool ahci_bad_64bit;
	pci_intr_handle_t intrhandle;

	sc->sc_atac.atac_dev = self;

	if (pci_mapreg_map(pa, AHCI_PCI_ABAR,
	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &sc->sc_ahcit, &sc->sc_ahcih, NULL, &sc->sc_ahcis) != 0) {
		aprint_error_dev(self, "can't map ahci registers\n");
		return;
	}
	psc->sc_pc = pa->pa_pc;
	psc->sc_pcitag = pa->pa_tag;

	pci_aprint_devinfo(pa, "AHCI disk controller");
	
	if (pci_intr_map(pa, &intrhandle) != 0) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, intrhandle);
	psc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO, ahci_intr, sc);
	if (psc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt\n");
		return;
	}
	aprint_normal_dev(self, "interrupting at %s\n",
	    intrstr ? intrstr : "unknown interrupt");

	sc->sc_dmat = pa->pa_dmat;

	sc->sc_ahci_quirks = ahci_pci_has_quirk(PCI_VENDOR(pa->pa_id),
					    PCI_PRODUCT(pa->pa_id));

	ahci_cap_64bit = (AHCI_READ(sc, AHCI_CAP) & AHCI_CAP_64BIT) != 0;
	ahci_bad_64bit = ((sc->sc_ahci_quirks & AHCI_PCI_QUIRK_BAD64) != 0);

	if (pci_dma64_available(pa) && ahci_cap_64bit) {
		if (!ahci_bad_64bit)
			sc->sc_dmat = pa->pa_dmat64;
		aprint_verbose_dev(self, "64-bit DMA%s\n",
		    (sc->sc_dmat == pa->pa_dmat) ? " unavailable" : "");
	}

	if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) {
		AHCIDEBUG_PRINT(("%s: RAID mode\n", AHCINAME(sc)), DEBUG_PROBE);
		sc->sc_atac_capflags = ATAC_CAP_RAID;
	} else {
		AHCIDEBUG_PRINT(("%s: SATA mode\n", AHCINAME(sc)), DEBUG_PROBE);
	}

	ahci_attach(sc);

	if (!pmf_device_register(self, NULL, ahci_pci_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");
}
示例#3
0
static void
siisata_pci_attach(device_t parent, device_t self, void *aux)
{
    struct pci_attach_args *pa = aux;
    struct siisata_pci_softc *psc = device_private(self);
    struct siisata_softc *sc = &psc->si_sc;
    char devinfo[256];
    const char *intrstr;
    pci_intr_handle_t intrhandle;
    pcireg_t csr, memtype;
    const struct siisata_pci_product *spp;
    void *ih;
    bus_space_tag_t memt;
    bus_space_handle_t memh;
    uint32_t gcreg;
    int memh_valid;
    bus_size_t grsize, prsize;

    sc->sc_atac.atac_dev = self;

    psc->sc_pc = pa->pa_pc;
    psc->sc_pcitag = pa->pa_tag;

    pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo, sizeof(devinfo));
    aprint_naive(": SATA-II HBA\n");
    aprint_normal(": %s\n", devinfo);

    /* map bar0 */
#if 1
    memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIISATA_PCI_BAR0);
#else
    memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT;
#endif
    switch (memtype) {
    case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
    case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
        memh_valid = (pci_mapreg_map(pa, SIISATA_PCI_BAR0,
                                     memtype, 0, &memt, &memh, NULL, &grsize) == 0);
        break;
    default:
        memh_valid = 0;
    }
    if (memh_valid) {
        sc->sc_grt = memt;
        sc->sc_grh = memh;
    } else {
        aprint_error("%s: unable to map device global registers\n",
                     SIISATANAME(sc));
        return;
    }

    /* map bar1 */
#if 1
    memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SIISATA_PCI_BAR1);
#else
    memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT;
#endif
    switch (memtype) {
    case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
    case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
        memh_valid = (pci_mapreg_map(pa, SIISATA_PCI_BAR1,
                                     memtype, 0, &memt, &memh, NULL, &prsize) == 0);
        break;
    default:
        memh_valid = 0;
    }
    if (memh_valid) {
        sc->sc_prt = memt;
        sc->sc_prh = memh;
    } else {
        bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize);
        aprint_error("%s: unable to map device port registers\n",
                     SIISATANAME(sc));
        return;
    }

    if (pci_dma64_available(pa)) {
        sc->sc_dmat = pa->pa_dmat64;
        sc->sc_have_dma64 = 1;
        aprint_debug("64-bit PCI DMA available\n");
    } else {
        sc->sc_dmat = pa->pa_dmat;
        sc->sc_have_dma64 = 0;
    }

    /* map interrupt */
    if (pci_intr_map(pa, &intrhandle) != 0) {
        bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize);
        bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize);
        aprint_error("%s: couldn't map interrupt\n", SIISATANAME(sc));
        return;
    }
    intrstr = pci_intr_string(pa->pa_pc, intrhandle);
    ih = pci_intr_establish(pa->pa_pc, intrhandle,
                            IPL_BIO, siisata_intr, sc);
    if (ih == NULL) {
        bus_space_unmap(sc->sc_grt, sc->sc_grh, grsize);
        bus_space_unmap(sc->sc_prt, sc->sc_prh, prsize);
        aprint_error("%s: couldn't establish interrupt"
                     "at %s\n", SIISATANAME(sc), intrstr);
        return;
    }
    aprint_normal("%s: interrupting at %s\n", SIISATANAME(sc),
                  intrstr ? intrstr : "unknown interrupt");

    /* fill in number of ports on this device */
    spp = siisata_pci_lookup(pa);
    if (spp != NULL) {
        sc->sc_atac.atac_nchannels = spp->spp_ports;
        sc->sc_chip = spp->spp_chip;
    } else
        /* _match() should prevent us from getting here */
        panic("siisata: the universe might be falling apart!\n");

    gcreg = GRREAD(sc, GR_GC);

    aprint_normal("%s: SiI%d on ", SIISATANAME(sc), sc->sc_chip);
    if (sc->sc_chip == 3124) {
        aprint_normal("%d-bit, ", (gcreg & GR_GC_REQ64) ? 64 : 32);
        switch (gcreg & (GR_GC_DEVSEL | GR_GC_STOP | GR_GC_TRDY)) {
        case 0:
            aprint_normal("%d", (gcreg & GR_GC_M66EN) ? 66 : 33);
            break;
        case GR_GC_TRDY:
            aprint_normal("%d", 66);
            break;
        case GR_GC_STOP:
            aprint_normal("%d", 100);
            break;
        case GR_GC_STOP | GR_GC_TRDY:
            aprint_normal("%d", 133);
            break;
        default:
            break;
        }
        aprint_normal("MHz PCI%s bus.", (gcreg & (GR_GC_DEVSEL | GR_GC_STOP | GR_GC_TRDY)) ? "-X" : "");
    } else {
        /* XXX - but only x1 devices so far */
        aprint_normal("PCI-Express x1 port.");
    }
    if (gcreg & GR_GC_3GBPS)
        aprint_normal(" 3.0Gb/s capable.\n");
    else
        aprint_normal("\n");

    /* enable bus mastering in case the firmware didn't */
    csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
    csr |= PCI_COMMAND_MASTER_ENABLE;
    csr |= PCI_COMMAND_MEM_ENABLE;
    pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, csr);

    siisata_attach(sc);

    if (!pmf_device_register(self, NULL, siisata_pci_resume))
        aprint_error_dev(self, "couldn't establish power handler\n");
}
示例#4
0
static void
xhci_pci_attach(device_t parent, device_t self, void *aux)
{
	struct xhci_pci_softc * const psc = device_private(self);
	struct xhci_softc * const sc = &psc->sc_xhci;
	struct pci_attach_args *const pa = (struct pci_attach_args *)aux;
	const pci_chipset_tag_t pc = pa->pa_pc;
	const pcitag_t tag = pa->pa_tag;
	char const *intrstr;
	pci_intr_handle_t ih;
	pcireg_t csr, memtype;
	int err;
	//const char *vendor;
	uint32_t hccparams;
	char intrbuf[PCI_INTRSTR_LEN];

	sc->sc_dev = self;
	sc->sc_bus.hci_private = sc;

	pci_aprint_devinfo(pa, "USB Controller");

	/* Check for quirks */
	sc->sc_xhci_quirks = xhci_pci_has_quirk(PCI_VENDOR(pa->pa_id),
						PCI_PRODUCT(pa->pa_id));

	/* check if memory space access is enabled */
	csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
#ifdef DEBUG
	printf("csr: %08x\n", csr);
#endif
	if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) {
		aprint_error_dev(self, "memory access is disabled\n");
		return;
	}

	/* map MMIO registers */
	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_CBMEM);
	switch (memtype) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		if (pci_mapreg_map(pa, PCI_CBMEM, memtype, 0,
			   &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios)) {
			sc->sc_ios = 0;
			aprint_error_dev(self, "can't map mem space\n");
			return;
		}
		break;
	default:
		aprint_error_dev(self, "BAR not 64 or 32-bit MMIO\n");
		return;
		break;
	}

	psc->sc_pc = pc;
	psc->sc_tag = tag;

	hccparams = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 0x10);

	if (pci_dma64_available(pa) && ((hccparams&1)==1))
		sc->sc_bus.dmatag = pa->pa_dmat64;
	else
		sc->sc_bus.dmatag = pa->pa_dmat;

	/* Enable the device. */
	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
		       csr | PCI_COMMAND_MASTER_ENABLE);

	/* Map and establish the interrupt. */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(self, "couldn't map interrupt\n");
		goto fail;
	}

	/*
	 * Allocate IRQ
	 */
	intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, xhci_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		goto fail;
	}
	aprint_normal_dev(self, "interrupting at %s\n", intrstr);

#if 0
	/* Figure out vendor for root hub descriptor. */
	vendor = pci_findvendor(pa->pa_id);
	sc->sc_id_vendor = PCI_VENDOR(pa->pa_id);
	if (vendor)
		strlcpy(sc->sc_vendor, vendor, sizeof(sc->sc_vendor));
	else
		snprintf(sc->sc_vendor, sizeof(sc->sc_vendor),
		    "vendor 0x%04x", PCI_VENDOR(pa->pa_id));
#endif

	err = xhci_init(sc);
	if (err) {
		aprint_error_dev(self, "init failed, error=%d\n", err);
		goto fail;
	}

	/* Intel chipset requires SuperSpeed enable and USB2 port routing */
	switch (PCI_VENDOR(pa->pa_id)) {
	case PCI_VENDOR_INTEL:
		xhci_pci_port_route(psc);
		break;
	default:
		break;
	}

	if (!pmf_device_register1(self, xhci_suspend, xhci_resume,
	                          xhci_shutdown))
		aprint_error_dev(self, "couldn't establish power handler\n");

	/* Attach usb device. */
	sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
	return;

fail:
	if (sc->sc_ih) {
		pci_intr_disestablish(psc->sc_pc, sc->sc_ih);
		sc->sc_ih = NULL;
	}
	if (sc->sc_ios) {
		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
		sc->sc_ios = 0;
	}
	return;
}