1/* $Id: ide.h,v 1.1.1.1 2008/10/15 03:29:18 james26_jang Exp $ 2 * ide.h: Ultra/PCI specific IDE glue. 3 * 4 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) 5 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) 6 */ 7 8#ifndef _SPARC64_IDE_H 9#define _SPARC64_IDE_H 10 11#ifdef __KERNEL__ 12 13#include <linux/config.h> 14#include <asm/pgalloc.h> 15#include <asm/io.h> 16#include <asm/hdreg.h> 17#include <asm/page.h> 18#include <asm/spitfire.h> 19 20#undef MAX_HWIFS 21#define MAX_HWIFS 2 22 23#define ide__sti() __sti() 24 25static __inline__ int ide_default_irq(ide_ioreg_t base) 26{ 27 return 0; 28} 29 30static __inline__ ide_ioreg_t ide_default_io_base(int index) 31{ 32 return 0; 33} 34 35static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) 36{ 37 ide_ioreg_t reg = data_port; 38 int i; 39 40 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { 41 hw->io_ports[i] = reg; 42 reg += 1; 43 } 44 if (ctrl_port) { 45 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; 46 } else { 47 hw->io_ports[IDE_CONTROL_OFFSET] = 0; 48 } 49 if (irq != NULL) 50 *irq = 0; 51 hw->io_ports[IDE_IRQ_OFFSET] = 0; 52} 53 54/* 55 * This registers the standard ports for this architecture with the IDE 56 * driver. 57 */ 58static __inline__ void ide_init_default_hwifs(void) 59{ 60#ifndef CONFIG_BLK_DEV_IDEPCI 61 hw_regs_t hw; 62 int index; 63 64 for (index = 0; index < MAX_HWIFS; index++) { 65 ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL); 66 hw.irq = ide_default_irq(ide_default_io_base(index)); 67 ide_register_hw(&hw, NULL); 68 } 69#endif /* CONFIG_BLK_DEV_IDEPCI */ 70} 71 72typedef union { 73 unsigned int all : 8; /* all of the bits together */ 74 struct { 75 unsigned int bit7 : 1; 76 unsigned int lba : 1; 77 unsigned int bit5 : 1; 78 unsigned int unit : 1; 79 unsigned int head : 4; 80 } b; 81} select_t; 82 83typedef union { 84 unsigned int all : 8; /* all of the bits together */ 85 struct { 86 unsigned int HOB : 1; /* 48-bit address ordering */ 87 unsigned int reserved456: 3; 88 unsigned bit3 : 1; /* ATA-2 thingy */ 89 unsigned int SRST : 1; /* host soft reset bit */ 90 unsigned int nIEN : 1; /* device INTRQ to host */ 91 unsigned int bit0 : 1; 92 } b; 93} control_t; 94 95static __inline__ int ide_request_irq(unsigned int irq, 96 void (*handler)(int, void *, struct pt_regs *), 97 unsigned long flags, const char *name, void *devid) 98{ 99 return request_irq(irq, handler, SA_SHIRQ, name, devid); 100} 101 102static __inline__ void ide_free_irq(unsigned int irq, void *dev_id) 103{ 104 free_irq(irq, dev_id); 105} 106 107static __inline__ int ide_check_region(ide_ioreg_t base, unsigned int size) 108{ 109 return check_region(base, size); 110} 111 112static __inline__ void ide_request_region(ide_ioreg_t base, unsigned int size, 113 const char *name) 114{ 115 request_region(base, size, name); 116} 117 118static __inline__ void ide_release_region(ide_ioreg_t base, unsigned int size) 119{ 120 release_region(base, size); 121} 122 123#undef SUPPORT_SLOW_DATA_PORTS 124#define SUPPORT_SLOW_DATA_PORTS 0 125 126#undef SUPPORT_VLB_SYNC 127#define SUPPORT_VLB_SYNC 0 128 129#undef HD_DATA 130#define HD_DATA ((ide_ioreg_t)0) 131 132/* From m68k code... */ 133 134#ifdef insl 135#undef insl 136#endif 137#ifdef outsl 138#undef outsl 139#endif 140#ifdef insw 141#undef insw 142#endif 143#ifdef outsw 144#undef outsw 145#endif 146 147#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1) 148#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1) 149 150#define insw(port, buf, nr) ide_insw((port), (buf), (nr)) 151#define outsw(port, buf, nr) ide_outsw((port), (buf), (nr)) 152 153static __inline__ unsigned int inw_be(unsigned long addr) 154{ 155 unsigned int ret; 156 157 __asm__ __volatile__("lduha [%1] %2, %0" 158 : "=r" (ret) 159 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 160 161 return ret; 162} 163 164static __inline__ void ide_insw(unsigned long port, 165 void *dst, 166 unsigned long count) 167{ 168#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ 169 unsigned long end = (unsigned long)dst + (count << 1); 170#endif 171 u16 *ps = dst; 172 u32 *pi; 173 174 if(((u64)ps) & 0x2) { 175 *ps++ = inw_be(port); 176 count--; 177 } 178 pi = (u32 *)ps; 179 while(count >= 2) { 180 u32 w; 181 182 w = inw_be(port) << 16; 183 w |= inw_be(port); 184 *pi++ = w; 185 count -= 2; 186 } 187 ps = (u16 *)pi; 188 if(count) 189 *ps++ = inw_be(port); 190 191#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ 192 __flush_dcache_range((unsigned long)dst, end); 193#endif 194} 195 196static __inline__ void outw_be(unsigned short w, unsigned long addr) 197{ 198 __asm__ __volatile__("stha %0, [%1] %2" 199 : /* no outputs */ 200 : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 201} 202 203static __inline__ void ide_outsw(unsigned long port, 204 const void *src, 205 unsigned long count) 206{ 207#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ 208 unsigned long end = (unsigned long)src + (count << 1); 209#endif 210 const u16 *ps = src; 211 const u32 *pi; 212 213 if(((u64)src) & 0x2) { 214 outw_be(*ps++, port); 215 count--; 216 } 217 pi = (const u32 *)ps; 218 while(count >= 2) { 219 u32 w; 220 221 w = *pi++; 222 outw_be((w >> 16), port); 223 outw_be(w, port); 224 count -= 2; 225 } 226 ps = (const u16 *)pi; 227 if(count) 228 outw_be(*ps, port); 229 230#if (L1DCACHE_SIZE > PAGE_SIZE) /* is there D$ aliasing problem */ 231 __flush_dcache_range((unsigned long)src, end); 232#endif 233} 234 235static __inline__ void ide_fix_driveid(struct hd_driveid *id) 236{ 237 int i; 238 u16 *stringcast; 239 240 id->config = __le16_to_cpu(id->config); 241 id->cyls = __le16_to_cpu(id->cyls); 242 id->reserved2 = __le16_to_cpu(id->reserved2); 243 id->heads = __le16_to_cpu(id->heads); 244 id->track_bytes = __le16_to_cpu(id->track_bytes); 245 id->sector_bytes = __le16_to_cpu(id->sector_bytes); 246 id->sectors = __le16_to_cpu(id->sectors); 247 id->vendor0 = __le16_to_cpu(id->vendor0); 248 id->vendor1 = __le16_to_cpu(id->vendor1); 249 id->vendor2 = __le16_to_cpu(id->vendor2); 250 stringcast = (u16 *)&id->serial_no[0]; 251 for (i = 0; i < (20/2); i++) 252 stringcast[i] = __le16_to_cpu(stringcast[i]); 253 id->buf_type = __le16_to_cpu(id->buf_type); 254 id->buf_size = __le16_to_cpu(id->buf_size); 255 id->ecc_bytes = __le16_to_cpu(id->ecc_bytes); 256 stringcast = (u16 *)&id->fw_rev[0]; 257 for (i = 0; i < (8/2); i++) 258 stringcast[i] = __le16_to_cpu(stringcast[i]); 259 stringcast = (u16 *)&id->model[0]; 260 for (i = 0; i < (40/2); i++) 261 stringcast[i] = __le16_to_cpu(stringcast[i]); 262 id->dword_io = __le16_to_cpu(id->dword_io); 263 id->reserved50 = __le16_to_cpu(id->reserved50); 264 id->field_valid = __le16_to_cpu(id->field_valid); 265 id->cur_cyls = __le16_to_cpu(id->cur_cyls); 266 id->cur_heads = __le16_to_cpu(id->cur_heads); 267 id->cur_sectors = __le16_to_cpu(id->cur_sectors); 268 id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0); 269 id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1); 270 id->lba_capacity = __le32_to_cpu(id->lba_capacity); 271 id->dma_1word = __le16_to_cpu(id->dma_1word); 272 id->dma_mword = __le16_to_cpu(id->dma_mword); 273 id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes); 274 id->eide_dma_min = __le16_to_cpu(id->eide_dma_min); 275 id->eide_dma_time = __le16_to_cpu(id->eide_dma_time); 276 id->eide_pio = __le16_to_cpu(id->eide_pio); 277 id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy); 278 for (i = 0; i < 2; i++) 279 id->words69_70[i] = __le16_to_cpu(id->words69_70[i]); 280 for (i = 0; i < 4; i++) 281 id->words71_74[i] = __le16_to_cpu(id->words71_74[i]); 282 id->queue_depth = __le16_to_cpu(id->queue_depth); 283 for (i = 0; i < 4; i++) 284 id->words76_79[i] = __le16_to_cpu(id->words76_79[i]); 285 id->major_rev_num = __le16_to_cpu(id->major_rev_num); 286 id->minor_rev_num = __le16_to_cpu(id->minor_rev_num); 287 id->command_set_1 = __le16_to_cpu(id->command_set_1); 288 id->command_set_2 = __le16_to_cpu(id->command_set_2); 289 id->cfsse = __le16_to_cpu(id->cfsse); 290 id->cfs_enable_1 = __le16_to_cpu(id->cfs_enable_1); 291 id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2); 292 id->csf_default = __le16_to_cpu(id->csf_default); 293 id->dma_ultra = __le16_to_cpu(id->dma_ultra); 294 id->word89 = __le16_to_cpu(id->word89); 295 id->word90 = __le16_to_cpu(id->word90); 296 id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues); 297 id->word92 = __le16_to_cpu(id->word92); 298 id->hw_config = __le16_to_cpu(id->hw_config); 299 id->acoustic = __le16_to_cpu(id->acoustic); 300 for (i = 0; i < 5; i++) 301 id->words95_99[i] = __le16_to_cpu(id->words95_99[i]); 302 id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2); 303 for (i = 0; i < 22; i++) 304 id->words104_125[i] = __le16_to_cpu(id->words104_125[i]); 305 id->last_lun = __le16_to_cpu(id->last_lun); 306 id->word127 = __le16_to_cpu(id->word127); 307 id->dlf = __le16_to_cpu(id->dlf); 308 id->csfo = __le16_to_cpu(id->csfo); 309 for (i = 0; i < 26; i++) 310 id->words130_155[i] = __le16_to_cpu(id->words130_155[i]); 311 id->word156 = __le16_to_cpu(id->word156); 312 for (i = 0; i < 3; i++) 313 id->words157_159[i] = __le16_to_cpu(id->words157_159[i]); 314 id->cfa_power = __le16_to_cpu(id->cfa_power); 315 for (i = 0; i < 14; i++) 316 id->words161_175[i] = __le16_to_cpu(id->words161_175[i]); 317 for (i = 0; i < 31; i++) 318 id->words176_205[i] = __le16_to_cpu(id->words176_205[i]); 319 for (i = 0; i < 48; i++) 320 id->words206_254[i] = __le16_to_cpu(id->words206_254[i]); 321 id->integrity_word = __le16_to_cpu(id->integrity_word); 322} 323 324/* 325 * The following are not needed for the non-m68k ports 326 */ 327#define ide_ack_intr(hwif) (1) 328#define ide_release_lock(lock) do {} while (0) 329#define ide_get_lock(lock, hdlr, data) do {} while (0) 330 331#endif /* __KERNEL__ */ 332 333#endif /* _SPARC64_IDE_H */ 334