diff -urN linux-2.5.14/drivers/ide/ide.c linux/drivers/ide/ide.c --- linux-2.5.14/drivers/ide/ide.c 2002-05-07 02:36:37.000000000 +0200 +++ linux/drivers/ide/ide.c 2002-05-07 02:15:18.000000000 +0200 @@ -193,7 +193,7 @@ #ifdef CONFIG_BLK_DEV_HD if (ch->io_ports[IDE_DATA_OFFSET] == HD_DATA) ch->noprobe = 1; /* may be overridden by ide_setup() */ -#endif /* CONFIG_BLK_DEV_HD */ +#endif ch->major = ide_major[index]; sprintf(ch->name, "ide%d", index); ch->bus_state = BUSSTATE_ON; @@ -201,15 +201,14 @@ for (unit = 0; unit < MAX_DRIVES; ++unit) { struct ata_device *drive = &ch->drives[unit]; - drive->type = ATA_DISK; - drive->select.all = (unit<<4)|0xa0; - drive->channel = ch; - drive->ctl = 0x08; - drive->ready_stat = READY_STAT; - drive->bad_wstat = BAD_W_STAT; - drive->special_cmd = (ATA_SPECIAL_RECALIBRATE | ATA_SPECIAL_GEOMETRY); + drive->type = ATA_DISK; + drive->select.all = (unit<<4)|0xa0; + drive->channel = ch; + drive->ctl = 0x08; + drive->ready_stat = READY_STAT; + drive->bad_wstat = BAD_W_STAT; sprintf(drive->name, "hd%c", 'a' + (index * MAX_DRIVES) + unit); - drive->max_failures = IDE_DEFAULT_MAX_FAILURES; + drive->max_failures = IDE_DEFAULT_MAX_FAILURES; init_waitqueue_head(&drive->wqueue); } @@ -354,11 +353,8 @@ spin_unlock_irqrestore(&ide_lock, flags); } -static void ata_pre_reset(struct ata_device *drive) +static void check_crc_errors(struct ata_device *drive) { - if (ata_ops(drive) && ata_ops(drive)->pre_reset) - ata_ops(drive)->pre_reset(drive); - if (!drive->using_dma) return; @@ -392,38 +388,6 @@ return ~0UL; } -/* - * This is used to issue WIN_SPECIFY, WIN_RESTORE, and WIN_SETMULT commands to - * a drive. - */ -static ide_startstop_t ata_special(struct ata_device *drive) -{ - unsigned char special_cmd = drive->special_cmd; - -#ifdef DEBUG - printk("%s: ata_special: 0x%02x\n", drive->name, special_cmd); -#endif - if (special_cmd & ATA_SPECIAL_TUNE) { - drive->special_cmd &= ~ATA_SPECIAL_TUNE; - if (drive->channel->tuneproc != NULL) - drive->channel->tuneproc(drive, drive->tune_req); - } else if (drive->driver != NULL) { - if (ata_ops(drive)->special) - return ata_ops(drive)->special(drive); - else { - drive->special_cmd = 0; - drive->mult_req = 0; - - return ide_stopped; - } - } else if (special_cmd) { - printk("%s: bad special flag: 0x%02x\n", drive->name, special_cmd); - drive->special_cmd = 0; - } - - return ide_stopped; -} - extern struct block_device_operations ide_fops[]; /* @@ -460,24 +424,24 @@ */ static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct request *__rq) { - ide_hwgroup_t *hwgroup = HWGROUP(drive); - byte stat; + struct ata_channel *ch = drive->channel; + u8 stat; - SELECT_DRIVE(drive->channel,drive); + SELECT_DRIVE(ch,drive); udelay (10); if (OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)) { printk("%s: ATAPI reset complete\n", drive->name); } else { - if (time_before(jiffies, hwgroup->poll_timeout)) { + if (time_before(jiffies, ch->poll_timeout)) { ide_set_handler (drive, atapi_reset_pollfunc, HZ/20, NULL); return ide_started; /* continue polling */ } - hwgroup->poll_timeout = 0; /* end of polling */ + ch->poll_timeout = 0; /* end of polling */ printk("%s: ATAPI reset timed-out, status=0x%02x\n", drive->name, stat); return do_reset1 (drive, 1); /* do it the old fashioned way */ } - hwgroup->poll_timeout = 0; /* done polling */ + ch->poll_timeout = 0; /* done polling */ return ide_stopped; } @@ -489,19 +453,18 @@ */ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *__rq) { - ide_hwgroup_t *hwgroup = HWGROUP(drive); - struct ata_channel *hwif = drive->channel; + struct ata_channel *ch = drive->channel; u8 stat; if (!OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)) { - if (time_before(jiffies, hwgroup->poll_timeout)) { + if (time_before(jiffies, ch->poll_timeout)) { ide_set_handler(drive, reset_pollfunc, HZ/20, NULL); return ide_started; /* continue polling */ } - printk("%s: reset timed-out, status=0x%02x\n", hwif->name, stat); + printk("%s: reset timed-out, status=0x%02x\n", ch->name, stat); drive->failures++; } else { - printk("%s: reset: ", hwif->name); + printk("%s: reset: ", ch->name); if ((stat = GET_ERR()) == 1) { printk("success\n"); drive->failures = 0; @@ -531,7 +494,8 @@ drive->failures++; } } - hwgroup->poll_timeout = 0; /* done polling */ + ch->poll_timeout = 0; /* done polling */ + return ide_stopped; } @@ -555,21 +519,21 @@ { unsigned int unit; unsigned long flags; - struct ata_channel *hwif = drive->channel; - ide_hwgroup_t *hwgroup = HWGROUP(drive); + struct ata_channel *ch = drive->channel; __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only */ /* For an ATAPI device, first try an ATAPI SRST. */ if (drive->type != ATA_DISK && !do_not_try_atapi) { - ata_pre_reset(drive); - SELECT_DRIVE(hwif,drive); + check_crc_errors(drive); + SELECT_DRIVE(ch, drive); udelay (20); OUT_BYTE(WIN_SRST, IDE_COMMAND_REG); - hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + ch->poll_timeout = jiffies + WAIT_WORSTCASE; ide_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL); __restore_flags(flags); /* local CPU only */ + return ide_started; } @@ -578,11 +542,12 @@ * for any of the drives on this interface. */ for (unit = 0; unit < MAX_DRIVES; ++unit) - ata_pre_reset(&hwif->drives[unit]); + check_crc_errors(&ch->drives[unit]); #if OK_TO_RESET_CONTROLLER if (!IDE_CONTROL_REG) { __restore_flags(flags); + return ide_stopped; } /* @@ -601,7 +566,7 @@ OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */ } udelay(10); /* more than enough time */ - hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + ch->poll_timeout = jiffies + WAIT_WORSTCASE; ide_set_handler(drive, reset_pollfunc, HZ/20, NULL); /* @@ -609,9 +574,10 @@ * state when the disks are reset this way. At least, the Winbond * 553 documentation says that */ - if (hwif->resetproc != NULL) - hwif->resetproc(drive); + if (ch->resetproc != NULL) + ch->resetproc(drive); + /* FIXME: we should handle mulit mode setting here as well ! */ #endif __restore_flags (flags); /* local CPU only */ @@ -789,6 +755,36 @@ } } +#ifdef CONFIG_BLK_DEV_PDC4030 +# define IS_PDC4030_DRIVE (drive->channel->chipset == ide_pdc4030) +#else +# define IS_PDC4030_DRIVE (0) /* auto-NULLs out pdc4030 code */ +#endif + +/* + * We are still on the old request path here so issuing the recalibrate command + * directly should just work. + */ +static int do_recalibrate(struct ata_device *drive) +{ + printk(KERN_INFO "%s: recalibrating!\n", drive->name); + + if (drive->type != ATA_DISK) + return ide_stopped; + + if (!IS_PDC4030_DRIVE) { + struct ata_taskfile args; + + memset(&args, 0, sizeof(args)); + args.taskfile.sector_count = drive->sect; + args.taskfile.command = WIN_RESTORE; + args.handler = recal_intr; + ata_taskfile(drive, &args, NULL); + } + + return IS_PDC4030_DRIVE ? ide_stopped : ide_started; +} + /* * Take action based on the error returned by the drive. */ @@ -835,13 +831,11 @@ else ide_end_request(drive, rq, 0); } else { - if ((rq->errors & ERROR_RESET) == ERROR_RESET) { - ++rq->errors; + ++rq->errors; + if ((rq->errors & ERROR_RESET) == ERROR_RESET) return do_reset1(drive, 0); - } if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) - drive->special_cmd |= ATA_SPECIAL_RECALIBRATE; - ++rq->errors; + return do_recalibrate(drive); } return ide_stopped; } @@ -960,7 +954,7 @@ goto kill_rq; } - block = rq->sector; + block = rq->sector; /* Strange disk manager remap. */ @@ -991,14 +985,6 @@ } } - /* FIXME: We can see nicely here that all commands should be submitted - * through the request queue and that the special field in drive should - * go as soon as possible! - */ - - if (drive->special_cmd) - return ata_special(drive); - /* This issues a special drive command, usually initiated by ioctl() * from the external hdparm program. */ @@ -1011,7 +997,7 @@ ata_taskfile(drive, args, NULL); if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) || - (args->command_type == IDE_DRIVE_TASK_OUT)) && + (args->command_type == IDE_DRIVE_TASK_OUT)) && args->prehandler && args->handler) return args->prehandler(drive, rq); @@ -1053,6 +1039,7 @@ return ata_ops(drive)->do_request(drive, rq, block); else { ide_end_request(drive, rq, 0); + return ide_stopped; } } @@ -1499,7 +1486,7 @@ disable_irq(ch->irq); /* disable_irq_nosync ?? */ #endif __cli(); /* local CPU only, as if we were handling an interrupt */ - if (hwgroup->poll_timeout != 0) { + if (ch->poll_timeout != 0) { startstop = handler(drive, ch->hwgroup->rq); } else if (drive_is_ready(drive)) { if (drive->waiting_for_dma) @@ -1598,7 +1585,7 @@ if (!ide_ack_intr(ch)) goto out_lock; - if (handler == NULL || hwgroup->poll_timeout != 0) { + if (handler == NULL || ch->poll_timeout != 0) { #if 0 printk(KERN_INFO "ide: unexpected interrupt %d %d\n", ch->unit, irq); #endif @@ -2327,23 +2314,24 @@ int ide_spin_wait_hwgroup(struct ata_device *drive) { ide_hwgroup_t *hwgroup = HWGROUP(drive); - unsigned long timeout = jiffies + (3 * HZ); + + /* FIXME: Wait on a proper timer. Instead of playing games on the + * spin_lock(). + */ + + unsigned long timeout = jiffies + (10 * HZ); spin_lock_irq(&ide_lock); while (test_bit(IDE_BUSY, &hwgroup->flags)) { - unsigned long lflags; spin_unlock_irq(&ide_lock); - __save_flags(lflags); /* local CPU only */ - __sti(); /* local CPU only; needed for jiffies */ - if (0 < (signed long)(jiffies - timeout)) { - __restore_flags(lflags); /* local CPU only */ + if (time_after(jiffies, timeout)) { printk("%s: channel busy\n", drive->name); return -EBUSY; } - __restore_flags(lflags); /* local CPU only */ spin_lock_irq(&ide_lock); } + return 0; } @@ -2411,18 +2399,17 @@ static int set_pio_mode(struct ata_device *drive, int arg) { - struct request rq; - if (!drive->channel->tuneproc) return -ENOSYS; - if (drive->special_cmd & ATA_SPECIAL_TUNE) + /* FIXME: This is very much the same kind of problem as we have with + * set_mutlmode() see for a edscription there. + */ + if (HWGROUP(drive)->handler) return -EBUSY; - ide_init_drive_cmd(&rq); - drive->tune_req = (u8) arg; - drive->special_cmd |= ATA_SPECIAL_TUNE; - ide_do_drive_cmd(drive, &rq, ide_wait); + if (drive->channel->tuneproc != NULL) + drive->channel->tuneproc(drive, (u8) arg); return 0; } diff -urN linux-2.5.14/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c --- linux-2.5.14/drivers/ide/ide-disk.c 2002-05-07 02:36:37.000000000 +0200 +++ linux/drivers/ide/ide-disk.c 2002-05-07 02:01:48.000000000 +0200 @@ -34,9 +34,9 @@ #include #ifdef CONFIG_BLK_DEV_PDC4030 -#define IS_PDC4030_DRIVE (drive->channel->chipset == ide_pdc4030) +# define IS_PDC4030_DRIVE (drive->channel->chipset == ide_pdc4030) #else -#define IS_PDC4030_DRIVE (0) /* auto-NULLs out pdc4030 code */ +# define IS_PDC4030_DRIVE (0) /* auto-NULLs out pdc4030 code */ #endif /* @@ -304,9 +304,9 @@ } if (IS_PDC4030_DRIVE) { - extern ide_startstop_t promise_rw_disk(struct ata_device *, struct request *, unsigned long); + extern ide_startstop_t promise_do_request(struct ata_device *, struct request *, sector_t); - return promise_rw_disk(drive, rq, block); + return promise_do_request(drive, rq, block); } /* @@ -364,7 +364,7 @@ * point. */ - if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) + if (drive->doorlocking && ide_raw_taskfile(drive, &args)) drive->doorlocking = 0; } return 0; @@ -383,10 +383,10 @@ ide_cmd_type_parser(&args); - return ide_raw_taskfile(drive, &args, NULL); + return ide_raw_taskfile(drive, &args); } -static void idedisk_release (struct inode *inode, struct file *filp, struct ata_device *drive) +static void idedisk_release(struct inode *inode, struct file *filp, struct ata_device *drive) { if (drive->removable && !drive->usage) { struct ata_taskfile args; @@ -398,7 +398,7 @@ ide_cmd_type_parser(&args); if (drive->doorlocking && - ide_raw_taskfile(drive, &args, NULL)) + ide_raw_taskfile(drive, &args)) drive->doorlocking = 0; } if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) @@ -419,75 +419,6 @@ return drive->capacity - drive->sect0; } -static ide_startstop_t idedisk_special(struct ata_device *drive) -{ - unsigned char special_cmd = drive->special_cmd; - - if (special_cmd & ATA_SPECIAL_GEOMETRY) { - struct ata_taskfile args; - - drive->special_cmd &= ~ATA_SPECIAL_GEOMETRY; - - memset(&args, 0, sizeof(args)); - args.taskfile.sector_number = drive->sect; - args.taskfile.low_cylinder = drive->cyl; - args.taskfile.high_cylinder = drive->cyl>>8; - args.taskfile.device_head = ((drive->head-1)|drive->select.all)&0xBF; - if (!IS_PDC4030_DRIVE) { - args.taskfile.sector_count = drive->sect; - args.taskfile.command = WIN_SPECIFY; - args.handler = set_geometry_intr;; - } - ata_taskfile(drive, &args, NULL); - } else if (special_cmd & ATA_SPECIAL_RECALIBRATE) { - drive->special_cmd &= ~ATA_SPECIAL_RECALIBRATE; - - if (!IS_PDC4030_DRIVE) { - struct ata_taskfile args; - - memset(&args, 0, sizeof(args)); - args.taskfile.sector_count = drive->sect; - args.taskfile.command = WIN_RESTORE; - args.handler = recal_intr; - ata_taskfile(drive, &args, NULL); - } - } else if (special_cmd & ATA_SPECIAL_MMODE) { - drive->special_cmd &= ~ATA_SPECIAL_MMODE; - if (drive->id && drive->mult_req > drive->id->max_multsect) - drive->mult_req = drive->id->max_multsect; - if (!IS_PDC4030_DRIVE) { - struct ata_taskfile args; - - memset(&args, 0, sizeof(args)); - args.taskfile.sector_count = drive->mult_req; - args.taskfile.command = WIN_SETMULT; - args.handler = set_multmode_intr; - - ata_taskfile(drive, &args, NULL); - } - } else if (special_cmd) { - drive->special_cmd = 0; - - printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special_cmd); - return ide_stopped; - } - return IS_PDC4030_DRIVE ? ide_stopped : ide_started; -} - -static void idedisk_pre_reset(struct ata_device *drive) -{ - int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1; - - if (legacy) - drive->special_cmd = (ATA_SPECIAL_GEOMETRY | ATA_SPECIAL_RECALIBRATE); - else - drive->special_cmd = 0; - if (OK_TO_RESET_CONTROLLER) - drive->mult_count = 0; - if (drive->mult_req != drive->mult_count) - drive->special_cmd |= ATA_SPECIAL_MMODE; -} - #ifdef CONFIG_PROC_FS #ifdef CONFIG_BLK_DEV_IDE_TCQ @@ -556,28 +487,58 @@ */ static int set_multcount(struct ata_device *drive, int arg) { - struct request rq; + struct ata_taskfile args; + + /* Setting multi mode count on this channel type is not supported/not + * handled. + */ + if (IS_PDC4030_DRIVE) + return -EIO; + + /* Hugh, we still didn't detect the devices capabilities. + */ + if (!drive->id) + return -EIO; - if (drive->special_cmd & ATA_SPECIAL_MMODE) + /* FIXME: Hmm... just bailing out my be problematic, since there *is* + * activity during boot. For now the same problem persists in + * set_pio_mode() we will have to do something about it soon. + */ + if (HWGROUP(drive)->handler) return -EBUSY; - ide_init_drive_cmd(&rq); + if (arg > drive->id->max_multsect) + arg = drive->id->max_multsect; - drive->mult_req = arg; - drive->special_cmd |= ATA_SPECIAL_MMODE; + memset(&args, 0, sizeof(args)); + args.taskfile.sector_count = arg; + args.taskfile.command = WIN_SETMULT; + ide_cmd_type_parser(&args); - ide_do_drive_cmd(drive, &rq, ide_wait); + if (!ide_raw_taskfile(drive, &args)) { + /* all went well track this setting as valid */ + drive->mult_count = arg; + + return 0; + } else + drive->mult_count = 0; /* reset */ - return (drive->mult_count == arg) ? 0 : -EIO; + return -EIO; } static int set_nowerr(struct ata_device *drive, int arg) { - if (ide_spin_wait_hwgroup(drive)) + if (HWGROUP(drive)->handler) return -EBUSY; + drive->nowerr = arg; drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; + + /* FIXME: I'm less then sure that we are under the global request lock here! + */ +#if 0 spin_unlock_irq(&ide_lock); +#endif return 0; } @@ -593,7 +554,7 @@ args.taskfile.feature = (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; args.taskfile.command = WIN_SETFEATURES; ide_cmd_type_parser(&args); - ide_raw_taskfile(drive, &args, NULL); + ide_raw_taskfile(drive, &args); drive->wcache = arg; @@ -608,7 +569,7 @@ args.taskfile.command = WIN_STANDBYNOW1; ide_cmd_type_parser(&args); - return ide_raw_taskfile(drive, &args, NULL); + return ide_raw_taskfile(drive, &args); } static int set_acoustic(struct ata_device *drive, int arg) @@ -620,7 +581,7 @@ args.taskfile.sector_count = arg; args.taskfile.command = WIN_SETFEATURES; ide_cmd_type_parser(&args); - ide_raw_taskfile(drive, &args, NULL); + ide_raw_taskfile(drive, &args); drive->acoustic = arg; @@ -673,17 +634,11 @@ { struct hd_driveid *id = drive->id; - ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->bios_cyl, NULL); - ide_add_setting(drive, "bios_head", SETTING_RW, -1, -1, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); - ide_add_setting(drive, "bios_sect", SETTING_RW, -1, -1, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); ide_add_setting(drive, "address", SETTING_RW, HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, TYPE_INTA, 0, 2, 1, 1, &drive->addressing, set_lba_addressing); ide_add_setting(drive, "multcount", id ? SETTING_RW : SETTING_READ, HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, TYPE_BYTE, 0, id ? id->max_multsect : 0, 1, 1, &drive->mult_count, set_multcount); ide_add_setting(drive, "nowerr", SETTING_RW, HDIO_GET_NOWERR, HDIO_SET_NOWERR, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr); - ide_add_setting(drive, "lun", SETTING_RW, -1, -1, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL); ide_add_setting(drive, "wcache", SETTING_RW, HDIO_GET_WCACHE, HDIO_SET_WCACHE, TYPE_BYTE, 0, 1, 1, 1, &drive->wcache, write_cache); ide_add_setting(drive, "acoustic", SETTING_RW, HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, TYPE_BYTE, 0, 254, 1, 1, &drive->acoustic, set_acoustic); - ide_add_setting(drive, "failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL); - ide_add_setting(drive, "max_failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL); #ifdef CONFIG_BLK_DEV_IDE_TCQ ide_add_setting(drive, "using_tcq", SETTING_RW, HDIO_GET_QDMA, HDIO_SET_QDMA, TYPE_BYTE, 0, IDE_MAX_TAG, 1, 1, &drive->using_tcq, set_using_tcq); #endif @@ -761,7 +716,7 @@ args.handler = task_no_data_intr; /* submit command request */ - ide_raw_taskfile(drive, &args, NULL); + ide_raw_taskfile(drive, &args); /* if OK, compute maximum address value */ if ((args.taskfile.command & 0x01) == 0) { @@ -789,7 +744,7 @@ args.handler = task_no_data_intr; /* submit command request */ - ide_raw_taskfile(drive, &args, NULL); + ide_raw_taskfile(drive, &args); /* if OK, compute maximum address value */ if ((args.taskfile.command & 0x01) == 0) { @@ -829,7 +784,7 @@ args.taskfile.command = WIN_SET_MAX; args.handler = task_no_data_intr; /* submit command request */ - ide_raw_taskfile(drive, &args, NULL); + ide_raw_taskfile(drive, &args); /* if OK, read new maximum address value */ if ((args.taskfile.command & 0x01) == 0) { addr_set = ((args.taskfile.device_head & 0x0f) << 24) @@ -865,7 +820,7 @@ args.handler = task_no_data_intr; /* submit command request */ - ide_raw_taskfile(drive, &args, NULL); + ide_raw_taskfile(drive, &args); /* if OK, compute maximum address value */ if ((args.taskfile.command & 0x01) == 0) { u32 high = (args.hobfile.high_cylinder << 16) | @@ -1078,7 +1033,13 @@ printk("\n"); drive->mult_count = 0; +#if 0 if (id->max_multsect) { + + /* FIXME: reenable this again after making it to use + * the same code path as the ioctl stuff. + */ + #ifdef CONFIG_IDEDISK_MULTI_MODE id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0; id->multsect_valid = id->multsect ? 1 : 0; @@ -1094,6 +1055,7 @@ drive->special_cmd |= ATA_SPECIAL_MMODE; #endif } +#endif /* FIXME: Nowadays there are many chipsets out there which *require* 32 * bit IO. Those will most propably not work properly with drives not @@ -1136,9 +1098,7 @@ release: idedisk_release, check_media_change: idedisk_check_media_change, revalidate: NULL, /* use default method */ - pre_reset: idedisk_pre_reset, capacity: idedisk_capacity, - special: idedisk_special, proc: idedisk_proc }; diff -urN linux-2.5.14/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c --- linux-2.5.14/drivers/ide/ide-tape.c 2002-05-07 02:36:37.000000000 +0200 +++ linux/drivers/ide/ide-tape.c 2002-05-07 01:23:42.000000000 +0200 @@ -4273,16 +4273,6 @@ } /* - * idetape_pre_reset is called before an ATAPI/ATA software reset. - */ -static void idetape_pre_reset (ide_drive_t *drive) -{ - idetape_tape_t *tape = drive->driver_data; - if (tape != NULL) - set_bit (IDETAPE_IGNORE_DSC, &tape->flags); -} - -/* * Character device interface functions */ static ide_drive_t *get_drive_ptr (kdev_t i_rdev) @@ -6164,8 +6154,6 @@ release: idetape_blkdev_release, check_media_change: NULL, revalidate: idetape_revalidate, - pre_reset: idetape_pre_reset, - capacity: NULL, proc: idetape_proc }; diff -urN linux-2.5.14/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c --- linux-2.5.14/drivers/ide/ide-taskfile.c 2002-05-07 02:36:37.000000000 +0200 +++ linux/drivers/ide/ide-taskfile.c 2002-05-07 02:30:11.000000000 +0200 @@ -489,40 +489,6 @@ } /* - * This is invoked on completion of a WIN_SETMULT cmd. - */ -ide_startstop_t set_multmode_intr(struct ata_device *drive, struct request *__rq) -{ - u8 stat; - - if (OK_STAT(stat = GET_STAT(),READY_STAT,BAD_STAT)) { - drive->mult_count = drive->mult_req; - } else { - drive->mult_req = drive->mult_count = 0; - drive->special_cmd |= ATA_SPECIAL_RECALIBRATE; - ide_dump_status(drive, "set_multmode", stat); - } - return ide_stopped; -} - -/* - * This is invoked on completion of a WIN_SPECIFY cmd. - */ -ide_startstop_t set_geometry_intr(struct ata_device *drive, struct request *__rq) -{ - u8 stat; - - if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) - return ide_stopped; - - if (stat & (ERR_STAT|DRQ_STAT)) - return ide_error(drive, "set_geometry_intr", stat); - - ide_set_handler(drive, set_geometry_intr, WAIT_CMD, NULL); - return ide_started; -} - -/* * This is invoked on completion of a WIN_RESTORE (recalibrate) cmd. */ ide_startstop_t recal_intr(struct ata_device *drive, struct request *__rq) @@ -729,11 +695,11 @@ args->command_type = IDE_DRIVE_TASK_IN; return; + case CFA_WRITE_SECT_WO_ERASE: case WIN_WRITE: case WIN_WRITE_EXT: case WIN_WRITE_VERIFY: case WIN_WRITE_BUFFER: - case CFA_WRITE_SECT_WO_ERASE: case WIN_DOWNLOAD_MICROCODE: args->prehandler = pre_task_out_intr; args->handler = task_out_intr; @@ -832,7 +798,7 @@ } case WIN_SPECIFY: - args->handler = set_geometry_intr; + args->handler = task_no_data_intr; args->command_type = IDE_DRIVE_TASK_NO_DATA; return; @@ -874,7 +840,7 @@ return; case WIN_SETMULT: - args->handler = set_multmode_intr; + args->handler = task_no_data_intr; args->command_type = IDE_DRIVE_TASK_NO_DATA; return; @@ -894,19 +860,19 @@ } } -int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *args, byte *buf) +int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *args) { struct request rq; memset(&rq, 0, sizeof(rq)); rq.flags = REQ_DRIVE_ACB; - rq.buffer = buf; +#if 0 if (args->command_type != IDE_DRIVE_TASK_NO_DATA) rq.current_nr_sectors = rq.nr_sectors = (args->hobfile.sector_count << 8) | args->taskfile.sector_count; - +#endif rq.special = args; return ide_do_drive_cmd(drive, &rq, ide_wait); @@ -996,8 +962,6 @@ EXPORT_SYMBOL(atapi_write); EXPORT_SYMBOL(ata_taskfile); EXPORT_SYMBOL(recal_intr); -EXPORT_SYMBOL(set_geometry_intr); -EXPORT_SYMBOL(set_multmode_intr); EXPORT_SYMBOL(task_no_data_intr); EXPORT_SYMBOL(ide_raw_taskfile); EXPORT_SYMBOL(ide_cmd_type_parser); diff -urN linux-2.5.14/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c --- linux-2.5.14/drivers/ide/pdc4030.c 2002-05-06 05:37:57.000000000 +0200 +++ linux/drivers/ide/pdc4030.c 2002-05-06 19:55:23.000000000 +0200 @@ -39,6 +39,7 @@ * Version 0.90 Transition to BETA code. No lost/unexpected interrupts * Version 0.91 Bring in line with new bio code in 2.5.1 * Version 0.92 Update for IDE driver taskfile changes + * Version 0.93 Sync with 2.5.10, minor taskfile changes */ /* @@ -380,6 +381,7 @@ } /* + * promise_complete_pollfunc() * This is the polling function for waiting (nicely!) until drive stops * being busy. It is invoked at the end of a write, after the previous poll * has finished. @@ -388,20 +390,20 @@ */ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struct request *rq) { - ide_hwgroup_t *hwgroup = HWGROUP(drive); + struct ata_channel *ch = drive->channel; if (GET_STAT() & BUSY_STAT) { - if (time_before(jiffies, hwgroup->poll_timeout)) { + if (time_before(jiffies, ch->poll_timeout)) { ide_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL); return ide_started; /* continue polling... */ } - hwgroup->poll_timeout = 0; + ch->poll_timeout = 0; printk(KERN_ERR "%s: completion timeout - still busy!\n", drive->name); return ide_error(drive, "busy timeout", GET_STAT()); } - hwgroup->poll_timeout = 0; + ch->poll_timeout = 0; #ifdef DEBUG_WRITE printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name); #endif @@ -432,7 +434,7 @@ nsect = mcount; mcount -= nsect; - buffer = bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq); + buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq); rq->sector += nsect; rq->nr_sectors -= nsect; rq->current_nr_sectors -= nsect; @@ -467,23 +469,23 @@ */ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct request *rq) { - ide_hwgroup_t *hwgroup = HWGROUP(drive); + struct ata_channel *ch = drive->channel; if (IN_BYTE(IDE_NSECTOR_REG) != 0) { - if (time_before(jiffies, hwgroup->poll_timeout)) { + if (time_before(jiffies, ch->poll_timeout)) { ide_set_handler(drive, promise_write_pollfunc, HZ/100, NULL); return ide_started; /* continue polling... */ } - hwgroup->poll_timeout = 0; + ch->poll_timeout = 0; printk(KERN_ERR "%s: write timed-out!\n",drive->name); - return ide_error (drive, "write timeout", GET_STAT()); + return ide_error(drive, "write timeout", GET_STAT()); } /* * Now write out last 4 sectors and poll for not BUSY */ promise_multwrite(drive, rq, 4); - hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + ch->poll_timeout = jiffies + WAIT_WORSTCASE; ide_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL); #ifdef DEBUG_WRITE printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n", @@ -501,7 +503,7 @@ */ static ide_startstop_t promise_write(struct ata_device *drive, struct request *rq) { - ide_hwgroup_t *hwgroup = HWGROUP(drive); + struct ata_channel *ch = drive->channel; #ifdef DEBUG_WRITE printk(KERN_DEBUG "%s: promise_write: sectors(%ld-%ld), " @@ -516,7 +518,7 @@ if (rq->nr_sectors > 4) { if (promise_multwrite(drive, rq, rq->nr_sectors - 4)) return ide_stopped; - hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + ch->poll_timeout = jiffies + WAIT_WORSTCASE; ide_set_handler(drive, promise_write_pollfunc, HZ/100, NULL); return ide_started; } else { @@ -526,7 +528,7 @@ */ if (promise_multwrite(drive, rq, rq->nr_sectors)) return ide_stopped; - hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; + ch->poll_timeout = jiffies + WAIT_WORSTCASE; ide_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL); #ifdef DEBUG_WRITE printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, " @@ -537,13 +539,13 @@ } /* - * do_pdc4030_io() is called from do_rw_disk, having had the block number - * already set up. It issues a READ or WRITE command to the Promise + * do_pdc4030_io() is called from promise_do_request, having had the block + * number already set up. It issues a READ or WRITE command to the Promise * controller, assuming LBA has been used to set up the block number. */ -ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *task, struct request *rq) +ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *args, struct request *rq) { - struct hd_drive_task_hdr *taskfile = &task->taskfile; + struct hd_drive_task_hdr *taskfile = &(args->taskfile); unsigned long timeout; byte stat; @@ -628,7 +630,7 @@ } } -ide_startstop_t promise_rw_disk(struct ata_device *drive, struct request *rq, sector_t block) +ide_startstop_t promise_do_request(struct ata_device *drive, struct request *rq, sector_t block) { struct ata_taskfile args; @@ -647,12 +649,12 @@ args.taskfile.device_head = ((block>>8)&0x0f)|drive->select.all; args.taskfile.command = (rq_data_dir(rq)==READ)?PROMISE_READ:PROMISE_WRITE; - ide_cmd_type_parser(&args); - /* We don't use the generic inerrupt handlers here? */ - args.prehandler = NULL; + /* We can't call ide_cmd_type_parser here, since it won't understand + our command, but that doesn't matter, since we don't use the + generic interrupt handlers either. Setup the bits of args that we + will need. */ args.handler = NULL; rq->special = &args; return do_pdc4030_io(drive, &args, rq); } - diff -urN linux-2.5.14/drivers/ide/tcq.c linux/drivers/ide/tcq.c --- linux-2.5.14/drivers/ide/tcq.c 2002-05-06 05:38:05.000000000 +0200 +++ linux/drivers/ide/tcq.c 2002-05-06 20:11:27.000000000 +0200 @@ -418,7 +418,7 @@ * pass NOP with sub-code 0x01 to device, so the command will not * fail there */ - ide_raw_taskfile(drive, &args, NULL); + ide_raw_taskfile(drive, &args); if (args.taskfile.feature & ABRT_ERR) return 1; @@ -448,7 +448,7 @@ args.taskfile.command = WIN_SETFEATURES; ide_cmd_type_parser(&args); - if (ide_raw_taskfile(drive, &args, NULL)) { + if (ide_raw_taskfile(drive, &args)) { printk("%s: failed to enable write cache\n", drive->name); return 1; } @@ -462,7 +462,7 @@ args.taskfile.command = WIN_SETFEATURES; ide_cmd_type_parser(&args); - if (ide_raw_taskfile(drive, &args, NULL)) { + if (ide_raw_taskfile(drive, &args)) { printk("%s: disabling release interrupt fail\n", drive->name); return 1; } @@ -476,7 +476,7 @@ args.taskfile.command = WIN_SETFEATURES; ide_cmd_type_parser(&args); - if (ide_raw_taskfile(drive, &args, NULL)) { + if (ide_raw_taskfile(drive, &args)) { printk("%s: enabling service interrupt fail\n", drive->name); return 1; } diff -urN linux-2.5.14/include/linux/ide.h linux/include/linux/ide.h --- linux-2.5.14/include/linux/ide.h 2002-05-07 02:36:38.000000000 +0200 +++ linux/include/linux/ide.h 2002-05-07 02:30:15.000000000 +0200 @@ -47,7 +47,7 @@ # define DISK_RECOVERY_TIME 0 /* for hardware that needs it */ #endif #ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */ -# define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */ +# define OK_TO_RESET_CONTROLLER 0 /* 0 for use with AH2372A/B interface */ #endif #ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */ # define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */ @@ -327,19 +327,9 @@ */ request_queue_t queue; /* per device request queue */ - unsigned long sleep; /* sleep until this time */ - /* Flags requesting/indicating one of the following special commands - * executed on the request queue. - */ -#define ATA_SPECIAL_GEOMETRY 0x01 -#define ATA_SPECIAL_RECALIBRATE 0x02 -#define ATA_SPECIAL_MMODE 0x04 -#define ATA_SPECIAL_TUNE 0x08 - unsigned char special_cmd; - u8 mult_req; /* requested multiple sector setting */ - u8 tune_req; /* requested drive tuning setting */ + u8 XXX_tune_req; /* requested drive tuning setting */ byte using_dma; /* disk is using dma for read/write */ byte using_tcq; /* disk is using queueing */ @@ -409,6 +399,7 @@ unsigned int failures; /* current failure count */ unsigned int max_failures; /* maximum allowed failure count */ struct device device; /* global device tree handle */ + /* * tcq statistics */ @@ -517,6 +508,8 @@ /* driver soft-power interface */ int (*busproc)(struct ata_device *, int); byte bus_state; /* power state of the IDE bus */ + + unsigned long poll_timeout; /* timeout value during polled operations */ }; /* @@ -565,17 +558,19 @@ return 1; } #else -#define ata_pending_commands(drive) (0) -#define ata_can_queue(drive) (1) +# define ata_pending_commands(drive) (0) +# define ata_can_queue(drive) (1) #endif typedef struct hwgroup_s { + /* FIXME: We should look for busy request queues instead of looking at + * the !NULL state of this field. + */ ide_startstop_t (*handler)(struct ata_device *, struct request *); /* irq handler, if active */ unsigned long flags; /* BUSY, SLEEPING */ struct ata_device *XXX_drive; /* current drive */ struct request *rq; /* current request */ struct timer_list timer; /* failsafe timer */ - unsigned long poll_timeout; /* timeout value during long polls */ int (*expiry)(struct ata_device *, struct request *); /* irq handler, if active */ } ide_hwgroup_t; @@ -675,9 +670,7 @@ int (*check_media_change)(struct ata_device *); void (*revalidate)(struct ata_device *); - void (*pre_reset)(struct ata_device *); sector_t (*capacity)(struct ata_device *); - ide_startstop_t (*special)(struct ata_device *); ide_proc_entry_t *proc; }; @@ -827,15 +820,13 @@ */ extern ide_startstop_t recal_intr(struct ata_device *, struct request *); -extern ide_startstop_t set_geometry_intr(struct ata_device *, struct request *); -extern ide_startstop_t set_multmode_intr(struct ata_device *, struct request *); extern ide_startstop_t task_no_data_intr(struct ata_device *, struct request *); /* This is setting up all fields in args, which depend upon the command type. */ extern void ide_cmd_type_parser(struct ata_taskfile *args); -extern int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *cmd, byte *buf); +extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *); extern int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg); void ide_delay_50ms(void);