X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fide%2Fide-iops.c;h=133d9cd7be50e245bedbb1cd328fc6c16dddbe63;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=c104120ae669c9d07d671b35a0341bc552759940;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index c104120ae..133d9cd7b 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -6,7 +6,6 @@ * */ -#include #include #include #include @@ -23,12 +22,13 @@ #include #include #include +#include +#include #include #include #include #include -#include /* * Conventional PIO operations for ATA devices @@ -104,8 +104,6 @@ void default_hwif_iops (ide_hwif_t *hwif) hwif->INSL = ide_insl; } -EXPORT_SYMBOL(default_hwif_iops); - /* * MMIO operations, typically used for SATA controllers */ @@ -184,16 +182,6 @@ void default_hwif_mmiops (ide_hwif_t *hwif) EXPORT_SYMBOL(default_hwif_mmiops); -void default_hwif_transport (ide_hwif_t *hwif) -{ - hwif->ata_input_data = ata_input_data; - hwif->ata_output_data = ata_output_data; - hwif->atapi_input_bytes = atapi_input_bytes; - hwif->atapi_output_bytes = atapi_output_bytes; -} - -EXPORT_SYMBOL(default_hwif_transport); - u32 ide_read_24 (ide_drive_t *drive) { u8 hcyl = HWIF(drive)->INB(IDE_HCYL_REG); @@ -202,8 +190,6 @@ u32 ide_read_24 (ide_drive_t *drive) return (hcyl<<16)|(lcyl<<8)|sect; } -EXPORT_SYMBOL(ide_read_24); - void SELECT_DRIVE (ide_drive_t *drive) { if (HWIF(drive)->selectproc) @@ -221,24 +207,18 @@ void SELECT_INTERRUPT (ide_drive_t *drive) HWIF(drive)->OUTB(drive->ctl|2, IDE_CONTROL_REG); } -EXPORT_SYMBOL(SELECT_INTERRUPT); - void SELECT_MASK (ide_drive_t *drive, int mask) { if (HWIF(drive)->maskproc) HWIF(drive)->maskproc(drive, mask); } -EXPORT_SYMBOL(SELECT_MASK); - void QUIRK_LIST (ide_drive_t *drive) { if (HWIF(drive)->quirkproc) drive->quirk_list = HWIF(drive)->quirkproc(drive); } -EXPORT_SYMBOL(QUIRK_LIST); - /* * Some localbus EIDE interfaces require a special access sequence * when using 32-bit I/O instructions to transfer data. We call this @@ -246,19 +226,17 @@ EXPORT_SYMBOL(QUIRK_LIST); * of the sector count register location, with interrupts disabled * to ensure that the reads all happen together. */ -void ata_vlb_sync (ide_drive_t *drive, unsigned long port) +static void ata_vlb_sync(ide_drive_t *drive, unsigned long port) { (void) HWIF(drive)->INB(port); (void) HWIF(drive)->INB(port); (void) HWIF(drive)->INB(port); } -EXPORT_SYMBOL(ata_vlb_sync); - /* * This is used for most PIO data transfers *from* the IDE interface */ -void ata_input_data (ide_drive_t *drive, void *buffer, u32 wcount) +static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount) { ide_hwif_t *hwif = HWIF(drive); u8 io_32bit = drive->io_32bit; @@ -277,12 +255,10 @@ void ata_input_data (ide_drive_t *drive, void *buffer, u32 wcount) } } -EXPORT_SYMBOL(ata_input_data); - /* * This is used for most PIO data transfers *to* the IDE interface */ -void ata_output_data (ide_drive_t *drive, void *buffer, u32 wcount) +static void ata_output_data(ide_drive_t *drive, void *buffer, u32 wcount) { ide_hwif_t *hwif = HWIF(drive); u8 io_32bit = drive->io_32bit; @@ -301,8 +277,6 @@ void ata_output_data (ide_drive_t *drive, void *buffer, u32 wcount) } } -EXPORT_SYMBOL(ata_output_data); - /* * The following routines are mainly used by the ATAPI drivers. * @@ -311,7 +285,7 @@ EXPORT_SYMBOL(ata_output_data); * extra byte allocated for the buffer. */ -void atapi_input_bytes (ide_drive_t *drive, void *buffer, u32 bytecount) +static void atapi_input_bytes(ide_drive_t *drive, void *buffer, u32 bytecount) { ide_hwif_t *hwif = HWIF(drive); @@ -328,9 +302,7 @@ void atapi_input_bytes (ide_drive_t *drive, void *buffer, u32 bytecount) hwif->INSW(IDE_DATA_REG, ((u8 *)buffer)+(bytecount & ~0x03), 1); } -EXPORT_SYMBOL(atapi_input_bytes); - -void atapi_output_bytes (ide_drive_t *drive, void *buffer, u32 bytecount) +static void atapi_output_bytes(ide_drive_t *drive, void *buffer, u32 bytecount) { ide_hwif_t *hwif = HWIF(drive); @@ -347,7 +319,13 @@ void atapi_output_bytes (ide_drive_t *drive, void *buffer, u32 bytecount) hwif->OUTSW(IDE_DATA_REG, ((u8*)buffer)+(bytecount & ~0x03), 1); } -EXPORT_SYMBOL(atapi_output_bytes); +void default_hwif_transport(ide_hwif_t *hwif) +{ + hwif->ata_input_data = ata_input_data; + hwif->ata_output_data = ata_output_data; + hwif->atapi_input_bytes = atapi_input_bytes; + hwif->atapi_output_bytes = atapi_output_bytes; +} /* * Beginning of Taskfile OPCODE Library and feature sets. @@ -449,6 +427,7 @@ void ide_fix_driveid (struct hd_driveid *id) #endif } +/* FIXME: exported for use by the USB storage (isd200.c) code only */ EXPORT_SYMBOL(ide_fix_driveid); void ide_fixstring (u8 *s, const int bytecount, const int byteswap) @@ -546,8 +525,6 @@ int wait_for_ready (ide_drive_t *drive, int timeout) return 0; } -EXPORT_SYMBOL(wait_for_ready); - /* * This routine busy-waits for the drive status to be not "busy". * It then checks the status for all of the "good" bits and none @@ -588,7 +565,7 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b break; local_irq_restore(flags); - *startstop = DRIVER(drive)->error(drive, "status timeout", stat); + *startstop = ide_error(drive, "status timeout", stat); return 1; } } @@ -606,7 +583,7 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) return 0; } - *startstop = DRIVER(drive)->error(drive, "status error", stat); + *startstop = ide_error(drive, "status error", stat); return 1; } @@ -618,44 +595,30 @@ EXPORT_SYMBOL(ide_wait_stat); */ u8 eighty_ninty_three (ide_drive_t *drive) { -#if 0 - if (!HWIF(drive)->udma_four) + if(HWIF(drive)->udma_four == 0) return 0; - if (drive->id->major_rev_num) { - int hssbd = 0; - int i; - /* - * Determine highest Supported SPEC - */ - for (i=1; i<=15; i++) - if (drive->id->major_rev_num & (1<id->hw_config & 0x4000) && -#endif /* CONFIG_IDEDMA_IVB */ - (drive->id->hw_config & 0x6000)) ? 1 : 0); + printk(KERN_INFO "%s: hw_config=%04x\n", + drive->name, drive->id->hw_config); -#else - - return ((u8) ((HWIF(drive)->udma_four) && + /* Check for SATA but only if we are ATA5 or higher */ + if (drive->id->hw_config == 0 && (drive->id->major_rev_num & 0x7FE0)) + return 1; + if (!(drive->id->hw_config & 0x6000)) + return 0; #ifndef CONFIG_IDEDMA_IVB - (drive->id->hw_config & 0x4000) && + if(!(drive->id->hw_config & 0x4000)) + return 0; #endif /* CONFIG_IDEDMA_IVB */ - (drive->id->hw_config & 0x6000)) ? 1 : 0); +/* + * FIXME: enable this after fixing master/slave IDENTIFY order, + * also ignore the result if the slave device is pre-ATA3 one + */ +#if 0 + if (!(drive->id->hw_config & 0x2000)) + return 0; #endif + return 1; } EXPORT_SYMBOL(eighty_ninty_three); @@ -685,8 +648,6 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) return 0; } -EXPORT_SYMBOL(ide_ata66_check); - /* * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER. * 1 : Safe to update drive->id DMA registers. @@ -705,9 +666,8 @@ int set_transfer (ide_drive_t *drive, ide_task_t *args) return 0; } -EXPORT_SYMBOL(set_transfer); - -u8 ide_auto_reduce_xfer (ide_drive_t *drive) +#ifdef CONFIG_BLK_DEV_IDEDMA +static u8 ide_auto_reduce_xfer (ide_drive_t *drive) { if (!drive->crc_count) return drive->current_speed; @@ -731,8 +691,7 @@ u8 ide_auto_reduce_xfer (ide_drive_t *drive) default: return XFER_PIO_4; } } - -EXPORT_SYMBOL(ide_auto_reduce_xfer); +#endif /* CONFIG_BLK_DEV_IDEDMA */ /* * Update the @@ -807,8 +766,6 @@ int ide_driveid_update (ide_drive_t *drive) #endif } -EXPORT_SYMBOL(ide_driveid_update); - /* * Similar to ide_wait_stat(), except it never calls ide_error internally. * This is a kludge to handle the new ide_config_drive_speed() function, @@ -948,7 +905,7 @@ EXPORT_SYMBOL(ide_config_drive_speed); * * See also ide_execute_command */ -void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, +static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry) { ide_hwgroup_t *hwgroup = HWGROUP(drive); @@ -964,8 +921,6 @@ void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, add_timer(&hwgroup->timer); } -EXPORT_SYMBOL(__ide_set_handler); - void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry) { @@ -999,8 +954,7 @@ void ide_execute_command(ide_drive_t *drive, task_ioreg_t cmd, ide_handler_t *ha spin_lock_irqsave(&ide_lock, flags); - if(hwgroup->handler) - BUG(); + BUG_ON(hwgroup->handler); hwgroup->handler = handler; hwgroup->expiry = expiry; hwgroup->timer.expires = jiffies + timeout; @@ -1041,21 +995,21 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) printk("%s: ATAPI reset complete\n", drive->name); } else { if (time_before(jiffies, hwgroup->poll_timeout)) { - if (HWGROUP(drive)->handler != NULL) - BUG(); + BUG_ON(HWGROUP(drive)->handler != NULL); ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); /* continue polling */ return ide_started; } /* end of polling */ - hwgroup->poll_timeout = 0; + hwgroup->polling = 0; printk("%s: ATAPI reset timed-out, status=0x%02x\n", drive->name, stat); /* do it the old fashioned way */ return do_reset1(drive, 1); } /* done polling */ - hwgroup->poll_timeout = 0; + hwgroup->polling = 0; + hwgroup->resetting = 0; return ide_stopped; } @@ -1081,8 +1035,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) if (!OK_STAT(tmp = hwif->INB(IDE_STATUS_REG), 0, BUSY_STAT)) { if (time_before(jiffies, hwgroup->poll_timeout)) { - if (HWGROUP(drive)->handler != NULL) - BUG(); + BUG_ON(HWGROUP(drive)->handler != NULL); ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); /* continue polling */ return ide_started; @@ -1115,7 +1068,8 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) printk("\n"); } } - hwgroup->poll_timeout = 0; /* done polling */ + hwgroup->polling = 0; /* done polling */ + hwgroup->resetting = 0; /* done reset attempt */ return ide_stopped; } @@ -1132,9 +1086,27 @@ static void check_dma_crc(ide_drive_t *drive) #endif } -void pre_reset (ide_drive_t *drive) +static void ide_disk_pre_reset(ide_drive_t *drive) +{ + int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1; + + drive->special.all = 0; + drive->special.b.set_geometry = legacy; + drive->special.b.recalibrate = legacy; + if (OK_TO_RESET_CONTROLLER) + drive->mult_count = 0; + if (!drive->keep_settings && !drive->using_dma) + drive->mult_req = 0; + if (drive->mult_req != drive->mult_count) + drive->special.b.set_multmode = 1; +} + +static void pre_reset(ide_drive_t *drive) { - DRIVER(drive)->pre_reset(drive); + if (drive->media == ide_disk) + ide_disk_pre_reset(drive); + else + drive->post_reset = 1; if (!drive->keep_settings) { if (drive->using_dma) { @@ -1151,6 +1123,9 @@ void pre_reset (ide_drive_t *drive) if (HWIF(drive)->pre_reset != NULL) HWIF(drive)->pre_reset(drive); + if (drive->current_speed != 0xff) + drive->desired_speed = drive->current_speed; + drive->current_speed = 0xff; } /* @@ -1180,16 +1155,18 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) hwgroup = HWGROUP(drive); /* We must not reset with running handlers */ - if(hwgroup->handler != NULL) - BUG(); + BUG_ON(hwgroup->handler != NULL); /* For an ATAPI device, first try an ATAPI SRST. */ if (drive->media != ide_disk && !do_not_try_atapi) { + hwgroup->resetting = 1; pre_reset(drive); SELECT_DRIVE(drive); udelay (20); - hwif->OUTB(WIN_SRST, IDE_COMMAND_REG); + hwif->OUTBSYNC(drive, WIN_SRST, IDE_COMMAND_REG); + ndelay(400); hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + hwgroup->polling = 1; __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); spin_unlock_irqrestore(&ide_lock, flags); return ide_started; @@ -1208,6 +1185,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) return ide_stopped; } + hwgroup->resetting = 1; /* * Note that we also set nIEN while resetting the device, * to mask unwanted interrupts from the interface during the reset. @@ -1230,6 +1208,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) /* more than enough time */ udelay(10); hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + hwgroup->polling = 1; __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); /* @@ -1282,6 +1261,8 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) */ if (stat == 0xff) return -ENODEV; + touch_softlockup_watchdog(); + touch_nmi_watchdog(); } return -EBUSY; }