diff options
Diffstat (limited to 'drivers/scsi/aha152x.c')
-rw-r--r-- | drivers/scsi/aha152x.c | 50 |
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 | */ |
552 | struct aha152x_scdata { | 552 | struct 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 | */ |
972 | static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, void (*done)(Scsi_Cmnd *)) | 972 | static 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 | ||
1142 | static 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) | |||
1161 | static int aha152x_device_reset(Scsi_Cmnd * SCpnt) | 1147 | static 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; |