diff options
-rw-r--r-- | drivers/ide/ide-io.c | 67 | ||||
-rw-r--r-- | include/linux/ide.h | 7 |
2 files changed, 30 insertions, 44 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index ecacc008fdaf..23754bc5e595 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -778,8 +778,10 @@ repeat: | |||
778 | * the driver. This makes the driver much more friendlier to shared IRQs | 778 | * the driver. This makes the driver much more friendlier to shared IRQs |
779 | * than previous designs, while remaining 100% (?) SMP safe and capable. | 779 | * than previous designs, while remaining 100% (?) SMP safe and capable. |
780 | */ | 780 | */ |
781 | static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | 781 | void do_ide_request(struct request_queue *q) |
782 | { | 782 | { |
783 | ide_drive_t *orig_drive = q->queuedata; | ||
784 | ide_hwgroup_t *hwgroup = orig_drive->hwif->hwgroup; | ||
783 | ide_drive_t *drive; | 785 | ide_drive_t *drive; |
784 | ide_hwif_t *hwif; | 786 | ide_hwif_t *hwif; |
785 | struct request *rq; | 787 | struct request *rq; |
@@ -837,10 +839,14 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
837 | } | 839 | } |
838 | 840 | ||
839 | /* no more work for this hwgroup (for now) */ | 841 | /* no more work for this hwgroup (for now) */ |
840 | return; | 842 | goto plug_device; |
841 | } | 843 | } |
842 | again: | 844 | |
843 | hwif = HWIF(drive); | 845 | if (drive != orig_drive) |
846 | goto plug_device; | ||
847 | again: | ||
848 | hwif = drive->hwif; | ||
849 | |||
844 | if (hwif != hwgroup->hwif) { | 850 | if (hwif != hwgroup->hwif) { |
845 | /* | 851 | /* |
846 | * set nIEN for previous hwif, drives in the | 852 | * set nIEN for previous hwif, drives in the |
@@ -888,41 +894,26 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
888 | goto again; | 894 | goto again; |
889 | /* We clear busy, there should be no pending ATA command at this point. */ | 895 | /* We clear busy, there should be no pending ATA command at this point. */ |
890 | hwgroup->busy = 0; | 896 | hwgroup->busy = 0; |
891 | break; | 897 | goto plug_device; |
892 | } | 898 | } |
893 | 899 | ||
894 | hwgroup->rq = rq; | 900 | hwgroup->rq = rq; |
895 | 901 | ||
896 | /* | 902 | spin_unlock_irq(&hwgroup->lock); |
897 | * Some systems have trouble with IDE IRQs arriving while | ||
898 | * the driver is still setting things up. So, here we disable | ||
899 | * the IRQ used by this interface while the request is being started. | ||
900 | * This may look bad at first, but pretty much the same thing | ||
901 | * happens anyway when any interrupt comes in, IDE or otherwise | ||
902 | * -- the kernel masks the IRQ while it is being handled. | ||
903 | */ | ||
904 | if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) | ||
905 | disable_irq_nosync(hwif->irq); | ||
906 | spin_unlock(&hwgroup->lock); | ||
907 | local_irq_enable_in_hardirq(); | ||
908 | /* allow other IRQs while we start this request */ | ||
909 | startstop = start_request(drive, rq); | 903 | startstop = start_request(drive, rq); |
910 | spin_lock_irq(&hwgroup->lock); | 904 | spin_lock_irq(&hwgroup->lock); |
911 | if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) | 905 | |
912 | enable_irq(hwif->irq); | 906 | if (startstop == ide_stopped) { |
913 | if (startstop == ide_stopped) | ||
914 | hwgroup->busy = 0; | 907 | hwgroup->busy = 0; |
908 | if (!elv_queue_empty(orig_drive->queue)) | ||
909 | blk_plug_device(orig_drive->queue); | ||
910 | } | ||
915 | } | 911 | } |
916 | } | 912 | return; |
917 | 913 | ||
918 | /* | 914 | plug_device: |
919 | * Passes the stuff to ide_do_request | 915 | if (!elv_queue_empty(orig_drive->queue)) |
920 | */ | 916 | blk_plug_device(orig_drive->queue); |
921 | void do_ide_request(struct request_queue *q) | ||
922 | { | ||
923 | ide_drive_t *drive = q->queuedata; | ||
924 | |||
925 | ide_do_request(HWGROUP(drive), IDE_NO_IRQ); | ||
926 | } | 917 | } |
927 | 918 | ||
928 | /* | 919 | /* |
@@ -1074,11 +1065,13 @@ void ide_timer_expiry (unsigned long data) | |||
1074 | drive->service_time = jiffies - drive->service_start; | 1065 | drive->service_time = jiffies - drive->service_start; |
1075 | spin_lock_irq(&hwgroup->lock); | 1066 | spin_lock_irq(&hwgroup->lock); |
1076 | enable_irq(hwif->irq); | 1067 | enable_irq(hwif->irq); |
1077 | if (startstop == ide_stopped) | 1068 | if (startstop == ide_stopped) { |
1078 | hwgroup->busy = 0; | 1069 | hwgroup->busy = 0; |
1070 | if (!elv_queue_empty(drive->queue)) | ||
1071 | blk_plug_device(drive->queue); | ||
1072 | } | ||
1079 | } | 1073 | } |
1080 | } | 1074 | } |
1081 | ide_do_request(hwgroup, IDE_NO_IRQ); | ||
1082 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 1075 | spin_unlock_irqrestore(&hwgroup->lock, flags); |
1083 | } | 1076 | } |
1084 | 1077 | ||
@@ -1271,11 +1264,11 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1271 | if (startstop == ide_stopped) { | 1264 | if (startstop == ide_stopped) { |
1272 | if (hwgroup->handler == NULL) { /* paranoia */ | 1265 | if (hwgroup->handler == NULL) { /* paranoia */ |
1273 | hwgroup->busy = 0; | 1266 | hwgroup->busy = 0; |
1274 | ide_do_request(hwgroup, hwif->irq); | 1267 | if (!elv_queue_empty(drive->queue)) |
1275 | } else { | 1268 | blk_plug_device(drive->queue); |
1276 | printk(KERN_ERR "%s: ide_intr: huh? expected NULL handler " | 1269 | } else |
1277 | "on exit\n", drive->name); | 1270 | printk(KERN_ERR "%s: %s: huh? expected NULL handler " |
1278 | } | 1271 | "on exit\n", __func__, drive->name); |
1279 | } | 1272 | } |
1280 | out_handled: | 1273 | out_handled: |
1281 | irq_ret = IRQ_HANDLED; | 1274 | irq_ret = IRQ_HANDLED; |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 62fccaea3110..968ca8f60531 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -32,13 +32,6 @@ | |||
32 | # define SUPPORT_VLB_SYNC 1 | 32 | # define SUPPORT_VLB_SYNC 1 |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | /* | ||
36 | * Used to indicate "no IRQ", should be a value that cannot be an IRQ | ||
37 | * number. | ||
38 | */ | ||
39 | |||
40 | #define IDE_NO_IRQ (-1) | ||
41 | |||
42 | typedef unsigned char byte; /* used everywhere */ | 35 | typedef unsigned char byte; /* used everywhere */ |
43 | 36 | ||
44 | /* | 37 | /* |