ata-card.c revision 111188
173897Ssos/*- 2111188Ssos * Copyright (c) 1998 - 2003 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 * 3. The name of the author may not be used to endorse or promote products 1573897Ssos * derived from this software without specific prior written permission. 1673897Ssos * 1773897Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1873897Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1973897Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2073897Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2173897Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2273897Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2373897Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2473897Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2573897Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2673897Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2773897Ssos * 2873897Ssos * $FreeBSD: head/sys/dev/ata/ata-card.c 111188 2003-02-20 20:02:32Z sos $ 2973897Ssos */ 3073897Ssos 3173897Ssos#include <sys/param.h> 3273897Ssos#include <sys/systm.h> 3373897Ssos#include <sys/kernel.h> 3473897Ssos#include <sys/module.h> 3573897Ssos#include <sys/bus.h> 3673897Ssos#include <sys/malloc.h> 3773897Ssos#include <machine/stdarg.h> 3873897Ssos#include <machine/resource.h> 3973897Ssos#include <machine/bus.h> 4073897Ssos#include <sys/rman.h> 4173897Ssos#include <dev/ata/ata-all.h> 4289915Ssos#include <dev/pccard/pccardreg.h> 4389915Ssos#include <dev/pccard/pccardvar.h> 4489915Ssos#include <dev/pccard/pccarddevs.h> 4573897Ssos 4673897Ssosstatic int 4789915Ssosata_pccard_match(device_t dev) 4889915Ssos{ 4990215Ssos u_int32_t fcn = PCCARD_FUNCTION_UNSPEC; 5090215Ssos int error = 0; 5189915Ssos 5289915Ssos error = pccard_get_function(dev, &fcn); 5389915Ssos if (error != 0) 5489915Ssos return (error); 5589915Ssos 5689915Ssos /* if it says its a disk we should register it */ 5789915Ssos if (fcn == PCCARD_FUNCTION_DISK) 5889915Ssos return (0); 5989915Ssos 6089915Ssos /* other devices might need to be matched here */ 6189915Ssos return(ENXIO); 6289915Ssos} 6389915Ssos 64107660Ssosstatic void 65107660Ssosata_pccard_locknoop(struct ata_channel *ch, int type) 66107660Ssos{ 67107660Ssos} 68107660Ssos 69107660Ssosstatic int 7073897Ssosata_pccard_probe(device_t dev) 7173897Ssos{ 7290215Ssos struct ata_channel *ch = device_get_softc(dev); 7373897Ssos struct resource *io; 7473897Ssos int rid, len, start, end; 7573897Ssos u_long tmp; 7673897Ssos 7773897Ssos /* allocate the io range to get start and length */ 7873897Ssos rid = ATA_IOADDR_RID; 7973897Ssos len = bus_get_resource_count(dev, SYS_RES_IOPORT, rid); 8073897Ssos io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 8173897Ssos ATA_IOSIZE, RF_ACTIVE); 8273897Ssos if (!io) 8373897Ssos return ENOMEM; 8473897Ssos 8573897Ssos /* reallocate the io address to only cover the io ports */ 8673897Ssos start = rman_get_start(io); 8773897Ssos end = start + ATA_IOSIZE - 1; 8873897Ssos bus_release_resource(dev, SYS_RES_IOPORT, rid, io); 8973897Ssos io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 9073897Ssos start, end, ATA_IOSIZE, RF_ACTIVE); 9173897Ssos bus_release_resource(dev, SYS_RES_IOPORT, rid, io); 9273897Ssos 9373897Ssos /* 9473897Ssos * if we got more than the default ATA_IOSIZE ports, this is likely 9573897Ssos * a pccard system where the altio ports are located at offset 14 9673897Ssos * otherwise its the normal altio offset 9773897Ssos */ 9873897Ssos if (bus_get_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID, &tmp, &tmp)) { 9973897Ssos if (len > ATA_IOSIZE) { 10073897Ssos bus_set_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID, 10173897Ssos start + ATA_PCCARD_ALTOFFSET, ATA_ALTIOSIZE); 10273897Ssos } 10373897Ssos else { 10473897Ssos bus_set_resource(dev, SYS_RES_IOPORT, ATA_ALTADDR_RID, 10573897Ssos start + ATA_ALTOFFSET, ATA_ALTIOSIZE); 10673897Ssos } 10773897Ssos } 10873897Ssos else 10973897Ssos return ENOMEM; 11073897Ssos 11190215Ssos ch->unit = 0; 11290215Ssos ch->flags |= (ATA_USE_16BIT | ATA_NO_SLAVE); 113111188Ssos ch->locking = ata_pccard_locknoop; 11473897Ssos return ata_probe(dev); 11573897Ssos} 11673897Ssos 11773897Ssosstatic device_method_t ata_pccard_methods[] = { 11873897Ssos /* device interface */ 11989915Ssos DEVMETHOD(device_probe, pccard_compat_probe), 12089915Ssos DEVMETHOD(device_attach, pccard_compat_attach), 12173897Ssos DEVMETHOD(device_detach, ata_detach), 12289915Ssos 12389915Ssos /* Card interface */ 12489915Ssos DEVMETHOD(card_compat_match, ata_pccard_match), 12589915Ssos DEVMETHOD(card_compat_probe, ata_pccard_probe), 12689915Ssos DEVMETHOD(card_compat_attach, ata_attach), 12773897Ssos { 0, 0 } 12873897Ssos}; 12973897Ssos 13073897Ssosstatic driver_t ata_pccard_driver = { 13173897Ssos "ata", 13273897Ssos ata_pccard_methods, 13390215Ssos sizeof(struct ata_channel), 13473897Ssos}; 13573897Ssos 13673897SsosDRIVER_MODULE(ata, pccard, ata_pccard_driver, ata_devclass, 0, 0); 137