ata_zbbus.c revision 195333
11553Srgrimes/*- 21553Srgrimes * Copyright (c) 2009 Neelkanth Natu 31553Srgrimes * All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 141553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 151553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 181553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241553Srgrimes * SUCH DAMAGE. 251553Srgrimes */ 261553Srgrimes 271553Srgrimes#include <sys/param.h> 281553Srgrimes#include <sys/kernel.h> 291553Srgrimes#include <sys/systm.h> 301553Srgrimes#include <sys/module.h> 311553Srgrimes#include <sys/bus.h> 321553Srgrimes#include <sys/rman.h> 331553Srgrimes#include <sys/lock.h> 341553Srgrimes#include <sys/mutex.h> 351553Srgrimes#include <sys/sema.h> 361553Srgrimes#include <sys/taskqueue.h> 371553Srgrimes 381553Srgrimes#include <machine/bus.h> 391553Srgrimes 401553Srgrimes#include <vm/uma.h> 411553Srgrimes 421553Srgrimes#include <sys/ata.h> 431553Srgrimes#include <dev/ata/ata-all.h> 441553Srgrimes 451553Srgrimes#include <machine/resource.h> 461553Srgrimes 471553Srgrimes__FBSDID("$FreeBSD: projects/mips/sys/mips/sibyte/ata_zbbus.c 195333 2009-07-04 03:05:48Z imp $"); 481553Srgrimes 491553Srgrimesstatic int 501553Srgrimesata_zbbus_probe(device_t dev) 514571Sgibbs{ 521553Srgrimes 531553Srgrimes return (ata_probe(dev)); 541553Srgrimes} 551553Srgrimes 561553Srgrimesstatic int 571553Srgrimesata_zbbus_attach(device_t dev) 581553Srgrimes{ 591553Srgrimes int i, rid, regshift, regoffset; 601553Srgrimes struct ata_channel *ch; 611553Srgrimes struct resource *io; 621553Srgrimes 631553Srgrimes ch = device_get_softc(dev); 641553Srgrimes 651553Srgrimes if (ch->attached) 661553Srgrimes return (0); 671553Srgrimes ch->attached = 1; 681553Srgrimes 691553Srgrimes rid = 0; 701553Srgrimes io = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, RF_ACTIVE); 711553Srgrimes if (io == NULL) 721553Srgrimes return (ENXIO); 731553Srgrimes 741553Srgrimes /* 751553Srgrimes * SWARM needs an address shift of 5 when accessing ATA registers. 761553Srgrimes * 771553Srgrimes * For e.g. an access to register 4 actually needs an address 781553Srgrimes * of (4 << 5) to be output on the generic bus. 791553Srgrimes */ 801553Srgrimes regshift = 5; 811553Srgrimes resource_int_value(device_get_name(dev), device_get_unit(dev), 821553Srgrimes "regshift", ®shift); 831553Srgrimes if (regshift && bootverbose) 841553Srgrimes device_printf(dev, "using a register shift of %d\n", regshift); 851553Srgrimes 861553Srgrimes regoffset = 0x1F0; 871553Srgrimes resource_int_value(device_get_name(dev), device_get_unit(dev), 881553Srgrimes "regoffset", ®offset); 891553Srgrimes if (regoffset && bootverbose) { 901553Srgrimes device_printf(dev, "using a register offset of 0x%0x\n", 911553Srgrimes regoffset); 921553Srgrimes } 931553Srgrimes 941553Srgrimes /* setup the ata register addresses */ 951553Srgrimes for (i = ATA_DATA; i <= ATA_COMMAND; ++i) { 961553Srgrimes ch->r_io[i].res = io; 971553Srgrimes ch->r_io[i].offset = (regoffset + i) << regshift; 984571Sgibbs } 994571Sgibbs 1001553Srgrimes ch->r_io[ATA_CONTROL].res = io; 1011553Srgrimes ch->r_io[ATA_CONTROL].offset = (regoffset + ATA_CTLOFFSET) << regshift; 1021553Srgrimes ch->r_io[ATA_IDX_ADDR].res = io; /* XXX what is this used for */ 1031553Srgrimes ata_default_registers(dev); 1041553Srgrimes 1051553Srgrimes /* initialize softc for this channel */ 1061553Srgrimes ch->unit = 0; 1071553Srgrimes ch->flags |= ATA_USE_16BIT; 1081553Srgrimes ata_generic_hw(dev); 1091553Srgrimes 1101553Srgrimes return (ata_attach(dev)); 1111553Srgrimes} 1121553Srgrimes 1131553Srgrimesstatic int 1141553Srgrimesata_zbbus_detach(device_t dev) 1151553Srgrimes{ 1161553Srgrimes int error; 1171553Srgrimes struct ata_channel *ch = device_get_softc(dev); 1181553Srgrimes 1191553Srgrimes if (!ch->attached) 1201553Srgrimes return (0); 1211553Srgrimes ch->attached = 0; 1221553Srgrimes 1231553Srgrimes error = ata_detach(dev); 1241553Srgrimes 1251553Srgrimes bus_release_resource(dev, SYS_RES_MEMORY, 0, 1261553Srgrimes ch->r_io[ATA_IDX_ADDR].res); 1271553Srgrimes 1281553Srgrimes return (error); 1291553Srgrimes} 1301553Srgrimes 1311553Srgrimesstatic int 1321553Srgrimesata_zbbus_suspend(device_t dev) 1331553Srgrimes{ 1341553Srgrimes struct ata_channel *ch = device_get_softc(dev); 1351553Srgrimes 1361553Srgrimes if (!ch->attached) 1371553Srgrimes return (0); 1381553Srgrimes 1391553Srgrimes return (ata_suspend(dev)); 1401553Srgrimes} 1411553Srgrimes 1421553Srgrimesstatic int 1431553Srgrimesata_zbbus_resume(device_t dev) 1441553Srgrimes{ 1451553Srgrimes struct ata_channel *ch = device_get_softc(dev); 1461553Srgrimes 1471553Srgrimes if (!ch->attached) 1481553Srgrimes return (0); 1491553Srgrimes 1501553Srgrimes return (ata_resume(dev)); 1511553Srgrimes} 1521553Srgrimes 1531553Srgrimesstatic device_method_t ata_zbbus_methods[] = { 1541553Srgrimes /* device interface */ 1551553Srgrimes DEVMETHOD(device_probe, ata_zbbus_probe), 1561553Srgrimes DEVMETHOD(device_attach, ata_zbbus_attach), 1571553Srgrimes DEVMETHOD(device_detach, ata_zbbus_detach), 1581553Srgrimes DEVMETHOD(device_suspend, ata_zbbus_suspend), 1591553Srgrimes DEVMETHOD(device_resume, ata_zbbus_resume), 1601553Srgrimes 1611553Srgrimes { 0, 0 } 1621553Srgrimes}; 1631553Srgrimes 1641553Srgrimesstatic driver_t ata_zbbus_driver = { 1651553Srgrimes "ata", 1661553Srgrimes ata_zbbus_methods, 1671553Srgrimes sizeof(struct ata_channel) 1681553Srgrimes}; 1691553Srgrimes 1701553SrgrimesDRIVER_MODULE(ata, zbbus, ata_zbbus_driver, ata_devclass, 0, 0); 1711553Srgrimes