diff options
| -rw-r--r-- | Documentation/ioctl/hdio.txt | 2 | ||||
| -rw-r--r-- | drivers/ide/ide-iops.c | 18 | ||||
| -rw-r--r-- | drivers/ide/ide.c | 10 | ||||
| -rw-r--r-- | drivers/ide/pci/siimage.c | 3 |
4 files changed, 20 insertions, 13 deletions
diff --git a/Documentation/ioctl/hdio.txt b/Documentation/ioctl/hdio.txt index 44d283d6b136..91a6ecbae0bb 100644 --- a/Documentation/ioctl/hdio.txt +++ b/Documentation/ioctl/hdio.txt | |||
| @@ -508,6 +508,8 @@ HDIO_DRIVE_RESET execute a device reset | |||
| 508 | 508 | ||
| 509 | error returns: | 509 | error returns: |
| 510 | EACCES Access denied: requires CAP_SYS_ADMIN | 510 | EACCES Access denied: requires CAP_SYS_ADMIN |
| 511 | ENXIO No such device: phy dead or ctl_addr == 0 | ||
| 512 | EIO I/O error: reset timed out or hardware error | ||
| 511 | 513 | ||
| 512 | notes: | 514 | notes: |
| 513 | 515 | ||
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 96f63eb12092..44aaec256a30 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
| @@ -905,12 +905,12 @@ void ide_execute_pkt_cmd(ide_drive_t *drive) | |||
| 905 | } | 905 | } |
| 906 | EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); | 906 | EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); |
| 907 | 907 | ||
| 908 | static inline void ide_complete_drive_reset(ide_drive_t *drive) | 908 | static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) |
| 909 | { | 909 | { |
| 910 | struct request *rq = drive->hwif->hwgroup->rq; | 910 | struct request *rq = drive->hwif->hwgroup->rq; |
| 911 | 911 | ||
| 912 | if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) | 912 | if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) |
| 913 | ide_end_request(drive, 1, 0); | 913 | ide_end_request(drive, err ? err : 1, 0); |
| 914 | } | 914 | } |
| 915 | 915 | ||
| 916 | /* needed below */ | 916 | /* needed below */ |
| @@ -948,7 +948,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | |||
| 948 | } | 948 | } |
| 949 | /* done polling */ | 949 | /* done polling */ |
| 950 | hwgroup->polling = 0; | 950 | hwgroup->polling = 0; |
| 951 | ide_complete_drive_reset(drive); | 951 | ide_complete_drive_reset(drive, 0); |
| 952 | return ide_stopped; | 952 | return ide_stopped; |
| 953 | } | 953 | } |
| 954 | 954 | ||
| @@ -964,9 +964,11 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
| 964 | ide_hwif_t *hwif = HWIF(drive); | 964 | ide_hwif_t *hwif = HWIF(drive); |
| 965 | const struct ide_port_ops *port_ops = hwif->port_ops; | 965 | const struct ide_port_ops *port_ops = hwif->port_ops; |
| 966 | u8 tmp; | 966 | u8 tmp; |
| 967 | int err = 0; | ||
| 967 | 968 | ||
| 968 | if (port_ops && port_ops->reset_poll) { | 969 | if (port_ops && port_ops->reset_poll) { |
| 969 | if (port_ops->reset_poll(drive)) { | 970 | err = port_ops->reset_poll(drive); |
| 971 | if (err) { | ||
| 970 | printk(KERN_ERR "%s: host reset_poll failure for %s.\n", | 972 | printk(KERN_ERR "%s: host reset_poll failure for %s.\n", |
| 971 | hwif->name, drive->name); | 973 | hwif->name, drive->name); |
| 972 | goto out; | 974 | goto out; |
| @@ -983,6 +985,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
| 983 | } | 985 | } |
| 984 | printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp); | 986 | printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp); |
| 985 | drive->failures++; | 987 | drive->failures++; |
| 988 | err = -EIO; | ||
| 986 | } else { | 989 | } else { |
| 987 | printk("%s: reset: ", hwif->name); | 990 | printk("%s: reset: ", hwif->name); |
| 988 | tmp = ide_read_error(drive); | 991 | tmp = ide_read_error(drive); |
| @@ -1009,11 +1012,12 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
| 1009 | if (tmp & 0x80) | 1012 | if (tmp & 0x80) |
| 1010 | printk("; slave: failed"); | 1013 | printk("; slave: failed"); |
| 1011 | printk("\n"); | 1014 | printk("\n"); |
| 1015 | err = -EIO; | ||
| 1012 | } | 1016 | } |
| 1013 | } | 1017 | } |
| 1014 | hwgroup->polling = 0; /* done polling */ | ||
| 1015 | out: | 1018 | out: |
| 1016 | ide_complete_drive_reset(drive); | 1019 | hwgroup->polling = 0; /* done polling */ |
| 1020 | ide_complete_drive_reset(drive, err); | ||
| 1017 | return ide_stopped; | 1021 | return ide_stopped; |
| 1018 | } | 1022 | } |
| 1019 | 1023 | ||
| @@ -1120,7 +1124,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
| 1120 | 1124 | ||
| 1121 | if (io_ports->ctl_addr == 0) { | 1125 | if (io_ports->ctl_addr == 0) { |
| 1122 | spin_unlock_irqrestore(&ide_lock, flags); | 1126 | spin_unlock_irqrestore(&ide_lock, flags); |
| 1123 | ide_complete_drive_reset(drive); | 1127 | ide_complete_drive_reset(drive, -ENXIO); |
| 1124 | return ide_stopped; | 1128 | return ide_stopped; |
| 1125 | } | 1129 | } |
| 1126 | 1130 | ||
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 1ec983b00511..d4a6b102a772 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
| @@ -529,17 +529,20 @@ static int generic_ide_resume(struct device *dev) | |||
| 529 | return err; | 529 | return err; |
| 530 | } | 530 | } |
| 531 | 531 | ||
| 532 | static void generic_drive_reset(ide_drive_t *drive) | 532 | static int generic_drive_reset(ide_drive_t *drive) |
| 533 | { | 533 | { |
| 534 | struct request *rq; | 534 | struct request *rq; |
| 535 | int ret = 0; | ||
| 535 | 536 | ||
| 536 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | 537 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
| 537 | rq->cmd_type = REQ_TYPE_SPECIAL; | 538 | rq->cmd_type = REQ_TYPE_SPECIAL; |
| 538 | rq->cmd_len = 1; | 539 | rq->cmd_len = 1; |
| 539 | rq->cmd[0] = REQ_DRIVE_RESET; | 540 | rq->cmd[0] = REQ_DRIVE_RESET; |
| 540 | rq->cmd_flags |= REQ_SOFTBARRIER; | 541 | rq->cmd_flags |= REQ_SOFTBARRIER; |
| 541 | blk_execute_rq(drive->queue, NULL, rq, 1); | 542 | if (blk_execute_rq(drive->queue, NULL, rq, 1)) |
| 543 | ret = rq->errors; | ||
| 542 | blk_put_request(rq); | 544 | blk_put_request(rq); |
| 545 | return ret; | ||
| 543 | } | 546 | } |
| 544 | 547 | ||
| 545 | int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, | 548 | int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, |
| @@ -616,8 +619,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
| 616 | if (!capable(CAP_SYS_ADMIN)) | 619 | if (!capable(CAP_SYS_ADMIN)) |
| 617 | return -EACCES; | 620 | return -EACCES; |
| 618 | 621 | ||
| 619 | generic_drive_reset(drive); | 622 | return generic_drive_reset(drive); |
| 620 | return 0; | ||
| 621 | 623 | ||
| 622 | case HDIO_GET_BUSSTATE: | 624 | case HDIO_GET_BUSSTATE: |
| 623 | if (!capable(CAP_SYS_ADMIN)) | 625 | if (!capable(CAP_SYS_ADMIN)) |
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index b75e9bb390a7..6e9d7655d89c 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c | |||
| @@ -421,8 +421,7 @@ static int sil_sata_reset_poll(ide_drive_t *drive) | |||
| 421 | if ((sata_stat & 0x03) != 0x03) { | 421 | if ((sata_stat & 0x03) != 0x03) { |
| 422 | printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n", | 422 | printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n", |
| 423 | hwif->name, sata_stat); | 423 | hwif->name, sata_stat); |
| 424 | HWGROUP(drive)->polling = 0; | 424 | return -ENXIO; |
| 425 | return ide_started; | ||
| 426 | } | 425 | } |
| 427 | } | 426 | } |
| 428 | 427 | ||
