diff options
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 117 |
1 files changed, 73 insertions, 44 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index a896a283f27f..1c51949833be 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/ide.h> | 42 | #include <linux/ide.h> |
43 | #include <linux/hdreg.h> | ||
43 | #include <linux/completion.h> | 44 | #include <linux/completion.h> |
44 | #include <linux/reboot.h> | 45 | #include <linux/reboot.h> |
45 | #include <linux/cdrom.h> | 46 | #include <linux/cdrom.h> |
@@ -183,18 +184,18 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
183 | if (drive->media != ide_disk) | 184 | if (drive->media != ide_disk) |
184 | break; | 185 | break; |
185 | /* Not supported? Switch to next step now. */ | 186 | /* Not supported? Switch to next step now. */ |
186 | if (!drive->wcache || !ide_id_has_flush_cache(drive->id)) { | 187 | if (!drive->wcache || ata_id_flush_enabled(drive->id) == 0) { |
187 | ide_complete_power_step(drive, rq, 0, 0); | 188 | ide_complete_power_step(drive, rq, 0, 0); |
188 | return ide_stopped; | 189 | return ide_stopped; |
189 | } | 190 | } |
190 | if (ide_id_has_flush_cache_ext(drive->id)) | 191 | if (ata_id_flush_ext_enabled(drive->id)) |
191 | args->tf.command = WIN_FLUSH_CACHE_EXT; | 192 | args->tf.command = ATA_CMD_FLUSH_EXT; |
192 | else | 193 | else |
193 | args->tf.command = WIN_FLUSH_CACHE; | 194 | args->tf.command = ATA_CMD_FLUSH; |
194 | goto out_do_tf; | 195 | goto out_do_tf; |
195 | 196 | ||
196 | case idedisk_pm_standby: /* Suspend step 2 (standby) */ | 197 | case idedisk_pm_standby: /* Suspend step 2 (standby) */ |
197 | args->tf.command = WIN_STANDBYNOW1; | 198 | args->tf.command = ATA_CMD_STANDBYNOW1; |
198 | goto out_do_tf; | 199 | goto out_do_tf; |
199 | 200 | ||
200 | case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */ | 201 | case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */ |
@@ -209,7 +210,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
209 | return ide_stopped; | 210 | return ide_stopped; |
210 | 211 | ||
211 | case idedisk_pm_idle: /* Resume step 2 (idle) */ | 212 | case idedisk_pm_idle: /* Resume step 2 (idle) */ |
212 | args->tf.command = WIN_IDLEIMMEDIATE; | 213 | args->tf.command = ATA_CMD_IDLEIMMEDIATE; |
213 | goto out_do_tf; | 214 | goto out_do_tf; |
214 | 215 | ||
215 | case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */ | 216 | case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */ |
@@ -322,7 +323,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
322 | ide_task_t *task = (ide_task_t *)rq->special; | 323 | ide_task_t *task = (ide_task_t *)rq->special; |
323 | 324 | ||
324 | if (rq->errors == 0) | 325 | if (rq->errors == 0) |
325 | rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT); | 326 | rq->errors = !OK_STAT(stat, ATA_DRDY, BAD_STAT); |
326 | 327 | ||
327 | if (task) { | 328 | if (task) { |
328 | struct ide_taskfile *tf = &task->tf; | 329 | struct ide_taskfile *tf = &task->tf; |
@@ -373,29 +374,29 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 | |||
373 | { | 374 | { |
374 | ide_hwif_t *hwif = drive->hwif; | 375 | ide_hwif_t *hwif = drive->hwif; |
375 | 376 | ||
376 | if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { | 377 | if ((stat & ATA_BUSY) || ((stat & ATA_DF) && !drive->nowerr)) { |
377 | /* other bits are useless when BUSY */ | 378 | /* other bits are useless when BUSY */ |
378 | rq->errors |= ERROR_RESET; | 379 | rq->errors |= ERROR_RESET; |
379 | } else if (stat & ERR_STAT) { | 380 | } else if (stat & ATA_ERR) { |
380 | /* err has different meaning on cdrom and tape */ | 381 | /* err has different meaning on cdrom and tape */ |
381 | if (err == ABRT_ERR) { | 382 | if (err == ATA_ABORTED) { |
382 | if (drive->select.b.lba && | 383 | if (drive->select.b.lba && |
383 | /* some newer drives don't support WIN_SPECIFY */ | 384 | /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */ |
384 | hwif->tp_ops->read_status(hwif) == WIN_SPECIFY) | 385 | hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS) |
385 | return ide_stopped; | 386 | return ide_stopped; |
386 | } else if ((err & BAD_CRC) == BAD_CRC) { | 387 | } else if ((err & BAD_CRC) == BAD_CRC) { |
387 | /* UDMA crc error, just retry the operation */ | 388 | /* UDMA crc error, just retry the operation */ |
388 | drive->crc_count++; | 389 | drive->crc_count++; |
389 | } else if (err & (BBD_ERR | ECC_ERR)) { | 390 | } else if (err & (ATA_BBK | ATA_UNC)) { |
390 | /* retries won't help these */ | 391 | /* retries won't help these */ |
391 | rq->errors = ERROR_MAX; | 392 | rq->errors = ERROR_MAX; |
392 | } else if (err & TRK0_ERR) { | 393 | } else if (err & ATA_TRK0NF) { |
393 | /* help it find track zero */ | 394 | /* help it find track zero */ |
394 | rq->errors |= ERROR_RECAL; | 395 | rq->errors |= ERROR_RECAL; |
395 | } | 396 | } |
396 | } | 397 | } |
397 | 398 | ||
398 | if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && | 399 | if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ && |
399 | (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) { | 400 | (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) { |
400 | int nsect = drive->mult_count ? drive->mult_count : 1; | 401 | int nsect = drive->mult_count ? drive->mult_count : 1; |
401 | 402 | ||
@@ -407,7 +408,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 | |||
407 | return ide_stopped; | 408 | return ide_stopped; |
408 | } | 409 | } |
409 | 410 | ||
410 | if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT)) | 411 | if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ)) |
411 | rq->errors |= ERROR_RESET; | 412 | rq->errors |= ERROR_RESET; |
412 | 413 | ||
413 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | 414 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { |
@@ -427,16 +428,16 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u | |||
427 | { | 428 | { |
428 | ide_hwif_t *hwif = drive->hwif; | 429 | ide_hwif_t *hwif = drive->hwif; |
429 | 430 | ||
430 | if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr)) { | 431 | if ((stat & ATA_BUSY) || ((stat & ATA_DF) && !drive->nowerr)) { |
431 | /* other bits are useless when BUSY */ | 432 | /* other bits are useless when BUSY */ |
432 | rq->errors |= ERROR_RESET; | 433 | rq->errors |= ERROR_RESET; |
433 | } else { | 434 | } else { |
434 | /* add decoding error stuff */ | 435 | /* add decoding error stuff */ |
435 | } | 436 | } |
436 | 437 | ||
437 | if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT)) | 438 | if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ)) |
438 | /* force an abort */ | 439 | /* force an abort */ |
439 | hwif->tp_ops->exec_command(hwif, WIN_IDLEIMMEDIATE); | 440 | hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE); |
440 | 441 | ||
441 | if (rq->errors >= ERROR_MAX) { | 442 | if (rq->errors >= ERROR_MAX) { |
442 | ide_kill_rq(drive, rq); | 443 | ide_kill_rq(drive, rq); |
@@ -509,19 +510,19 @@ static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | |||
509 | tf->lbam = drive->cyl; | 510 | tf->lbam = drive->cyl; |
510 | tf->lbah = drive->cyl >> 8; | 511 | tf->lbah = drive->cyl >> 8; |
511 | tf->device = ((drive->head - 1) | drive->select.all) & ~ATA_LBA; | 512 | tf->device = ((drive->head - 1) | drive->select.all) & ~ATA_LBA; |
512 | tf->command = WIN_SPECIFY; | 513 | tf->command = ATA_CMD_INIT_DEV_PARAMS; |
513 | } | 514 | } |
514 | 515 | ||
515 | static void ide_tf_set_restore_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 516 | static void ide_tf_set_restore_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
516 | { | 517 | { |
517 | tf->nsect = drive->sect; | 518 | tf->nsect = drive->sect; |
518 | tf->command = WIN_RESTORE; | 519 | tf->command = ATA_CMD_RESTORE; |
519 | } | 520 | } |
520 | 521 | ||
521 | static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 522 | static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
522 | { | 523 | { |
523 | tf->nsect = drive->mult_req; | 524 | tf->nsect = drive->mult_req; |
524 | tf->command = WIN_SETMULT; | 525 | tf->command = ATA_CMD_SET_MULTI; |
525 | } | 526 | } |
526 | 527 | ||
527 | static ide_startstop_t ide_disk_special(ide_drive_t *drive) | 528 | static ide_startstop_t ide_disk_special(ide_drive_t *drive) |
@@ -540,8 +541,6 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) | |||
540 | ide_tf_set_restore_cmd(drive, &args.tf); | 541 | ide_tf_set_restore_cmd(drive, &args.tf); |
541 | } else if (s->b.set_multmode) { | 542 | } else if (s->b.set_multmode) { |
542 | s->b.set_multmode = 0; | 543 | s->b.set_multmode = 0; |
543 | if (drive->mult_req > drive->id->max_multsect) | ||
544 | drive->mult_req = drive->id->max_multsect; | ||
545 | ide_tf_set_setmult_cmd(drive, &args.tf); | 544 | ide_tf_set_setmult_cmd(drive, &args.tf); |
546 | } else if (s->all) { | 545 | } else if (s->all) { |
547 | int special = s->all; | 546 | int special = s->all; |
@@ -586,9 +585,10 @@ static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) | |||
586 | * do_special - issue some special commands | 585 | * do_special - issue some special commands |
587 | * @drive: drive the command is for | 586 | * @drive: drive the command is for |
588 | * | 587 | * |
589 | * do_special() is used to issue WIN_SPECIFY, WIN_RESTORE, and WIN_SETMULT | 588 | * do_special() is used to issue ATA_CMD_INIT_DEV_PARAMS, |
590 | * commands to a drive. It used to do much more, but has been scaled | 589 | * ATA_CMD_RESTORE and ATA_CMD_SET_MULTI commands to a drive. |
591 | * back. | 590 | * |
591 | * It used to do much more, but has been scaled back. | ||
592 | */ | 592 | */ |
593 | 593 | ||
594 | static ide_startstop_t do_special (ide_drive_t *drive) | 594 | static ide_startstop_t do_special (ide_drive_t *drive) |
@@ -716,9 +716,49 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
716 | return ide_stopped; | 716 | return ide_stopped; |
717 | } | 717 | } |
718 | 718 | ||
719 | int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting, | ||
720 | int arg) | ||
721 | { | ||
722 | struct request_queue *q = drive->queue; | ||
723 | struct request *rq; | ||
724 | int ret = 0; | ||
725 | |||
726 | if (!(setting->flags & DS_SYNC)) | ||
727 | return setting->set(drive, arg); | ||
728 | |||
729 | rq = blk_get_request(q, READ, GFP_KERNEL); | ||
730 | if (!rq) | ||
731 | return -ENOMEM; | ||
732 | |||
733 | rq->cmd_type = REQ_TYPE_SPECIAL; | ||
734 | rq->cmd_len = 5; | ||
735 | rq->cmd[0] = REQ_DEVSET_EXEC; | ||
736 | *(int *)&rq->cmd[1] = arg; | ||
737 | rq->special = setting->set; | ||
738 | |||
739 | if (blk_execute_rq(q, NULL, rq, 0)) | ||
740 | ret = rq->errors; | ||
741 | blk_put_request(rq); | ||
742 | |||
743 | return ret; | ||
744 | } | ||
745 | EXPORT_SYMBOL_GPL(ide_devset_execute); | ||
746 | |||
719 | static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) | 747 | static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) |
720 | { | 748 | { |
721 | switch (rq->cmd[0]) { | 749 | switch (rq->cmd[0]) { |
750 | case REQ_DEVSET_EXEC: | ||
751 | { | ||
752 | int err, (*setfunc)(ide_drive_t *, int) = rq->special; | ||
753 | |||
754 | err = setfunc(drive, *(int *)&rq->cmd[1]); | ||
755 | if (err) | ||
756 | rq->errors = err; | ||
757 | else | ||
758 | err = 1; | ||
759 | ide_end_request(drive, err, 0); | ||
760 | return ide_stopped; | ||
761 | } | ||
722 | case REQ_DRIVE_RESET: | 762 | case REQ_DRIVE_RESET: |
723 | return ide_do_reset(drive); | 763 | return ide_do_reset(drive); |
724 | default: | 764 | default: |
@@ -766,9 +806,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) | |||
766 | * start_request - start of I/O and command issuing for IDE | 806 | * start_request - start of I/O and command issuing for IDE |
767 | * | 807 | * |
768 | * start_request() initiates handling of a new I/O request. It | 808 | * start_request() initiates handling of a new I/O request. It |
769 | * accepts commands and I/O (read/write) requests. It also does | 809 | * accepts commands and I/O (read/write) requests. |
770 | * the final remapping for weird stuff like EZDrive. Once | ||
771 | * device mapper can work sector level the EZDrive stuff can go away | ||
772 | * | 810 | * |
773 | * FIXME: this function needs a rename | 811 | * FIXME: this function needs a rename |
774 | */ | 812 | */ |
@@ -776,7 +814,6 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) | |||
776 | static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | 814 | static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) |
777 | { | 815 | { |
778 | ide_startstop_t startstop; | 816 | ide_startstop_t startstop; |
779 | sector_t block; | ||
780 | 817 | ||
781 | BUG_ON(!blk_rq_started(rq)); | 818 | BUG_ON(!blk_rq_started(rq)); |
782 | 819 | ||
@@ -791,21 +828,12 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
791 | goto kill_rq; | 828 | goto kill_rq; |
792 | } | 829 | } |
793 | 830 | ||
794 | block = rq->sector; | ||
795 | if (blk_fs_request(rq) && | ||
796 | (drive->media == ide_disk || drive->media == ide_floppy)) { | ||
797 | block += drive->sect0; | ||
798 | } | ||
799 | /* Yecch - this will shift the entire interval, | ||
800 | possibly killing some innocent following sector */ | ||
801 | if (block == 0 && drive->remap_0_to_1 == 1) | ||
802 | block = 1; /* redirect MBR access to EZ-Drive partn table */ | ||
803 | |||
804 | if (blk_pm_request(rq)) | 831 | if (blk_pm_request(rq)) |
805 | ide_check_pm_state(drive, rq); | 832 | ide_check_pm_state(drive, rq); |
806 | 833 | ||
807 | SELECT_DRIVE(drive); | 834 | SELECT_DRIVE(drive); |
808 | if (ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) { | 835 | if (ide_wait_stat(&startstop, drive, drive->ready_stat, |
836 | ATA_BUSY | ATA_DRQ, WAIT_READY)) { | ||
809 | printk(KERN_ERR "%s: drive not ready for command\n", drive->name); | 837 | printk(KERN_ERR "%s: drive not ready for command\n", drive->name); |
810 | return startstop; | 838 | return startstop; |
811 | } | 839 | } |
@@ -844,7 +872,8 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
844 | return ide_special_rq(drive, rq); | 872 | return ide_special_rq(drive, rq); |
845 | 873 | ||
846 | drv = *(ide_driver_t **)rq->rq_disk->private_data; | 874 | drv = *(ide_driver_t **)rq->rq_disk->private_data; |
847 | return drv->do_request(drive, rq, block); | 875 | |
876 | return drv->do_request(drive, rq, rq->sector); | ||
848 | } | 877 | } |
849 | return do_special(drive); | 878 | return do_special(drive); |
850 | kill_rq: | 879 | kill_rq: |
@@ -1325,7 +1354,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) | |||
1325 | if (hwif->irq == irq) { | 1354 | if (hwif->irq == irq) { |
1326 | stat = hwif->tp_ops->read_status(hwif); | 1355 | stat = hwif->tp_ops->read_status(hwif); |
1327 | 1356 | ||
1328 | if (!OK_STAT(stat, READY_STAT, BAD_STAT)) { | 1357 | if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) { |
1329 | /* Try to not flood the console with msgs */ | 1358 | /* Try to not flood the console with msgs */ |
1330 | static unsigned long last_msgtime, count; | 1359 | static unsigned long last_msgtime, count; |
1331 | ++count; | 1360 | ++count; |