void ahci_pci_attach(struct device *parent, struct device *self, void *aux) { struct ahci_pci_softc *psc = (struct ahci_pci_softc *)self; struct ahci_softc *sc = &psc->psc_ahci; struct pci_attach_args *pa = aux; const struct ahci_device *ad; pci_intr_handle_t ih; int mapped = 0; psc->psc_pc = pa->pa_pc; psc->psc_tag = pa->pa_tag; sc->sc_dmat = pa->pa_dmat; ad = ahci_lookup_device(pa); if (ad != NULL && ad->ad_attach != NULL) { if (ad->ad_attach(sc, pa) != 0) { /* error should be printed by ad_attach */ return; } } if (!(sc->sc_flags & AHCI_F_NO_MSI)) mapped = pci_intr_map_msi(pa, &ih) != 0 ? 0 : 1; if (!mapped && pci_intr_map(pa, &ih) != 0) { printf(": unable to map interrupt\n"); return; } printf(": %s,", pci_intr_string(pa->pa_pc, ih)); if (ahci_map_regs(psc, pa) != 0) { /* error already printed by ahci_map_regs */ return; } if (ahci_map_intr(psc, pa, ih) != 0) { /* error already printed by ahci_map_intr */ goto unmap; } if (ahci_attach(sc) != 0) { /* error printed by ahci_attach */ goto unmap; } return; unmap: ahci_unmap_regs(psc); return; }
/* * Device bus method procedures */ static int ahci_probe (device_t dev) { const struct ahci_device *ad; if (kgetenv("hint.ahci.disabled")) return(ENXIO); ad = ahci_lookup_device(dev); if (ad) { device_set_desc(dev, ad->name); return(-5); /* higher priority the NATA */ } return(ENXIO); }
static int ahci_attach (device_t dev) { struct ahci_softc *sc = device_get_softc(dev); char name[16]; int error; sc->sc_ad = ahci_lookup_device(dev); if (sc->sc_ad == NULL) return(ENXIO); /* * Some chipsets do not properly implement the AHCI spec and may * require the link speed to be specifically requested. */ if (kgetenv("hint.ahci.force150")) AhciForceGen = 1; if (kgetenv("hint.ahci.force300")) AhciForceGen = 2; if (kgetenv("hint.ahci.force600")) AhciForceGen = 3; if (kgetenv("hint.ahci.nofeatures")) AhciNoFeatures = -1; if (kgetenv("hint.ahci.forcefbss")) sc->sc_flags |= AHCI_F_FORCE_FBSS; sysctl_ctx_init(&sc->sysctl_ctx); ksnprintf(name, sizeof(name), "%s%d", device_get_name(dev), device_get_unit(dev)); sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, name, CTLFLAG_RD, 0, ""); error = sc->sc_ad->ad_attach(dev); if (error) { sysctl_ctx_free(&sc->sysctl_ctx); sc->sysctl_tree = NULL; } return (error); }
int ahci_pci_match(struct device *parent, void *match, void *aux) { struct pci_attach_args *pa = aux; const struct ahci_device *ad; ad = ahci_lookup_device(pa); if (ad != NULL) { /* the device may need special checks to see if it matches */ if (ad->ad_match != NULL) return (ad->ad_match(pa)); return (2); /* match higher than pciide */ } if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_SATA && PCI_INTERFACE(pa->pa_class) == AHCI_PCI_INTERFACE) return (2); return (0); }