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