aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic7xxx/aic79xx_osm.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2006-01-30 10:10:31 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2006-01-31 15:39:50 -0500
commiteb221849540b7f4165c58b6c79d98b97ac902fdb (patch)
tree606f04871288b2b062f52fe2804e9320aa924644 /drivers/scsi/aic7xxx/aic79xx_osm.c
parentd60256b1b3ceb79cb06a5dd5e259b23bd27d4c61 (diff)
[SCSI] aic79xx: Fix timer handling
Fix the timer handling in aic79xx to use the SCSI-ML provided handling instead of implementing our own. It also fixes a deadlock in the command recovery code. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aic7xxx/aic79xx_osm.c')
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 815c06312c88..7254ea535a16 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -1089,7 +1089,6 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa
1089 return (ENOMEM); 1089 return (ENOMEM);
1090 1090
1091 *((struct ahd_softc **)host->hostdata) = ahd; 1091 *((struct ahd_softc **)host->hostdata) = ahd;
1092 ahd_lock(ahd, &s);
1093 ahd->platform_data->host = host; 1092 ahd->platform_data->host = host;
1094 host->can_queue = AHD_MAX_QUEUE; 1093 host->can_queue = AHD_MAX_QUEUE;
1095 host->cmd_per_lun = 2; 1094 host->cmd_per_lun = 2;
@@ -1100,7 +1099,9 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa
1100 host->max_lun = AHD_NUM_LUNS; 1099 host->max_lun = AHD_NUM_LUNS;
1101 host->max_channel = 0; 1100 host->max_channel = 0;
1102 host->sg_tablesize = AHD_NSEG; 1101 host->sg_tablesize = AHD_NSEG;
1102 ahd_lock(ahd, &s);
1103 ahd_set_unit(ahd, ahd_linux_unit++); 1103 ahd_set_unit(ahd, ahd_linux_unit++);
1104 ahd_unlock(ahd, &s);
1104 sprintf(buf, "scsi%d", host->host_no); 1105 sprintf(buf, "scsi%d", host->host_no);
1105 new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); 1106 new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
1106 if (new_name != NULL) { 1107 if (new_name != NULL) {
@@ -1110,7 +1111,6 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa
1110 host->unique_id = ahd->unit; 1111 host->unique_id = ahd->unit;
1111 ahd_linux_initialize_scsi_bus(ahd); 1112 ahd_linux_initialize_scsi_bus(ahd);
1112 ahd_intr_enable(ahd, TRUE); 1113 ahd_intr_enable(ahd, TRUE);
1113 ahd_unlock(ahd, &s);
1114 1114
1115 host->transportt = ahd_linux_transport_template; 1115 host->transportt = ahd_linux_transport_template;
1116 1116
@@ -1144,6 +1144,7 @@ ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd)
1144{ 1144{
1145 u_int target_id; 1145 u_int target_id;
1146 u_int numtarg; 1146 u_int numtarg;
1147 unsigned long s;
1147 1148
1148 target_id = 0; 1149 target_id = 0;
1149 numtarg = 0; 1150 numtarg = 0;
@@ -1156,6 +1157,8 @@ ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd)
1156 else 1157 else
1157 numtarg = (ahd->features & AHD_WIDE) ? 16 : 8; 1158 numtarg = (ahd->features & AHD_WIDE) ? 16 : 8;
1158 1159
1160 ahd_lock(ahd, &s);
1161
1159 /* 1162 /*
1160 * Force negotiation to async for all targets that 1163 * Force negotiation to async for all targets that
1161 * will not see an initial bus reset. 1164 * will not see an initial bus reset.
@@ -1172,16 +1175,12 @@ ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd)
1172 ahd_update_neg_request(ahd, &devinfo, tstate, 1175 ahd_update_neg_request(ahd, &devinfo, tstate,
1173 tinfo, AHD_NEG_ALWAYS); 1176 tinfo, AHD_NEG_ALWAYS);
1174 } 1177 }
1178 ahd_unlock(ahd, &s);
1175 /* Give the bus some time to recover */ 1179 /* Give the bus some time to recover */
1176 if ((ahd->flags & AHD_RESET_BUS_A) != 0) { 1180 if ((ahd->flags & AHD_RESET_BUS_A) != 0) {
1177 ahd_freeze_simq(ahd); 1181 ahd_freeze_simq(ahd);
1178 init_timer(&ahd->platform_data->reset_timer); 1182 msleep(AIC79XX_RESET_DELAY);
1179 ahd->platform_data->reset_timer.data = (u_long)ahd; 1183 ahd_release_simq(ahd);
1180 ahd->platform_data->reset_timer.expires =
1181 jiffies + (AIC79XX_RESET_DELAY * HZ)/1000;
1182 ahd->platform_data->reset_timer.function =
1183 (ahd_linux_callback_t *)ahd_release_simq;
1184 add_timer(&ahd->platform_data->reset_timer);
1185 } 1184 }
1186} 1185}
1187 1186
@@ -2050,6 +2049,9 @@ ahd_linux_sem_timeout(u_long arg)
2050void 2049void
2051ahd_freeze_simq(struct ahd_softc *ahd) 2050ahd_freeze_simq(struct ahd_softc *ahd)
2052{ 2051{
2052 unsigned long s;
2053
2054 ahd_lock(ahd, &s);
2053 ahd->platform_data->qfrozen++; 2055 ahd->platform_data->qfrozen++;
2054 if (ahd->platform_data->qfrozen == 1) { 2056 if (ahd->platform_data->qfrozen == 1) {
2055 scsi_block_requests(ahd->platform_data->host); 2057 scsi_block_requests(ahd->platform_data->host);
@@ -2057,6 +2059,7 @@ ahd_freeze_simq(struct ahd_softc *ahd)
2057 CAM_LUN_WILDCARD, SCB_LIST_NULL, 2059 CAM_LUN_WILDCARD, SCB_LIST_NULL,
2058 ROLE_INITIATOR, CAM_REQUEUE_REQ); 2060 ROLE_INITIATOR, CAM_REQUEUE_REQ);
2059 } 2061 }
2062 ahd_unlock(ahd, &s);
2060} 2063}
2061 2064
2062void 2065void
@@ -2361,8 +2364,9 @@ done:
2361 ahd_name(ahd), dev->active); 2364 ahd_name(ahd), dev->active);
2362 retval = FAILED; 2365 retval = FAILED;
2363 } 2366 }
2364 } 2367 } else
2365 ahd_unlock(ahd, &flags); 2368 ahd_unlock(ahd, &flags);
2369
2366 return (retval); 2370 return (retval);
2367} 2371}
2368 2372