1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  ATAPI device driver			File: dev_atapi.c
5    *
6    *  This is a simple driver for ATAPI devices.  The disks
7    *  are expected to be connected to the generic bus (this
8    *  driver doesn't support PCI).
9    *
10    *  Author:  Mitch Lichtenberg
11    *
12    *********************************************************************
13    *
14    *  Copyright 2000,2001,2002,2003
15    *  Broadcom Corporation. All rights reserved.
16    *
17    *  This software is furnished under license and may be used and
18    *  copied only in accordance with the following terms and
19    *  conditions.  Subject to these conditions, you may download,
20    *  copy, install, use, modify and distribute modified or unmodified
21    *  copies of this software in source and/or binary form.  No title
22    *  or ownership is transferred hereby.
23    *
24    *  1) Any source code used, modified or distributed must reproduce
25    *     and retain this copyright notice and list of conditions
26    *     as they appear in the source file.
27    *
28    *  2) No right is granted to use any trade name, trademark, or
29    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
30    *     name may not be used to endorse or promote products derived
31    *     from this software without the prior written permission of
32    *     Broadcom Corporation.
33    *
34    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
35    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
36    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
38    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
39    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
40    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
45    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
46    *     THE POSSIBILITY OF SUCH DAMAGE.
47    ********************************************************************* */
48
49
50#include "cfe.h"
51
52#include "dev_ide_common.h"
53
54/*  *********************************************************************
55    *  Macros
56    ********************************************************************* */
57
58#define GETWORD_LE(buf,wordidx) (((unsigned int) (buf)[(wordidx)*2]) + \
59             (((unsigned int) (buf)[(wordidx)*2+1]) << 8))
60
61
62/*  *********************************************************************
63    *  Forward declarations
64    ********************************************************************* */
65
66extern void _wbflush(void);
67static void atapidrv_probe(cfe_driver_t *drv,
68			      unsigned long probe_a, unsigned long probe_b,
69			      void *probe_ptr);
70
71
72const static cfe_devdisp_t atapidrv_dispatch = {
73    idecommon_open,
74    idecommon_read,
75    idecommon_inpstat,
76    idecommon_write,
77    idecommon_ioctl,
78    idecommon_close,
79    NULL,
80    NULL
81};
82
83const cfe_driver_t atapidrv = {
84    "ATAPI device",
85    "atapi",
86    CFE_DEV_DISK,
87    &atapidrv_dispatch,
88    atapidrv_probe
89};
90
91
92
93/*  *********************************************************************
94    *  Port I/O routines
95    *
96    *  These routines are called back from the common code to do
97    *  I/O cycles to the IDE disk.  We provide routines for
98    *  reading and writing bytes, words, and strings of words.
99    ********************************************************************* */
100
101static uint8_t atapidrv_inb(idecommon_dispatch_t *disp,uint32_t reg)
102{
103    return *((volatile uint8_t *) PHYS_TO_K1(reg+disp->baseaddr));
104}
105
106static uint16_t atapidrv_inw(idecommon_dispatch_t *disp,uint32_t reg)
107{
108    return *((volatile uint16_t *) PHYS_TO_K1((reg+disp->baseaddr)));
109}
110
111static void atapidrv_ins(idecommon_dispatch_t *disp,uint32_t reg,uint8_t *buf,int len)
112{
113    uint16_t data;
114
115    while (len > 0) {
116	data = *((volatile uint16_t *) PHYS_TO_K1(reg+disp->baseaddr));
117
118#ifdef _BYTESWAP_
119	*buf++ = (data >> 8) & 0xFF;
120	*buf++ = (data & 0xFF);
121#else
122	*buf++ = (data & 0xFF);
123	*buf++ = (data >> 8) & 0xFF;
124#endif
125	len--;
126	len--;
127	}
128
129}
130
131static void atapidrv_outb(idecommon_dispatch_t *disp,uint32_t reg,uint8_t val)
132{
133    *((volatile uint8_t *) PHYS_TO_K1(reg+disp->baseaddr)) = val;
134    _wbflush();
135}
136
137static void atapidrv_outw(idecommon_dispatch_t *disp,uint32_t reg,uint16_t val)
138{
139    *((volatile uint16_t *) PHYS_TO_K1(reg+disp->baseaddr)) = val;
140    _wbflush();
141}
142
143static void atapidrv_outs(idecommon_dispatch_t *disp,uint32_t reg,uint8_t *buf,int len)
144{
145    uint16_t data;
146
147    while (len > 0) {
148#ifdef _BYTESWAP_
149	data = (uint16_t) buf[1] + ((uint16_t) buf[0] << 8);
150#else
151	data = (uint16_t) buf[0] + ((uint16_t) buf[1] << 8);
152#endif
153
154	*((volatile uint16_t *) PHYS_TO_K1(reg+disp->baseaddr)) = data;
155	_wbflush();
156
157	buf++;
158	buf++;
159	len--;
160	len--;
161	}
162}
163
164
165
166static void atapidrv_probe(cfe_driver_t *drv,
167			      unsigned long probe_a, unsigned long probe_b,
168			      void *probe_ptr)
169{
170    idecommon_t *softc;
171    idecommon_dispatch_t *disp;
172    char descr[80];
173    char unitstr[50];
174    int res;
175
176    /*
177     * probe_a is the IDE base address
178     * probe_b is the unit number and other flags
179     * probe_ptr is unused.
180     */
181
182    softc = (idecommon_t *) KMALLOC(sizeof(idecommon_t),0);
183    disp = (idecommon_dispatch_t *) KMALLOC(sizeof(idecommon_dispatch_t),0);
184
185    if (softc && disp) {
186	softc->idecommon_addr = probe_a;
187	softc->idecommon_unit = probe_b;
188
189	disp->ref = softc;
190	disp->baseaddr = softc->idecommon_addr;
191	softc->idecommon_dispatch = disp;
192
193	disp->outb = atapidrv_outb;
194	disp->outw = atapidrv_outw;
195	disp->outs = atapidrv_outs;
196
197	disp->inb = atapidrv_inb;
198	disp->inw = atapidrv_inw;
199	disp->ins = atapidrv_ins;
200
201	res = idecommon_devprobe(softc);
202	if (res < 0) {
203	    KFREE(softc);
204	    KFREE(disp);
205	    return;
206	    }
207
208	xsprintf(descr,"%s unit %d at %08X",drv->drv_description,probe_b,probe_a);
209	xsprintf(unitstr,"%d",probe_b);
210	cfe_attach(drv,softc,unitstr,descr);
211	}
212}
213
214
215