]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.drivers/qla2xxx-8.02.01-k8-update
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / qla2xxx-8.02.01-k8-update
1 From: Andrew Vasquez
2 Subject: Update qla2xxx to 8.02.01-k8
3 References: FATE#304113
4
5 This patch updates the qla2xxx driver to version 8.02.01-k8.
6
7 Signed-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