1195333Simp/*- 2195333Simp * Copyright (c) 2009 Neelkanth Natu 3195333Simp * All rights reserved. 4195333Simp * 5195333Simp * Redistribution and use in source and binary forms, with or without 6195333Simp * modification, are permitted provided that the following conditions 7195333Simp * are met: 8195333Simp * 1. Redistributions of source code must retain the above copyright 9195333Simp * notice, this list of conditions and the following disclaimer. 10195333Simp * 2. Redistributions in binary form must reproduce the above copyright 11195333Simp * notice, this list of conditions and the following disclaimer in the 12195333Simp * documentation and/or other materials provided with the distribution. 13195333Simp * 14195333Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15195333Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16195333Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17195333Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18195333Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19195333Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20195333Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21195333Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22195333Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23195333Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24195333Simp * SUCH DAMAGE. 25195333Simp */ 26195333Simp 27195333Simp#include <sys/param.h> 28195333Simp#include <sys/kernel.h> 29195333Simp#include <sys/systm.h> 30195333Simp#include <sys/module.h> 31195333Simp#include <sys/bus.h> 32195333Simp#include <sys/rman.h> 33195333Simp#include <sys/lock.h> 34195333Simp#include <sys/mutex.h> 35195333Simp#include <sys/sema.h> 36195333Simp#include <sys/taskqueue.h> 37195333Simp 38195333Simp#include <machine/bus.h> 39195333Simp 40195333Simp#include <vm/uma.h> 41195333Simp 42195333Simp#include <sys/ata.h> 43195333Simp#include <dev/ata/ata-all.h> 44195333Simp 45195333Simp#include <machine/resource.h> 46195333Simp 47195333Simp__FBSDID("$FreeBSD$"); 48195333Simp 49195333Simpstatic int 50195333Simpata_zbbus_probe(device_t dev) 51195333Simp{ 52195333Simp 53195333Simp return (ata_probe(dev)); 54195333Simp} 55195333Simp 56195333Simpstatic int 57195333Simpata_zbbus_attach(device_t dev) 58195333Simp{ 59195333Simp int i, rid, regshift, regoffset; 60195333Simp struct ata_channel *ch; 61195333Simp struct resource *io; 62195333Simp 63195333Simp ch = device_get_softc(dev); 64195333Simp 65195333Simp if (ch->attached) 66195333Simp return (0); 67195333Simp ch->attached = 1; 68195333Simp 69195333Simp rid = 0; 70295790Sjhibbits io = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 71195333Simp if (io == NULL) 72195333Simp return (ENXIO); 73195333Simp 74195333Simp /* 75195333Simp * SWARM needs an address shift of 5 when accessing ATA registers. 76195333Simp * 77195333Simp * For e.g. an access to register 4 actually needs an address 78195333Simp * of (4 << 5) to be output on the generic bus. 79195333Simp */ 80195333Simp regshift = 5; 81195333Simp resource_int_value(device_get_name(dev), device_get_unit(dev), 82195333Simp "regshift", ®shift); 83195333Simp if (regshift && bootverbose) 84195333Simp device_printf(dev, "using a register shift of %d\n", regshift); 85195333Simp 86195333Simp regoffset = 0x1F0; 87195333Simp resource_int_value(device_get_name(dev), device_get_unit(dev), 88195333Simp "regoffset", ®offset); 89195333Simp if (regoffset && bootverbose) { 90195333Simp device_printf(dev, "using a register offset of 0x%0x\n", 91195333Simp regoffset); 92195333Simp } 93195333Simp 94195333Simp /* setup the ata register addresses */ 95195333Simp for (i = ATA_DATA; i <= ATA_COMMAND; ++i) { 96195333Simp ch->r_io[i].res = io; 97195333Simp ch->r_io[i].offset = (regoffset + i) << regshift; 98195333Simp } 99195333Simp 100195333Simp ch->r_io[ATA_CONTROL].res = io; 101195333Simp ch->r_io[ATA_CONTROL].offset = (regoffset + ATA_CTLOFFSET) << regshift; 102195333Simp ch->r_io[ATA_IDX_ADDR].res = io; /* XXX what is this used for */ 103195333Simp ata_default_registers(dev); 104195333Simp 105195333Simp /* initialize softc for this channel */ 106195333Simp ch->unit = 0; 107195333Simp ch->flags |= ATA_USE_16BIT; 108195333Simp ata_generic_hw(dev); 109195333Simp 110195333Simp return (ata_attach(dev)); 111195333Simp} 112195333Simp 113195333Simpstatic int 114195333Simpata_zbbus_detach(device_t dev) 115195333Simp{ 116195333Simp int error; 117195333Simp struct ata_channel *ch = device_get_softc(dev); 118195333Simp 119195333Simp if (!ch->attached) 120195333Simp return (0); 121195333Simp ch->attached = 0; 122195333Simp 123195333Simp error = ata_detach(dev); 124195333Simp 125195333Simp bus_release_resource(dev, SYS_RES_MEMORY, 0, 126195333Simp ch->r_io[ATA_IDX_ADDR].res); 127195333Simp 128195333Simp return (error); 129195333Simp} 130195333Simp 131195333Simpstatic int 132195333Simpata_zbbus_suspend(device_t dev) 133195333Simp{ 134195333Simp struct ata_channel *ch = device_get_softc(dev); 135195333Simp 136195333Simp if (!ch->attached) 137195333Simp return (0); 138195333Simp 139195333Simp return (ata_suspend(dev)); 140195333Simp} 141195333Simp 142195333Simpstatic int 143195333Simpata_zbbus_resume(device_t dev) 144195333Simp{ 145195333Simp struct ata_channel *ch = device_get_softc(dev); 146195333Simp 147195333Simp if (!ch->attached) 148195333Simp return (0); 149195333Simp 150195333Simp return (ata_resume(dev)); 151195333Simp} 152195333Simp 153195333Simpstatic device_method_t ata_zbbus_methods[] = { 154195333Simp /* device interface */ 155195333Simp DEVMETHOD(device_probe, ata_zbbus_probe), 156195333Simp DEVMETHOD(device_attach, ata_zbbus_attach), 157195333Simp DEVMETHOD(device_detach, ata_zbbus_detach), 158195333Simp DEVMETHOD(device_suspend, ata_zbbus_suspend), 159195333Simp DEVMETHOD(device_resume, ata_zbbus_resume), 160195333Simp 161195333Simp { 0, 0 } 162195333Simp}; 163195333Simp 164195333Simpstatic driver_t ata_zbbus_driver = { 165195333Simp "ata", 166195333Simp ata_zbbus_methods, 167195333Simp sizeof(struct ata_channel) 168195333Simp}; 169195333Simp 170195333SimpDRIVER_MODULE(ata, zbbus, ata_zbbus_driver, ata_devclass, 0, 0); 171