ahci_generic.c revision 302408
1164190Sjkoshy/*-
2164190Sjkoshy * Copyright (c) 2009-2012 Alexander Motin <mav@FreeBSD.org>
3164190Sjkoshy * All rights reserved.
4164190Sjkoshy *
5164190Sjkoshy * Redistribution and use in source and binary forms, with or without
6164190Sjkoshy * modification, are permitted provided that the following conditions
7164190Sjkoshy * are met:
8164190Sjkoshy * 1. Redistributions of source code must retain the above copyright
9164190Sjkoshy *    notice, this list of conditions and the following disclaimer,
10164190Sjkoshy *    without modification, immediately at the beginning of the file.
11164190Sjkoshy * 2. Redistributions in binary form must reproduce the above copyright
12164190Sjkoshy *    notice, this list of conditions and the following disclaimer in the
13164190Sjkoshy *    documentation and/or other materials provided with the distribution.
14164190Sjkoshy *
15164190Sjkoshy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16164190Sjkoshy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17164190Sjkoshy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18164190Sjkoshy * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19164190Sjkoshy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20164190Sjkoshy * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21164190Sjkoshy * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22164190Sjkoshy * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23164190Sjkoshy * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24164190Sjkoshy * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25164190Sjkoshy */
26164190Sjkoshy
27164190Sjkoshy#include <sys/cdefs.h>
28164190Sjkoshy__FBSDID("$FreeBSD: stable/11/sys/dev/ahci/ahci_generic.c 291689 2015-12-03 11:24:11Z andrew $");
29164190Sjkoshy
30164190Sjkoshy#include <sys/param.h>
31164190Sjkoshy#include <sys/module.h>
32164190Sjkoshy#include <sys/systm.h>
33164190Sjkoshy#include <sys/kernel.h>
34164190Sjkoshy#include <sys/bus.h>
35164190Sjkoshy#include <sys/conf.h>
36164190Sjkoshy#include <sys/endian.h>
37164190Sjkoshy#include <sys/malloc.h>
38164190Sjkoshy#include <sys/lock.h>
39164190Sjkoshy#include <sys/mutex.h>
40164190Sjkoshy#include <sys/rman.h>
41164190Sjkoshy
42164190Sjkoshy#include <machine/bus.h>
43164190Sjkoshy#include <machine/resource.h>
44164190Sjkoshy
45164190Sjkoshy#include <dev/ahci/ahci.h>
46164190Sjkoshy
47164190Sjkoshy#include <dev/ofw/ofw_bus.h>
48164190Sjkoshy#include <dev/ofw/ofw_bus_subr.h>
49164190Sjkoshy
50164190Sjkoshystatic struct ofw_compat_data compat_data[] = {
51164190Sjkoshy	{"generic-ahci", 	1},
52164190Sjkoshy	{"snps,dwc-ahci",	1},
53164190Sjkoshy	{NULL,			0}
54164190Sjkoshy};
55164190Sjkoshy
56164190Sjkoshystatic int
57164190Sjkoshyahci_gen_ctlr_reset(device_t dev)
58164190Sjkoshy{
59164190Sjkoshy
60164190Sjkoshy	return ahci_ctlr_reset(dev);
61164190Sjkoshy}
62164190Sjkoshy
63164190Sjkoshystatic int
64164190Sjkoshyahci_probe(device_t dev)
65165316Sjkoshy{
66164190Sjkoshy
67164190Sjkoshy	if (!ofw_bus_status_okay(dev))
68164190Sjkoshy		return (ENXIO);
69164190Sjkoshy
70164190Sjkoshy	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
71165316Sjkoshy		return (ENXIO);
72164190Sjkoshy
73164190Sjkoshy	device_set_desc_copy(dev, "AHCI SATA controller");
74164190Sjkoshy	return (BUS_PROBE_DEFAULT);
75164190Sjkoshy}
76165316Sjkoshy
77164190Sjkoshystatic int
78164190Sjkoshyahci_gen_attach(device_t dev)
79164190Sjkoshy{
80164190Sjkoshy	struct ahci_controller *ctlr = device_get_softc(dev);
81164190Sjkoshy	int	error;
82164190Sjkoshy
83164190Sjkoshy	ctlr->r_rid = 0;
84164190Sjkoshy	ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &ctlr->r_rid,
85164190Sjkoshy	    RF_ACTIVE);
86164190Sjkoshy	if (ctlr->r_mem == NULL)
87165316Sjkoshy		return (ENXIO);
88164190Sjkoshy
89164190Sjkoshy	/* Setup controller defaults. */
90164190Sjkoshy	ctlr->numirqs = 1;
91164190Sjkoshy
92164190Sjkoshy	/* Reset controller */
93164190Sjkoshy	if ((error = ahci_gen_ctlr_reset(dev)) == 0)
94164190Sjkoshy		error = ahci_attach(dev);
95164190Sjkoshy
96164190Sjkoshy	if (error != 0) {
97164190Sjkoshy		if (ctlr->r_mem != NULL)
98164190Sjkoshy			bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid,
99164190Sjkoshy			    ctlr->r_mem);
100164190Sjkoshy	}
101164190Sjkoshy	return error;
102164190Sjkoshy}
103164190Sjkoshy
104164190Sjkoshystatic int
105164190Sjkoshyahci_gen_detach(device_t dev)
106164190Sjkoshy{
107164190Sjkoshy
108164190Sjkoshy	ahci_detach(dev);
109164190Sjkoshy	return (0);
110164190Sjkoshy}
111164190Sjkoshy
112164190Sjkoshystatic devclass_t ahci_gen_devclass;
113165316Sjkoshystatic device_method_t ahci_methods[] = {
114164190Sjkoshy	DEVMETHOD(device_probe,     ahci_probe),
115164190Sjkoshy	DEVMETHOD(device_attach,    ahci_gen_attach),
116164190Sjkoshy	DEVMETHOD(device_detach,    ahci_gen_detach),
117164190Sjkoshy	DEVMETHOD(bus_print_child,  ahci_print_child),
118164190Sjkoshy	DEVMETHOD(bus_alloc_resource,       ahci_alloc_resource),
119165316Sjkoshy	DEVMETHOD(bus_release_resource,     ahci_release_resource),
120164190Sjkoshy	DEVMETHOD(bus_setup_intr,   ahci_setup_intr),
121164190Sjkoshy	DEVMETHOD(bus_teardown_intr,ahci_teardown_intr),
122164190Sjkoshy	DEVMETHOD(bus_child_location_str, ahci_child_location_str),
123164190Sjkoshy	DEVMETHOD(bus_get_dma_tag,  ahci_get_dma_tag),
124165316Sjkoshy	DEVMETHOD_END
125164190Sjkoshy};
126164190Sjkoshystatic driver_t ahci_driver = {
127164190Sjkoshy	"ahci",
128164190Sjkoshy	ahci_methods,
129164190Sjkoshy	sizeof(struct ahci_controller)
130164190Sjkoshy};
131164190SjkoshyDRIVER_MODULE(ahci, simplebus, ahci_driver, ahci_gen_devclass, NULL, NULL);
132164190Sjkoshy