Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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