diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 80ad4f234f3f..44aaec256a30 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -905,6 +905,14 @@ 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, int err) | ||
909 | { | ||
910 | struct request *rq = drive->hwif->hwgroup->rq; | ||
911 | |||
912 | if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) | ||
913 | ide_end_request(drive, err ? err : 1, 0); | ||
914 | } | ||
915 | |||
908 | /* needed below */ | 916 | /* needed below */ |
909 | static ide_startstop_t do_reset1 (ide_drive_t *, int); | 917 | static ide_startstop_t do_reset1 (ide_drive_t *, int); |
910 | 918 | ||
@@ -940,7 +948,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | |||
940 | } | 948 | } |
941 | /* done polling */ | 949 | /* done polling */ |
942 | hwgroup->polling = 0; | 950 | hwgroup->polling = 0; |
943 | hwgroup->resetting = 0; | 951 | ide_complete_drive_reset(drive, 0); |
944 | return ide_stopped; | 952 | return ide_stopped; |
945 | } | 953 | } |
946 | 954 | ||
@@ -956,12 +964,14 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
956 | ide_hwif_t *hwif = HWIF(drive); | 964 | ide_hwif_t *hwif = HWIF(drive); |
957 | const struct ide_port_ops *port_ops = hwif->port_ops; | 965 | const struct ide_port_ops *port_ops = hwif->port_ops; |
958 | u8 tmp; | 966 | u8 tmp; |
967 | int err = 0; | ||
959 | 968 | ||
960 | if (port_ops && port_ops->reset_poll) { | 969 | if (port_ops && port_ops->reset_poll) { |
961 | if (port_ops->reset_poll(drive)) { | 970 | err = port_ops->reset_poll(drive); |
971 | if (err) { | ||
962 | printk(KERN_ERR "%s: host reset_poll failure for %s.\n", | 972 | printk(KERN_ERR "%s: host reset_poll failure for %s.\n", |
963 | hwif->name, drive->name); | 973 | hwif->name, drive->name); |
964 | return ide_stopped; | 974 | goto out; |
965 | } | 975 | } |
966 | } | 976 | } |
967 | 977 | ||
@@ -975,6 +985,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
975 | } | 985 | } |
976 | 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); |
977 | drive->failures++; | 987 | drive->failures++; |
988 | err = -EIO; | ||
978 | } else { | 989 | } else { |
979 | printk("%s: reset: ", hwif->name); | 990 | printk("%s: reset: ", hwif->name); |
980 | tmp = ide_read_error(drive); | 991 | tmp = ide_read_error(drive); |
@@ -1001,10 +1012,12 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
1001 | if (tmp & 0x80) | 1012 | if (tmp & 0x80) |
1002 | printk("; slave: failed"); | 1013 | printk("; slave: failed"); |
1003 | printk("\n"); | 1014 | printk("\n"); |
1015 | err = -EIO; | ||
1004 | } | 1016 | } |
1005 | } | 1017 | } |
1018 | out: | ||
1006 | hwgroup->polling = 0; /* done polling */ | 1019 | hwgroup->polling = 0; /* done polling */ |
1007 | hwgroup->resetting = 0; /* done reset attempt */ | 1020 | ide_complete_drive_reset(drive, err); |
1008 | return ide_stopped; | 1021 | return ide_stopped; |
1009 | } | 1022 | } |
1010 | 1023 | ||
@@ -1090,7 +1103,6 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1090 | 1103 | ||
1091 | /* For an ATAPI device, first try an ATAPI SRST. */ | 1104 | /* For an ATAPI device, first try an ATAPI SRST. */ |
1092 | if (drive->media != ide_disk && !do_not_try_atapi) { | 1105 | if (drive->media != ide_disk && !do_not_try_atapi) { |
1093 | hwgroup->resetting = 1; | ||
1094 | pre_reset(drive); | 1106 | pre_reset(drive); |
1095 | SELECT_DRIVE(drive); | 1107 | SELECT_DRIVE(drive); |
1096 | udelay (20); | 1108 | udelay (20); |
@@ -1112,10 +1124,10 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1112 | 1124 | ||
1113 | if (io_ports->ctl_addr == 0) { | 1125 | if (io_ports->ctl_addr == 0) { |
1114 | spin_unlock_irqrestore(&ide_lock, flags); | 1126 | spin_unlock_irqrestore(&ide_lock, flags); |
1127 | ide_complete_drive_reset(drive, -ENXIO); | ||
1115 | return ide_stopped; | 1128 | return ide_stopped; |
1116 | } | 1129 | } |
1117 | 1130 | ||
1118 | hwgroup->resetting = 1; | ||
1119 | /* | 1131 | /* |
1120 | * Note that we also set nIEN while resetting the device, | 1132 | * Note that we also set nIEN while resetting the device, |
1121 | * to mask unwanted interrupts from the interface during the reset. | 1133 | * to mask unwanted interrupts from the interface during the reset. |