diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-io.c | 107 |
1 files changed, 46 insertions, 61 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2fe5a7088744..cc163319dfbd 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -920,60 +920,55 @@ void ide_timer_expiry (unsigned long data) | |||
920 | * Either way, we don't really want to complain about anything. | 920 | * Either way, we don't really want to complain about anything. |
921 | */ | 921 | */ |
922 | } else { | 922 | } else { |
923 | ide_expiry_t *expiry = hwif->expiry; | ||
924 | ide_startstop_t startstop = ide_stopped; | ||
925 | |||
923 | drive = hwif->cur_dev; | 926 | drive = hwif->cur_dev; |
924 | if (!drive) { | 927 | |
925 | printk(KERN_ERR "%s: ->cur_dev was NULL\n", __func__); | 928 | if (expiry) { |
926 | hwif->handler = NULL; | 929 | wait = expiry(drive); |
927 | } else { | 930 | if (wait > 0) { /* continue */ |
928 | ide_expiry_t *expiry = hwif->expiry; | 931 | /* reset timer */ |
929 | ide_startstop_t startstop = ide_stopped; | 932 | hwif->timer.expires = jiffies + wait; |
930 | 933 | hwif->req_gen_timer = hwif->req_gen; | |
931 | if (expiry) { | 934 | add_timer(&hwif->timer); |
932 | /* continue */ | 935 | spin_unlock_irqrestore(&hwif->lock, flags); |
933 | if ((wait = expiry(drive)) > 0) { | 936 | return; |
934 | /* reset timer */ | ||
935 | hwif->timer.expires = jiffies + wait; | ||
936 | hwif->req_gen_timer = hwif->req_gen; | ||
937 | add_timer(&hwif->timer); | ||
938 | spin_unlock_irqrestore(&hwif->lock, flags); | ||
939 | return; | ||
940 | } | ||
941 | } | ||
942 | hwif->handler = NULL; | ||
943 | /* | ||
944 | * We need to simulate a real interrupt when invoking | ||
945 | * the handler() function, which means we need to | ||
946 | * globally mask the specific IRQ: | ||
947 | */ | ||
948 | spin_unlock(&hwif->lock); | ||
949 | /* disable_irq_nosync ?? */ | ||
950 | disable_irq(hwif->irq); | ||
951 | /* local CPU only, | ||
952 | * as if we were handling an interrupt */ | ||
953 | local_irq_disable(); | ||
954 | if (hwif->polling) { | ||
955 | startstop = handler(drive); | ||
956 | } else if (drive_is_ready(drive)) { | ||
957 | if (drive->waiting_for_dma) | ||
958 | hwif->dma_ops->dma_lost_irq(drive); | ||
959 | (void)ide_ack_intr(hwif); | ||
960 | printk(KERN_WARNING "%s: lost interrupt\n", drive->name); | ||
961 | startstop = handler(drive); | ||
962 | } else { | ||
963 | if (drive->waiting_for_dma) { | ||
964 | startstop = ide_dma_timeout_retry(drive, wait); | ||
965 | } else | ||
966 | startstop = | ||
967 | ide_error(drive, "irq timeout", | ||
968 | hwif->tp_ops->read_status(hwif)); | ||
969 | } | ||
970 | spin_lock_irq(&hwif->lock); | ||
971 | enable_irq(hwif->irq); | ||
972 | if (startstop == ide_stopped) { | ||
973 | ide_unlock_port(hwif); | ||
974 | plug_device = 1; | ||
975 | } | 937 | } |
976 | } | 938 | } |
939 | hwif->handler = NULL; | ||
940 | /* | ||
941 | * We need to simulate a real interrupt when invoking | ||
942 | * the handler() function, which means we need to | ||
943 | * globally mask the specific IRQ: | ||
944 | */ | ||
945 | spin_unlock(&hwif->lock); | ||
946 | /* disable_irq_nosync ?? */ | ||
947 | disable_irq(hwif->irq); | ||
948 | /* local CPU only, as if we were handling an interrupt */ | ||
949 | local_irq_disable(); | ||
950 | if (hwif->polling) { | ||
951 | startstop = handler(drive); | ||
952 | } else if (drive_is_ready(drive)) { | ||
953 | if (drive->waiting_for_dma) | ||
954 | hwif->dma_ops->dma_lost_irq(drive); | ||
955 | (void)ide_ack_intr(hwif); | ||
956 | printk(KERN_WARNING "%s: lost interrupt\n", | ||
957 | drive->name); | ||
958 | startstop = handler(drive); | ||
959 | } else { | ||
960 | if (drive->waiting_for_dma) | ||
961 | startstop = ide_dma_timeout_retry(drive, wait); | ||
962 | else | ||
963 | startstop = ide_error(drive, "irq timeout", | ||
964 | hwif->tp_ops->read_status(hwif)); | ||
965 | } | ||
966 | spin_lock_irq(&hwif->lock); | ||
967 | enable_irq(hwif->irq); | ||
968 | if (startstop == ide_stopped) { | ||
969 | ide_unlock_port(hwif); | ||
970 | plug_device = 1; | ||
971 | } | ||
977 | } | 972 | } |
978 | spin_unlock_irqrestore(&hwif->lock, flags); | 973 | spin_unlock_irqrestore(&hwif->lock, flags); |
979 | 974 | ||
@@ -1115,15 +1110,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1115 | } | 1110 | } |
1116 | 1111 | ||
1117 | drive = hwif->cur_dev; | 1112 | drive = hwif->cur_dev; |
1118 | if (!drive) { | ||
1119 | /* | ||
1120 | * This should NEVER happen, and there isn't much | ||
1121 | * we could do about it here. | ||
1122 | * | ||
1123 | * [Note - this can occur if the drive is hot unplugged] | ||
1124 | */ | ||
1125 | goto out_handled; | ||
1126 | } | ||
1127 | 1113 | ||
1128 | if (!drive_is_ready(drive)) | 1114 | if (!drive_is_ready(drive)) |
1129 | /* | 1115 | /* |
@@ -1162,7 +1148,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1162 | ide_unlock_port(hwif); | 1148 | ide_unlock_port(hwif); |
1163 | plug_device = 1; | 1149 | plug_device = 1; |
1164 | } | 1150 | } |
1165 | out_handled: | ||
1166 | irq_ret = IRQ_HANDLED; | 1151 | irq_ret = IRQ_HANDLED; |
1167 | out: | 1152 | out: |
1168 | spin_unlock_irqrestore(&hwif->lock, flags); | 1153 | spin_unlock_irqrestore(&hwif->lock, flags); |