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