aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-io.c32
-rw-r--r--drivers/ide/ide-park.c2
-rw-r--r--include/linux/ide.h20
3 files changed, 32 insertions, 22 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index c60512196f61..ab480042757a 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -790,10 +790,7 @@ void do_ide_request(struct request_queue *q)
790 /* caller must own hwgroup->lock */ 790 /* caller must own hwgroup->lock */
791 BUG_ON(!irqs_disabled()); 791 BUG_ON(!irqs_disabled());
792 792
793 while (!hwgroup->busy) { 793 while (!ide_lock_hwgroup(hwgroup)) {
794 hwgroup->busy = 1;
795 /* for atari only */
796 ide_get_lock(ide_intr, hwgroup);
797 drive = choose_drive(hwgroup); 794 drive = choose_drive(hwgroup);
798 if (drive == NULL) { 795 if (drive == NULL) {
799 int sleeping = 0; 796 int sleeping = 0;
@@ -825,17 +822,10 @@ void do_ide_request(struct request_queue *q)
825 hwgroup->sleeping = 1; 822 hwgroup->sleeping = 1;
826 hwgroup->req_gen_timer = hwgroup->req_gen; 823 hwgroup->req_gen_timer = hwgroup->req_gen;
827 mod_timer(&hwgroup->timer, sleep); 824 mod_timer(&hwgroup->timer, sleep);
828 /* we purposely leave hwgroup->busy==1 825 /* we purposely leave hwgroup locked
829 * while sleeping */ 826 * while sleeping */
830 } else { 827 } else
831 /* Ugly, but how can we sleep for the lock 828 ide_unlock_hwgroup(hwgroup);
832 * otherwise? perhaps from tq_disk?
833 */
834
835 /* for atari only */
836 ide_release_lock();
837 hwgroup->busy = 0;
838 }
839 829
840 /* no more work for this hwgroup (for now) */ 830 /* no more work for this hwgroup (for now) */
841 goto plug_device; 831 goto plug_device;
@@ -865,7 +855,7 @@ void do_ide_request(struct request_queue *q)
865 */ 855 */
866 rq = elv_next_request(drive->queue); 856 rq = elv_next_request(drive->queue);
867 if (!rq) { 857 if (!rq) {
868 hwgroup->busy = 0; 858 ide_unlock_hwgroup(hwgroup);
869 break; 859 break;
870 } 860 }
871 861
@@ -885,8 +875,8 @@ void do_ide_request(struct request_queue *q)
885 if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && 875 if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
886 blk_pm_request(rq) == 0 && 876 blk_pm_request(rq) == 0 &&
887 (rq->cmd_flags & REQ_PREEMPT) == 0) { 877 (rq->cmd_flags & REQ_PREEMPT) == 0) {
888 /* We clear busy, there should be no pending ATA command at this point. */ 878 /* there should be no pending command at this point */
889 hwgroup->busy = 0; 879 ide_unlock_hwgroup(hwgroup);
890 goto plug_device; 880 goto plug_device;
891 } 881 }
892 882
@@ -897,7 +887,7 @@ void do_ide_request(struct request_queue *q)
897 spin_lock_irq(&hwgroup->lock); 887 spin_lock_irq(&hwgroup->lock);
898 888
899 if (startstop == ide_stopped) { 889 if (startstop == ide_stopped) {
900 hwgroup->busy = 0; 890 ide_unlock_hwgroup(hwgroup);
901 if (!elv_queue_empty(orig_drive->queue)) 891 if (!elv_queue_empty(orig_drive->queue))
902 blk_plug_device(orig_drive->queue); 892 blk_plug_device(orig_drive->queue);
903 } 893 }
@@ -1001,7 +991,7 @@ void ide_timer_expiry (unsigned long data)
1001 */ 991 */
1002 if (hwgroup->sleeping) { 992 if (hwgroup->sleeping) {
1003 hwgroup->sleeping = 0; 993 hwgroup->sleeping = 0;
1004 hwgroup->busy = 0; 994 ide_unlock_hwgroup(hwgroup);
1005 } 995 }
1006 } else { 996 } else {
1007 ide_drive_t *drive = hwgroup->drive; 997 ide_drive_t *drive = hwgroup->drive;
@@ -1056,7 +1046,7 @@ void ide_timer_expiry (unsigned long data)
1056 spin_lock_irq(&hwgroup->lock); 1046 spin_lock_irq(&hwgroup->lock);
1057 enable_irq(hwif->irq); 1047 enable_irq(hwif->irq);
1058 if (startstop == ide_stopped) { 1048 if (startstop == ide_stopped) {
1059 hwgroup->busy = 0; 1049 ide_unlock_hwgroup(hwgroup);
1060 if (!elv_queue_empty(drive->queue)) 1050 if (!elv_queue_empty(drive->queue))
1061 blk_plug_device(drive->queue); 1051 blk_plug_device(drive->queue);
1062 } 1052 }
@@ -1249,7 +1239,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
1249 drive->service_time = jiffies - drive->service_start; 1239 drive->service_time = jiffies - drive->service_start;
1250 if (startstop == ide_stopped) { 1240 if (startstop == ide_stopped) {
1251 if (hwgroup->handler == NULL) { /* paranoia */ 1241 if (hwgroup->handler == NULL) { /* paranoia */
1252 hwgroup->busy = 0; 1242 ide_unlock_hwgroup(hwgroup);
1253 if (!elv_queue_empty(drive->queue)) 1243 if (!elv_queue_empty(drive->queue))
1254 blk_plug_device(drive->queue); 1244 blk_plug_device(drive->queue);
1255 } else 1245 } else
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index 63d01c55f865..44c6787f8aeb 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -22,7 +22,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
22 if (reset_timer && hwgroup->sleeping && 22 if (reset_timer && hwgroup->sleeping &&
23 del_timer(&hwgroup->timer)) { 23 del_timer(&hwgroup->timer)) {
24 hwgroup->sleeping = 0; 24 hwgroup->sleeping = 0;
25 hwgroup->busy = 0; 25 ide_unlock_hwgroup(hwgroup);
26 blk_start_queueing(q); 26 blk_start_queueing(q);
27 } 27 }
28 spin_unlock_irq(&hwgroup->lock); 28 spin_unlock_irq(&hwgroup->lock);
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 968ca8f60531..f408d6123f14 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1280,6 +1280,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
1280 1280
1281extern void ide_timer_expiry(unsigned long); 1281extern void ide_timer_expiry(unsigned long);
1282extern irqreturn_t ide_intr(int irq, void *dev_id); 1282extern irqreturn_t ide_intr(int irq, void *dev_id);
1283
1284static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup)
1285{
1286 if (hwgroup->busy)
1287 return 1;
1288
1289 hwgroup->busy = 1;
1290 /* for atari only */
1291 ide_get_lock(ide_intr, hwgroup);
1292
1293 return 0;
1294}
1295
1296static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)
1297{
1298 /* for atari only */
1299 ide_release_lock();
1300 hwgroup->busy = 0;
1301}
1302
1283extern void do_ide_request(struct request_queue *); 1303extern void do_ide_request(struct request_queue *);
1284 1304
1285void ide_init_disk(struct gendisk *, ide_drive_t *); 1305void ide_init_disk(struct gendisk *, ide_drive_t *);