void mfi_pci_attach(struct device *parent, struct device *self, void *aux) { struct mfi_softc *sc = (struct mfi_softc *)self; struct pci_attach_args *pa = aux; const struct mfi_pci_device *mpd; pci_intr_handle_t ih; bus_size_t size; pcireg_t reg; int regbar; mpd = mfi_pci_find_device(pa); if (mpd == NULL) { printf(": can't find matching pci device\n"); return; } if (mpd->mpd_iop == MFI_IOP_GEN2 || mpd->mpd_iop == MFI_IOP_SKINNY) regbar = MFI_BAR_GEN2; else regbar = MFI_BAR; reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, regbar); if (pci_mapreg_map(pa, regbar, reg, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &size, MFI_PCI_MEMSIZE)) { printf(": can't map controller pci space\n"); return; } sc->sc_dmat = pa->pa_dmat; if (pci_intr_map(pa, &ih) != 0) { printf(": can't map interrupt\n"); goto unmap; } printf(": %s\n", pci_intr_string(pa->pa_pc, ih)); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, mfi_intr, sc, sc->sc_dev.dv_xname); if (!sc->sc_ih) { printf("%s: can't establish interrupt\n", DEVNAME(sc)); goto unmap; } if (mfi_attach(sc, mpd->mpd_iop)) { printf("%s: can't attach\n", DEVNAME(sc)); goto unintr; } return; unintr: pci_intr_disestablish(pa->pa_pc, sc->sc_ih); sc->sc_ih = NULL; unmap: bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); }
void mfi_pci_attach(struct device *parent, struct device *self, void *aux) { struct mfi_softc *sc = (struct mfi_softc *)self; struct pci_attach_args *pa = aux; const char *intrstr; pci_intr_handle_t ih; bus_size_t size; pcireg_t csr; uint32_t subsysid, i; subsysid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); for (i = 0; mfi_pci_devices[i].mpd_vendor; i++) if (mfi_pci_devices[i].mpd_subvendor == PCI_VENDOR(subsysid) && mfi_pci_devices[i].mpd_subproduct == PCI_PRODUCT(subsysid)){ printf(", %s", mfi_pci_devices[i].mpd_model); break; } csr = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MFI_BAR); csr |= PCI_MAPREG_MEM_TYPE_32BIT; if (pci_mapreg_map(pa, MFI_BAR, csr, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &size, MFI_PCI_MEMSIZE)) { printf(": can't map controller pci space\n"); return; } sc->sc_dmat = pa->pa_dmat; if (pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); return; } intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, mfi_intr, sc, sc->sc_dev.dv_xname); if (!sc->sc_ih) { printf(": can't establish interrupt"); if (intrstr) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); return; } printf(": %s\n", intrstr); if (mfi_attach(sc)) { printf("%s: can't attach", DEVNAME(sc)); pci_intr_disestablish(pa->pa_pc, sc->sc_ih); sc->sc_ih = NULL; bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); } }
static int mfi_pci_attach(device_t dev) { struct mfi_softc *sc; struct mfi_ident *m; int count, error; sc = device_get_softc(dev); bzero(sc, sizeof(*sc)); sc->mfi_dev = dev; m = mfi_find_ident(dev); sc->mfi_flags = m->flags; /* Ensure busmastering is enabled */ pci_enable_busmaster(dev); /* Allocate PCI registers */ if ((sc->mfi_flags & MFI_FLAGS_1064R) || (sc->mfi_flags & MFI_FLAGS_1078)) { /* 1068/1078: Memory mapped BAR is at offset 0x10 */ sc->mfi_regs_rid = PCIR_BAR(0); } else if ((sc->mfi_flags & MFI_FLAGS_GEN2) || (sc->mfi_flags & MFI_FLAGS_SKINNY) || (sc->mfi_flags & MFI_FLAGS_TBOLT)) { /* Gen2/Skinny: Memory mapped BAR is at offset 0x14 */ sc->mfi_regs_rid = PCIR_BAR(1); } if ((sc->mfi_regs_resource = bus_alloc_resource_any(sc->mfi_dev, SYS_RES_MEMORY, &sc->mfi_regs_rid, RF_ACTIVE)) == NULL) { device_printf(dev, "Cannot allocate PCI registers\n"); return (ENXIO); } sc->mfi_btag = rman_get_bustag(sc->mfi_regs_resource); sc->mfi_bhandle = rman_get_bushandle(sc->mfi_regs_resource); error = ENOMEM; /* Allocate parent DMA tag */ if (bus_dma_tag_create( bus_get_dma_tag(dev), /* PCI parent */ 1, 0, /* algnmnt, boundary */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ BUS_SPACE_MAXSIZE_32BIT,/* maxsize */ BUS_SPACE_UNRESTRICTED, /* nsegments */ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &sc->mfi_parent_dmat)) { device_printf(dev, "Cannot allocate parent DMA tag\n"); goto out; } /* Allocate IRQ resource. */ sc->mfi_irq_rid = 0; count = 1; if (mfi_msi && pci_alloc_msi(sc->mfi_dev, &count) == 0) { device_printf(sc->mfi_dev, "Using MSI\n"); sc->mfi_irq_rid = 1; } if ((sc->mfi_irq = bus_alloc_resource_any(sc->mfi_dev, SYS_RES_IRQ, &sc->mfi_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(sc->mfi_dev, "Cannot allocate interrupt\n"); error = EINVAL; goto out; } error = mfi_attach(sc); out: if (error) { mfi_free(sc); mfi_pci_free(sc); } return (error); }
void mfi_pci_attach(struct device *parent, struct device *self, void *aux) { struct mfi_softc *sc = (struct mfi_softc *)self; struct pci_attach_args *pa = aux; const struct mfi_pci_device *mpd; const struct mfi_pci_subtype *st; const char *intrstr; pci_intr_handle_t ih; bus_size_t size; pcireg_t reg; const char *subtype = NULL; char subid[32]; mpd = mfi_pci_find_device(pa); reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MFI_BAR); if (pci_mapreg_map(pa, MFI_BAR, reg, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &size, MFI_PCI_MEMSIZE)) { printf(": can't map controller pci space\n"); return; } sc->sc_dmat = pa->pa_dmat; if (pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); return; } intrstr = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, mfi_intr, sc, sc->sc_dev.dv_xname); if (!sc->sc_ih) { printf(": can't establish interrupt"); if (intrstr) printf(" at %s", intrstr); printf("\n"); bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); return; } reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); if (mpd->mpd_subtype != NULL) { st = mpd->mpd_subtype; while (st->st_id != 0x0) { if (st->st_id == reg) { subtype = st->st_string; break; } st++; } } if (subtype == NULL) { snprintf(subid, sizeof(subid), "0x%08x", reg); subtype = subid; } printf(": %s, %s\n", intrstr, subtype); if (mfi_attach(sc, mpd->mpd_iop)) { printf("%s: can't attach\n", DEVNAME(sc)); pci_intr_disestablish(pa->pa_pc, sc->sc_ih); sc->sc_ih = NULL; bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); } }
static int mfi_pci_attach(device_t dev) { struct mfi_softc *sc; struct mfi_ident *m; uint32_t command; int count, error; sc = device_get_softc(dev); bzero(sc, sizeof(*sc)); sc->mfi_dev = dev; m = mfi_find_ident(dev); sc->mfi_flags = m->flags; /* Verify that the adapter can be set up in PCI space */ command = pci_read_config(dev, PCIR_COMMAND, 2); command |= PCIM_CMD_BUSMASTEREN; pci_write_config(dev, PCIR_COMMAND, command, 2); command = pci_read_config(dev, PCIR_COMMAND, 2); if ((command & PCIM_CMD_BUSMASTEREN) == 0) { device_printf(dev, "Can't enable PCI busmaster\n"); return (ENXIO); } if ((command & PCIM_CMD_MEMEN) == 0) { device_printf(dev, "PCI memory window not available\n"); return (ENXIO); } /* Allocate PCI registers */ if ((sc->mfi_flags & MFI_FLAGS_1064R) || (sc->mfi_flags & MFI_FLAGS_1078)) { /* 1068/1078: Memory mapped BAR is at offset 0x10 */ sc->mfi_regs_rid = PCIR_BAR(0); } else if (sc->mfi_flags & MFI_FLAGS_GEN2) { /* GEN2: Memory mapped BAR is at offset 0x14 */ sc->mfi_regs_rid = PCIR_BAR(1); } if ((sc->mfi_regs_resource = bus_alloc_resource_any(sc->mfi_dev, SYS_RES_MEMORY, &sc->mfi_regs_rid, RF_ACTIVE)) == NULL) { device_printf(dev, "Cannot allocate PCI registers\n"); return (ENXIO); } sc->mfi_btag = rman_get_bustag(sc->mfi_regs_resource); sc->mfi_bhandle = rman_get_bushandle(sc->mfi_regs_resource); error = ENOMEM; /* Allocate parent DMA tag */ if (bus_dma_tag_create( NULL, /* parent */ 1, 0, /* algnmnt, boundary */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ BUS_SPACE_MAXSIZE_32BIT,/* maxsize */ BUS_SPACE_UNRESTRICTED, /* nsegments */ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 0, /* flags */ NULL, NULL, /* lockfunc, lockarg */ &sc->mfi_parent_dmat)) { device_printf(dev, "Cannot allocate parent DMA tag\n"); goto out; } /* Allocate IRQ resource. */ sc->mfi_irq_rid = 0; count = 1; if (mfi_msi && pci_alloc_msi(sc->mfi_dev, &count) == 0) { device_printf(sc->mfi_dev, "Using MSI\n"); sc->mfi_irq_rid = 1; } if ((sc->mfi_irq = bus_alloc_resource_any(sc->mfi_dev, SYS_RES_IRQ, &sc->mfi_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { device_printf(sc->mfi_dev, "Cannot allocate interrupt\n"); error = EINVAL; goto out; } error = mfi_attach(sc); out: if (error) { mfi_free(sc); mfi_pci_free(sc); } return (error); }