1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * This file contains the MIPS architecture specific IDE code. 7 * 8 * Copyright (C) 1994-1996 Linus Torvalds & authors 9 */ 10#ifndef __ASM_IDE_H 11#define __ASM_IDE_H 12 13#ifdef __KERNEL__ 14 15#include <linux/config.h> 16#include <asm/io.h> 17 18#ifndef MAX_HWIFS 19# ifdef CONFIG_BLK_DEV_IDEPCI 20#define MAX_HWIFS 10 21# else 22#define MAX_HWIFS 6 23# endif 24#endif 25 26#define ide__sti() __sti() 27 28struct ide_ops { 29 int (*ide_default_irq)(ide_ioreg_t base); 30 ide_ioreg_t (*ide_default_io_base)(int index); 31 void (*ide_init_hwif_ports)(hw_regs_t *hw, ide_ioreg_t data_port, 32 ide_ioreg_t ctrl_port, int *irq); 33 int (*ide_request_irq)(unsigned int irq, void (*handler)(int, void *, 34 struct pt_regs *), unsigned long flags, 35 const char *device, void *dev_id); 36 void (*ide_free_irq)(unsigned int irq, void *dev_id); 37 int (*ide_check_region) (ide_ioreg_t from, unsigned int extent); 38 void (*ide_request_region)(ide_ioreg_t from, unsigned int extent, 39 const char *name); 40 void (*ide_release_region)(ide_ioreg_t from, unsigned int extent); 41}; 42 43extern struct ide_ops *ide_ops; 44 45static __inline__ int ide_default_irq(ide_ioreg_t base) 46{ 47 return ide_ops->ide_default_irq(base); 48} 49 50static __inline__ ide_ioreg_t ide_default_io_base(int index) 51{ 52 return ide_ops->ide_default_io_base(index); 53} 54 55static inline void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, 56 ide_ioreg_t ctrl_port, int *irq) 57{ 58 ide_ops->ide_init_hwif_ports(hw, data_port, ctrl_port, irq); 59} 60 61static __inline__ void ide_init_default_hwifs(void) 62{ 63#ifndef CONFIG_BLK_DEV_IDEPCI 64 hw_regs_t hw; 65 int index; 66 67 for(index = 0; index < MAX_HWIFS; index++) { 68 ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL); 69 hw.irq = ide_default_irq(ide_default_io_base(index)); 70 ide_register_hw(&hw, NULL); 71 } 72#endif /* CONFIG_BLK_DEV_IDEPCI */ 73} 74 75typedef union { 76 unsigned all : 8; /* all of the bits together */ 77 struct { 78#ifdef __MIPSEB__ 79 unsigned bit7 : 1; /* always 1 */ 80 unsigned lba : 1; /* using LBA instead of CHS */ 81 unsigned bit5 : 1; /* always 1 */ 82 unsigned unit : 1; /* drive select number, 0 or 1 */ 83 unsigned head : 4; /* always zeros here */ 84#else 85 unsigned head : 4; /* always zeros here */ 86 unsigned unit : 1; /* drive select number, 0 or 1 */ 87 unsigned bit5 : 1; /* always 1 */ 88 unsigned lba : 1; /* using LBA instead of CHS */ 89 unsigned bit7 : 1; /* always 1 */ 90#endif 91 } b; 92} select_t; 93 94typedef union { 95 unsigned all : 8; /* all of the bits together */ 96 struct { 97#ifdef __MIPSEB__ 98 unsigned HOB : 1; /* 48-bit address ordering */ 99 unsigned reserved456 : 3; 100 unsigned bit3 : 1; /* ATA-2 thingy */ 101 unsigned SRST : 1; /* host soft reset bit */ 102 unsigned nIEN : 1; /* device INTRQ to host */ 103 unsigned bit0 : 1; 104#else 105 unsigned bit0 : 1; 106 unsigned nIEN : 1; /* device INTRQ to host */ 107 unsigned SRST : 1; /* host soft reset bit */ 108 unsigned bit3 : 1; /* ATA-2 thingy */ 109 unsigned reserved456 : 3; 110 unsigned HOB : 1; /* 48-bit address ordering */ 111#endif 112 } b; 113} control_t; 114 115static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int,void *, struct pt_regs *), 116 unsigned long flags, const char *device, void *dev_id) 117{ 118 return ide_ops->ide_request_irq(irq, handler, flags, device, dev_id); 119} 120 121static __inline__ void ide_free_irq(unsigned int irq, void *dev_id) 122{ 123 ide_ops->ide_free_irq(irq, dev_id); 124} 125 126static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent) 127{ 128 return ide_ops->ide_check_region(from, extent); 129} 130 131static __inline__ void ide_request_region(ide_ioreg_t from, unsigned int extent, 132 const char *name) 133{ 134 ide_ops->ide_request_region(from, extent, name); 135} 136 137static __inline__ void ide_release_region(ide_ioreg_t from, unsigned int extent) 138{ 139 ide_ops->ide_release_region(from, extent); 140} 141 142#if defined(CONFIG_SWAP_IO_SPACE_L) && defined(__MIPSEB__) 143 144/* get rid of defs from io.h - ide has its private and conflicting versions */ 145#ifdef insw 146#undef insw 147#endif 148#ifdef outsw 149#undef outsw 150#endif 151#ifdef insl 152#undef insl 153#endif 154#ifdef outsl 155#undef outsl 156#endif 157 158#define insw(port, addr, count) ide_insw(port, addr, count) 159#define insl(port, addr, count) ide_insl(port, addr, count) 160#define outsw(port, addr, count) ide_outsw(port, addr, count) 161#define outsl(port, addr, count) ide_outsl(port, addr, count) 162 163static inline void ide_insw(unsigned long port, void *addr, unsigned int count) 164{ 165 while (count--) { 166 *(u16 *)addr = *(volatile u16 *)(mips_io_port_base + port); 167 addr += 2; 168 } 169} 170 171static inline void ide_outsw(unsigned long port, void *addr, unsigned int count) 172{ 173 while (count--) { 174 *(volatile u16 *)(mips_io_port_base + (port)) = *(u16 *)addr; 175 addr += 2; 176 } 177} 178 179static inline void ide_insl(unsigned long port, void *addr, unsigned int count) 180{ 181 while (count--) { 182 *(u32 *)addr = *(volatile u32 *)(mips_io_port_base + port); 183 addr += 4; 184 } 185} 186 187static inline void ide_outsl(unsigned long port, void *addr, unsigned int count) 188{ 189 while (count--) { 190 *(volatile u32 *)(mips_io_port_base + (port)) = *(u32 *)addr; 191 addr += 4; 192 } 193} 194 195#define T_CHAR (0x0000) /* char: don't touch */ 196#define T_SHORT (0x4000) /* short: 12 -> 21 */ 197#define T_INT (0x8000) /* int: 1234 -> 4321 */ 198#define T_TEXT (0xc000) /* text: 12 -> 21 */ 199 200#define T_MASK_TYPE (0xc000) 201#define T_MASK_COUNT (0x3fff) 202 203#define D_CHAR(cnt) (T_CHAR | (cnt)) 204#define D_SHORT(cnt) (T_SHORT | (cnt)) 205#define D_INT(cnt) (T_INT | (cnt)) 206#define D_TEXT(cnt) (T_TEXT | (cnt)) 207 208static u_short driveid_types[] = { 209 D_SHORT(10), /* config - vendor2 */ 210 D_TEXT(20), /* serial_no */ 211 D_SHORT(3), /* buf_type - ecc_bytes */ 212 D_TEXT(48), /* fw_rev - model */ 213 D_CHAR(2), /* max_multsect - vendor3 */ 214 D_SHORT(1), /* dword_io */ 215 D_CHAR(2), /* vendor4 - capability */ 216 D_SHORT(1), /* reserved50 */ 217 D_CHAR(4), /* vendor5 - tDMA */ 218 D_SHORT(4), /* field_valid - cur_sectors */ 219 D_INT(1), /* cur_capacity */ 220 D_CHAR(2), /* multsect - multsect_valid */ 221 D_INT(1), /* lba_capacity */ 222 D_SHORT(194) /* dma_1word - reservedyy */ 223}; 224 225#define num_driveid_types (sizeof(driveid_types)/sizeof(*driveid_types)) 226 227static __inline__ void ide_fix_driveid(struct hd_driveid *id) 228{ 229 u_char *p = (u_char *)id; 230 int i, j, cnt; 231 u_char t; 232 233 for (i = 0; i < num_driveid_types; i++) { 234 cnt = driveid_types[i] & T_MASK_COUNT; 235 switch (driveid_types[i] & T_MASK_TYPE) { 236 case T_CHAR: 237 p += cnt; 238 break; 239 case T_SHORT: 240 for (j = 0; j < cnt; j++) { 241 t = p[0]; 242 p[0] = p[1]; 243 p[1] = t; 244 p += 2; 245 } 246 break; 247 case T_INT: 248 for (j = 0; j < cnt; j++) { 249 t = p[0]; 250 p[0] = p[3]; 251 p[3] = t; 252 t = p[1]; 253 p[1] = p[2]; 254 p[2] = t; 255 p += 4; 256 } 257 break; 258 case T_TEXT: 259 for (j = 0; j < cnt; j += 2) { 260 t = p[0]; 261 p[0] = p[1]; 262 p[1] = t; 263 p += 2; 264 } 265 break; 266 }; 267 } 268} 269 270#else /* defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__) */ 271 272#define ide_fix_driveid(id) do {} while (0) 273 274#endif 275 276/* 277 * The following are not needed for the non-m68k ports 278 */ 279#define ide_ack_intr(hwif) (1) 280#define ide_release_lock(lock) do {} while (0) 281#define ide_get_lock(lock, hdlr, data) do {} while (0) 282 283#endif /* __KERNEL__ */ 284 285#endif /* __ASM_IDE_H */ 286