1211923Sjchandra/*-
2211923Sjchandra * Copyright (c) 2003-2009 RMI Corporation
3211923Sjchandra * All rights reserved.
4211923Sjchandra *
5211923Sjchandra * Redistribution and use in source and binary forms, with or without
6211923Sjchandra * modification, are permitted provided that the following conditions
7211923Sjchandra * are met:
8211923Sjchandra * 1. Redistributions of source code must retain the above copyright
9211923Sjchandra *    notice, this list of conditions and the following disclaimer.
10211923Sjchandra * 2. Redistributions in binary form must reproduce the above copyright
11211923Sjchandra *    notice, this list of conditions and the following disclaimer in the
12211923Sjchandra *    documentation and/or other materials provided with the distribution.
13211923Sjchandra * 3. Neither the name of RMI Corporation, nor the names of its contributors,
14211923Sjchandra *    may be used to endorse or promote products derived from this software
15211923Sjchandra *    without specific prior written permission.
16211923Sjchandra *
17211923Sjchandra * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18211923Sjchandra * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19211923Sjchandra * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20211923Sjchandra * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21211923Sjchandra * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22211923Sjchandra * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23211923Sjchandra * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24211923Sjchandra * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25211923Sjchandra * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26211923Sjchandra * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27211923Sjchandra * SUCH DAMAGE.
28211923Sjchandra *
29211923Sjchandra * RMI_BSD */
30211923Sjchandra/*
31211923Sjchandra * ATA driver for the XLR_PCMCIA Host adapter on the RMI XLR/XLS/.
32211923Sjchandra */
33211923Sjchandra#include <sys/cdefs.h>
34211923Sjchandra__FBSDID("$FreeBSD$");
35211923Sjchandra
36211923Sjchandra#include <sys/param.h>
37211923Sjchandra#include <sys/systm.h>
38211923Sjchandra#include <sys/kernel.h>
39211923Sjchandra#include <sys/module.h>
40211923Sjchandra#include <sys/bus.h>
41211923Sjchandra#include <sys/rman.h>
42211923Sjchandra#include <vm/uma.h>
43211923Sjchandra#include <sys/ata.h>
44211923Sjchandra#include <sys/sema.h>
45211923Sjchandra#include <sys/taskqueue.h>
46211923Sjchandra#include <sys/bus_dma.h>
47211923Sjchandra
48211923Sjchandra#include <dev/ata/ata-all.h>
49211923Sjchandra#include <mips/rmi/pic.h>
50211923Sjchandra#include <mips/rmi/iomap.h>
51211923Sjchandra#include <mips/include/resource.h>
52211923Sjchandra#include <mips/rmi/interrupt.h>
53211923Sjchandra
54211923Sjchandra#define	XLR_PCMCIA_DATA_REG		0x1f0
55211923Sjchandra#define	XLR_PCMCIA_ERROR_REG		0x1f1
56211923Sjchandra#define	XLR_PCMCIA_SECT_CNT_REG		0x1f2
57211923Sjchandra#define	XLR_PCMCIA_SECT_NUM_REG		0x1f3
58211923Sjchandra#define	XLR_PCMCIA_CYLINDER_LOW_REG	0x1f4
59211923Sjchandra#define	XLR_PCMCIA_CYLINDER_HIGH_REG	0x1f5
60211923Sjchandra#define	XLR_PCMCIA_SECT_DRIVE_HEAD_REG	0x1f6
61211923Sjchandra#define	XLR_PCMCIA_CMD_STATUS_REG	0x1f7
62211923Sjchandra#define	XLR_PCMCIA_ALT_STATUS_REG	0x3f6
63211923Sjchandra#define	XLR_PCMCIA_CONTROL_REG		0x3f6
64211923Sjchandra
65211923Sjchandra/*
66211923Sjchandra * Device methods
67211923Sjchandra */
68211923Sjchandrastatic int xlr_pcmcia_probe(device_t);
69211923Sjchandrastatic int xlr_pcmcia_attach(device_t);
70211923Sjchandrastatic int xlr_pcmcia_detach(device_t);
71211923Sjchandra
72211923Sjchandrastatic int
73211923Sjchandraxlr_pcmcia_probe(device_t dev)
74211923Sjchandra{
75211923Sjchandra	struct ata_channel *ch = device_get_softc(dev);
76211923Sjchandra
77211923Sjchandra	ch->unit = 0;
78211923Sjchandra	ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE ;
79211923Sjchandra	device_set_desc(dev, "PCMCIA ATA controller");
80211923Sjchandra
81211923Sjchandra	return (ata_probe(dev));
82211923Sjchandra}
83211923Sjchandra
84211923Sjchandra/*
85211923Sjchandra * We add all the devices which we know about.
86211923Sjchandra * The generic attach routine will attach them if they are alive.
87211923Sjchandra */
88211923Sjchandrastatic int
89211923Sjchandraxlr_pcmcia_attach(device_t dev)
90211923Sjchandra{
91211923Sjchandra	struct ata_channel *ch = device_get_softc(dev);
92211923Sjchandra	int i;
93211923Sjchandra	int rid =0;
94211923Sjchandra	struct resource *mem_res;
95211923Sjchandra
96211923Sjchandra
97211923Sjchandra	mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,  RF_ACTIVE);
98211923Sjchandra	for (i = 0; i < ATA_MAX_RES; i++)
99211923Sjchandra		ch->r_io[i].res = mem_res;
100211923Sjchandra
101211923Sjchandra	/*
102211923Sjchandra	 * CF+ Specification.
103211923Sjchandra	 */
104211923Sjchandra	ch->r_io[ATA_DATA].offset 	= XLR_PCMCIA_DATA_REG;
105211923Sjchandra	ch->r_io[ATA_FEATURE].offset 	= XLR_PCMCIA_ERROR_REG;
106211923Sjchandra	ch->r_io[ATA_COUNT].offset 	= XLR_PCMCIA_SECT_CNT_REG;
107211923Sjchandra	ch->r_io[ATA_SECTOR].offset 	= XLR_PCMCIA_SECT_NUM_REG;
108211923Sjchandra	ch->r_io[ATA_CYL_LSB].offset 	= XLR_PCMCIA_CYLINDER_LOW_REG;
109211923Sjchandra	ch->r_io[ATA_CYL_MSB].offset 	= XLR_PCMCIA_CYLINDER_HIGH_REG;
110211923Sjchandra	ch->r_io[ATA_DRIVE].offset 	= XLR_PCMCIA_SECT_DRIVE_HEAD_REG;
111211923Sjchandra	ch->r_io[ATA_COMMAND].offset 	= XLR_PCMCIA_CMD_STATUS_REG;
112211923Sjchandra	ch->r_io[ATA_ERROR].offset 	= XLR_PCMCIA_ERROR_REG;
113211923Sjchandra	ch->r_io[ATA_IREASON].offset 	= XLR_PCMCIA_SECT_CNT_REG;
114211923Sjchandra	ch->r_io[ATA_STATUS].offset 	= XLR_PCMCIA_CMD_STATUS_REG;
115211923Sjchandra	ch->r_io[ATA_ALTSTAT].offset 	= XLR_PCMCIA_ALT_STATUS_REG;
116211923Sjchandra	ch->r_io[ATA_CONTROL].offset 	= XLR_PCMCIA_CONTROL_REG;
117211923Sjchandra
118211923Sjchandra	/* Should point at the base of registers. */
119211923Sjchandra	ch->r_io[ATA_IDX_ADDR].offset = XLR_PCMCIA_DATA_REG;
120211923Sjchandra
121211923Sjchandra	ata_generic_hw(dev);
122211923Sjchandra
123211923Sjchandra	return (ata_attach(dev));
124211923Sjchandra}
125211923Sjchandra
126211923Sjchandrastatic int
127211923Sjchandraxlr_pcmcia_detach(device_t dev)
128211923Sjchandra{
129211923Sjchandra	bus_generic_detach(dev);
130211923Sjchandra
131211923Sjchandra	return (0);
132211923Sjchandra}
133211923Sjchandra
134211923Sjchandrastatic device_method_t xlr_pcmcia_methods[] = {
135211923Sjchandra    /* device interface */
136211923Sjchandra    DEVMETHOD(device_probe,         xlr_pcmcia_probe),
137211923Sjchandra    DEVMETHOD(device_attach,        xlr_pcmcia_attach),
138211923Sjchandra    DEVMETHOD(device_detach,        xlr_pcmcia_detach),
139211923Sjchandra
140211923Sjchandra    { 0, 0 }
141211923Sjchandra};
142211923Sjchandra
143211923Sjchandrastatic driver_t xlr_pcmcia_driver = {
144211923Sjchandra        "ata",
145211923Sjchandra        xlr_pcmcia_methods,
146211923Sjchandra        sizeof(struct ata_channel),
147211923Sjchandra};
148211923Sjchandra
149211923SjchandraDRIVER_MODULE(ata, iodi, xlr_pcmcia_driver, ata_devclass, 0, 0);
150