1c1b3d7c5SThomas E. Spanjaard /*-
2*f6e8a0a1SImre Vadasz * Copyright (c) 1998 - 2006 Søren Schmidt <sos@FreeBSD.org>
3c1b3d7c5SThomas E. Spanjaard * All rights reserved.
4c1b3d7c5SThomas E. Spanjaard *
5c1b3d7c5SThomas E. Spanjaard * Redistribution and use in source and binary forms, with or without
6c1b3d7c5SThomas E. Spanjaard * modification, are permitted provided that the following conditions
7c1b3d7c5SThomas E. Spanjaard * are met:
8c1b3d7c5SThomas E. Spanjaard * 1. Redistributions of source code must retain the above copyright
9c1b3d7c5SThomas E. Spanjaard * notice, this list of conditions and the following disclaimer,
10c1b3d7c5SThomas E. Spanjaard * without modification, immediately at the beginning of the file.
11c1b3d7c5SThomas E. Spanjaard * 2. Redistributions in binary form must reproduce the above copyright
12c1b3d7c5SThomas E. Spanjaard * notice, this list of conditions and the following disclaimer in the
13c1b3d7c5SThomas E. Spanjaard * documentation and/or other materials provided with the distribution.
14c1b3d7c5SThomas E. Spanjaard *
15c1b3d7c5SThomas E. Spanjaard * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16c1b3d7c5SThomas E. Spanjaard * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17c1b3d7c5SThomas E. Spanjaard * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18c1b3d7c5SThomas E. Spanjaard * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19c1b3d7c5SThomas E. Spanjaard * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20c1b3d7c5SThomas E. Spanjaard * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21c1b3d7c5SThomas E. Spanjaard * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22c1b3d7c5SThomas E. Spanjaard * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23c1b3d7c5SThomas E. Spanjaard * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24c1b3d7c5SThomas E. Spanjaard * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25c1b3d7c5SThomas E. Spanjaard *
26c1b3d7c5SThomas E. Spanjaard * $FreeBSD: src/sys/dev/ata/ata-card.c,v 1.39 2006/01/05 21:27:19 sos Exp $
27c1b3d7c5SThomas E. Spanjaard */
28c1b3d7c5SThomas E. Spanjaard
29c1b3d7c5SThomas E. Spanjaard #include "opt_ata.h"
30c1b3d7c5SThomas E. Spanjaard
31c1b3d7c5SThomas E. Spanjaard #include <sys/param.h>
32c1b3d7c5SThomas E. Spanjaard #include <sys/bus.h>
33c1b3d7c5SThomas E. Spanjaard #include <sys/module.h>
34c1b3d7c5SThomas E. Spanjaard #include <sys/nata.h>
35c1b3d7c5SThomas E. Spanjaard #include <sys/rman.h>
36c1b3d7c5SThomas E. Spanjaard
373aef8050SSepherosa Ziehau #include <bus/pccard/pccard_cis.h>
38c1b3d7c5SThomas E. Spanjaard #include <bus/pccard/pccardreg.h>
39c1b3d7c5SThomas E. Spanjaard #include <bus/pccard/pccardvar.h>
40dcb4b80dSSascha Wildner
41dcb4b80dSSascha Wildner #include "pccarddevs.h"
42c1b3d7c5SThomas E. Spanjaard
43c1b3d7c5SThomas E. Spanjaard #include "ata-all.h"
44c1b3d7c5SThomas E. Spanjaard #include "ata_if.h"
45c1b3d7c5SThomas E. Spanjaard
46c1b3d7c5SThomas E. Spanjaard static const struct pccard_product ata_pccard_products[] = {
47c1b3d7c5SThomas E. Spanjaard PCMCIA_CARD(FREECOM, PCCARDIDE, 0),
48c1b3d7c5SThomas E. Spanjaard PCMCIA_CARD(EXP, EXPMULTIMEDIA, 0),
493aef8050SSepherosa Ziehau PCMCIA_CARD(IODATA3, CBIDE2, 0),
50c1b3d7c5SThomas E. Spanjaard PCMCIA_CARD(OEM2, CDROM1, 0),
51c1b3d7c5SThomas E. Spanjaard PCMCIA_CARD(OEM2, IDE, 0),
52c1b3d7c5SThomas E. Spanjaard PCMCIA_CARD(PANASONIC, KXLC005, 0),
53c1b3d7c5SThomas E. Spanjaard PCMCIA_CARD(TEAC, IDECARDII, 0),
54c1b3d7c5SThomas E. Spanjaard {NULL}
55c1b3d7c5SThomas E. Spanjaard };
56c1b3d7c5SThomas E. Spanjaard
57c1b3d7c5SThomas E. Spanjaard static int
ata_pccard_probe(device_t dev)58c1b3d7c5SThomas E. Spanjaard ata_pccard_probe(device_t dev)
59c1b3d7c5SThomas E. Spanjaard {
60c1b3d7c5SThomas E. Spanjaard const struct pccard_product *pp;
61c1b3d7c5SThomas E. Spanjaard u_int32_t fcn = PCCARD_FUNCTION_UNSPEC;
62c1b3d7c5SThomas E. Spanjaard
636fec3ceaSThomas E. Spanjaard fcn = pccard_get_function_number(dev);
64c1b3d7c5SThomas E. Spanjaard
65c1b3d7c5SThomas E. Spanjaard /* if it says its a disk we should register it */
66c1b3d7c5SThomas E. Spanjaard if (fcn == PCCARD_FUNCTION_DISK)
67c1b3d7c5SThomas E. Spanjaard return 0;
68c1b3d7c5SThomas E. Spanjaard
69c1b3d7c5SThomas E. Spanjaard /* match other devices here, primarily cdrom/dvd rom */
70c1b3d7c5SThomas E. Spanjaard if ((pp = pccard_product_lookup(dev, ata_pccard_products,
71c1b3d7c5SThomas E. Spanjaard sizeof(ata_pccard_products[0]), NULL))) {
72c1b3d7c5SThomas E. Spanjaard if (pp->pp_name)
73c1b3d7c5SThomas E. Spanjaard device_set_desc(dev, pp->pp_name);
74c1b3d7c5SThomas E. Spanjaard return 0;
75c1b3d7c5SThomas E. Spanjaard }
76c1b3d7c5SThomas E. Spanjaard return ENXIO;
77c1b3d7c5SThomas E. Spanjaard }
78c1b3d7c5SThomas E. Spanjaard
79c1b3d7c5SThomas E. Spanjaard static int
ata_pccard_attach(device_t dev)80c1b3d7c5SThomas E. Spanjaard ata_pccard_attach(device_t dev)
81c1b3d7c5SThomas E. Spanjaard {
82c1b3d7c5SThomas E. Spanjaard struct ata_channel *ch = device_get_softc(dev);
83c1b3d7c5SThomas E. Spanjaard struct resource *io, *ctlio;
84c1b3d7c5SThomas E. Spanjaard int i, rid, err;
85c1b3d7c5SThomas E. Spanjaard
86c1b3d7c5SThomas E. Spanjaard /* allocate the io range to get start and length */
87c1b3d7c5SThomas E. Spanjaard rid = ATA_IOADDR_RID;
88c1b3d7c5SThomas E. Spanjaard if (!(io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
89c1b3d7c5SThomas E. Spanjaard ATA_IOSIZE, RF_ACTIVE)))
90c1b3d7c5SThomas E. Spanjaard return (ENXIO);
91c1b3d7c5SThomas E. Spanjaard
92c1b3d7c5SThomas E. Spanjaard /* setup the resource vectors */
93c1b3d7c5SThomas E. Spanjaard for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
94c1b3d7c5SThomas E. Spanjaard ch->r_io[i].res = io;
95c1b3d7c5SThomas E. Spanjaard ch->r_io[i].offset = i;
96c1b3d7c5SThomas E. Spanjaard }
97c1b3d7c5SThomas E. Spanjaard ch->r_io[ATA_IDX_ADDR].res = io;
98c1b3d7c5SThomas E. Spanjaard
99c1b3d7c5SThomas E. Spanjaard /*
100c1b3d7c5SThomas E. Spanjaard * if we got more than the default ATA_IOSIZE ports, this is a device
101c1b3d7c5SThomas E. Spanjaard * where ctlio is located at offset 14 into "normal" io space.
102c1b3d7c5SThomas E. Spanjaard */
103c1b3d7c5SThomas E. Spanjaard if (rman_get_size(io) > ATA_IOSIZE) {
104c1b3d7c5SThomas E. Spanjaard ch->r_io[ATA_CONTROL].res = io;
105c1b3d7c5SThomas E. Spanjaard ch->r_io[ATA_CONTROL].offset = 14;
106c1b3d7c5SThomas E. Spanjaard }
107c1b3d7c5SThomas E. Spanjaard else {
108c1b3d7c5SThomas E. Spanjaard rid = ATA_CTLADDR_RID;
109c1b3d7c5SThomas E. Spanjaard if (!(ctlio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
110c1b3d7c5SThomas E. Spanjaard ATA_CTLIOSIZE, RF_ACTIVE))) {
111c1b3d7c5SThomas E. Spanjaard bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io);
112c1b3d7c5SThomas E. Spanjaard for (i = ATA_DATA; i < ATA_MAX_RES; i++)
113c1b3d7c5SThomas E. Spanjaard ch->r_io[i].res = NULL;
114c1b3d7c5SThomas E. Spanjaard return (ENXIO);
115c1b3d7c5SThomas E. Spanjaard }
116c1b3d7c5SThomas E. Spanjaard ch->r_io[ATA_CONTROL].res = ctlio;
117c1b3d7c5SThomas E. Spanjaard ch->r_io[ATA_CONTROL].offset = 0;
118c1b3d7c5SThomas E. Spanjaard }
119c1b3d7c5SThomas E. Spanjaard ata_default_registers(dev);
120c1b3d7c5SThomas E. Spanjaard
121c1b3d7c5SThomas E. Spanjaard /* initialize softc for this channel */
122c1b3d7c5SThomas E. Spanjaard ch->unit = 0;
123c1b3d7c5SThomas E. Spanjaard ch->flags |= (ATA_USE_16BIT | ATA_NO_SLAVE);
124c1b3d7c5SThomas E. Spanjaard ata_generic_hw(dev);
125c1b3d7c5SThomas E. Spanjaard err = ata_probe(dev);
126c1b3d7c5SThomas E. Spanjaard if (err)
127c1b3d7c5SThomas E. Spanjaard return (err);
128c1b3d7c5SThomas E. Spanjaard return (ata_attach(dev));
129c1b3d7c5SThomas E. Spanjaard }
130c1b3d7c5SThomas E. Spanjaard
131c1b3d7c5SThomas E. Spanjaard static int
ata_pccard_detach(device_t dev)132c1b3d7c5SThomas E. Spanjaard ata_pccard_detach(device_t dev)
133c1b3d7c5SThomas E. Spanjaard {
134c1b3d7c5SThomas E. Spanjaard struct ata_channel *ch = device_get_softc(dev);
135c1b3d7c5SThomas E. Spanjaard int i;
136c1b3d7c5SThomas E. Spanjaard
137c1b3d7c5SThomas E. Spanjaard ata_detach(dev);
138c1b3d7c5SThomas E. Spanjaard if (ch->r_io[ATA_CONTROL].res != ch->r_io[ATA_DATA].res)
139c1b3d7c5SThomas E. Spanjaard bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID,
140c1b3d7c5SThomas E. Spanjaard ch->r_io[ATA_CONTROL].res);
141c1b3d7c5SThomas E. Spanjaard bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID,
142c1b3d7c5SThomas E. Spanjaard ch->r_io[ATA_DATA].res);
143c1b3d7c5SThomas E. Spanjaard for (i = ATA_DATA; i < ATA_MAX_RES; i++)
144c1b3d7c5SThomas E. Spanjaard ch->r_io[i].res = NULL;
145c1b3d7c5SThomas E. Spanjaard return 0;
146c1b3d7c5SThomas E. Spanjaard }
147c1b3d7c5SThomas E. Spanjaard
148c1b3d7c5SThomas E. Spanjaard static device_method_t ata_pccard_methods[] = {
149c1b3d7c5SThomas E. Spanjaard /* device interface */
150c1b3d7c5SThomas E. Spanjaard DEVMETHOD(device_probe, ata_pccard_probe),
151c1b3d7c5SThomas E. Spanjaard DEVMETHOD(device_attach, ata_pccard_attach),
152c1b3d7c5SThomas E. Spanjaard DEVMETHOD(device_detach, ata_pccard_detach),
153c1b3d7c5SThomas E. Spanjaard
154d3c9c58eSSascha Wildner DEVMETHOD_END
155c1b3d7c5SThomas E. Spanjaard };
156c1b3d7c5SThomas E. Spanjaard
157c1b3d7c5SThomas E. Spanjaard static driver_t ata_pccard_driver = {
158c1b3d7c5SThomas E. Spanjaard "ata",
159c1b3d7c5SThomas E. Spanjaard ata_pccard_methods,
160c1b3d7c5SThomas E. Spanjaard sizeof(struct ata_channel),
161c1b3d7c5SThomas E. Spanjaard };
162c1b3d7c5SThomas E. Spanjaard
163aa2b9d05SSascha Wildner DRIVER_MODULE(ata, pccard, ata_pccard_driver, ata_devclass, NULL, NULL);
164c1b3d7c5SThomas E. Spanjaard MODULE_DEPEND(ata, ata, 1, 1, 1);
165