• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/cfe/cfe/arch/mips/board/bcm1250cpci/src/
1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  IDE disk driver				File: dev_ide.c
5    *
6    *  This is a simple driver for IDE hard disks.  The disks
7    *  are expected to be connected to the generic bus (this
8    *  driver doesn't support PCI).
9    *
10    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
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 "sbmips.h"
51#include "lib_types.h"
52#include "lib_malloc.h"
53#include "lib_printf.h"
54#include "lib_string.h"
55#include "cfe_timer.h"
56#include "cfe_iocb.h"
57#include "cfe_device.h"
58#include "cfe_ioctl.h"
59
60#include "dev_ide_common.h"
61
62#include "dev_ide.h"
63
64/*  *********************************************************************
65    *  Macros
66    ********************************************************************* */
67
68/*  *********************************************************************
69    *  Forward declarations
70    ********************************************************************* */
71
72static void idedrv_probe(cfe_driver_t *drv,
73			      unsigned long probe_a, unsigned long probe_b,
74			      void *probe_ptr);
75
76/*  *********************************************************************
77    *  Device Dispatch
78    ********************************************************************* */
79
80static cfe_devdisp_t idedrv_dispatch = {
81    NULL,
82    NULL,
83    NULL,
84    NULL,
85    NULL,
86    NULL,
87    NULL,
88    NULL
89};
90
91const cfe_driver_t idedrv = {
92    "IDE disk",
93    "ide",
94    CFE_DEV_DISK,
95    &idedrv_dispatch,
96    idedrv_probe
97};
98
99const cfe_driver_t atapidrv = {
100    "ATAPI device",
101    "atapi",
102    CFE_DEV_DISK,
103    &idedrv_dispatch,
104    idedrv_probe
105};
106
107
108#define IDE_REG_ADDR_SHIFT	5
109
110
111/*  *********************************************************************
112    *  Port I/O routines
113    *
114    *  These routines are called back from the common code to do
115    *  I/O cycles to the IDE disk.  We provide routines for
116    *  reading and writing bytes, words, and strings of words.
117    ********************************************************************* */
118
119static uint8_t idedrv_inb(idecommon_dispatch_t *disp,uint32_t reg)
120{
121    reg <<= IDE_REG_ADDR_SHIFT;
122
123    return  (*((volatile uint8_t *) PHYS_TO_K1(reg+disp->baseaddr)));
124}
125
126static uint16_t idedrv_inw(idecommon_dispatch_t *disp,uint32_t reg)
127{
128    reg <<= IDE_REG_ADDR_SHIFT;
129
130    return *((volatile uint16_t *) PHYS_TO_K1((reg+disp->baseaddr)));
131}
132
133static void idedrv_ins(idecommon_dispatch_t *disp,uint32_t reg,uint8_t *buf,int len)
134{
135    uint16_t data;
136    uint16_t *buf16;
137
138    reg <<= IDE_REG_ADDR_SHIFT;
139
140    /* Do 16-bit reads/writes so that the byteswaps will work out right */
141
142    buf16 = (uint16_t *) buf;
143
144    while (len > 0) {
145	data = *((volatile uint16_t *) PHYS_TO_K1(reg+disp->baseaddr));
146	*buf16++ = data;
147	len--;
148	len--;
149	}
150
151}
152
153static void idedrv_outb(idecommon_dispatch_t *disp,uint32_t reg,uint8_t val)
154{
155    reg <<= IDE_REG_ADDR_SHIFT;
156
157    *((volatile uint8_t *) PHYS_TO_K1(reg+disp->baseaddr)) = (uint8_t) (val);
158}
159
160static void idedrv_outw(idecommon_dispatch_t *disp,uint32_t reg,uint16_t val)
161{
162    reg <<= IDE_REG_ADDR_SHIFT;
163
164    *((volatile uint16_t *) PHYS_TO_K1(reg+disp->baseaddr)) = val;
165}
166
167static void idedrv_outs(idecommon_dispatch_t *disp,uint32_t reg,uint8_t *buf,int len)
168{
169    uint16_t data;
170    uint16_t *buf16;
171
172    reg <<= IDE_REG_ADDR_SHIFT;
173
174    buf16 = (uint16_t *) buf;
175
176    while (len > 0) {
177	data = *buf16++;
178	*((volatile uint16_t *) PHYS_TO_K1(reg+disp->baseaddr)) = data;
179	len--;
180	len--;
181	}
182}
183
184
185
186/*  *********************************************************************
187    *  idedrv_probe(drv,probe_a,probe_b,probe_ptr)
188    *
189    *  Our probe routine.  Attach an IDE device to the firmware.
190    *
191    *  Input parameters:
192    *  	   drv - driver structure
193    *  	   probe_a - physical address of IDE registers
194    *  	   probe_b - unit number
195    *  	   probe_ptr - not used
196    *
197    *  Return value:
198    *  	   nothing
199    ********************************************************************* */
200
201static void idedrv_probe(cfe_driver_t *drv,
202			      unsigned long probe_a, unsigned long probe_b,
203			      void *probe_ptr)
204{
205    idecommon_t *softc = NULL;
206    idecommon_dispatch_t *disp = NULL;
207    char descr[80];
208    char unitstr[50];
209    int res;
210    cfe_driver_t *realdrv;
211    int unit;
212
213    /*
214     * probe_a is the IDE base address
215     * probe_b is a bitmask of unit numbers to check
216     * probe_ptr is unused.
217     */
218
219    for (unit = 0; unit < 2; unit++) {
220
221	if (IDE_PROBE_GET_TYPE(probe_b,unit) == IDE_DEVTYPE_NOPROBE) {
222	    continue;
223	    }
224
225	softc = (idecommon_t *) KMALLOC(sizeof(idecommon_t),0);
226	disp = (idecommon_dispatch_t *) KMALLOC(sizeof(idecommon_dispatch_t),0);
227
228	if (!softc || !disp) {
229	    if (softc) KFREE(softc);
230	    if (disp) KFREE(disp);
231	    return;		/* out of memory, stop here */
232	    }
233
234	softc->idecommon_addr = probe_a;
235	softc->idecommon_unit = unit;
236	softc->idecommon_deferprobe = 0;
237
238	disp->ref = softc;
239	disp->baseaddr = softc->idecommon_addr;
240	softc->idecommon_dispatch = disp;
241
242	disp->outb = idedrv_outb;
243	disp->outw = idedrv_outw;
244	disp->outs = idedrv_outs;
245
246	disp->inb = idedrv_inb;
247	disp->inw = idedrv_inw;
248	disp->ins = idedrv_ins;
249
250	/*
251	 * If we're autoprobing, do it now.  Loop back if we have
252	 * trouble finding the device.
253	 *
254	 * If not autoprobing, assume the device is there and set the
255	 * common routines to double check later.
256	 */
257
258	if (IDE_PROBE_GET_TYPE(probe_b,unit) == IDE_DEVTYPE_AUTO) {
259	    res = idecommon_devprobe(softc,1);
260	    if (res < 0) {
261		KFREE(softc);
262		KFREE(disp);
263		continue;
264		}
265	    }
266	else {
267	    idecommon_init(softc,IDE_PROBE_GET_TYPE(probe_b,unit));
268	    softc->idecommon_deferprobe = 1;
269	    }
270
271
272	xsprintf(descr,"%s unit %d at %08X",drv->drv_description,unit,probe_a);
273	xsprintf(unitstr,"%d",unit);
274
275	realdrv = (cfe_driver_t *) (softc->idecommon_atapi ? &atapidrv : &idedrv);
276	idecommon_attach(&idedrv_dispatch);
277
278	cfe_attach(realdrv,softc,unitstr,descr);
279	}
280}
281