diff options
author | James Bottomley <James.Bottomley@steeleye.com> | 2006-01-10 13:11:42 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2006-01-12 12:49:07 -0500 |
commit | dacee84b070c4e705a5b6446f1f0a6a6e2f8d7a4 (patch) | |
tree | 795285f4124ce7687ed29557bbb5afd7e608213f /drivers/scsi/aic7xxx | |
parent | 8e0df4a757db82a571f3a179108b62d09258eaf2 (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>
Diffstat (limited to 'drivers/scsi/aic7xxx')
-rw-r--r-- | drivers/scsi/aic7xxx/Kconfig.aic7xxx | 4 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.c | 28 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.h | 25 |
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 | |||
42 | config AIC7XXX_RESET_DELAY_MS | 42 | config 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 | ||
53 | config AIC7XXX_PROBE_EISA_VL | 53 | config 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); |
376 | static void ahc_linux_sem_timeout(u_long arg); | 376 | static void ahc_linux_sem_timeout(u_long arg); |
377 | static void ahc_linux_freeze_simq(struct ahc_softc *ahc); | 377 | static void ahc_linux_freeze_simq(struct ahc_softc *ahc); |
378 | static void ahc_linux_release_simq(u_long arg); | 378 | static void ahc_linux_release_simq(struct ahc_softc *ahc); |
379 | static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); | 379 | static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); |
380 | static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); | 380 | static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); |
381 | static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, | 381 | static 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) | |||
2059 | static void | 2058 | static void |
2060 | ahc_linux_freeze_simq(struct ahc_softc *ahc) | 2059 | ahc_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 | ||
2073 | static void | 2076 | static void |
2074 | ahc_linux_release_simq(u_long arg) | 2077 | ahc_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 ******************************/ | ||
227 | typedef 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 | ||
240 | typedef void ahc_linux_callback_t (u_long); | ||
241 | static __inline void ahc_timer_reset(ahc_timer_t *timer, int usec, | ||
242 | ahc_callback_t *func, void *arg); | ||
243 | static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec); | ||
244 | |||
245 | static __inline void | ||
246 | ahc_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 | |||
258 | static __inline void | 235 | static __inline void |
259 | ahc_scb_timer_reset(struct scb *scb, u_int usec) | 236 | ahc_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) |