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