1258223a3SMatthew Dillon /* 2258223a3SMatthew Dillon * Copyright (c) 2009 The DragonFly Project. All rights reserved. 3258223a3SMatthew Dillon * 4258223a3SMatthew Dillon * This code is derived from software contributed to The DragonFly Project 5258223a3SMatthew Dillon * by Matthew Dillon <dillon@backplane.com> 6258223a3SMatthew Dillon * 7258223a3SMatthew Dillon * Redistribution and use in source and binary forms, with or without 8258223a3SMatthew Dillon * modification, are permitted provided that the following conditions 9258223a3SMatthew Dillon * are met: 10258223a3SMatthew Dillon * 11258223a3SMatthew Dillon * 1. Redistributions of source code must retain the above copyright 12258223a3SMatthew Dillon * notice, this list of conditions and the following disclaimer. 13258223a3SMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright 14258223a3SMatthew Dillon * notice, this list of conditions and the following disclaimer in 15258223a3SMatthew Dillon * the documentation and/or other materials provided with the 16258223a3SMatthew Dillon * distribution. 17258223a3SMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its 18258223a3SMatthew Dillon * contributors may be used to endorse or promote products derived 19258223a3SMatthew Dillon * from this software without specific, prior written permission. 20258223a3SMatthew Dillon * 21258223a3SMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22258223a3SMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23258223a3SMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24258223a3SMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25258223a3SMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26258223a3SMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27258223a3SMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28258223a3SMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29258223a3SMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30258223a3SMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31258223a3SMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32258223a3SMatthew Dillon * SUCH DAMAGE. 33258223a3SMatthew Dillon */ 34258223a3SMatthew Dillon /* 35258223a3SMatthew Dillon * Primary device and CAM interface to OpenBSD AHCI driver, for DragonFly 36258223a3SMatthew Dillon */ 37258223a3SMatthew Dillon 38258223a3SMatthew Dillon #include "ahci.h" 39258223a3SMatthew Dillon 40258223a3SMatthew Dillon /* 41258223a3SMatthew Dillon * Device bus methods 42258223a3SMatthew Dillon */ 43258223a3SMatthew Dillon 44258223a3SMatthew Dillon static int ahci_probe (device_t dev); 45258223a3SMatthew Dillon static int ahci_attach (device_t dev); 46258223a3SMatthew Dillon static int ahci_detach (device_t dev); 47258223a3SMatthew Dillon #if 0 48258223a3SMatthew Dillon static int ahci_shutdown (device_t dev); 49258223a3SMatthew Dillon static int ahci_suspend (device_t dev); 50258223a3SMatthew Dillon static int ahci_resume (device_t dev); 51258223a3SMatthew Dillon #endif 52258223a3SMatthew Dillon 53258223a3SMatthew Dillon static device_method_t ahci_methods[] = { 54258223a3SMatthew Dillon DEVMETHOD(device_probe, ahci_probe), 55258223a3SMatthew Dillon DEVMETHOD(device_attach, ahci_attach), 56258223a3SMatthew Dillon DEVMETHOD(device_detach, ahci_detach), 57258223a3SMatthew Dillon #if 0 58258223a3SMatthew Dillon DEVMETHOD(device_shutdown, ahci_shutdown), 59258223a3SMatthew Dillon DEVMETHOD(device_suspend, ahci_suspend), 60258223a3SMatthew Dillon DEVMETHOD(device_resume, ahci_resume), 61258223a3SMatthew Dillon #endif 62258223a3SMatthew Dillon 63258223a3SMatthew Dillon DEVMETHOD(bus_print_child, bus_generic_print_child), 64258223a3SMatthew Dillon DEVMETHOD(bus_driver_added, bus_generic_driver_added), 65258223a3SMatthew Dillon {0, 0} 66258223a3SMatthew Dillon }; 67258223a3SMatthew Dillon 68258223a3SMatthew Dillon static devclass_t ahci_devclass; 69258223a3SMatthew Dillon 70258223a3SMatthew Dillon static driver_t ahci_driver = { 71258223a3SMatthew Dillon "ahci", 72258223a3SMatthew Dillon ahci_methods, 73258223a3SMatthew Dillon sizeof(struct ahci_softc) 74258223a3SMatthew Dillon }; 75258223a3SMatthew Dillon 76258223a3SMatthew Dillon MODULE_DEPEND(ahci, cam, 1, 1, 1); 77258223a3SMatthew Dillon DRIVER_MODULE(ahci, pci, ahci_driver, ahci_devclass, 0, 0); 78258223a3SMatthew Dillon 79258223a3SMatthew Dillon /* 80258223a3SMatthew Dillon * Device bus method procedures 81258223a3SMatthew Dillon */ 82258223a3SMatthew Dillon static int 83258223a3SMatthew Dillon ahci_probe (device_t dev) 84258223a3SMatthew Dillon { 85258223a3SMatthew Dillon const struct ahci_device *ad; 86258223a3SMatthew Dillon 87258223a3SMatthew Dillon ad = ahci_lookup_device(dev); 88258223a3SMatthew Dillon if (ad) { 89258223a3SMatthew Dillon device_set_desc(dev, ad->name); 90258223a3SMatthew Dillon return(-5); /* higher priority the NATA */ 91258223a3SMatthew Dillon } 92258223a3SMatthew Dillon return(ENXIO); 93258223a3SMatthew Dillon } 94258223a3SMatthew Dillon 95258223a3SMatthew Dillon static int 96258223a3SMatthew Dillon ahci_attach (device_t dev) 97258223a3SMatthew Dillon { 98258223a3SMatthew Dillon struct ahci_softc *sc = device_get_softc(dev); 99258223a3SMatthew Dillon int error; 100258223a3SMatthew Dillon 101258223a3SMatthew Dillon sc->sc_ad = ahci_lookup_device(dev); 102258223a3SMatthew Dillon if (sc->sc_ad == NULL) 103258223a3SMatthew Dillon return(ENXIO); 104258223a3SMatthew Dillon error = sc->sc_ad->ad_attach(dev); 105258223a3SMatthew Dillon return (error); 106258223a3SMatthew Dillon } 107258223a3SMatthew Dillon 108258223a3SMatthew Dillon static int 109258223a3SMatthew Dillon ahci_detach (device_t dev) 110258223a3SMatthew Dillon { 111258223a3SMatthew Dillon struct ahci_softc *sc = device_get_softc(dev); 112258223a3SMatthew Dillon int error = 0; 113258223a3SMatthew Dillon 114258223a3SMatthew Dillon if (sc->sc_ad) { 115258223a3SMatthew Dillon error = sc->sc_ad->ad_detach(dev); 116258223a3SMatthew Dillon sc->sc_ad = NULL; 117258223a3SMatthew Dillon } 118258223a3SMatthew Dillon return(error); 119258223a3SMatthew Dillon } 120258223a3SMatthew Dillon 121258223a3SMatthew Dillon #if 0 122258223a3SMatthew Dillon 123258223a3SMatthew Dillon static int 124258223a3SMatthew Dillon ahci_shutdown (device_t dev) 125258223a3SMatthew Dillon { 126258223a3SMatthew Dillon return (0); 127258223a3SMatthew Dillon } 128258223a3SMatthew Dillon 129258223a3SMatthew Dillon static int 130258223a3SMatthew Dillon ahci_suspend (device_t dev) 131258223a3SMatthew Dillon { 132258223a3SMatthew Dillon return (0); 133258223a3SMatthew Dillon } 134258223a3SMatthew Dillon 135258223a3SMatthew Dillon static int 136258223a3SMatthew Dillon ahci_resume (device_t dev) 137258223a3SMatthew Dillon { 138258223a3SMatthew Dillon return (0); 139258223a3SMatthew Dillon } 140258223a3SMatthew Dillon 141258223a3SMatthew Dillon #endif 142*3209f581SMatthew Dillon 143*3209f581SMatthew Dillon void 144*3209f581SMatthew Dillon ahci_os_sleep(int ms) 145*3209f581SMatthew Dillon { 146*3209f581SMatthew Dillon int ticks; 147*3209f581SMatthew Dillon 148*3209f581SMatthew Dillon #if 0 149*3209f581SMatthew Dillon if (mygd->gd_intr_nesting_level) { 150*3209f581SMatthew Dillon DELAY(ms * 1000); 151*3209f581SMatthew Dillon } else { 152*3209f581SMatthew Dillon #endif 153*3209f581SMatthew Dillon { 154*3209f581SMatthew Dillon ticks = hz * ms / 1000 + 1; 155*3209f581SMatthew Dillon tsleep(&ticks, 0, "ahslp", ticks); 156*3209f581SMatthew Dillon } 157*3209f581SMatthew Dillon } 158