aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-io.c67
-rw-r--r--include/linux/ide.h7
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 */
781static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) 781void 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;
847again:
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/* 914plug_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);
921void 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 }
1280out_handled: 1273out_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
42typedef unsigned char byte; /* used everywhere */ 35typedef unsigned char byte; /* used everywhere */
43 36
44/* 37/*