f2e7bb61310e695b9d34c8671b58077da627b2cf
[dragonfly.git] / sys / dev / disk / ahci / ahci_dragonfly.c
1 /*
2  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 /*
35  * Primary device and CAM interface to OpenBSD AHCI driver, for DragonFly
36  */
37
38 #include "ahci.h"
39
40 /*
41  * Device bus methods
42  */
43
44 static int      ahci_probe (device_t dev);
45 static int      ahci_attach (device_t dev);
46 static int      ahci_detach (device_t dev);
47 #if 0
48 static int      ahci_shutdown (device_t dev);
49 static int      ahci_suspend (device_t dev);
50 static int      ahci_resume (device_t dev);
51 #endif
52
53 static device_method_t ahci_methods[] = {
54         DEVMETHOD(device_probe,         ahci_probe),
55         DEVMETHOD(device_attach,        ahci_attach),
56         DEVMETHOD(device_detach,        ahci_detach),
57 #if 0
58         DEVMETHOD(device_shutdown,      ahci_shutdown),
59         DEVMETHOD(device_suspend,       ahci_suspend),
60         DEVMETHOD(device_resume,        ahci_resume),
61 #endif
62
63         DEVMETHOD(bus_print_child,      bus_generic_print_child),
64         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
65         {0, 0}
66 };
67
68 static devclass_t       ahci_devclass;
69
70 static driver_t ahci_driver = {
71         "ahci",
72         ahci_methods,
73         sizeof(struct ahci_softc)
74 };
75
76 MODULE_DEPEND(ahci, cam, 1, 1, 1);
77 DRIVER_MODULE(ahci, pci, ahci_driver, ahci_devclass, 0, 0);
78
79 /*
80  * Device bus method procedures
81  */
82 static int
83 ahci_probe (device_t dev)
84 {
85         const struct ahci_device *ad;
86
87         ad = ahci_lookup_device(dev);
88         if (ad) {
89                 device_set_desc(dev, ad->name);
90                 return(-5);     /* higher priority the NATA */
91         }
92         return(ENXIO);
93 }
94
95 static int
96 ahci_attach (device_t dev)
97 {
98         struct ahci_softc *sc = device_get_softc(dev);
99         int error;
100
101         sc->sc_ad = ahci_lookup_device(dev);
102         if (sc->sc_ad == NULL)
103                 return(ENXIO);
104         error = sc->sc_ad->ad_attach(dev);
105         return (error);
106 }
107
108 static int
109 ahci_detach (device_t dev)
110 {
111         struct ahci_softc *sc = device_get_softc(dev);
112         int error = 0;
113
114         if (sc->sc_ad) {
115                 error = sc->sc_ad->ad_detach(dev);
116                 sc->sc_ad = NULL;
117         }
118         return(error);
119 }
120
121 #if 0
122
123 static int
124 ahci_shutdown (device_t dev)
125 {
126         return (0);
127 }
128
129 static int
130 ahci_suspend (device_t dev)
131 {
132         return (0);
133 }
134
135 static int
136 ahci_resume (device_t dev)
137 {
138         return (0);
139 }
140
141 #endif
142
143 void
144 ahci_os_sleep(int ms)
145 {
146         int ticks;
147
148 #if 0
149         if (mygd->gd_intr_nesting_level) {
150                 DELAY(ms * 1000);
151         } else {
152 #endif
153         {
154                 ticks = hz * ms / 1000 + 1;
155                 tsleep(&ticks, 0, "ahslp", ticks);
156         }
157 }