diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2009-01-05 14:18:08 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-01-07 16:50:31 -0500 |
commit | bb99de6703526ebed42e29b8dee402df235f28c7 (patch) | |
tree | 069bada1baedaa8b5fb1feef07de9ff8b46774ee /drivers | |
parent | 3fd67cdf9e68b653ed631056bf1660700088c8c8 (diff) |
[SCSI] qla2xxx: Collapse EFT/FCE copy procedures during a firmware dump.
In preparation for new ISP types with varying dump procedures.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 75 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 4 |
3 files changed, 53 insertions, 27 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 1cf77772623b..49040ed3cea8 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -310,6 +310,43 @@ qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count, | |||
310 | *buf++ = htons(RD_REG_WORD(dmp_reg++)); | 310 | *buf++ = htons(RD_REG_WORD(dmp_reg++)); |
311 | } | 311 | } |
312 | 312 | ||
313 | static inline void * | ||
314 | qla24xx_copy_eft(struct qla_hw_data *ha, void *ptr) | ||
315 | { | ||
316 | if (!ha->eft) | ||
317 | return ptr; | ||
318 | |||
319 | memcpy(ptr, ha->eft, ntohl(ha->fw_dump->eft_size)); | ||
320 | return ptr + ntohl(ha->fw_dump->eft_size); | ||
321 | } | ||
322 | |||
323 | static inline void * | ||
324 | qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) | ||
325 | { | ||
326 | uint32_t cnt; | ||
327 | uint32_t *iter_reg; | ||
328 | struct qla2xxx_fce_chain *fcec = ptr; | ||
329 | |||
330 | if (!ha->fce) | ||
331 | return ptr; | ||
332 | |||
333 | *last_chain = &fcec->type; | ||
334 | fcec->type = __constant_htonl(DUMP_CHAIN_FCE); | ||
335 | fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) + | ||
336 | fce_calc_size(ha->fce_bufs)); | ||
337 | fcec->size = htonl(fce_calc_size(ha->fce_bufs)); | ||
338 | fcec->addr_l = htonl(LSD(ha->fce_dma)); | ||
339 | fcec->addr_h = htonl(MSD(ha->fce_dma)); | ||
340 | |||
341 | iter_reg = fcec->eregs; | ||
342 | for (cnt = 0; cnt < 8; cnt++) | ||
343 | *iter_reg++ = htonl(ha->fce_mb[cnt]); | ||
344 | |||
345 | memcpy(iter_reg, ha->fce, ntohl(fcec->size)); | ||
346 | |||
347 | return iter_reg; | ||
348 | } | ||
349 | |||
313 | /** | 350 | /** |
314 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. | 351 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. |
315 | * @ha: HA context | 352 | * @ha: HA context |
@@ -913,8 +950,8 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
913 | goto qla24xx_fw_dump_failed_0; | 950 | goto qla24xx_fw_dump_failed_0; |
914 | 951 | ||
915 | nxt = qla2xxx_copy_queues(ha, nxt); | 952 | nxt = qla2xxx_copy_queues(ha, nxt); |
916 | if (ha->eft) | 953 | |
917 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); | 954 | qla24xx_copy_eft(ha, nxt); |
918 | 955 | ||
919 | qla24xx_fw_dump_failed_0: | 956 | qla24xx_fw_dump_failed_0: |
920 | if (rval != QLA_SUCCESS) { | 957 | if (rval != QLA_SUCCESS) { |
@@ -950,7 +987,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
950 | struct qla25xx_fw_dump *fw; | 987 | struct qla25xx_fw_dump *fw; |
951 | uint32_t ext_mem_cnt; | 988 | uint32_t ext_mem_cnt; |
952 | void *nxt; | 989 | void *nxt; |
953 | struct qla2xxx_fce_chain *fcec; | 990 | uint32_t *last_chain = NULL; |
954 | struct qla2xxx_mq_chain *mq = NULL; | 991 | struct qla2xxx_mq_chain *mq = NULL; |
955 | uint32_t qreg_size; | 992 | uint32_t qreg_size; |
956 | uint8_t req_cnt, rsp_cnt, que_cnt; | 993 | uint8_t req_cnt, rsp_cnt, que_cnt; |
@@ -1012,6 +1049,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1012 | que_cnt = req_cnt > rsp_cnt ? req_cnt : rsp_cnt; | 1049 | que_cnt = req_cnt > rsp_cnt ? req_cnt : rsp_cnt; |
1013 | mq->count = htonl(que_cnt); | 1050 | mq->count = htonl(que_cnt); |
1014 | mq->chain_size = htonl(qreg_size); | 1051 | mq->chain_size = htonl(qreg_size); |
1052 | last_chain = &mq->type; | ||
1015 | mq->type = __constant_htonl(DUMP_CHAIN_MQ); | 1053 | mq->type = __constant_htonl(DUMP_CHAIN_MQ); |
1016 | for (cnt = 0; cnt < que_cnt; cnt++) { | 1054 | for (cnt = 0; cnt < que_cnt; cnt++) { |
1017 | reg25 = (struct device_reg_25xxmq *) ((void *) | 1055 | reg25 = (struct device_reg_25xxmq *) ((void *) |
@@ -1249,37 +1287,22 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1249 | if (rval != QLA_SUCCESS) | 1287 | if (rval != QLA_SUCCESS) |
1250 | goto qla25xx_fw_dump_failed_0; | 1288 | goto qla25xx_fw_dump_failed_0; |
1251 | 1289 | ||
1252 | /* Fibre Channel Trace Buffer. */ | ||
1253 | nxt = qla2xxx_copy_queues(ha, nxt); | 1290 | nxt = qla2xxx_copy_queues(ha, nxt); |
1254 | if (ha->eft) | ||
1255 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); | ||
1256 | 1291 | ||
1257 | /* Fibre Channel Event Buffer. */ | 1292 | nxt = qla24xx_copy_eft(ha, nxt); |
1258 | if (!ha->fce) | ||
1259 | goto qla25xx_fw_dump_failed_0; | ||
1260 | |||
1261 | ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); | ||
1262 | 1293 | ||
1294 | /* Chain entries. */ | ||
1263 | if (ha->mqenable) { | 1295 | if (ha->mqenable) { |
1264 | nxt = nxt + ntohl(ha->fw_dump->eft_size); | ||
1265 | memcpy(nxt, mq, qreg_size); | 1296 | memcpy(nxt, mq, qreg_size); |
1266 | kfree(mq); | 1297 | kfree(mq); |
1267 | fcec = nxt + qreg_size; | 1298 | nxt += qreg_size; |
1268 | } else { | ||
1269 | fcec = nxt + ntohl(ha->fw_dump->eft_size); | ||
1270 | } | 1299 | } |
1271 | fcec->type = __constant_htonl(DUMP_CHAIN_FCE | DUMP_CHAIN_LAST); | ||
1272 | fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) + | ||
1273 | fce_calc_size(ha->fce_bufs)); | ||
1274 | fcec->size = htonl(fce_calc_size(ha->fce_bufs)); | ||
1275 | fcec->addr_l = htonl(LSD(ha->fce_dma)); | ||
1276 | fcec->addr_h = htonl(MSD(ha->fce_dma)); | ||
1277 | |||
1278 | iter_reg = fcec->eregs; | ||
1279 | for (cnt = 0; cnt < 8; cnt++) | ||
1280 | *iter_reg++ = htonl(ha->fce_mb[cnt]); | ||
1281 | 1300 | ||
1282 | memcpy(iter_reg, ha->fce, ntohl(fcec->size)); | 1301 | qla25xx_copy_fce(ha, nxt, &last_chain); |
1302 | if (last_chain) { | ||
1303 | ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); | ||
1304 | *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); | ||
1305 | } | ||
1283 | 1306 | ||
1284 | qla25xx_fw_dump_failed_0: | 1307 | qla25xx_fw_dump_failed_0: |
1285 | if (rval != QLA_SUCCESS) { | 1308 | if (rval != QLA_SUCCESS) { |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 191c95de7c67..c8e5af5f56a7 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2477,6 +2477,7 @@ struct qla_hw_data { | |||
2477 | dma_addr_t eft_dma; | 2477 | dma_addr_t eft_dma; |
2478 | void *eft; | 2478 | void *eft; |
2479 | 2479 | ||
2480 | uint32_t chain_offset; | ||
2480 | struct dentry *dfs_dir; | 2481 | struct dentry *dfs_dir; |
2481 | struct dentry *dfs_fce; | 2482 | struct dentry *dfs_fce; |
2482 | dma_addr_t fce_dma; | 2483 | dma_addr_t fce_dma; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 3ec6eaca96d4..6038aedc1239 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -850,7 +850,9 @@ cont_alloc: | |||
850 | 850 | ||
851 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); | 851 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); |
852 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + | 852 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + |
853 | mq_size + eft_size + fce_size; | 853 | eft_size; |
854 | ha->chain_offset = dump_size; | ||
855 | dump_size += mq_size + fce_size; | ||
854 | 856 | ||
855 | ha->fw_dump = vmalloc(dump_size); | 857 | ha->fw_dump = vmalloc(dump_size); |
856 | if (!ha->fw_dump) { | 858 | if (!ha->fw_dump) { |