Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.25-rc4 855 lines 20 kB view raw
1/* 2 * Copyright (C) 2000, 2001 Wolfgang Denk, wd@denx.de 3 * Modified for direct IDE interface 4 * by Thomas Lange, thomas@corelatus.com 5 * Modified for direct IDE interface on 8xx without using the PCMCIA 6 * controller 7 * by Steven.Scholz@imc-berlin.de 8 * Moved out of arch/ppc/kernel/m8xx_setup.c, other minor cleanups 9 * by Mathew Locke <mattl@mvista.com> 10 */ 11 12#include <linux/errno.h> 13#include <linux/kernel.h> 14#include <linux/mm.h> 15#include <linux/stddef.h> 16#include <linux/unistd.h> 17#include <linux/ptrace.h> 18#include <linux/slab.h> 19#include <linux/user.h> 20#include <linux/tty.h> 21#include <linux/major.h> 22#include <linux/interrupt.h> 23#include <linux/reboot.h> 24#include <linux/init.h> 25#include <linux/ioport.h> 26#include <linux/ide.h> 27#include <linux/bootmem.h> 28 29#include <asm/mpc8xx.h> 30#include <asm/mmu.h> 31#include <asm/processor.h> 32#include <asm/io.h> 33#include <asm/pgtable.h> 34#include <asm/ide.h> 35#include <asm/8xx_immap.h> 36#include <asm/machdep.h> 37#include <asm/irq.h> 38 39static int identify (volatile u8 *p); 40static void print_fixed (volatile u8 *p); 41static void print_funcid (int func); 42static int check_ide_device (unsigned long base); 43 44static void ide_interrupt_ack (void *dev); 45static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio); 46 47typedef struct ide_ioport_desc { 48 unsigned long base_off; /* Offset to PCMCIA memory */ 49 unsigned long reg_off[IDE_NR_PORTS]; /* controller register offsets */ 50 int irq; /* IRQ */ 51} ide_ioport_desc_t; 52 53ide_ioport_desc_t ioport_dsc[MAX_HWIFS] = { 54#ifdef IDE0_BASE_OFFSET 55 { IDE0_BASE_OFFSET, 56 { 57 IDE0_DATA_REG_OFFSET, 58 IDE0_ERROR_REG_OFFSET, 59 IDE0_NSECTOR_REG_OFFSET, 60 IDE0_SECTOR_REG_OFFSET, 61 IDE0_LCYL_REG_OFFSET, 62 IDE0_HCYL_REG_OFFSET, 63 IDE0_SELECT_REG_OFFSET, 64 IDE0_STATUS_REG_OFFSET, 65 IDE0_CONTROL_REG_OFFSET, 66 IDE0_IRQ_REG_OFFSET, 67 }, 68 IDE0_INTERRUPT, 69 }, 70#ifdef IDE1_BASE_OFFSET 71 { IDE1_BASE_OFFSET, 72 { 73 IDE1_DATA_REG_OFFSET, 74 IDE1_ERROR_REG_OFFSET, 75 IDE1_NSECTOR_REG_OFFSET, 76 IDE1_SECTOR_REG_OFFSET, 77 IDE1_LCYL_REG_OFFSET, 78 IDE1_HCYL_REG_OFFSET, 79 IDE1_SELECT_REG_OFFSET, 80 IDE1_STATUS_REG_OFFSET, 81 IDE1_CONTROL_REG_OFFSET, 82 IDE1_IRQ_REG_OFFSET, 83 }, 84 IDE1_INTERRUPT, 85 }, 86#endif /* IDE1_BASE_OFFSET */ 87#endif /* IDE0_BASE_OFFSET */ 88}; 89 90ide_pio_timings_t ide_pio_clocks[6]; 91int hold_time[6] = {30, 20, 15, 10, 10, 10 }; /* PIO Mode 5 with IORDY (nonstandard) */ 92 93/* 94 * Warning: only 1 (ONE) PCMCIA slot supported here, 95 * which must be correctly initialized by the firmware (PPCBoot). 96 */ 97static int _slot_ = -1; /* will be read from PCMCIA registers */ 98 99/* Make clock cycles and always round up */ 100#define PCMCIA_MK_CLKS( t, T ) (( (t) * ((T)/1000000) + 999U ) / 1000U ) 101 102 103 104/* 105 * IDE stuff. 106 */ 107static int 108m8xx_ide_default_irq(unsigned long base) 109{ 110#ifdef CONFIG_BLK_DEV_MPC8xx_IDE 111 if (base >= MAX_HWIFS) 112 return 0; 113 114 printk("[%d] m8xx_ide_default_irq %d\n",__LINE__,ioport_dsc[base].irq); 115 116 return (ioport_dsc[base].irq); 117#else 118 return 9; 119#endif 120} 121 122static unsigned long 123m8xx_ide_default_io_base(int index) 124{ 125 return index; 126} 127 128#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4)) 129#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4)) 130 131/* 132 * The TQM850L hardware has two pins swapped! Grrrrgh! 133 */ 134#ifdef CONFIG_TQM850L 135#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXOE 136#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXRESET 137#else 138#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXRESET 139#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXOE 140#endif 141 142#if defined(CONFIG_BLK_DEV_MPC8xx_IDE) && defined(CONFIG_IDE_8xx_PCCARD) 143#define PCMCIA_SCHLVL IDE0_INTERRUPT /* Status Change Interrupt Level */ 144static int pcmcia_schlvl = PCMCIA_SCHLVL; 145#endif 146 147/* 148 * See include/linux/ide.h for definition of hw_regs_t (p, base) 149 */ 150 151/* 152 * m8xx_ide_init_hwif_ports for a direct IDE interface _using_ 153 */ 154#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) 155static void 156m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, 157 unsigned long ctrl_port, int *irq) 158{ 159 unsigned long *p = hw->io_ports; 160 int i; 161 162 typedef struct { 163 ulong br; 164 ulong or; 165 } pcmcia_win_t; 166 volatile pcmcia_win_t *win; 167 volatile pcmconf8xx_t *pcmp; 168 169 uint *pgcrx; 170 u32 pcmcia_phy_base; 171 u32 pcmcia_phy_end; 172 static unsigned long pcmcia_base = 0; 173 unsigned long base; 174 175 *p = 0; 176 if (irq) 177 *irq = 0; 178 179 pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia)); 180 181 if (!pcmcia_base) { 182 /* 183 * Read out PCMCIA registers. Since the reset values 184 * are undefined, we sure hope that they have been 185 * set up by firmware 186 */ 187 188 /* Scan all registers for valid settings */ 189 pcmcia_phy_base = 0xFFFFFFFF; 190 pcmcia_phy_end = 0; 191 /* br0 is start of brX and orX regs */ 192 win = (pcmcia_win_t *) \ 193 (&(((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0)); 194 for (i = 0; i < 8; i++) { 195 if (win->or & 1) { /* This bank is marked as valid */ 196 if (win->br < pcmcia_phy_base) { 197 pcmcia_phy_base = win->br; 198 } 199 if ((win->br + PCMCIA_MEM_SIZE) > pcmcia_phy_end) { 200 pcmcia_phy_end = win->br + PCMCIA_MEM_SIZE; 201 } 202 /* Check which slot that has been defined */ 203 _slot_ = (win->or >> 2) & 1; 204 205 } /* Valid bank */ 206 win++; 207 } /* for */ 208 209 printk ("PCMCIA slot %c: phys mem %08x...%08x (size %08x)\n", 210 'A' + _slot_, 211 pcmcia_phy_base, pcmcia_phy_end, 212 pcmcia_phy_end - pcmcia_phy_base); 213 214 pcmcia_base=(unsigned long)ioremap(pcmcia_phy_base, 215 pcmcia_phy_end-pcmcia_phy_base); 216 217#ifdef DEBUG 218 printk ("PCMCIA virt base: %08lx\n", pcmcia_base); 219#endif 220 /* Compute clock cycles for PIO timings */ 221 for (i=0; i<6; ++i) { 222 bd_t *binfo = (bd_t *)__res; 223 224 hold_time[i] = 225 PCMCIA_MK_CLKS (hold_time[i], 226 binfo->bi_busfreq); 227 ide_pio_clocks[i].setup_time = 228 PCMCIA_MK_CLKS (ide_pio_timings[i].setup_time, 229 binfo->bi_busfreq); 230 ide_pio_clocks[i].active_time = 231 PCMCIA_MK_CLKS (ide_pio_timings[i].active_time, 232 binfo->bi_busfreq); 233 ide_pio_clocks[i].cycle_time = 234 PCMCIA_MK_CLKS (ide_pio_timings[i].cycle_time, 235 binfo->bi_busfreq); 236#if 0 237 printk ("PIO mode %d timings: %d/%d/%d => %d/%d/%d\n", 238 i, 239 ide_pio_clocks[i].setup_time, 240 ide_pio_clocks[i].active_time, 241 ide_pio_clocks[i].hold_time, 242 ide_pio_clocks[i].cycle_time, 243 ide_pio_timings[i].setup_time, 244 ide_pio_timings[i].active_time, 245 ide_pio_timings[i].hold_time, 246 ide_pio_timings[i].cycle_time); 247#endif 248 } 249 } 250 251 if (data_port >= MAX_HWIFS) 252 return; 253 254 if (_slot_ == -1) { 255 printk ("PCMCIA slot has not been defined! Using A as default\n"); 256 _slot_ = 0; 257 } 258 259#ifdef CONFIG_IDE_8xx_PCCARD 260 261#ifdef DEBUG 262 printk ("PIPR = 0x%08X slot %c ==> mask = 0x%X\n", 263 pcmp->pcmc_pipr, 264 'A' + _slot_, 265 M8XX_PCMCIA_CD1(_slot_) | M8XX_PCMCIA_CD2(_slot_) ); 266#endif /* DEBUG */ 267 268 if (pcmp->pcmc_pipr & (M8XX_PCMCIA_CD1(_slot_)|M8XX_PCMCIA_CD2(_slot_))) { 269 printk ("No card in slot %c: PIPR=%08x\n", 270 'A' + _slot_, (u32) pcmp->pcmc_pipr); 271 return; /* No card in slot */ 272 } 273 274 check_ide_device (pcmcia_base); 275 276#endif /* CONFIG_IDE_8xx_PCCARD */ 277 278 base = pcmcia_base + ioport_dsc[data_port].base_off; 279#ifdef DEBUG 280 printk ("base: %08x + %08x = %08x\n", 281 pcmcia_base, ioport_dsc[data_port].base_off, base); 282#endif 283 284 for (i = 0; i < IDE_NR_PORTS; ++i) { 285#ifdef DEBUG 286 printk ("port[%d]: %08x + %08x = %08x\n", 287 i, 288 base, 289 ioport_dsc[data_port].reg_off[i], 290 i, base + ioport_dsc[data_port].reg_off[i]); 291#endif 292 *p++ = base + ioport_dsc[data_port].reg_off[i]; 293 } 294 295 if (irq) { 296#ifdef CONFIG_IDE_8xx_PCCARD 297 unsigned int reg; 298 299 *irq = ioport_dsc[data_port].irq; 300 if (_slot_) 301 pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcrb; 302 else 303 pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcra; 304 305 reg = *pgcrx; 306 reg |= mk_int_int_mask (pcmcia_schlvl) << 24; 307 reg |= mk_int_int_mask (pcmcia_schlvl) << 16; 308 *pgcrx = reg; 309#else /* direct connected IDE drive, i.e. external IRQ, not the PCMCIA irq */ 310 *irq = ioport_dsc[data_port].irq; 311#endif /* CONFIG_IDE_8xx_PCCARD */ 312 } 313 314 ide_hwifs[data_port].pio_mask = ATA_PIO4; 315 ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode; 316 ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack; 317 318 /* Enable Harddisk Interrupt, 319 * and make it edge sensitive 320 */ 321 /* (11-18) Set edge detect for irq, no wakeup from low power mode */ 322 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |= 323 (0x80000000 >> ioport_dsc[data_port].irq); 324 325#ifdef CONFIG_IDE_8xx_PCCARD 326 /* Make sure we don't get garbage irq */ 327 ((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pscr = 0xFFFF; 328 329 /* Enable falling edge irq */ 330 pcmp->pcmc_per = 0x100000 >> (16 * _slot_); 331#endif /* CONFIG_IDE_8xx_PCCARD */ 332} /* m8xx_ide_init_hwif_ports() using 8xx internal PCMCIA interface */ 333#endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */ 334 335/* 336 * m8xx_ide_init_hwif_ports for a direct IDE interface _not_ using 337 * MPC8xx's internal PCMCIA interface 338 */ 339#if defined(CONFIG_IDE_EXT_DIRECT) 340void m8xx_ide_init_hwif_ports (hw_regs_t *hw, 341 unsigned long data_port, unsigned long ctrl_port, int *irq) 342{ 343 unsigned long *p = hw->io_ports; 344 int i; 345 346 u32 ide_phy_base; 347 u32 ide_phy_end; 348 static unsigned long ide_base = 0; 349 unsigned long base; 350 351 *p = 0; 352 if (irq) 353 *irq = 0; 354 355 if (!ide_base) { 356 357 /* TODO: 358 * - add code to read ORx, BRx 359 */ 360 ide_phy_base = CFG_ATA_BASE_ADDR; 361 ide_phy_end = CFG_ATA_BASE_ADDR + 0x200; 362 363 printk ("IDE phys mem : %08x...%08x (size %08x)\n", 364 ide_phy_base, ide_phy_end, 365 ide_phy_end - ide_phy_base); 366 367 ide_base=(unsigned long)ioremap(ide_phy_base, 368 ide_phy_end-ide_phy_base); 369 370#ifdef DEBUG 371 printk ("IDE virt base: %08lx\n", ide_base); 372#endif 373 } 374 375 if (data_port >= MAX_HWIFS) 376 return; 377 378 base = ide_base + ioport_dsc[data_port].base_off; 379#ifdef DEBUG 380 printk ("base: %08x + %08x = %08x\n", 381 ide_base, ioport_dsc[data_port].base_off, base); 382#endif 383 384 for (i = 0; i < IDE_NR_PORTS; ++i) { 385#ifdef DEBUG 386 printk ("port[%d]: %08x + %08x = %08x\n", 387 i, 388 base, 389 ioport_dsc[data_port].reg_off[i], 390 i, base + ioport_dsc[data_port].reg_off[i]); 391#endif 392 *p++ = base + ioport_dsc[data_port].reg_off[i]; 393 } 394 395 if (irq) { 396 /* direct connected IDE drive, i.e. external IRQ */ 397 *irq = ioport_dsc[data_port].irq; 398 } 399 400 ide_hwifs[data_port].pio_mask = ATA_PIO4; 401 ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode; 402 ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack; 403 404 /* Enable Harddisk Interrupt, 405 * and make it edge sensitive 406 */ 407 /* (11-18) Set edge detect for irq, no wakeup from low power mode */ 408 ((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |= 409 (0x80000000 >> ioport_dsc[data_port].irq); 410} /* m8xx_ide_init_hwif_ports() for CONFIG_IDE_8xx_DIRECT */ 411 412#endif /* CONFIG_IDE_8xx_DIRECT */ 413 414 415/* -------------------------------------------------------------------- */ 416 417 418/* PCMCIA Timing */ 419#ifndef PCMCIA_SHT 420#define PCMCIA_SHT(t) ((t & 0x0F)<<16) /* Strobe Hold Time */ 421#define PCMCIA_SST(t) ((t & 0x0F)<<12) /* Strobe Setup Time */ 422#define PCMCIA_SL(t) ((t==32) ? 0 : ((t & 0x1F)<<7)) /* Strobe Length */ 423#endif 424 425/* Calculate PIO timings */ 426static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) 427{ 428#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT) 429 volatile pcmconf8xx_t *pcmp; 430 ulong timing, mask, reg; 431 432 pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia)); 433 434 mask = ~(PCMCIA_SHT(0xFF) | PCMCIA_SST(0xFF) | PCMCIA_SL(0xFF)); 435 436 timing = PCMCIA_SHT(hold_time[pio] ) 437 | PCMCIA_SST(ide_pio_clocks[pio].setup_time ) 438 | PCMCIA_SL (ide_pio_clocks[pio].active_time) 439 ; 440 441#if 1 442 printk ("Setting timing bits 0x%08lx in PCMCIA controller\n", timing); 443#endif 444 if ((reg = pcmp->pcmc_por0 & mask) != 0) 445 pcmp->pcmc_por0 = reg | timing; 446 447 if ((reg = pcmp->pcmc_por1 & mask) != 0) 448 pcmp->pcmc_por1 = reg | timing; 449 450 if ((reg = pcmp->pcmc_por2 & mask) != 0) 451 pcmp->pcmc_por2 = reg | timing; 452 453 if ((reg = pcmp->pcmc_por3 & mask) != 0) 454 pcmp->pcmc_por3 = reg | timing; 455 456 if ((reg = pcmp->pcmc_por4 & mask) != 0) 457 pcmp->pcmc_por4 = reg | timing; 458 459 if ((reg = pcmp->pcmc_por5 & mask) != 0) 460 pcmp->pcmc_por5 = reg | timing; 461 462 if ((reg = pcmp->pcmc_por6 & mask) != 0) 463 pcmp->pcmc_por6 = reg | timing; 464 465 if ((reg = pcmp->pcmc_por7 & mask) != 0) 466 pcmp->pcmc_por7 = reg | timing; 467 468#elif defined(CONFIG_IDE_EXT_DIRECT) 469 470 printk("%s[%d] %s: not implemented yet!\n", 471 __FILE__,__LINE__,__FUNCTION__); 472#endif /* defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_PCMCIA */ 473} 474 475static void 476ide_interrupt_ack (void *dev) 477{ 478#ifdef CONFIG_IDE_8xx_PCCARD 479 u_int pscr, pipr; 480 481#if (PCMCIA_SOCKETS_NO == 2) 482 u_int _slot_; 483#endif 484 485 /* get interrupt sources */ 486 487 pscr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr; 488 pipr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr; 489 490 /* 491 * report only if both card detect signals are the same 492 * not too nice done, 493 * we depend on that CD2 is the bit to the left of CD1... 494 */ 495 496 if(_slot_==-1){ 497 printk("PCMCIA slot has not been defined! Using A as default\n"); 498 _slot_=0; 499 } 500 501 if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1) ^ 502 (pipr & M8XX_PCMCIA_CD1(_slot_)) ) { 503 printk ("card detect interrupt\n"); 504 } 505 /* clear the interrupt sources */ 506 ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr; 507 508#else /* ! CONFIG_IDE_8xx_PCCARD */ 509 /* 510 * Only CONFIG_IDE_8xx_PCCARD is using the interrupt of the 511 * MPC8xx's PCMCIA controller, so there is nothing to be done here 512 * for CONFIG_IDE_8xx_DIRECT and CONFIG_IDE_EXT_DIRECT. 513 * The interrupt is handled somewhere else. -- Steven 514 */ 515#endif /* CONFIG_IDE_8xx_PCCARD */ 516} 517 518 519 520/* 521 * CIS Tupel codes 522 */ 523#define CISTPL_NULL 0x00 524#define CISTPL_DEVICE 0x01 525#define CISTPL_LONGLINK_CB 0x02 526#define CISTPL_INDIRECT 0x03 527#define CISTPL_CONFIG_CB 0x04 528#define CISTPL_CFTABLE_ENTRY_CB 0x05 529#define CISTPL_LONGLINK_MFC 0x06 530#define CISTPL_BAR 0x07 531#define CISTPL_PWR_MGMNT 0x08 532#define CISTPL_EXTDEVICE 0x09 533#define CISTPL_CHECKSUM 0x10 534#define CISTPL_LONGLINK_A 0x11 535#define CISTPL_LONGLINK_C 0x12 536#define CISTPL_LINKTARGET 0x13 537#define CISTPL_NO_LINK 0x14 538#define CISTPL_VERS_1 0x15 539#define CISTPL_ALTSTR 0x16 540#define CISTPL_DEVICE_A 0x17 541#define CISTPL_JEDEC_C 0x18 542#define CISTPL_JEDEC_A 0x19 543#define CISTPL_CONFIG 0x1a 544#define CISTPL_CFTABLE_ENTRY 0x1b 545#define CISTPL_DEVICE_OC 0x1c 546#define CISTPL_DEVICE_OA 0x1d 547#define CISTPL_DEVICE_GEO 0x1e 548#define CISTPL_DEVICE_GEO_A 0x1f 549#define CISTPL_MANFID 0x20 550#define CISTPL_FUNCID 0x21 551#define CISTPL_FUNCE 0x22 552#define CISTPL_SWIL 0x23 553#define CISTPL_END 0xff 554 555/* 556 * CIS Function ID codes 557 */ 558#define CISTPL_FUNCID_MULTI 0x00 559#define CISTPL_FUNCID_MEMORY 0x01 560#define CISTPL_FUNCID_SERIAL 0x02 561#define CISTPL_FUNCID_PARALLEL 0x03 562#define CISTPL_FUNCID_FIXED 0x04 563#define CISTPL_FUNCID_VIDEO 0x05 564#define CISTPL_FUNCID_NETWORK 0x06 565#define CISTPL_FUNCID_AIMS 0x07 566#define CISTPL_FUNCID_SCSI 0x08 567 568/* 569 * Fixed Disk FUNCE codes 570 */ 571#define CISTPL_IDE_INTERFACE 0x01 572 573#define CISTPL_FUNCE_IDE_IFACE 0x01 574#define CISTPL_FUNCE_IDE_MASTER 0x02 575#define CISTPL_FUNCE_IDE_SLAVE 0x03 576 577/* First feature byte */ 578#define CISTPL_IDE_SILICON 0x04 579#define CISTPL_IDE_UNIQUE 0x08 580#define CISTPL_IDE_DUAL 0x10 581 582/* Second feature byte */ 583#define CISTPL_IDE_HAS_SLEEP 0x01 584#define CISTPL_IDE_HAS_STANDBY 0x02 585#define CISTPL_IDE_HAS_IDLE 0x04 586#define CISTPL_IDE_LOW_POWER 0x08 587#define CISTPL_IDE_REG_INHIBIT 0x10 588#define CISTPL_IDE_HAS_INDEX 0x20 589#define CISTPL_IDE_IOIS16 0x40 590 591 592/* -------------------------------------------------------------------- */ 593 594 595#define MAX_TUPEL_SZ 512 596#define MAX_FEATURES 4 597 598static int check_ide_device (unsigned long base) 599{ 600 volatile u8 *ident = NULL; 601 volatile u8 *feature_p[MAX_FEATURES]; 602 volatile u8 *p, *start; 603 int n_features = 0; 604 u8 func_id = ~0; 605 u8 code, len; 606 unsigned short config_base = 0; 607 int found = 0; 608 int i; 609 610#ifdef DEBUG 611 printk ("PCMCIA MEM: %08lX\n", base); 612#endif 613 start = p = (volatile u8 *) base; 614 615 while ((p - start) < MAX_TUPEL_SZ) { 616 617 code = *p; p += 2; 618 619 if (code == 0xFF) { /* End of chain */ 620 break; 621 } 622 623 len = *p; p += 2; 624#ifdef DEBUG_PCMCIA 625 { volatile u8 *q = p; 626 printk ("\nTuple code %02x length %d\n\tData:", 627 code, len); 628 629 for (i = 0; i < len; ++i) { 630 printk (" %02x", *q); 631 q+= 2; 632 } 633 } 634#endif /* DEBUG_PCMCIA */ 635 switch (code) { 636 case CISTPL_VERS_1: 637 ident = p + 4; 638 break; 639 case CISTPL_FUNCID: 640 func_id = *p; 641 break; 642 case CISTPL_FUNCE: 643 if (n_features < MAX_FEATURES) 644 feature_p[n_features++] = p; 645 break; 646 case CISTPL_CONFIG: 647 config_base = (*(p+6) << 8) + (*(p+4)); 648 default: 649 break; 650 } 651 p += 2 * len; 652 } 653 654 found = identify (ident); 655 656 if (func_id != ((u8)~0)) { 657 print_funcid (func_id); 658 659 if (func_id == CISTPL_FUNCID_FIXED) 660 found = 1; 661 else 662 return (1); /* no disk drive */ 663 } 664 665 for (i=0; i<n_features; ++i) { 666 print_fixed (feature_p[i]); 667 } 668 669 if (!found) { 670 printk ("unknown card type\n"); 671 return (1); 672 } 673 674 /* set level mode irq and I/O mapped device in config reg*/ 675 *((u8 *)(base + config_base)) = 0x41; 676 677 return (0); 678} 679 680/* ------------------------------------------------------------------------- */ 681 682static void print_funcid (int func) 683{ 684 switch (func) { 685 case CISTPL_FUNCID_MULTI: 686 printk (" Multi-Function"); 687 break; 688 case CISTPL_FUNCID_MEMORY: 689 printk (" Memory"); 690 break; 691 case CISTPL_FUNCID_SERIAL: 692 printk (" Serial Port"); 693 break; 694 case CISTPL_FUNCID_PARALLEL: 695 printk (" Parallel Port"); 696 break; 697 case CISTPL_FUNCID_FIXED: 698 printk (" Fixed Disk"); 699 break; 700 case CISTPL_FUNCID_VIDEO: 701 printk (" Video Adapter"); 702 break; 703 case CISTPL_FUNCID_NETWORK: 704 printk (" Network Adapter"); 705 break; 706 case CISTPL_FUNCID_AIMS: 707 printk (" AIMS Card"); 708 break; 709 case CISTPL_FUNCID_SCSI: 710 printk (" SCSI Adapter"); 711 break; 712 default: 713 printk (" Unknown"); 714 break; 715 } 716 printk (" Card\n"); 717} 718 719/* ------------------------------------------------------------------------- */ 720 721static void print_fixed (volatile u8 *p) 722{ 723 if (p == NULL) 724 return; 725 726 switch (*p) { 727 case CISTPL_FUNCE_IDE_IFACE: 728 { u8 iface = *(p+2); 729 730 printk ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown"); 731 printk (" interface "); 732 break; 733 } 734 case CISTPL_FUNCE_IDE_MASTER: 735 case CISTPL_FUNCE_IDE_SLAVE: 736 { u8 f1 = *(p+2); 737 u8 f2 = *(p+4); 738 739 printk ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]"); 740 741 if (f1 & CISTPL_IDE_UNIQUE) 742 printk (" [unique]"); 743 744 printk ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]"); 745 746 if (f2 & CISTPL_IDE_HAS_SLEEP) 747 printk (" [sleep]"); 748 749 if (f2 & CISTPL_IDE_HAS_STANDBY) 750 printk (" [standby]"); 751 752 if (f2 & CISTPL_IDE_HAS_IDLE) 753 printk (" [idle]"); 754 755 if (f2 & CISTPL_IDE_LOW_POWER) 756 printk (" [low power]"); 757 758 if (f2 & CISTPL_IDE_REG_INHIBIT) 759 printk (" [reg inhibit]"); 760 761 if (f2 & CISTPL_IDE_HAS_INDEX) 762 printk (" [index]"); 763 764 if (f2 & CISTPL_IDE_IOIS16) 765 printk (" [IOis16]"); 766 767 break; 768 } 769 } 770 printk ("\n"); 771} 772 773/* ------------------------------------------------------------------------- */ 774 775 776#define MAX_IDENT_CHARS 64 777#define MAX_IDENT_FIELDS 4 778 779static u8 *known_cards[] = { 780 "ARGOSY PnPIDE D5", 781 NULL 782}; 783 784static int identify (volatile u8 *p) 785{ 786 u8 id_str[MAX_IDENT_CHARS]; 787 u8 data; 788 u8 *t; 789 u8 **card; 790 int i, done; 791 792 if (p == NULL) 793 return (0); /* Don't know */ 794 795 t = id_str; 796 done =0; 797 798 for (i=0; i<=4 && !done; ++i, p+=2) { 799 while ((data = *p) != '\0') { 800 if (data == 0xFF) { 801 done = 1; 802 break; 803 } 804 *t++ = data; 805 if (t == &id_str[MAX_IDENT_CHARS-1]) { 806 done = 1; 807 break; 808 } 809 p += 2; 810 } 811 if (!done) 812 *t++ = ' '; 813 } 814 *t = '\0'; 815 while (--t > id_str) { 816 if (*t == ' ') 817 *t = '\0'; 818 else 819 break; 820 } 821 printk ("Card ID: %s\n", id_str); 822 823 for (card=known_cards; *card; ++card) { 824 if (strcmp(*card, id_str) == 0) { /* found! */ 825 return (1); 826 } 827 } 828 829 return (0); /* don't know */ 830} 831 832void m8xx_ide_init(void) 833{ 834 ppc_ide_md.default_irq = m8xx_ide_default_irq; 835 ppc_ide_md.default_io_base = m8xx_ide_default_io_base; 836 ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; 837} 838 839static int __init mpc8xx_ide_probe(void) 840{ 841 u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; 842 843#ifdef IDE0_BASE_OFFSET 844 idx[0] = 0; 845#ifdef IDE1_BASE_OFFSET 846 idx[1] = 1; 847#endif 848#endif 849 850 ide_device_add(idx, NULL); 851 852 return 0; 853} 854 855module_init(mpc8xx_ide_probe);