--- zzzz-none-000/linux-2.4.17/drivers/ide/ide.c 2001-10-25 20:58:35.000000000 +0000 +++ sangam-fb-401/linux-2.4.17/drivers/ide/ide.c 2005-05-13 14:50:37.000000000 +0000 @@ -230,23 +230,14 @@ static void init_hwif_data (unsigned int index) { unsigned int unit; - hw_regs_t hw; ide_hwif_t *hwif = &ide_hwifs[index]; /* bulk initialize hwif & drive info with zeros */ memset(hwif, 0, sizeof(ide_hwif_t)); - memset(&hw, 0, sizeof(hw_regs_t)); /* fill in any non-zero initial values */ hwif->index = index; - ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq); - memcpy(&hwif->hw, &hw, sizeof(hw)); - memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports)); - hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; -#ifdef CONFIG_BLK_DEV_HD - if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) - hwif->noprobe = 1; /* may be overridden by ide_setup() */ -#endif /* CONFIG_BLK_DEV_HD */ + hwif->noprobe = 1; hwif->major = ide_hwif_to_major[index]; hwif->name[0] = 'i'; hwif->name[1] = 'd'; @@ -273,6 +264,31 @@ } /* + * Old compatability function - initialise ports using ide_default_io_base + */ +static void ide_old_init_default_hwifs(void) +{ + unsigned int index; + ide_ioreg_t base; + ide_hwif_t *hwif; + + for (index = 0; index < MAX_HWIFS; index++) { + hwif = &ide_hwifs[index]; + + base = ide_default_io_base(index); + +#if !defined(CONFIG_REDWOOD_4) /* Redwood 4 has a base of 0x00000000 */ + if (base) +#endif + { + ide_init_hwif_ports(&hwif->hw, base, 0, &hwif->hw.irq); + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); + hwif->noprobe = 0; + } + } +} + +/* * init_ide_data() sets reasonable default values into all fields * of all instances of the hwifs and drives, but only on the first call. * Subsequent calls have no effect (they don't wipe out anything). @@ -301,8 +317,16 @@ init_hwif_data(index); /* Add default hw interfaces */ + ide_old_init_default_hwifs(); ide_init_default_hwifs(); +#ifdef CONFIG_BLK_DEV_HD + /* Check for any clashes with hd.c driver */ + for (index = 0; index < MAX_HWIFS; ++index) + if (ide_hwifs[index].hw.io_ports[IDE_DATA_OFFSET] == HD_DATA) + ide_hwifs[index].noprobe = 1; /* may be overridden by ide_setup() */ +#endif /* CONFIG_BLK_DEV_HD */ + idebus_parameter = 0; system_bus_speed = 0; } @@ -359,6 +383,7 @@ printk("ide: Assuming %dMHz system bus speed for PIO modes%s\n", system_bus_speed, idebus_parameter ? "" : "; override with idebus=xx"); } + DBG_IDE( "system_bus_speed: %d", system_bus_speed ); return system_bus_speed; } @@ -412,9 +437,10 @@ #if SUPPORT_SLOW_DATA_PORTS if (drive->slow) { unsigned short *ptr = (unsigned short *) buffer; + //printk( "reading to %p\n", ptr ); while (wcount--) { - *ptr++ = inw_p(IDE_DATA_REG); - *ptr++ = inw_p(IDE_DATA_REG); + *ptr++ = inw_p(IDE_DATA_REG); + *ptr++ = inw_p(IDE_DATA_REG); } } else #endif /* SUPPORT_SLOW_DATA_PORTS */ @@ -619,6 +645,8 @@ unsigned int unit; struct gendisk *gd = hwif->gd; + DBG_IDE( "ide_geninit ..." ); + for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; @@ -1075,6 +1103,7 @@ if (tuneproc != NULL) tuneproc(drive, drive->tune_req); } else if (drive->driver != NULL) { + DBG_IDE( "call special" ); return DRIVER(drive)->special(drive); } else if (s->all) { printk("%s: bad special flag: 0x%02x\n", drive->name, s->all); @@ -1200,8 +1229,16 @@ unsigned int minor = MINOR(rq->rq_dev), unit = minor >> PARTN_BITS; ide_hwif_t *hwif = HWIF(drive); -#ifdef DEBUG - printk("%s: start_request: current=0x%08lx\n", hwif->name, (unsigned long) rq); +#if defined(IDE_TEST) && 0 + DBG_IDE("%s: start_request:", hwif->name ); + DBG_IDE("status = %s", + rq->rq_status == RQ_INACTIVE ? "RQ_INACTIVE" : + rq->rq_status == RQ_ACTIVE ? "RQ_ACTIVE" : + rq->rq_status == RQ_SCSI_BUSY ? "RQ_SCSI_BUSY" : + rq->rq_status == RQ_SCSI_DONE ? "RQ_SCSI_DONE" : + rq->rq_status == RQ_SCSI_DISCONNECTING ? "RQ_SCSI_DISCONNECTING" : "???" ); + DBG_IDE("cmd = %s", rq->cmd == READ ? "READ" : rq->cmd == WRITE ? "WRITE" : "???" ); + DBG_IDE("sector = %ld nr_sectors = %ld", rq->sector, rq->nr_sectors ); #endif /* bail early if we've exceeded max_failures */ if (drive->max_failures && (drive->failures > drive->max_failures)) { @@ -1367,12 +1404,17 @@ * the driver. This makes the driver much more friendlier to shared IRQs * than previous designs, while remaining 100% (?) SMP safe and capable. */ -static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq) +/* --BenH: made non-static as ide-pmac.c uses it to kick the hwgroup back + * into life on wakeup from machine sleep. + */ +void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq) { ide_drive_t *drive; ide_hwif_t *hwif; ide_startstop_t startstop; + DBG_IDE( "ide_do_request " ); + ide_get_lock(&ide_lock, ide_intr, hwgroup); /* for atari only: POSSIBLY BROKEN HERE(?) */ __cli(); /* necessary paranoia: ensure IRQs are masked on local CPU */ @@ -1656,6 +1698,8 @@ ide_handler_t *handler; ide_startstop_t startstop; +// DBG_IDE( "ide_intr: %d", irq ); + spin_lock_irqsave(&io_request_lock, flags); hwif = hwgroup->hwif; @@ -1884,7 +1928,6 @@ if (drive->part[p].nr_sects > 0) { kdev_t devp = MKDEV(major, minor+p); invalidate_device(devp, 1); - set_blocksize(devp, 1024); } drive->part[p].start_sect = 0; drive->part[p].nr_sects = 0; @@ -2268,6 +2311,7 @@ int index, retry = 1; ide_hwif_t *hwif; + DBG_IDE( "ide_register_hw .." ); do { for (index = 0; index < MAX_HWIFS; ++index) { hwif = &ide_hwifs[index]; @@ -2992,7 +3036,7 @@ int __init ide_setup (char *s) { int i, vals[3]; - ide_hwif_t *hwif; + ide_hwif_t *hwif = NULL; ide_drive_t *drive; unsigned int hw, unit; const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1); @@ -3007,7 +3051,8 @@ strncmp(s,"hd",2)) /* hdx= & hdxlun= */ return 0; - printk("ide_setup: %s", s); + DBG_IDE("ide_setup: %s", s); + printk("ide_setup %s", s); init_ide_data (); #ifdef CONFIG_BLK_DEV_IDEDOUBLER @@ -3286,6 +3331,7 @@ hwif->irq = vals[2]; hwif->noprobe = 0; hwif->chipset = ide_generic; + DBG_IDE( "(ide_setup) index=%d hwif->io_ports[0]=0x%04lX irq=%d", hwif->index, hwif->io_ports[0], hwif->irq ); goto done; case 0: goto bad_option; @@ -3300,7 +3346,9 @@ bad_hwif: printk("-- NOT SUPPORTED ON ide%d", hw); done: - printk("\n"); + if ( hwif != NULL ) + DBG_IDE_HWIF( hwif ); +/* printk("\n"); */ return 1; } @@ -3379,6 +3427,12 @@ macide_init(); } #endif /* CONFIG_BLK_DEV_MAC_IDE */ +#ifdef CONFIG_BLK_DEV_CPCI405_IDE + { + extern void cpci405ide_init(void); + cpci405ide_init(); + } +#endif /* CONFIG_BLK_DEV_CPCI405_IDE */ #ifdef CONFIG_BLK_DEV_Q40IDE { extern void q40ide_init(void); @@ -3425,6 +3479,7 @@ #endif /* __mc68000__ || CONFIG_APUS */ #endif /* CONFIG_BLK_DEV_IDE */ + #ifdef CONFIG_PROC_FS proc_ide_create(); #endif @@ -3503,6 +3558,8 @@ { special_t *s = &drive->special; + DBG_IDE( "default_special " ); + s->all = 0; drive->mult_req = 0; return ide_stopped; @@ -3735,6 +3792,8 @@ ide_hwif_t *hwif = &ide_hwifs[i]; if (hwif->present) ide_geninit(hwif); + else + DBG_IDE( "ide_init: hwif %d not present", i ); } return 0; @@ -3749,6 +3808,7 @@ { char *next = line; + DBG_IDE("parse_options: '%s'\n", line); if (line == NULL || !*line) return; while ((line = next) != NULL) { @@ -3788,3 +3848,144 @@ __setup("", ide_setup); #endif /* MODULE */ + +#if defined(IDE_TEST) + +/* #define DEBUG_IN_OUT */ +#define IS_READ_CMD( cmd ) ((cmd) == 0xe4 || (cmd) == 0xc8 || (cmd) == 0xc9 || (cmd) == 0x22 || (cmd) == 0x23 || (cmd) == 0xc4 || (cmd) == 0x20 || (cmd) == 0x21 || (cmd) == 0x40 || (cmd) == 0x41 ) +/*-------------------------------------------------------------------------------------*\ +\*-------------------------------------------------------------------------------------*/ +unsigned char deb_inpb( unsigned long port ) +{ + u8 __val; + __val = *( volatile unsigned short * )( mips_io_port_base + port ); +#if defined(DEBUG_IN_OUT) + if ((( port & 0xbc000000 ) == 0xbc000000 ) || (( port & 0xbe000000 ) == 0xbe000000 )) + printk( "in: %p->%02X\n", ( void * ) port, __val ); +#endif + return __val; +} + +#define CMD_TABLE_ENTRY( cmd ) { (cmd), #cmd, -1, "" } + +struct _cmd_debug { + unsigned char cmd; + char *name; + int type; + char *special; +} deb_cmd_table[] = +{ +CMD_TABLE_ENTRY( WIN_RESTORE ), +CMD_TABLE_ENTRY( WIN_READ ), +CMD_TABLE_ENTRY( WIN_WRITE ), +CMD_TABLE_ENTRY( WIN_WRITE_VERIFY ), +CMD_TABLE_ENTRY( WIN_VERIFY ), +CMD_TABLE_ENTRY( WIN_FORMAT ), +CMD_TABLE_ENTRY( WIN_INIT ), +CMD_TABLE_ENTRY( WIN_SEEK ), +CMD_TABLE_ENTRY( WIN_DIAGNOSE ), +CMD_TABLE_ENTRY( WIN_SPECIFY ), +CMD_TABLE_ENTRY( WIN_IDLEIMMEDIATE ), +CMD_TABLE_ENTRY( WIN_SETIDLE1 ), +CMD_TABLE_ENTRY( WIN_SETIDLE2 ), + +CMD_TABLE_ENTRY( WIN_STANDBYNOW1 ), +CMD_TABLE_ENTRY( WIN_STANDBYNOW2 ), +CMD_TABLE_ENTRY( WIN_SLEEPNOW1 ), +CMD_TABLE_ENTRY( WIN_SLEEPNOW2 ), +CMD_TABLE_ENTRY( WIN_CHECKPOWERMODE1 ), +CMD_TABLE_ENTRY( WIN_CHECKPOWERMODE2 ), + +CMD_TABLE_ENTRY( WIN_DOORLOCK ), +CMD_TABLE_ENTRY( WIN_DOORUNLOCK ), + +CMD_TABLE_ENTRY( WIN_MULTREAD ), +CMD_TABLE_ENTRY( WIN_MULTWRITE ), +CMD_TABLE_ENTRY( WIN_SETMULT ), +CMD_TABLE_ENTRY( WIN_IDENTIFY ), +CMD_TABLE_ENTRY( WIN_IDENTIFY_DMA ), +CMD_TABLE_ENTRY( WIN_SETFEATURES ), +CMD_TABLE_ENTRY( WIN_READDMA ), +CMD_TABLE_ENTRY( WIN_WRITEDMA ), + +CMD_TABLE_ENTRY( WIN_QUEUED_SERVICE ), +CMD_TABLE_ENTRY( WIN_READDMA_QUEUED ), +CMD_TABLE_ENTRY( WIN_WRITEDMA_QUEUED ), + +CMD_TABLE_ENTRY( WIN_READ_BUFFER ), +CMD_TABLE_ENTRY( WIN_WRITE_BUFFER ), + +CMD_TABLE_ENTRY( WIN_SMART ), + +CMD_TABLE_ENTRY( WIN_PIDENTIFY ), +CMD_TABLE_ENTRY( WIN_SRST ), +CMD_TABLE_ENTRY( WIN_PACKETCMD ), + +CMD_TABLE_ENTRY( DISABLE_SEAGATE ), +CMD_TABLE_ENTRY( EXABYTE_ENABLE_NEST ), + +{ 0, NULL, -1, "" } +}; + +struct _cmd_debug *deb_get_cmd_entry( unsigned char cmd ) +{ + unsigned i=0; + while ( deb_cmd_table[i].name != NULL ) + { + if ( deb_cmd_table[i].cmd == cmd ) + return &deb_cmd_table[i]; + i++; + } + return NULL; +} +/*-------------------------------------------------------------------------------------*\ +\*-------------------------------------------------------------------------------------*/ +void deb_outpb( unsigned char val, unsigned long port ) +{ + unsigned long ioaddr = 0; + char *cmdname; + struct _cmd_debug * p_cmd_deb; + ioaddr = mips_io_port_base + port; +#if defined(DEBUG_IN_OUT) + if ((( ioaddr & 0xbc000000 ) == 0xbc000000 ) || (( ioaddr & 0xbe000000 ) == 0xbe000000 )) + printk( "out: %02X->%p\n", val, ( void * ) ioaddr ); + if ( ioaddr == 0xbc00000e ) { + p_cmd_deb = deb_get_cmd_entry( val ); + if ( p_cmd_deb ) + printk( "cmd: %s\n", p_cmd_deb->name ); + } +#endif + *(volatile unsigned short *)( ioaddr ) = __ioswab8(val); + SLOW_DOWN_IO; +} + +/*-------------------------------------------------------------------------------------*\ +\*-------------------------------------------------------------------------------------*/ +unsigned char deb_getstat( unsigned long port ) +{ + unsigned char val, err; + val = deb_inpb( port ); + if ( val & 1 ) + err = deb_inpb( 0xbc000002 ); + return val; +} +/*-------------------------------------------------------------------------------------*\ +\*-------------------------------------------------------------------------------------*/ +void deb_hexdump( char *head, unsigned char *buf, unsigned len ) +{ + unsigned i; + + if ( head ) + printk( "%s\n", head ); + else + printk( "\n" ); + + for (i=0; i