diff options
author | Harihara Kadayam <harihara.kadayam@qlogic.com> | 2008-04-03 16:13:26 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-07 13:19:15 -0400 |
commit | 4d4df1932b6b116aecc81039066fec27f2050762 (patch) | |
tree | ee02f449a0bb456e40fcdb5287609b98e8e8f62f /drivers/scsi/qla2xxx/qla_init.c | |
parent | b93480e319654b8921364b49528532dff4822a45 (diff) |
[SCSI] qla2xxx: Add ISP84XX support.
Signed-off-by: Ravi Anand <ravi.anand@qlogic.com>
Additional cleanups and
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 119 |
1 files changed, 111 insertions, 8 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 10e6995b39a7..916462ef1966 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -37,6 +37,9 @@ static int qla2x00_restart_isp(scsi_qla_host_t *); | |||
37 | 37 | ||
38 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); | 38 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); |
39 | 39 | ||
40 | static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *); | ||
41 | static int qla84xx_init_chip(scsi_qla_host_t *); | ||
42 | |||
40 | /****************************************************************************/ | 43 | /****************************************************************************/ |
41 | /* QLogic ISP2x00 Hardware Support Functions. */ | 44 | /* QLogic ISP2x00 Hardware Support Functions. */ |
42 | /****************************************************************************/ | 45 | /****************************************************************************/ |
@@ -108,6 +111,14 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
108 | return (rval); | 111 | return (rval); |
109 | qla2xxx_get_flash_info(ha); | 112 | qla2xxx_get_flash_info(ha); |
110 | } | 113 | } |
114 | if (IS_QLA84XX(ha)) { | ||
115 | ha->cs84xx = qla84xx_get_chip(ha); | ||
116 | if (!ha->cs84xx) { | ||
117 | qla_printk(KERN_ERR, ha, | ||
118 | "Unable to configure ISP84XX.\n"); | ||
119 | return QLA_FUNCTION_FAILED; | ||
120 | } | ||
121 | } | ||
111 | rval = qla2x00_init_rings(ha); | 122 | rval = qla2x00_init_rings(ha); |
112 | 123 | ||
113 | return (rval); | 124 | return (rval); |
@@ -1243,10 +1254,10 @@ static int | |||
1243 | qla2x00_fw_ready(scsi_qla_host_t *ha) | 1254 | qla2x00_fw_ready(scsi_qla_host_t *ha) |
1244 | { | 1255 | { |
1245 | int rval; | 1256 | int rval; |
1246 | unsigned long wtime, mtime; | 1257 | unsigned long wtime, mtime, cs84xx_time; |
1247 | uint16_t min_wait; /* Minimum wait time if loop is down */ | 1258 | uint16_t min_wait; /* Minimum wait time if loop is down */ |
1248 | uint16_t wait_time; /* Wait time if loop is coming ready */ | 1259 | uint16_t wait_time; /* Wait time if loop is coming ready */ |
1249 | uint16_t fw_state; | 1260 | uint16_t state[3]; |
1250 | 1261 | ||
1251 | rval = QLA_SUCCESS; | 1262 | rval = QLA_SUCCESS; |
1252 | 1263 | ||
@@ -1275,12 +1286,34 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1275 | ha->host_no)); | 1286 | ha->host_no)); |
1276 | 1287 | ||
1277 | do { | 1288 | do { |
1278 | rval = qla2x00_get_firmware_state(ha, &fw_state); | 1289 | rval = qla2x00_get_firmware_state(ha, state); |
1279 | if (rval == QLA_SUCCESS) { | 1290 | if (rval == QLA_SUCCESS) { |
1280 | if (fw_state < FSTATE_LOSS_OF_SYNC) { | 1291 | if (state[0] < FSTATE_LOSS_OF_SYNC) { |
1281 | ha->device_flags &= ~DFLG_NO_CABLE; | 1292 | ha->device_flags &= ~DFLG_NO_CABLE; |
1282 | } | 1293 | } |
1283 | if (fw_state == FSTATE_READY) { | 1294 | if (IS_QLA84XX(ha) && state[0] != FSTATE_READY) { |
1295 | DEBUG16(printk("scsi(%ld): fw_state=%x " | ||
1296 | "84xx=%x.\n", ha->host_no, state[0], | ||
1297 | state[2])); | ||
1298 | if ((state[2] & FSTATE_LOGGED_IN) && | ||
1299 | (state[2] & FSTATE_WAITING_FOR_VERIFY)) { | ||
1300 | DEBUG16(printk("scsi(%ld): Sending " | ||
1301 | "verify iocb.\n", ha->host_no)); | ||
1302 | |||
1303 | cs84xx_time = jiffies; | ||
1304 | rval = qla84xx_init_chip(ha); | ||
1305 | if (rval != QLA_SUCCESS) | ||
1306 | break; | ||
1307 | |||
1308 | /* Add time taken to initialize. */ | ||
1309 | cs84xx_time = jiffies - cs84xx_time; | ||
1310 | wtime += cs84xx_time; | ||
1311 | mtime += cs84xx_time; | ||
1312 | DEBUG16(printk("scsi(%ld): Increasing " | ||
1313 | "wait time by %ld. New time %ld\n", | ||
1314 | ha->host_no, cs84xx_time, wtime)); | ||
1315 | } | ||
1316 | } else if (state[0] == FSTATE_READY) { | ||
1284 | DEBUG(printk("scsi(%ld): F/W Ready - OK \n", | 1317 | DEBUG(printk("scsi(%ld): F/W Ready - OK \n", |
1285 | ha->host_no)); | 1318 | ha->host_no)); |
1286 | 1319 | ||
@@ -1294,7 +1327,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1294 | rval = QLA_FUNCTION_FAILED; | 1327 | rval = QLA_FUNCTION_FAILED; |
1295 | 1328 | ||
1296 | if (atomic_read(&ha->loop_down_timer) && | 1329 | if (atomic_read(&ha->loop_down_timer) && |
1297 | fw_state != FSTATE_READY) { | 1330 | state[0] != FSTATE_READY) { |
1298 | /* Loop down. Timeout on min_wait for states | 1331 | /* Loop down. Timeout on min_wait for states |
1299 | * other than Wait for Login. | 1332 | * other than Wait for Login. |
1300 | */ | 1333 | */ |
@@ -1319,11 +1352,11 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1319 | msleep(500); | 1352 | msleep(500); |
1320 | 1353 | ||
1321 | DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", | 1354 | DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", |
1322 | ha->host_no, fw_state, jiffies)); | 1355 | ha->host_no, state[0], jiffies)); |
1323 | } while (1); | 1356 | } while (1); |
1324 | 1357 | ||
1325 | DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", | 1358 | DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", |
1326 | ha->host_no, fw_state, jiffies)); | 1359 | ha->host_no, state[0], jiffies)); |
1327 | 1360 | ||
1328 | if (rval) { | 1361 | if (rval) { |
1329 | DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", | 1362 | DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", |
@@ -4038,3 +4071,73 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) | |||
4038 | 4071 | ||
4039 | return rval; | 4072 | return rval; |
4040 | } | 4073 | } |
4074 | |||
4075 | /* 84XX Support **************************************************************/ | ||
4076 | |||
4077 | static LIST_HEAD(qla_cs84xx_list); | ||
4078 | static DEFINE_MUTEX(qla_cs84xx_mutex); | ||
4079 | |||
4080 | static struct qla_chip_state_84xx * | ||
4081 | qla84xx_get_chip(struct scsi_qla_host *ha) | ||
4082 | { | ||
4083 | struct qla_chip_state_84xx *cs84xx; | ||
4084 | |||
4085 | mutex_lock(&qla_cs84xx_mutex); | ||
4086 | |||
4087 | /* Find any shared 84xx chip. */ | ||
4088 | list_for_each_entry(cs84xx, &qla_cs84xx_list, list) { | ||
4089 | if (cs84xx->bus == ha->pdev->bus) { | ||
4090 | kref_get(&cs84xx->kref); | ||
4091 | goto done; | ||
4092 | } | ||
4093 | } | ||
4094 | |||
4095 | cs84xx = kzalloc(sizeof(*cs84xx), GFP_KERNEL); | ||
4096 | if (!cs84xx) | ||
4097 | goto done; | ||
4098 | |||
4099 | kref_init(&cs84xx->kref); | ||
4100 | spin_lock_init(&cs84xx->access_lock); | ||
4101 | mutex_init(&cs84xx->fw_update_mutex); | ||
4102 | cs84xx->bus = ha->pdev->bus; | ||
4103 | |||
4104 | list_add_tail(&cs84xx->list, &qla_cs84xx_list); | ||
4105 | done: | ||
4106 | mutex_unlock(&qla_cs84xx_mutex); | ||
4107 | return cs84xx; | ||
4108 | } | ||
4109 | |||
4110 | static void | ||
4111 | __qla84xx_chip_release(struct kref *kref) | ||
4112 | { | ||
4113 | struct qla_chip_state_84xx *cs84xx = | ||
4114 | container_of(kref, struct qla_chip_state_84xx, kref); | ||
4115 | |||
4116 | mutex_lock(&qla_cs84xx_mutex); | ||
4117 | list_del(&cs84xx->list); | ||
4118 | mutex_unlock(&qla_cs84xx_mutex); | ||
4119 | kfree(cs84xx); | ||
4120 | } | ||
4121 | |||
4122 | void | ||
4123 | qla84xx_put_chip(struct scsi_qla_host *ha) | ||
4124 | { | ||
4125 | if (ha->cs84xx) | ||
4126 | kref_put(&ha->cs84xx->kref, __qla84xx_chip_release); | ||
4127 | } | ||
4128 | |||
4129 | static int | ||
4130 | qla84xx_init_chip(scsi_qla_host_t *ha) | ||
4131 | { | ||
4132 | int rval; | ||
4133 | uint16_t status[2]; | ||
4134 | |||
4135 | mutex_lock(&ha->cs84xx->fw_update_mutex); | ||
4136 | |||
4137 | rval = qla84xx_verify_chip(ha, status); | ||
4138 | |||
4139 | mutex_unlock(&ha->cs84xx->fw_update_mutex); | ||
4140 | |||
4141 | return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED: | ||
4142 | QLA_SUCCESS; | ||
4143 | } | ||