Пример #1
0
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;
}
Пример #2
0
/*
 * 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);
}
Пример #3
0
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);
}
Пример #4
0
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);
}