aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aha152x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aha152x.c')
-rw-r--r--drivers/scsi/aha152x.c50
1 files changed, 18 insertions, 32 deletions
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 4b4d1233ce8a..85f2394ffc3e 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -240,6 +240,7 @@
240#include <linux/io.h> 240#include <linux/io.h>
241#include <linux/blkdev.h> 241#include <linux/blkdev.h>
242#include <asm/system.h> 242#include <asm/system.h>
243#include <linux/completion.h>
243#include <linux/errno.h> 244#include <linux/errno.h>
244#include <linux/string.h> 245#include <linux/string.h>
245#include <linux/wait.h> 246#include <linux/wait.h>
@@ -253,7 +254,6 @@
253#include <linux/spinlock.h> 254#include <linux/spinlock.h>
254#include <linux/workqueue.h> 255#include <linux/workqueue.h>
255#include <linux/list.h> 256#include <linux/list.h>
256#include <asm/semaphore.h>
257#include <scsi/scsicam.h> 257#include <scsi/scsicam.h>
258 258
259#include "scsi.h" 259#include "scsi.h"
@@ -551,7 +551,7 @@ struct aha152x_hostdata {
551 */ 551 */
552struct aha152x_scdata { 552struct aha152x_scdata {
553 Scsi_Cmnd *next; /* next sc in queue */ 553 Scsi_Cmnd *next; /* next sc in queue */
554 struct semaphore *sem; /* semaphore to block on */ 554 struct completion *done;/* semaphore to block on */
555 unsigned char cmd_len; 555 unsigned char cmd_len;
556 unsigned char cmnd[MAX_COMMAND_SIZE]; 556 unsigned char cmnd[MAX_COMMAND_SIZE];
557 unsigned short use_sg; 557 unsigned short use_sg;
@@ -608,7 +608,7 @@ struct aha152x_scdata {
608 608
609#define SCDATA(SCpnt) ((struct aha152x_scdata *) (SCpnt)->host_scribble) 609#define SCDATA(SCpnt) ((struct aha152x_scdata *) (SCpnt)->host_scribble)
610#define SCNEXT(SCpnt) SCDATA(SCpnt)->next 610#define SCNEXT(SCpnt) SCDATA(SCpnt)->next
611#define SCSEM(SCpnt) SCDATA(SCpnt)->sem 611#define SCSEM(SCpnt) SCDATA(SCpnt)->done
612 612
613#define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page)+(buffer)->offset)) 613#define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page)+(buffer)->offset))
614 614
@@ -969,7 +969,8 @@ static int setup_expected_interrupts(struct Scsi_Host *shpnt)
969/* 969/*
970 * Queue a command and setup interrupts for a free bus. 970 * Queue a command and setup interrupts for a free bus.
971 */ 971 */
972static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, void (*done)(Scsi_Cmnd *)) 972static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete,
973 int phase, void (*done)(Scsi_Cmnd *))
973{ 974{
974 struct Scsi_Host *shpnt = SCpnt->device->host; 975 struct Scsi_Host *shpnt = SCpnt->device->host;
975 unsigned long flags; 976 unsigned long flags;
@@ -1013,7 +1014,7 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int p
1013 } 1014 }
1014 1015
1015 SCNEXT(SCpnt) = NULL; 1016 SCNEXT(SCpnt) = NULL;
1016 SCSEM(SCpnt) = sem; 1017 SCSEM(SCpnt) = complete;
1017 1018
1018 /* setup scratch area 1019 /* setup scratch area
1019 SCp.ptr : buffer pointer 1020 SCp.ptr : buffer pointer
@@ -1084,9 +1085,9 @@ static void reset_done(Scsi_Cmnd *SCpnt)
1084 DPRINTK(debug_eh, INFO_LEAD "reset_done called\n", CMDINFO(SCpnt)); 1085 DPRINTK(debug_eh, INFO_LEAD "reset_done called\n", CMDINFO(SCpnt));
1085#endif 1086#endif
1086 if(SCSEM(SCpnt)) { 1087 if(SCSEM(SCpnt)) {
1087 up(SCSEM(SCpnt)); 1088 complete(SCSEM(SCpnt));
1088 } else { 1089 } else {
1089 printk(KERN_ERR "aha152x: reset_done w/o semaphore\n"); 1090 printk(KERN_ERR "aha152x: reset_done w/o completion\n");
1090 } 1091 }
1091} 1092}
1092 1093
@@ -1139,21 +1140,6 @@ static int aha152x_abort(Scsi_Cmnd *SCpnt)
1139 return FAILED; 1140 return FAILED;
1140} 1141}
1141 1142
1142static void timer_expired(unsigned long p)
1143{
1144 Scsi_Cmnd *SCp = (Scsi_Cmnd *)p;
1145 struct semaphore *sem = SCSEM(SCp);
1146 struct Scsi_Host *shpnt = SCp->device->host;
1147 unsigned long flags;
1148
1149 /* remove command from issue queue */
1150 DO_LOCK(flags);
1151 remove_SC(&ISSUE_SC, SCp);
1152 DO_UNLOCK(flags);
1153
1154 up(sem);
1155}
1156
1157/* 1143/*
1158 * Reset a device 1144 * Reset a device
1159 * 1145 *
@@ -1161,14 +1147,14 @@ static void timer_expired(unsigned long p)
1161static int aha152x_device_reset(Scsi_Cmnd * SCpnt) 1147static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
1162{ 1148{
1163 struct Scsi_Host *shpnt = SCpnt->device->host; 1149 struct Scsi_Host *shpnt = SCpnt->device->host;
1164 DECLARE_MUTEX_LOCKED(sem); 1150 DECLARE_COMPLETION(done);
1165 struct timer_list timer;
1166 int ret, issued, disconnected; 1151 int ret, issued, disconnected;
1167 unsigned char old_cmd_len = SCpnt->cmd_len; 1152 unsigned char old_cmd_len = SCpnt->cmd_len;
1168 unsigned short old_use_sg = SCpnt->use_sg; 1153 unsigned short old_use_sg = SCpnt->use_sg;
1169 void *old_buffer = SCpnt->request_buffer; 1154 void *old_buffer = SCpnt->request_buffer;
1170 unsigned old_bufflen = SCpnt->request_bufflen; 1155 unsigned old_bufflen = SCpnt->request_bufflen;
1171 unsigned long flags; 1156 unsigned long flags;
1157 unsigned long timeleft;
1172 1158
1173#if defined(AHA152X_DEBUG) 1159#if defined(AHA152X_DEBUG)
1174 if(HOSTDATA(shpnt)->debug & debug_eh) { 1160 if(HOSTDATA(shpnt)->debug & debug_eh) {
@@ -1192,15 +1178,15 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
1192 SCpnt->request_buffer = NULL; 1178 SCpnt->request_buffer = NULL;
1193 SCpnt->request_bufflen = 0; 1179 SCpnt->request_bufflen = 0;
1194 1180
1195 init_timer(&timer); 1181 aha152x_internal_queue(SCpnt, &done, resetting, reset_done);
1196 timer.data = (unsigned long) SCpnt;
1197 timer.expires = jiffies + 100*HZ; /* 10s */
1198 timer.function = (void (*)(unsigned long)) timer_expired;
1199 1182
1200 aha152x_internal_queue(SCpnt, &sem, resetting, reset_done); 1183 timeleft = wait_for_completion_timeout(&done, 100*HZ);
1201 add_timer(&timer); 1184 if (!timeleft) {
1202 down(&sem); 1185 /* remove command from issue queue */
1203 del_timer(&timer); 1186 DO_LOCK(flags);
1187 remove_SC(&ISSUE_SC, SCpnt);
1188 DO_UNLOCK(flags);
1189 }
1204 1190
1205 SCpnt->cmd_len = old_cmd_len; 1191 SCpnt->cmd_len = old_cmd_len;
1206 SCpnt->use_sg = old_use_sg; 1192 SCpnt->use_sg = old_use_sg;