]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/qla2xxx-8.02.01-k8-update
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / qla2xxx-8.02.01-k8-update
CommitLineData
00e5a55c
BS
1From: Andrew Vasquez
2Subject: Update qla2xxx to 8.02.01-k8
3References: FATE#304113
4
5This patch updates the qla2xxx driver to version 8.02.01-k8.
6
7Signed-off-by: Hannes Reinecke <hare@suse.de>
8
9---
10 drivers/scsi/qla2xxx/qla_attr.c | 9
11 drivers/scsi/qla2xxx/qla_def.h | 12 +
12 drivers/scsi/qla2xxx/qla_fw.h | 71 +++++++
13 drivers/scsi/qla2xxx/qla_gbl.h | 4
14 drivers/scsi/qla2xxx/qla_init.c | 14 +
15 drivers/scsi/qla2xxx/qla_inline.h | 2
16 drivers/scsi/qla2xxx/qla_iocb.c | 30 ++-
17 drivers/scsi/qla2xxx/qla_isr.c | 17 +
18 drivers/scsi/qla2xxx/qla_mbx.c | 6
19 drivers/scsi/qla2xxx/qla_os.c | 9
20 drivers/scsi/qla2xxx/qla_sup.c | 336 +++++++++++++++++++++++++++++++++----
21 drivers/scsi/qla2xxx/qla_version.h | 2
22 12 files changed, 444 insertions(+), 68 deletions(-)
23
24--- a/drivers/scsi/qla2xxx/qla_attr.c
25+++ b/drivers/scsi/qla2xxx/qla_attr.c
26@@ -292,10 +292,11 @@ qla2x00_sysfs_write_optrom_ctl(struct ko
27 valid = 0;
28 if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
29 valid = 1;
30- else if (start == (FA_BOOT_CODE_ADDR*4) ||
31- start == (FA_RISC_CODE_ADDR*4))
32+ else if (start == (ha->flt_region_boot * 4) ||
33+ start == (ha->flt_region_fw * 4))
34 valid = 1;
35- else if (IS_QLA25XX(ha) && start == (FA_VPD_NVRAM_ADDR*4))
36+ else if (IS_QLA25XX(ha) &&
37+ start == (ha->flt_region_vpd_nvram * 4))
38 valid = 1;
39 if (!valid) {
40 qla_printk(KERN_WARNING, ha,
41@@ -1064,6 +1065,8 @@ qla2x00_get_fc_host_stats(struct Scsi_Ho
42 pfc_host_stat->dumped_frames = stats->dumped_frames;
43 pfc_host_stat->nos_count = stats->nos_rcvd;
44 }
45+ pfc_host_stat->fcp_input_megabytes = ha->qla_stats.input_bytes >> 20;
46+ pfc_host_stat->fcp_output_megabytes = ha->qla_stats.output_bytes >> 20;
47
48 done_free:
49 dma_pool_free(ha->s_dma_pool, stats, stats_dma);
50--- a/drivers/scsi/qla2xxx/qla_def.h
51+++ b/drivers/scsi/qla2xxx/qla_def.h
52@@ -2157,6 +2157,8 @@ struct qla_chip_state_84xx {
53
54 struct qla_statistics {
55 uint32_t total_isp_aborts;
56+ uint64_t input_bytes;
57+ uint64_t output_bytes;
58 };
59
60 /*
61@@ -2238,6 +2240,7 @@ typedef struct scsi_qla_host {
62 #define FCPORT_UPDATE_NEEDED 27
63 #define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */
64 #define UNLOADING 29
65+#define NPIV_CONFIG_NEEDED 30
66
67 uint32_t device_flags;
68 #define DFLG_LOCAL_DEVICES BIT_0
69@@ -2507,7 +2510,6 @@ typedef struct scsi_qla_host {
70 uint64_t fce_wr, fce_rd;
71 struct mutex fce_mutex;
72
73- uint32_t hw_event_start;
74 uint32_t hw_event_ptr;
75 uint32_t hw_event_pause_errors;
76
77@@ -2553,6 +2555,14 @@ typedef struct scsi_qla_host {
78 uint32_t fdt_unprotect_sec_cmd;
79 uint32_t fdt_protect_sec_cmd;
80
81+ uint32_t flt_region_flt;
82+ uint32_t flt_region_fdt;
83+ uint32_t flt_region_boot;
84+ uint32_t flt_region_fw;
85+ uint32_t flt_region_vpd_nvram;
86+ uint32_t flt_region_hw_event;
87+ uint32_t flt_region_npiv_conf;
88+
89 /* Needed for BEACON */
90 uint16_t beacon_blink_led;
91 uint8_t beacon_color_state;
92--- a/drivers/scsi/qla2xxx/qla_fw.h
93+++ b/drivers/scsi/qla2xxx/qla_fw.h
94@@ -789,14 +789,23 @@ struct device_reg_24xx {
95 #define FA_RISC_CODE_ADDR 0x20000
96 #define FA_RISC_CODE_SEGMENTS 2
97
98+#define FA_FLASH_DESCR_ADDR_24 0x11000
99+#define FA_FLASH_LAYOUT_ADDR_24 0x11400
100+#define FA_NPIV_CONF0_ADDR_24 0x16000
101+#define FA_NPIV_CONF1_ADDR_24 0x17000
102+
103 #define FA_FW_AREA_ADDR 0x40000
104 #define FA_VPD_NVRAM_ADDR 0x48000
105 #define FA_FEATURE_ADDR 0x4C000
106 #define FA_FLASH_DESCR_ADDR 0x50000
107+#define FA_FLASH_LAYOUT_ADDR 0x50400
108 #define FA_HW_EVENT0_ADDR 0x54000
109-#define FA_HW_EVENT1_ADDR 0x54200
110+#define FA_HW_EVENT1_ADDR 0x54400
111 #define FA_HW_EVENT_SIZE 0x200
112 #define FA_HW_EVENT_ENTRY_SIZE 4
113+#define FA_NPIV_CONF0_ADDR 0x5C000
114+#define FA_NPIV_CONF1_ADDR 0x5D000
115+
116 /*
117 * Flash Error Log Event Codes.
118 */
119@@ -806,10 +815,6 @@ struct device_reg_24xx {
120 #define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023
121 #define HW_EVENT_FLASH_FW_ERR 0xF024
122
123-#define FA_BOOT_LOG_ADDR 0x58000
124-#define FA_FW_DUMP0_ADDR 0x60000
125-#define FA_FW_DUMP1_ADDR 0x70000
126-
127 uint32_t flash_data; /* Flash/NVRAM BIOS data. */
128
129 uint32_t ctrl_status; /* Control/Status. */
130@@ -1203,6 +1208,62 @@ struct qla_fdt_layout {
131 uint8_t unused2[65];
132 };
133
134+/* Flash Layout Table ********************************************************/
135+
136+struct qla_flt_location {
137+ uint8_t sig[4];
138+ uint32_t start_lo;
139+ uint32_t start_hi;
140+ uint16_t unused;
141+ uint16_t checksum;
142+};
143+
144+struct qla_flt_header {
145+ uint16_t version;
146+ uint16_t length;
147+ uint16_t checksum;
148+ uint16_t unused;
149+};
150+
151+#define FLT_REG_FW 0x01
152+#define FLT_REG_BOOT_CODE 0x07
153+#define FLT_REG_VPD_0 0x14
154+#define FLT_REG_NVRAM_0 0x15
155+#define FLT_REG_VPD_1 0x16
156+#define FLT_REG_NVRAM_1 0x17
157+#define FLT_REG_FDT 0x1a
158+#define FLT_REG_FLT 0x1c
159+#define FLT_REG_HW_EVENT_0 0x1d
160+#define FLT_REG_HW_EVENT_1 0x1f
161+#define FLT_REG_NPIV_CONF_0 0x29
162+#define FLT_REG_NPIV_CONF_1 0x2a
163+
164+struct qla_flt_region {
165+ uint32_t code;
166+ uint32_t size;
167+ uint32_t start;
168+ uint32_t end;
169+};
170+
171+/* Flash NPIV Configuration Table ********************************************/
172+
173+struct qla_npiv_header {
174+ uint8_t sig[2];
175+ uint16_t version;
176+ uint16_t entries;
177+ uint16_t unused[4];
178+ uint16_t checksum;
179+};
180+
181+struct qla_npiv_entry {
182+ uint16_t flags;
183+ uint16_t vf_id;
184+ uint16_t qos;
185+ uint16_t unused1;
186+ uint8_t port_name[WWN_SIZE];
187+ uint8_t node_name[WWN_SIZE];
188+};
189+
190 /* 84XX Support **************************************************************/
191
192 #define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */
193--- a/drivers/scsi/qla2xxx/qla_gbl.h
194+++ b/drivers/scsi/qla2xxx/qla_gbl.h
195@@ -313,9 +313,11 @@ extern int qla24xx_get_flash_version(scs
196 extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t,
197 uint16_t, uint16_t);
198
199-extern void qla2xxx_get_flash_info(scsi_qla_host_t *);
200+extern int qla2xxx_get_flash_info(scsi_qla_host_t *);
201 extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
202
203+extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *);
204+
205 /*
206 * Global Function Prototypes in qla_dbg.c source file.
207 */
208--- a/drivers/scsi/qla2xxx/qla_init.c
209+++ b/drivers/scsi/qla2xxx/qla_init.c
210@@ -83,6 +83,13 @@ qla2x00_initialize_adapter(scsi_qla_host
211
212 ha->isp_ops->reset_chip(ha);
213
214+ rval = qla2xxx_get_flash_info(ha);
215+ if (rval) {
216+ DEBUG2(printk("scsi(%ld): Unable to validate FLASH data.\n",
217+ ha->host_no));
218+ return (rval);
219+ }
220+
221 ha->isp_ops->get_flash_version(ha, ha->request_ring);
222
223 qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n");
224@@ -109,7 +116,6 @@ qla2x00_initialize_adapter(scsi_qla_host
225 rval = qla2x00_setup_chip(ha);
226 if (rval)
227 return (rval);
228- qla2xxx_get_flash_info(ha);
229 }
230 if (IS_QLA84XX(ha)) {
231 ha->cs84xx = qla84xx_get_chip(ha);
232@@ -2016,7 +2022,7 @@ qla2x00_configure_loop(scsi_qla_host_t *
233 DEBUG3(printk("%s: exiting normally\n", __func__));
234 }
235
236- /* Restore state if a resync event occured during processing */
237+ /* Restore state if a resync event occurred during processing */
238 if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
239 if (test_bit(LOCAL_LOOP_UPDATE, &save_flags))
240 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
241@@ -2561,7 +2567,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho
242 rval = QLA_SUCCESS;
243
244 /* Try GID_PT to get device list, else GAN. */
245- swl = kcalloc(MAX_FIBRE_DEVICES, sizeof(sw_info_t), GFP_ATOMIC);
246+ swl = kcalloc(MAX_FIBRE_DEVICES, sizeof(sw_info_t), GFP_KERNEL);
247 if (!swl) {
248 /*EMPTY*/
249 DEBUG2(printk("scsi(%ld): GID_PT allocations failed, fallback "
250@@ -3751,7 +3757,7 @@ qla24xx_load_risc_flash(scsi_qla_host_t
251 rval = QLA_SUCCESS;
252
253 segments = FA_RISC_CODE_SEGMENTS;
254- faddr = FA_RISC_CODE_ADDR;
255+ faddr = ha->flt_region_fw;
256 dcode = (uint32_t *)ha->request_ring;
257 *srisc_addr = 0;
258
259--- a/drivers/scsi/qla2xxx/qla_inline.h
260+++ b/drivers/scsi/qla2xxx/qla_inline.h
261@@ -52,7 +52,7 @@ to_qla_parent(scsi_qla_host_t *ha)
262 * @ha: HA context
263 * @ha_locked: is function called with the hardware lock
264 *
265- * Returns non-zero if a failure occured, else zero.
266+ * Returns non-zero if a failure occurred, else zero.
267 */
268 static inline int
269 qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked)
270--- a/drivers/scsi/qla2xxx/qla_iocb.c
271+++ b/drivers/scsi/qla2xxx/qla_iocb.c
272@@ -21,17 +21,22 @@ static void qla2x00_isp_cmd(scsi_qla_hos
273 * Returns the proper CF_* direction based on CDB.
274 */
275 static inline uint16_t
276-qla2x00_get_cmd_direction(struct scsi_cmnd *cmd)
277+qla2x00_get_cmd_direction(srb_t *sp)
278 {
279 uint16_t cflags;
280
281 cflags = 0;
282
283 /* Set transfer direction */
284- if (cmd->sc_data_direction == DMA_TO_DEVICE)
285+ if (sp->cmd->sc_data_direction == DMA_TO_DEVICE) {
286 cflags = CF_WRITE;
287- else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
288+ sp->fcport->ha->qla_stats.output_bytes +=
289+ scsi_bufflen(sp->cmd);
290+ } else if (sp->cmd->sc_data_direction == DMA_FROM_DEVICE) {
291 cflags = CF_READ;
292+ sp->fcport->ha->qla_stats.input_bytes +=
293+ scsi_bufflen(sp->cmd);
294+ }
295 return (cflags);
296 }
297
298@@ -169,7 +174,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *
299
300 ha = sp->ha;
301
302- cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(cmd));
303+ cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));
304
305 /* Three DSDs are available in the Command Type 2 IOCB */
306 avail_dsds = 3;
307@@ -228,7 +233,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *
308
309 ha = sp->ha;
310
311- cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(cmd));
312+ cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));
313
314 /* Two DSDs are available in the Command Type 3 IOCB */
315 avail_dsds = 2;
316@@ -262,7 +267,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *
317 * qla2x00_start_scsi() - Send a SCSI command to the ISP
318 * @sp: command to send to the ISP
319 *
320- * Returns non-zero if a failure occured, else zero.
321+ * Returns non-zero if a failure occurred, else zero.
322 */
323 int
324 qla2x00_start_scsi(srb_t *sp)
325@@ -407,7 +412,7 @@ queuing_error:
326 *
327 * Can be called from both normal and interrupt context.
328 *
329- * Returns non-zero if a failure occured, else zero.
330+ * Returns non-zero if a failure occurred, else zero.
331 */
332 int
333 __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
334@@ -625,12 +630,17 @@ qla24xx_build_scsi_iocbs(srb_t *sp, stru
335 ha = sp->ha;
336
337 /* Set transfer direction */
338- if (cmd->sc_data_direction == DMA_TO_DEVICE)
339+ if (cmd->sc_data_direction == DMA_TO_DEVICE) {
340 cmd_pkt->task_mgmt_flags =
341 __constant_cpu_to_le16(TMF_WRITE_DATA);
342- else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
343+ sp->fcport->ha->qla_stats.output_bytes +=
344+ scsi_bufflen(sp->cmd);
345+ } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
346 cmd_pkt->task_mgmt_flags =
347 __constant_cpu_to_le16(TMF_READ_DATA);
348+ sp->fcport->ha->qla_stats.input_bytes +=
349+ scsi_bufflen(sp->cmd);
350+ }
351
352 /* One DSD is available in the Command Type 3 IOCB */
353 avail_dsds = 1;
354@@ -666,7 +676,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, stru
355 * qla24xx_start_scsi() - Send a SCSI command to the ISP
356 * @sp: command to send to the ISP
357 *
358- * Returns non-zero if a failure occured, else zero.
359+ * Returns non-zero if a failure occurred, else zero.
360 */
361 int
362 qla24xx_start_scsi(srb_t *sp)
363--- a/drivers/scsi/qla2xxx/qla_isr.c
364+++ b/drivers/scsi/qla2xxx/qla_isr.c
365@@ -391,9 +391,9 @@ qla2x00_async_event(scsi_qla_host_t *ha,
366 break;
367
368 case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */
369- DEBUG2(printk("scsi(%ld): LIP occured (%x).\n", ha->host_no,
370+ DEBUG2(printk("scsi(%ld): LIP occurred (%x).\n", ha->host_no,
371 mb[1]));
372- qla_printk(KERN_INFO, ha, "LIP occured (%x).\n", mb[1]);
373+ qla_printk(KERN_INFO, ha, "LIP occurred (%x).\n", mb[1]);
374
375 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
376 atomic_set(&ha->loop_state, LOOP_DOWN);
377@@ -460,7 +460,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
378 DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
379 ha->host_no, mb[1]));
380 qla_printk(KERN_INFO, ha,
381- "LIP reset occured (%x).\n", mb[1]);
382+ "LIP reset occurred (%x).\n", mb[1]);
383
384 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
385 atomic_set(&ha->loop_state, LOOP_DOWN);
386@@ -543,7 +543,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
387
388 case MBA_PORT_UPDATE: /* Port database update */
389 /*
390- * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
391+ * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET
392 * event etc. earlier indicating loop is down) then process
393 * it. Otherwise ignore it and Wait for RSCN to come in.
394 */
395@@ -589,7 +589,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
396 "scsi(%ld): RSCN database changed -- %04x %04x %04x.\n",
397 ha->host_no, mb[1], mb[2], mb[3]));
398
399- rscn_entry = (mb[1] << 16) | mb[2];
400+ rscn_entry = ((mb[1] & 0xff) << 16) | mb[2];
401 host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) |
402 ha->d_id.b.al_pa;
403 if (rscn_entry == host_pid) {
404@@ -600,6 +600,8 @@ qla2x00_async_event(scsi_qla_host_t *ha,
405 break;
406 }
407
408+ /* Ignore reserved bits from RSCN-payload. */
409+ rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2];
410 rscn_queue_index = ha->rscn_in_ptr + 1;
411 if (rscn_queue_index == MAX_RSCN_COUNT)
412 rscn_queue_index = 0;
413@@ -1060,8 +1062,9 @@ qla2x00_status_entry(scsi_qla_host_t *ha
414 resid = resid_len;
415 /* Use F/W calculated residual length. */
416 if (IS_FWI2_CAPABLE(ha)) {
417- if (scsi_status & SS_RESIDUAL_UNDER &&
418- resid != fw_resid_len) {
419+ if (!(scsi_status & SS_RESIDUAL_UNDER)) {
420+ lscsi_status = 0;
421+ } else if (resid != fw_resid_len) {
422 scsi_status &= ~SS_RESIDUAL_UNDER;
423 lscsi_status = 0;
424 }
425--- a/drivers/scsi/qla2xxx/qla_mbx.c
426+++ b/drivers/scsi/qla2xxx/qla_mbx.c
427@@ -233,7 +233,7 @@ qla2x00_mailbox_command(scsi_qla_host_t
428 DEBUG2_3_11(printk("%s(%ld): timeout schedule "
429 "isp_abort_needed.\n", __func__, ha->host_no));
430 qla_printk(KERN_WARNING, ha,
431- "Mailbox command timeout occured. Scheduling ISP "
432+ "Mailbox command timeout occurred. Scheduling ISP "
433 "abort.\n");
434 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
435 qla2xxx_wake_dpc(ha);
436@@ -244,7 +244,7 @@ qla2x00_mailbox_command(scsi_qla_host_t
437 DEBUG2_3_11(printk("%s(%ld): timeout calling "
438 "abort_isp\n", __func__, ha->host_no));
439 qla_printk(KERN_WARNING, ha,
440- "Mailbox command timeout occured. Issuing ISP "
441+ "Mailbox command timeout occurred. Issuing ISP "
442 "abort.\n");
443
444 set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
445@@ -1995,7 +1995,7 @@ qla2x00_get_fcal_position_map(scsi_qla_h
446 char *pmap;
447 dma_addr_t pmap_dma;
448
449- pmap = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &pmap_dma);
450+ pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
451 if (pmap == NULL) {
452 DEBUG2_3_11(printk("%s(%ld): **** Mem Alloc Failed ****",
453 __func__, ha->host_no));
454--- a/drivers/scsi/qla2xxx/qla_os.c
455+++ b/drivers/scsi/qla2xxx/qla_os.c
456@@ -1515,6 +1515,7 @@ qla2xxx_scan_start(struct Scsi_Host *sho
457 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
458 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
459 set_bit(RSCN_UPDATE, &ha->dpc_flags);
460+ set_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags);
461 }
462
463 static int
464@@ -1661,8 +1662,6 @@ qla2x00_probe_one(struct pci_dev *pdev,
465 ha->gid_list_info_size = 8;
466 ha->optrom_size = OPTROM_SIZE_25XX;
467 ha->isp_ops = &qla25xx_isp_ops;
468- ha->hw_event_start = PCI_FUNC(pdev->devfn) ?
469- FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR;
470 }
471 host->can_queue = ha->request_q_length + 128;
472
473@@ -2431,6 +2430,12 @@ qla2x00_do_dpc(void *data)
474 ha->host_no));
475 }
476
477+ if (test_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags) &&
478+ atomic_read(&ha->loop_state) == LOOP_READY) {
479+ clear_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags);
480+ qla2xxx_flash_npiv_conf(ha);
481+ }
482+
483 if (!ha->interrupts_on)
484 ha->isp_ops->enable_intrs(ha);
485
486--- a/drivers/scsi/qla2xxx/qla_sup.c
487+++ b/drivers/scsi/qla2xxx/qla_sup.c
488@@ -543,23 +543,198 @@ qla24xx_get_flash_manufacturer(scsi_qla_
489 }
490 }
491
492-void
493-qla2xxx_get_flash_info(scsi_qla_host_t *ha)
494+static int
495+qla2xxx_find_flt_start(scsi_qla_host_t *ha, uint32_t *start)
496+{
497+ const char *loc, *locations[] = { "DEF", "PCI" };
498+ uint32_t pcihdr, pcids;
499+ uint32_t *dcode;
500+ uint8_t *buf, *bcode, last_image;
501+ uint16_t cnt, chksum, *wptr;
502+ struct qla_flt_location *fltl;
503+
504+ /*
505+ * FLT-location structure resides after the last PCI region.
506+ */
507+
508+ /* Begin with sane defaults. */
509+ loc = locations[0];
510+ *start = IS_QLA24XX_TYPE(ha) ? FA_FLASH_LAYOUT_ADDR_24:
511+ FA_FLASH_LAYOUT_ADDR;
512+
513+ /* Begin with first PCI expansion ROM header. */
514+ buf = (uint8_t *)ha->request_ring;
515+ dcode = (uint32_t *)ha->request_ring;
516+ pcihdr = 0;
517+ last_image = 1;
518+ do {
519+ /* Verify PCI expansion ROM header. */
520+ qla24xx_read_flash_data(ha, dcode, pcihdr >> 2, 0x20);
521+ bcode = buf + (pcihdr % 4);
522+ if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa)
523+ goto end;
524+
525+ /* Locate PCI data structure. */
526+ pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
527+ qla24xx_read_flash_data(ha, dcode, pcids >> 2, 0x20);
528+ bcode = buf + (pcihdr % 4);
529+
530+ /* Validate signature of PCI data structure. */
531+ if (bcode[0x0] != 'P' || bcode[0x1] != 'C' ||
532+ bcode[0x2] != 'I' || bcode[0x3] != 'R')
533+ goto end;
534+
535+ last_image = bcode[0x15] & BIT_7;
536+
537+ /* Locate next PCI expansion ROM. */
538+ pcihdr += ((bcode[0x11] << 8) | bcode[0x10]) * 512;
539+ } while (!last_image);
540+
541+ /* Now verify FLT-location structure. */
542+ fltl = (struct qla_flt_location *)ha->request_ring;
543+ qla24xx_read_flash_data(ha, dcode, pcihdr >> 2,
544+ sizeof(struct qla_flt_location) >> 2);
545+ if (fltl->sig[0] != 'Q' || fltl->sig[1] != 'F' ||
546+ fltl->sig[2] != 'L' || fltl->sig[3] != 'T')
547+ goto end;
548+
549+ wptr = (uint16_t *)ha->request_ring;
550+ cnt = sizeof(struct qla_flt_location) >> 1;
551+ for (chksum = 0; cnt; cnt--)
552+ chksum += le16_to_cpu(*wptr++);
553+ if (chksum) {
554+ qla_printk(KERN_ERR, ha,
555+ "Inconsistent FLTL detected: checksum=0x%x.\n", chksum);
556+ qla2x00_dump_buffer(buf, sizeof(struct qla_flt_location));
557+ return QLA_FUNCTION_FAILED;
558+ }
559+
560+ /* Good data. Use specified location. */
561+ loc = locations[1];
562+ *start = le16_to_cpu(fltl->start_hi) << 16 |
563+ le16_to_cpu(fltl->start_lo);
564+end:
565+ DEBUG2(qla_printk(KERN_DEBUG, ha, "FLTL[%s] = 0x%x.\n", loc, *start));
566+ return QLA_SUCCESS;
567+}
568+
569+static void
570+qla2xxx_get_flt_info(scsi_qla_host_t *ha, uint32_t flt_addr)
571+{
572+ const char *loc, *locations[] = { "DEF", "FLT" };
573+ uint16_t *wptr;
574+ uint16_t cnt, chksum;
575+ uint32_t start;
576+ struct qla_flt_header *flt;
577+ struct qla_flt_region *region;
578+
579+ ha->flt_region_flt = flt_addr;
580+ wptr = (uint16_t *)ha->request_ring;
581+ flt = (struct qla_flt_header *)ha->request_ring;
582+ region = (struct qla_flt_region *)&flt[1];
583+ ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring,
584+ flt_addr << 2, OPTROM_BURST_SIZE);
585+ if (*wptr == __constant_cpu_to_le16(0xffff))
586+ goto no_flash_data;
587+ if (flt->version != __constant_cpu_to_le16(1)) {
588+ DEBUG2(qla_printk(KERN_INFO, ha, "Unsupported FLT detected: "
589+ "version=0x%x length=0x%x checksum=0x%x.\n",
590+ le16_to_cpu(flt->version), le16_to_cpu(flt->length),
591+ le16_to_cpu(flt->checksum)));
592+ goto no_flash_data;
593+ }
594+
595+ cnt = (sizeof(struct qla_flt_header) + le16_to_cpu(flt->length)) >> 1;
596+ for (chksum = 0; cnt; cnt--)
597+ chksum += le16_to_cpu(*wptr++);
598+ if (chksum) {
599+ DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent FLT detected: "
600+ "version=0x%x length=0x%x checksum=0x%x.\n",
601+ le16_to_cpu(flt->version), le16_to_cpu(flt->length),
602+ chksum));
603+ goto no_flash_data;
604+ }
605+
606+ loc = locations[1];
607+ cnt = le16_to_cpu(flt->length) / sizeof(struct qla_flt_region);
608+ for ( ; cnt; cnt--, region++) {
609+ /* Store addresses as DWORD offsets. */
610+ start = le32_to_cpu(region->start) >> 2;
611+
612+ DEBUG3(qla_printk(KERN_DEBUG, ha, "FLT[%02x]: start=0x%x "
613+ "end=0x%x size=0x%x.\n", le32_to_cpu(region->code), start,
614+ le32_to_cpu(region->end) >> 2, le32_to_cpu(region->size)));
615+
616+ switch (le32_to_cpu(region->code)) {
617+ case FLT_REG_FW:
618+ ha->flt_region_fw = start;
619+ break;
620+ case FLT_REG_BOOT_CODE:
621+ ha->flt_region_boot = start;
622+ break;
623+ case FLT_REG_VPD_0:
624+ ha->flt_region_vpd_nvram = start;
625+ break;
626+ case FLT_REG_FDT:
627+ ha->flt_region_fdt = start;
628+ break;
629+ case FLT_REG_HW_EVENT_0:
630+ if (!PCI_FUNC(ha->pdev->devfn))
631+ ha->flt_region_hw_event = start;
632+ break;
633+ case FLT_REG_HW_EVENT_1:
634+ if (PCI_FUNC(ha->pdev->devfn))
635+ ha->flt_region_hw_event = start;
636+ break;
637+ case FLT_REG_NPIV_CONF_0:
638+ if (!PCI_FUNC(ha->pdev->devfn))
639+ ha->flt_region_npiv_conf = start;
640+ break;
641+ case FLT_REG_NPIV_CONF_1:
642+ if (PCI_FUNC(ha->pdev->devfn))
643+ ha->flt_region_npiv_conf = start;
644+ break;
645+ }
646+ }
647+ goto done;
648+
649+no_flash_data:
650+ /* Use hardcoded defaults. */
651+ loc = locations[0];
652+ ha->flt_region_fw = FA_RISC_CODE_ADDR;
653+ ha->flt_region_boot = FA_BOOT_CODE_ADDR;
654+ ha->flt_region_vpd_nvram = FA_VPD_NVRAM_ADDR;
655+ ha->flt_region_fdt = IS_QLA24XX_TYPE(ha) ? FA_FLASH_DESCR_ADDR_24:
656+ FA_FLASH_DESCR_ADDR;
657+ ha->flt_region_hw_event = !PCI_FUNC(ha->pdev->devfn) ?
658+ FA_HW_EVENT0_ADDR: FA_HW_EVENT1_ADDR;
659+ ha->flt_region_npiv_conf = !PCI_FUNC(ha->pdev->devfn) ?
660+ (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF0_ADDR_24: FA_NPIV_CONF0_ADDR):
661+ (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF1_ADDR_24: FA_NPIV_CONF1_ADDR);
662+done:
663+ DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x "
664+ "vpd_nvram=0x%x fdt=0x%x flt=0x%x hwe=0x%x npiv=0x%x.\n", loc,
665+ ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram,
666+ ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_hw_event,
667+ ha->flt_region_npiv_conf));
668+}
669+
670+static void
671+qla2xxx_get_fdt_info(scsi_qla_host_t *ha)
672 {
673 #define FLASH_BLK_SIZE_32K 0x8000
674 #define FLASH_BLK_SIZE_64K 0x10000
675+ const char *loc, *locations[] = { "MID", "FDT" };
676 uint16_t cnt, chksum;
677 uint16_t *wptr;
678 struct qla_fdt_layout *fdt;
679 uint8_t man_id, flash_id;
680-
681- if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
682- return;
683+ uint16_t mid, fid;
684
685 wptr = (uint16_t *)ha->request_ring;
686 fdt = (struct qla_fdt_layout *)ha->request_ring;
687 ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring,
688- FA_FLASH_DESCR_ADDR << 2, OPTROM_BURST_SIZE);
689+ ha->flt_region_fdt << 2, OPTROM_BURST_SIZE);
690 if (*wptr == __constant_cpu_to_le16(0xffff))
691 goto no_flash_data;
692 if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' ||
693@@ -577,7 +752,10 @@ qla2xxx_get_flash_info(scsi_qla_host_t *
694 goto no_flash_data;
695 }
696
697- ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f;
698+ loc = locations[1];
699+ mid = le16_to_cpu(fdt->man_id);
700+ fid = le16_to_cpu(fdt->id);
701+ ha->fdt_odd_index = mid == 0x1f;
702 ha->fdt_wrt_disable = fdt->wrt_disable_bits;
703 ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd);
704 ha->fdt_block_size = le32_to_cpu(fdt->block_size);
705@@ -588,16 +766,12 @@ qla2xxx_get_flash_info(scsi_qla_host_t *
706 flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd):
707 flash_conf_to_access_addr(0x0336);
708 }
709-
710- DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x "
711- "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n",
712- le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd,
713- ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd,
714- ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size));
715- return;
716-
717+ goto done;
718 no_flash_data:
719+ loc = locations[0];
720 qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id);
721+ mid = man_id;
722+ fid = flash_id;
723 ha->fdt_wrt_disable = 0x9c;
724 ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8);
725 switch (man_id) {
726@@ -625,14 +799,115 @@ no_flash_data:
727 ha->fdt_block_size = FLASH_BLK_SIZE_64K;
728 break;
729 }
730-
731- DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x "
732- "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id,
733+done:
734+ DEBUG2(qla_printk(KERN_DEBUG, ha, "FDT[%s]: (0x%x/0x%x) erase=0x%x "
735+ "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", loc, mid, fid,
736 ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd,
737 ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable,
738 ha->fdt_block_size));
739 }
740
741+int
742+qla2xxx_get_flash_info(scsi_qla_host_t *ha)
743+{
744+ int ret;
745+ uint32_t flt_addr;
746+
747+ if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
748+ return QLA_SUCCESS;
749+
750+ ret = qla2xxx_find_flt_start(ha, &flt_addr);
751+ if (ret != QLA_SUCCESS)
752+ return ret;
753+
754+ qla2xxx_get_flt_info(ha, flt_addr);
755+ qla2xxx_get_fdt_info(ha);
756+
757+ return QLA_SUCCESS;
758+}
759+
760+void
761+qla2xxx_flash_npiv_conf(scsi_qla_host_t *ha)
762+{
763+#define NPIV_CONFIG_SIZE (16*1024)
764+ void *data;
765+ uint16_t *wptr;
766+ uint16_t cnt, chksum;
767+ struct qla_npiv_header hdr;
768+ struct qla_npiv_entry *entry;
769+
770+ if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
771+ return;
772+
773+ ha->isp_ops->read_optrom(ha, (uint8_t *)&hdr,
774+ ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header));
775+ if (hdr.version == __constant_cpu_to_le16(0xffff))
776+ return;
777+ if (hdr.version != __constant_cpu_to_le16(1)) {
778+ DEBUG2(qla_printk(KERN_INFO, ha, "Unsupported NPIV-Config "
779+ "detected: version=0x%x entries=0x%x checksum=0x%x.\n",
780+ le16_to_cpu(hdr.version), le16_to_cpu(hdr.entries),
781+ le16_to_cpu(hdr.checksum)));
782+ return;
783+ }
784+
785+ data = kmalloc(NPIV_CONFIG_SIZE, GFP_KERNEL);
786+ if (!data) {
787+ DEBUG2(qla_printk(KERN_INFO, ha, "NPIV-Config: Unable to "
788+ "allocate memory.\n"));
789+ return;
790+ }
791+
792+ ha->isp_ops->read_optrom(ha, (uint8_t *)data,
793+ ha->flt_region_npiv_conf << 2, NPIV_CONFIG_SIZE);
794+
795+ cnt = (sizeof(struct qla_npiv_header) + le16_to_cpu(hdr.entries) *
796+ sizeof(struct qla_npiv_entry)) >> 1;
797+ for (wptr = data, chksum = 0; cnt; cnt--)
798+ chksum += le16_to_cpu(*wptr++);
799+ if (chksum) {
800+ DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent NPIV-Config "
801+ "detected: version=0x%x entries=0x%x checksum=0x%x.\n",
802+ le16_to_cpu(hdr.version), le16_to_cpu(hdr.entries),
803+ chksum));
804+ goto done;
805+ }
806+
807+ entry = data + sizeof(struct qla_npiv_header);
808+ cnt = le16_to_cpu(hdr.entries);
809+ for ( ; cnt; cnt--, entry++) {
810+ uint16_t flags;
811+ struct fc_vport_identifiers vid;
812+ struct fc_vport *vport;
813+
814+ flags = le16_to_cpu(entry->flags);
815+ if (flags == 0xffff)
816+ continue;
817+ if ((flags & BIT_0) == 0)
818+ continue;
819+
820+ memset(&vid, 0, sizeof(vid));
821+ vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
822+ vid.vport_type = FC_PORTTYPE_NPIV;
823+ vid.disable = false;
824+ vid.port_name = wwn_to_u64(entry->port_name);
825+ vid.node_name = wwn_to_u64(entry->node_name);
826+
827+ DEBUG2(qla_printk(KERN_DEBUG, ha, "NPIV[%02x]: wwpn=%llx "
828+ "wwnn=%llx vf_id=0x%x qos=0x%x.\n", cnt, vid.port_name,
829+ vid.node_name, le16_to_cpu(entry->vf_id),
830+ le16_to_cpu(entry->qos)));
831+
832+ vport = fc_vport_create(ha->host, 0, &vid);
833+ if (!vport)
834+ qla_printk(KERN_INFO, ha, "NPIV-Config: Failed to "
835+ "create vport [%02x]: wwpn=%llx wwnn=%llx.\n", cnt,
836+ vid.port_name, vid.node_name);
837+ }
838+done:
839+ kfree(data);
840+}
841+
842 static void
843 qla24xx_unprotect_flash(scsi_qla_host_t *ha)
844 {
845@@ -920,7 +1195,8 @@ qla25xx_read_nvram_data(scsi_qla_host_t
846 dwptr = (uint32_t *)buf;
847 for (i = 0; i < bytes >> 2; i++, naddr++)
848 dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
849- flash_data_to_access_addr(FA_VPD_NVRAM_ADDR | naddr)));
850+ flash_data_to_access_addr(ha->flt_region_vpd_nvram |
851+ naddr)));
852
853 return buf;
854 }
855@@ -935,10 +1211,10 @@ qla25xx_write_nvram_data(scsi_qla_host_t
856 dbuf = vmalloc(RMW_BUFFER_SIZE);
857 if (!dbuf)
858 return QLA_MEMORY_ALLOC_FAILED;
859- ha->isp_ops->read_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2,
860+ ha->isp_ops->read_optrom(ha, dbuf, ha->flt_region_vpd_nvram << 2,
861 RMW_BUFFER_SIZE);
862 memcpy(dbuf + (naddr << 2), buf, bytes);
863- ha->isp_ops->write_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2,
864+ ha->isp_ops->write_optrom(ha, dbuf, ha->flt_region_vpd_nvram << 2,
865 RMW_BUFFER_SIZE);
866 vfree(dbuf);
867
868@@ -2166,7 +2442,7 @@ qla2x00_get_flash_version(scsi_qla_host_
869 memset(dbyte, 0, 8);
870 dcode = (uint16_t *)dbyte;
871
872- qla2x00_read_flash_data(ha, dbyte, FA_RISC_CODE_ADDR * 4 + 10,
873+ qla2x00_read_flash_data(ha, dbyte, ha->flt_region_fw * 4 + 10,
874 8);
875 DEBUG3(printk("%s(%ld): dumping fw ver from flash:\n",
876 __func__, ha->host_no));
877@@ -2177,7 +2453,7 @@ qla2x00_get_flash_version(scsi_qla_host_
878 (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
879 dcode[3] == 0)) {
880 DEBUG2(printk("%s(): Unrecognized fw revision at "
881- "%x.\n", __func__, FA_RISC_CODE_ADDR * 4));
882+ "%x.\n", __func__, ha->flt_region_fw * 4));
883 } else {
884 /* values are in big endian */
885 ha->fw_revision[0] = dbyte[0] << 16 | dbyte[1];
886@@ -2212,7 +2488,7 @@ qla24xx_get_flash_version(scsi_qla_host_
887 dcode = mbuf;
888
889 /* Begin with first PCI expansion ROM header. */
890- pcihdr = 0;
891+ pcihdr = ha->flt_region_boot;
892 last_image = 1;
893 do {
894 /* Verify PCI expansion ROM header. */
895@@ -2282,7 +2558,7 @@ qla24xx_get_flash_version(scsi_qla_host_
896 memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
897 dcode = mbuf;
898
899- qla24xx_read_flash_data(ha, dcode, FA_RISC_CODE_ADDR + 4, 4);
900+ qla24xx_read_flash_data(ha, dcode, ha->flt_region_fw + 4, 4);
901 for (i = 0; i < 4; i++)
902 dcode[i] = be32_to_cpu(dcode[i]);
903
904@@ -2291,7 +2567,7 @@ qla24xx_get_flash_version(scsi_qla_host_
905 (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
906 dcode[3] == 0)) {
907 DEBUG2(printk("%s(): Unrecognized fw version at %x.\n",
908- __func__, FA_RISC_CODE_ADDR));
909+ __func__, ha->flt_region_fw));
910 } else {
911 ha->fw_revision[0] = dcode[0];
912 ha->fw_revision[1] = dcode[1];
913@@ -2355,7 +2631,7 @@ qla2xxx_hw_event_store(scsi_qla_host_t *
914 /* Locate first empty entry. */
915 for (;;) {
916 if (ha->hw_event_ptr >=
917- ha->hw_event_start + FA_HW_EVENT_SIZE) {
918+ ha->flt_region_hw_event + FA_HW_EVENT_SIZE) {
919 DEBUG2(qla_printk(KERN_WARNING, ha,
920 "HW event -- Log Full!\n"));
921 return QLA_MEMORY_ALLOC_FAILED;
922@@ -2391,7 +2667,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha
923 int rval;
924 uint32_t marker[2], fdata[4];
925
926- if (ha->hw_event_start == 0)
927+ if (ha->flt_region_hw_event == 0)
928 return QLA_FUNCTION_FAILED;
929
930 DEBUG2(qla_printk(KERN_WARNING, ha,
931@@ -2406,7 +2682,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha
932 QLA_DRIVER_PATCH_VER, QLA_DRIVER_BETA_VER);
933
934 /* Locate marker. */
935- ha->hw_event_ptr = ha->hw_event_start;
936+ ha->hw_event_ptr = ha->flt_region_hw_event;
937 for (;;) {
938 qla24xx_read_flash_data(ha, fdata, ha->hw_event_ptr,
939 4);
940@@ -2415,7 +2691,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha
941 break;
942 ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE;
943 if (ha->hw_event_ptr >=
944- ha->hw_event_start + FA_HW_EVENT_SIZE) {
945+ ha->flt_region_hw_event + FA_HW_EVENT_SIZE) {
946 DEBUG2(qla_printk(KERN_WARNING, ha,
947 "HW event -- Log Full!\n"));
948 return QLA_MEMORY_ALLOC_FAILED;
949--- a/drivers/scsi/qla2xxx/qla_version.h
950+++ b/drivers/scsi/qla2xxx/qla_version.h
951@@ -7,7 +7,7 @@
952 /*
953 * Driver version
954 */
955-#define QLA2XXX_VERSION "8.02.01-k7"
956+#define QLA2XXX_VERSION "8.02.01-k8"
957
958 #define QLA_DRIVER_MAJOR_VER 8
959 #define QLA_DRIVER_MINOR_VER 2