173897Ssos/*- 2230132Suqs * Copyright (c) 1998 - 2008 S��ren Schmidt <sos@FreeBSD.org> 373897Ssos * All rights reserved. 473897Ssos * 573897Ssos * Redistribution and use in source and binary forms, with or without 673897Ssos * modification, are permitted provided that the following conditions 773897Ssos * are met: 873897Ssos * 1. Redistributions of source code must retain the above copyright 973897Ssos * notice, this list of conditions and the following disclaimer, 1073897Ssos * without modification, immediately at the beginning of the file. 1173897Ssos * 2. Redistributions in binary form must reproduce the above copyright 1273897Ssos * notice, this list of conditions and the following disclaimer in the 1373897Ssos * documentation and/or other materials provided with the distribution. 1473897Ssos * 1573897Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1673897Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1773897Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1873897Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1973897Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2073897Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2173897Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2273897Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2373897Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2473897Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2573897Ssos */ 2673897Ssos 27119418Sobrien#include <sys/cdefs.h> 28119418Sobrien__FBSDID("$FreeBSD$"); 29119418Sobrien 3073897Ssos#include <sys/param.h> 3173897Ssos#include <sys/systm.h> 32111809Ssos#include <sys/ata.h> 3373897Ssos#include <sys/kernel.h> 3473897Ssos#include <sys/module.h> 3573897Ssos#include <sys/bus.h> 3673897Ssos#include <sys/malloc.h> 37124403Ssos#include <sys/sema.h> 38119404Ssos#include <sys/taskqueue.h> 39124534Ssos#include <vm/uma.h> 4073897Ssos#include <machine/stdarg.h> 4173897Ssos#include <machine/resource.h> 4273897Ssos#include <machine/bus.h> 4373897Ssos#include <sys/rman.h> 4473897Ssos#include <isa/isavar.h> 4573897Ssos#include <dev/ata/ata-all.h> 46145000Ssos#include <ata_if.h> 4773897Ssos 4873897Ssos/* local vars */ 4973897Ssosstatic struct isa_pnp_id ata_ids[] = { 50144330Ssos {0x0006d041, "Generic ESDI/IDE/ATA controller"}, /* PNP0600 */ 51144330Ssos {0x0106d041, "Plus Hardcard II"}, /* PNP0601 */ 52144330Ssos {0x0206d041, "Plus Hardcard IIXL/EZ"}, /* PNP0602 */ 53144330Ssos {0x0306d041, "Generic ATA"}, /* PNP0603 */ 54111188Ssos /* PNP0680 */ 55144330Ssos {0x8006d041, "Standard bus mastering IDE hard disk controller"}, 5673897Ssos {0} 5773897Ssos}; 5873897Ssos 59136198Ssosstatic int 6073897Ssosata_isa_probe(device_t dev) 6173897Ssos{ 62144707Ssos struct resource *io = NULL, *ctlio = NULL; 6390215Ssos u_long tmp; 64188762Smav int rid; 6573897Ssos 6673897Ssos /* check isapnp ids */ 6773897Ssos if (ISA_PNP_PROBE(device_get_parent(dev), dev, ata_ids) == ENXIO) 6873897Ssos return ENXIO; 69188762Smav 70107562Ssos /* allocate the io port range */ 7173897Ssos rid = ATA_IOADDR_RID; 72145499Ssos if (!(io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 73145499Ssos ATA_IOSIZE, RF_ACTIVE))) 74112791Ssos return ENXIO; 7573897Ssos 7673897Ssos /* set the altport range */ 77144707Ssos if (bus_get_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, &tmp, &tmp)) { 78144707Ssos bus_set_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, 79144707Ssos rman_get_start(io) + ATA_CTLOFFSET, ATA_CTLIOSIZE); 8073897Ssos } 8173897Ssos 82112791Ssos /* allocate the altport range */ 83144707Ssos rid = ATA_CTLADDR_RID; 84145499Ssos if (!(ctlio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 85145499Ssos ATA_CTLIOSIZE, RF_ACTIVE))) { 86119404Ssos bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io); 87119404Ssos return ENXIO; 88112791Ssos } 89112791Ssos 90188762Smav /* Release resources to reallocate on attach. */ 91188762Smav bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, ctlio); 92188762Smav bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io); 93188762Smav 94226680Smav device_set_desc(dev, "ATA channel"); 95188762Smav return (ata_probe(dev)); 96188762Smav} 97188762Smav 98188762Smavstatic int 99188762Smavata_isa_attach(device_t dev) 100188762Smav{ 101188762Smav struct ata_channel *ch = device_get_softc(dev); 102188762Smav struct resource *io = NULL, *ctlio = NULL; 103188762Smav u_long tmp; 104188762Smav int i, rid; 105188762Smav 106188812Smav if (ch->attached) 107188812Smav return (0); 108188812Smav ch->attached = 1; 109188812Smav 110188762Smav /* allocate the io port range */ 111188762Smav rid = ATA_IOADDR_RID; 112188762Smav if (!(io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 113188762Smav ATA_IOSIZE, RF_ACTIVE))) 114188762Smav return ENXIO; 115188762Smav 116188762Smav /* set the altport range */ 117188762Smav if (bus_get_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, &tmp, &tmp)) { 118188762Smav bus_set_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, 119188762Smav rman_get_start(io) + ATA_CTLOFFSET, ATA_CTLIOSIZE); 120188762Smav } 121188762Smav 122188762Smav /* allocate the altport range */ 123188762Smav rid = ATA_CTLADDR_RID; 124188762Smav if (!(ctlio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 125188762Smav ATA_CTLIOSIZE, RF_ACTIVE))) { 126188762Smav bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io); 127188762Smav return ENXIO; 128188762Smav } 129188762Smav 130112791Ssos /* setup the resource vectors */ 131144707Ssos for (i = ATA_DATA; i <= ATA_COMMAND; i++) { 132112791Ssos ch->r_io[i].res = io; 133112791Ssos ch->r_io[i].offset = i; 134112791Ssos } 135144707Ssos ch->r_io[ATA_CONTROL].res = ctlio; 136144707Ssos ch->r_io[ATA_CONTROL].offset = 0; 137144707Ssos ch->r_io[ATA_IDX_ADDR].res = io; 138145713Ssos ata_default_registers(dev); 139144707Ssos 140112791Ssos /* initialize softc for this channel */ 14190215Ssos ch->unit = 0; 14290215Ssos ch->flags |= ATA_USE_16BIT; 143145713Ssos ata_generic_hw(dev); 144188762Smav return ata_attach(dev); 14573897Ssos} 14673897Ssos 147188762Smavstatic int 148188762Smavata_isa_detach(device_t dev) 149188762Smav{ 150188762Smav struct ata_channel *ch = device_get_softc(dev); 151188762Smav int error; 152188762Smav 153188812Smav if (!ch->attached) 154188812Smav return (0); 155188812Smav ch->attached = 0; 156188812Smav 157188762Smav error = ata_detach(dev); 158188762Smav 159188762Smav bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, 160188762Smav ch->r_io[ATA_CONTROL].res); 161188762Smav bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, 162188762Smav ch->r_io[ATA_IDX_ADDR].res); 163188762Smav return (error); 164188762Smav} 165188762Smav 166189600Smavstatic int 167189600Smavata_isa_suspend(device_t dev) 168189600Smav{ 169189600Smav struct ata_channel *ch = device_get_softc(dev); 170189600Smav 171189600Smav if (!ch->attached) 172189600Smav return (0); 173189600Smav 174189600Smav return ata_suspend(dev); 175189600Smav} 176189600Smav 177189600Smavstatic int 178189600Smavata_isa_resume(device_t dev) 179189600Smav{ 180189600Smav struct ata_channel *ch = device_get_softc(dev); 181189600Smav 182189600Smav if (!ch->attached) 183189600Smav return (0); 184189600Smav 185189600Smav return ata_resume(dev); 186189600Smav} 187189600Smav 188189600Smav 18973897Ssosstatic device_method_t ata_isa_methods[] = { 19073897Ssos /* device interface */ 191144330Ssos DEVMETHOD(device_probe, ata_isa_probe), 192188762Smav DEVMETHOD(device_attach, ata_isa_attach), 193188762Smav DEVMETHOD(device_detach, ata_isa_detach), 194189600Smav DEVMETHOD(device_suspend, ata_isa_suspend), 195189600Smav DEVMETHOD(device_resume, ata_isa_resume), 196145000Ssos 197249213Smarius DEVMETHOD_END 19873897Ssos}; 19973897Ssos 20073897Ssosstatic driver_t ata_isa_driver = { 20173897Ssos "ata", 20273897Ssos ata_isa_methods, 20390215Ssos sizeof(struct ata_channel), 20473897Ssos}; 20573897Ssos 206249213SmariusDRIVER_MODULE(ata, isa, ata_isa_driver, ata_devclass, NULL, NULL); 207144330SsosMODULE_DEPEND(ata, ata, 1, 1, 1); 208