aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2006-01-10 13:11:42 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2006-01-12 12:49:07 -0500
commitdacee84b070c4e705a5b6446f1f0a6a6e2f8d7a4 (patch)
tree795285f4124ce7687ed29557bbb5afd7e608213f
parent8e0df4a757db82a571f3a179108b62d09258eaf2 (diff)
[SCSI] aic7xxx: fix timer handling bug
The driver is doing a rather stupid mod_timer allegedly to "give request sense more time to complete". This is illegal and pointless, so just eliminate it. Also eliminate all the other uses of struct timer_list in the driver, which are mostly bogus. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/aic7xxx/Kconfig.aic7xxx4
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c28
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h25
3 files changed, 16 insertions, 41 deletions
diff --git a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
index ac8de03c9fa2..6c2c395554ff 100644
--- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx
+++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx
@@ -42,13 +42,13 @@ config AIC7XXX_CMDS_PER_DEVICE
42config AIC7XXX_RESET_DELAY_MS 42config AIC7XXX_RESET_DELAY_MS
43 int "Initial bus reset delay in milli-seconds" 43 int "Initial bus reset delay in milli-seconds"
44 depends on SCSI_AIC7XXX 44 depends on SCSI_AIC7XXX
45 default "15000" 45 default "5000"
46 ---help--- 46 ---help---
47 The number of milliseconds to delay after an initial bus reset. 47 The number of milliseconds to delay after an initial bus reset.
48 The bus settle delay following all error recovery actions is 48 The bus settle delay following all error recovery actions is
49 dictated by the SCSI layer and is not affected by this value. 49 dictated by the SCSI layer and is not affected by this value.
50 50
51 Default: 15000 (15 seconds) 51 Default: 5000 (5 seconds)
52 52
53config AIC7XXX_PROBE_EISA_VL 53config AIC7XXX_PROBE_EISA_VL
54 bool "Probe for EISA and VL AIC7XXX Adapters" 54 bool "Probe for EISA and VL AIC7XXX Adapters"
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index fd389e9f9460..051970efba68 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -375,7 +375,7 @@ static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
375 struct scsi_cmnd *cmd); 375 struct scsi_cmnd *cmd);
376static void ahc_linux_sem_timeout(u_long arg); 376static void ahc_linux_sem_timeout(u_long arg);
377static void ahc_linux_freeze_simq(struct ahc_softc *ahc); 377static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
378static void ahc_linux_release_simq(u_long arg); 378static void ahc_linux_release_simq(struct ahc_softc *ahc);
379static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); 379static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
380static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); 380static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
381static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, 381static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
@@ -1073,7 +1073,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
1073 return (ENOMEM); 1073 return (ENOMEM);
1074 1074
1075 *((struct ahc_softc **)host->hostdata) = ahc; 1075 *((struct ahc_softc **)host->hostdata) = ahc;
1076 ahc_lock(ahc, &s);
1077 ahc->platform_data->host = host; 1076 ahc->platform_data->host = host;
1078 host->can_queue = AHC_MAX_QUEUE; 1077 host->can_queue = AHC_MAX_QUEUE;
1079 host->cmd_per_lun = 2; 1078 host->cmd_per_lun = 2;
@@ -1084,7 +1083,9 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
1084 host->max_lun = AHC_NUM_LUNS; 1083 host->max_lun = AHC_NUM_LUNS;
1085 host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0; 1084 host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
1086 host->sg_tablesize = AHC_NSEG; 1085 host->sg_tablesize = AHC_NSEG;
1086 ahc_lock(ahc, &s);
1087 ahc_set_unit(ahc, ahc_linux_unit++); 1087 ahc_set_unit(ahc, ahc_linux_unit++);
1088 ahc_unlock(ahc, &s);
1088 sprintf(buf, "scsi%d", host->host_no); 1089 sprintf(buf, "scsi%d", host->host_no);
1089 new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); 1090 new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
1090 if (new_name != NULL) { 1091 if (new_name != NULL) {
@@ -1094,7 +1095,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
1094 host->unique_id = ahc->unit; 1095 host->unique_id = ahc->unit;
1095 ahc_linux_initialize_scsi_bus(ahc); 1096 ahc_linux_initialize_scsi_bus(ahc);
1096 ahc_intr_enable(ahc, TRUE); 1097 ahc_intr_enable(ahc, TRUE);
1097 ahc_unlock(ahc, &s);
1098 1098
1099 host->transportt = ahc_linux_transport_template; 1099 host->transportt = ahc_linux_transport_template;
1100 1100
@@ -1120,10 +1120,13 @@ ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
1120{ 1120{
1121 int i; 1121 int i;
1122 int numtarg; 1122 int numtarg;
1123 unsigned long s;
1123 1124
1124 i = 0; 1125 i = 0;
1125 numtarg = 0; 1126 numtarg = 0;
1126 1127
1128 ahc_lock(ahc, &s);
1129
1127 if (aic7xxx_no_reset != 0) 1130 if (aic7xxx_no_reset != 0)
1128 ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B); 1131 ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B);
1129 1132
@@ -1170,16 +1173,12 @@ ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
1170 ahc_update_neg_request(ahc, &devinfo, tstate, 1173 ahc_update_neg_request(ahc, &devinfo, tstate,
1171 tinfo, AHC_NEG_ALWAYS); 1174 tinfo, AHC_NEG_ALWAYS);
1172 } 1175 }
1176 ahc_unlock(ahc, &s);
1173 /* Give the bus some time to recover */ 1177 /* Give the bus some time to recover */
1174 if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) { 1178 if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
1175 ahc_linux_freeze_simq(ahc); 1179 ahc_linux_freeze_simq(ahc);
1176 init_timer(&ahc->platform_data->reset_timer); 1180 msleep(AIC7XXX_RESET_DELAY);
1177 ahc->platform_data->reset_timer.data = (u_long)ahc; 1181 ahc_linux_release_simq(ahc);
1178 ahc->platform_data->reset_timer.expires =
1179 jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000;
1180 ahc->platform_data->reset_timer.function =
1181 ahc_linux_release_simq;
1182 add_timer(&ahc->platform_data->reset_timer);
1183 } 1182 }
1184} 1183}
1185 1184
@@ -2059,6 +2058,9 @@ ahc_linux_sem_timeout(u_long arg)
2059static void 2058static void
2060ahc_linux_freeze_simq(struct ahc_softc *ahc) 2059ahc_linux_freeze_simq(struct ahc_softc *ahc)
2061{ 2060{
2061 unsigned long s;
2062
2063 ahc_lock(ahc, &s);
2062 ahc->platform_data->qfrozen++; 2064 ahc->platform_data->qfrozen++;
2063 if (ahc->platform_data->qfrozen == 1) { 2065 if (ahc->platform_data->qfrozen == 1) {
2064 scsi_block_requests(ahc->platform_data->host); 2066 scsi_block_requests(ahc->platform_data->host);
@@ -2068,17 +2070,15 @@ ahc_linux_freeze_simq(struct ahc_softc *ahc)
2068 CAM_LUN_WILDCARD, SCB_LIST_NULL, 2070 CAM_LUN_WILDCARD, SCB_LIST_NULL,
2069 ROLE_INITIATOR, CAM_REQUEUE_REQ); 2071 ROLE_INITIATOR, CAM_REQUEUE_REQ);
2070 } 2072 }
2073 ahc_unlock(ahc, &s);
2071} 2074}
2072 2075
2073static void 2076static void
2074ahc_linux_release_simq(u_long arg) 2077ahc_linux_release_simq(struct ahc_softc *ahc)
2075{ 2078{
2076 struct ahc_softc *ahc;
2077 u_long s; 2079 u_long s;
2078 int unblock_reqs; 2080 int unblock_reqs;
2079 2081
2080 ahc = (struct ahc_softc *)arg;
2081
2082 unblock_reqs = 0; 2082 unblock_reqs = 0;
2083 ahc_lock(ahc, &s); 2083 ahc_lock(ahc, &s);
2084 if (ahc->platform_data->qfrozen > 0) 2084 if (ahc->platform_data->qfrozen > 0)
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index f2a95447142c..e0edacae895f 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -223,9 +223,6 @@ int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t);
223 */ 223 */
224#define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op) 224#define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op)
225 225
226/************************** Timer DataStructures ******************************/
227typedef struct timer_list ahc_timer_t;
228
229/********************************** Includes **********************************/ 226/********************************** Includes **********************************/
230#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT 227#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT
231#define AIC_DEBUG_REGISTERS 1 228#define AIC_DEBUG_REGISTERS 1
@@ -235,30 +232,9 @@ typedef struct timer_list ahc_timer_t;
235#include "aic7xxx.h" 232#include "aic7xxx.h"
236 233
237/***************************** Timer Facilities *******************************/ 234/***************************** Timer Facilities *******************************/
238#define ahc_timer_init init_timer
239#define ahc_timer_stop del_timer_sync
240typedef void ahc_linux_callback_t (u_long);
241static __inline void ahc_timer_reset(ahc_timer_t *timer, int usec,
242 ahc_callback_t *func, void *arg);
243static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec);
244
245static __inline void
246ahc_timer_reset(ahc_timer_t *timer, int usec, ahc_callback_t *func, void *arg)
247{
248 struct ahc_softc *ahc;
249
250 ahc = (struct ahc_softc *)arg;
251 del_timer(timer);
252 timer->data = (u_long)arg;
253 timer->expires = jiffies + (usec * HZ)/1000000;
254 timer->function = (ahc_linux_callback_t*)func;
255 add_timer(timer);
256}
257
258static __inline void 235static __inline void
259ahc_scb_timer_reset(struct scb *scb, u_int usec) 236ahc_scb_timer_reset(struct scb *scb, u_int usec)
260{ 237{
261 mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000);
262} 238}
263 239
264/***************************** SMP support ************************************/ 240/***************************** SMP support ************************************/
@@ -393,7 +369,6 @@ struct ahc_platform_data {
393 369
394 spinlock_t spin_lock; 370 spinlock_t spin_lock;
395 u_int qfrozen; 371 u_int qfrozen;
396 struct timer_list reset_timer;
397 struct semaphore eh_sem; 372 struct semaphore eh_sem;
398 struct Scsi_Host *host; /* pointer to scsi host */ 373 struct Scsi_Host *host; /* pointer to scsi host */
399#define AHC_LINUX_NOIRQ ((uint32_t)~0) 374#define AHC_LINUX_NOIRQ ((uint32_t)~0)