xref: /linux/drivers/scsi/qla2xxx/qla_sup.c (revision 9ce7677cfd7cd871adb457c80bea3b581b839641)
1 /*
2  * QLogic Fibre Channel HBA Driver
3  * Copyright (c)  2003-2005 QLogic Corporation
4  *
5  * See LICENSE.qla2xxx for copyright and licensing details.
6  */
7 #include "qla_def.h"
8 
9 #include <linux/delay.h>
10 #include <asm/uaccess.h>
11 
12 static uint16_t qla2x00_nvram_request(scsi_qla_host_t *, uint32_t);
13 static void qla2x00_nv_deselect(scsi_qla_host_t *);
14 static void qla2x00_nv_write(scsi_qla_host_t *, uint16_t);
15 
16 /*
17  * NVRAM support routines
18  */
19 
20 /**
21  * qla2x00_lock_nvram_access() -
22  * @ha: HA context
23  */
24 void
25 qla2x00_lock_nvram_access(scsi_qla_host_t *ha)
26 {
27 	uint16_t data;
28 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
29 
30 	if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) {
31 		data = RD_REG_WORD(&reg->nvram);
32 		while (data & NVR_BUSY) {
33 			udelay(100);
34 			data = RD_REG_WORD(&reg->nvram);
35 		}
36 
37 		/* Lock resource */
38 		WRT_REG_WORD(&reg->u.isp2300.host_semaphore, 0x1);
39 		RD_REG_WORD(&reg->u.isp2300.host_semaphore);
40 		udelay(5);
41 		data = RD_REG_WORD(&reg->u.isp2300.host_semaphore);
42 		while ((data & BIT_0) == 0) {
43 			/* Lock failed */
44 			udelay(100);
45 			WRT_REG_WORD(&reg->u.isp2300.host_semaphore, 0x1);
46 			RD_REG_WORD(&reg->u.isp2300.host_semaphore);
47 			udelay(5);
48 			data = RD_REG_WORD(&reg->u.isp2300.host_semaphore);
49 		}
50 	}
51 }
52 
53 /**
54  * qla2x00_unlock_nvram_access() -
55  * @ha: HA context
56  */
57 void
58 qla2x00_unlock_nvram_access(scsi_qla_host_t *ha)
59 {
60 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
61 
62 	if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) {
63 		WRT_REG_WORD(&reg->u.isp2300.host_semaphore, 0);
64 		RD_REG_WORD(&reg->u.isp2300.host_semaphore);
65 	}
66 }
67 
68 /**
69  * qla2x00_get_nvram_word() - Calculates word position in NVRAM and calls the
70  *	request routine to get the word from NVRAM.
71  * @ha: HA context
72  * @addr: Address in NVRAM to read
73  *
74  * Returns the word read from nvram @addr.
75  */
76 uint16_t
77 qla2x00_get_nvram_word(scsi_qla_host_t *ha, uint32_t addr)
78 {
79 	uint16_t	data;
80 	uint32_t	nv_cmd;
81 
82 	nv_cmd = addr << 16;
83 	nv_cmd |= NV_READ_OP;
84 	data = qla2x00_nvram_request(ha, nv_cmd);
85 
86 	return (data);
87 }
88 
89 /**
90  * qla2x00_write_nvram_word() - Write NVRAM data.
91  * @ha: HA context
92  * @addr: Address in NVRAM to write
93  * @data: word to program
94  */
95 void
96 qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data)
97 {
98 	int count;
99 	uint16_t word;
100 	uint32_t nv_cmd;
101 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
102 
103 	qla2x00_nv_write(ha, NVR_DATA_OUT);
104 	qla2x00_nv_write(ha, 0);
105 	qla2x00_nv_write(ha, 0);
106 
107 	for (word = 0; word < 8; word++)
108 		qla2x00_nv_write(ha, NVR_DATA_OUT);
109 
110 	qla2x00_nv_deselect(ha);
111 
112 	/* Write data */
113 	nv_cmd = (addr << 16) | NV_WRITE_OP;
114 	nv_cmd |= data;
115 	nv_cmd <<= 5;
116 	for (count = 0; count < 27; count++) {
117 		if (nv_cmd & BIT_31)
118 			qla2x00_nv_write(ha, NVR_DATA_OUT);
119 		else
120 			qla2x00_nv_write(ha, 0);
121 
122 		nv_cmd <<= 1;
123 	}
124 
125 	qla2x00_nv_deselect(ha);
126 
127 	/* Wait for NVRAM to become ready */
128 	WRT_REG_WORD(&reg->nvram, NVR_SELECT);
129 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
130 	do {
131 		NVRAM_DELAY();
132 		word = RD_REG_WORD(&reg->nvram);
133 	} while ((word & NVR_DATA_IN) == 0);
134 
135 	qla2x00_nv_deselect(ha);
136 
137 	/* Disable writes */
138 	qla2x00_nv_write(ha, NVR_DATA_OUT);
139 	for (count = 0; count < 10; count++)
140 		qla2x00_nv_write(ha, 0);
141 
142 	qla2x00_nv_deselect(ha);
143 }
144 
145 static int
146 qla2x00_write_nvram_word_tmo(scsi_qla_host_t *ha, uint32_t addr, uint16_t data,
147     uint32_t tmo)
148 {
149 	int ret, count;
150 	uint16_t word;
151 	uint32_t nv_cmd;
152 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
153 
154 	ret = QLA_SUCCESS;
155 
156 	qla2x00_nv_write(ha, NVR_DATA_OUT);
157 	qla2x00_nv_write(ha, 0);
158 	qla2x00_nv_write(ha, 0);
159 
160 	for (word = 0; word < 8; word++)
161 		qla2x00_nv_write(ha, NVR_DATA_OUT);
162 
163 	qla2x00_nv_deselect(ha);
164 
165 	/* Write data */
166 	nv_cmd = (addr << 16) | NV_WRITE_OP;
167 	nv_cmd |= data;
168 	nv_cmd <<= 5;
169 	for (count = 0; count < 27; count++) {
170 		if (nv_cmd & BIT_31)
171 			qla2x00_nv_write(ha, NVR_DATA_OUT);
172 		else
173 			qla2x00_nv_write(ha, 0);
174 
175 		nv_cmd <<= 1;
176 	}
177 
178 	qla2x00_nv_deselect(ha);
179 
180 	/* Wait for NVRAM to become ready */
181 	WRT_REG_WORD(&reg->nvram, NVR_SELECT);
182 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
183 	do {
184 		NVRAM_DELAY();
185 		word = RD_REG_WORD(&reg->nvram);
186 		if (!--tmo) {
187 			ret = QLA_FUNCTION_FAILED;
188 			break;
189 		}
190 	} while ((word & NVR_DATA_IN) == 0);
191 
192 	qla2x00_nv_deselect(ha);
193 
194 	/* Disable writes */
195 	qla2x00_nv_write(ha, NVR_DATA_OUT);
196 	for (count = 0; count < 10; count++)
197 		qla2x00_nv_write(ha, 0);
198 
199 	qla2x00_nv_deselect(ha);
200 
201 	return ret;
202 }
203 
204 /**
205  * qla2x00_nvram_request() - Sends read command to NVRAM and gets data from
206  *	NVRAM.
207  * @ha: HA context
208  * @nv_cmd: NVRAM command
209  *
210  * Bit definitions for NVRAM command:
211  *
212  *	Bit 26     = start bit
213  *	Bit 25, 24 = opcode
214  *	Bit 23-16  = address
215  *	Bit 15-0   = write data
216  *
217  * Returns the word read from nvram @addr.
218  */
219 static uint16_t
220 qla2x00_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd)
221 {
222 	uint8_t		cnt;
223 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
224 	uint16_t	data = 0;
225 	uint16_t	reg_data;
226 
227 	/* Send command to NVRAM. */
228 	nv_cmd <<= 5;
229 	for (cnt = 0; cnt < 11; cnt++) {
230 		if (nv_cmd & BIT_31)
231 			qla2x00_nv_write(ha, NVR_DATA_OUT);
232 		else
233 			qla2x00_nv_write(ha, 0);
234 		nv_cmd <<= 1;
235 	}
236 
237 	/* Read data from NVRAM. */
238 	for (cnt = 0; cnt < 16; cnt++) {
239 		WRT_REG_WORD(&reg->nvram, NVR_SELECT | NVR_CLOCK);
240 		RD_REG_WORD(&reg->nvram);	/* PCI Posting. */
241 		NVRAM_DELAY();
242 		data <<= 1;
243 		reg_data = RD_REG_WORD(&reg->nvram);
244 		if (reg_data & NVR_DATA_IN)
245 			data |= BIT_0;
246 		WRT_REG_WORD(&reg->nvram, NVR_SELECT);
247 		RD_REG_WORD(&reg->nvram);	/* PCI Posting. */
248 		NVRAM_DELAY();
249 	}
250 
251 	/* Deselect chip. */
252 	WRT_REG_WORD(&reg->nvram, NVR_DESELECT);
253 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
254 	NVRAM_DELAY();
255 
256 	return (data);
257 }
258 
259 /**
260  * qla2x00_nv_write() - Clean NVRAM operations.
261  * @ha: HA context
262  */
263 static void
264 qla2x00_nv_deselect(scsi_qla_host_t *ha)
265 {
266 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
267 
268 	WRT_REG_WORD(&reg->nvram, NVR_DESELECT);
269 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
270 	NVRAM_DELAY();
271 }
272 
273 /**
274  * qla2x00_nv_write() - Prepare for NVRAM read/write operation.
275  * @ha: HA context
276  * @data: Serial interface selector
277  */
278 static void
279 qla2x00_nv_write(scsi_qla_host_t *ha, uint16_t data)
280 {
281 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
282 
283 	WRT_REG_WORD(&reg->nvram, data | NVR_SELECT | NVR_WRT_ENABLE);
284 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
285 	NVRAM_DELAY();
286 	WRT_REG_WORD(&reg->nvram, data | NVR_SELECT| NVR_CLOCK |
287 	    NVR_WRT_ENABLE);
288 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
289 	NVRAM_DELAY();
290 	WRT_REG_WORD(&reg->nvram, data | NVR_SELECT | NVR_WRT_ENABLE);
291 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
292 	NVRAM_DELAY();
293 }
294 
295 /**
296  * qla2x00_clear_nvram_protection() -
297  * @ha: HA context
298  */
299 static int
300 qla2x00_clear_nvram_protection(scsi_qla_host_t *ha)
301 {
302 	int ret, stat;
303 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
304 	uint32_t word;
305 	uint16_t wprot, wprot_old;
306 
307 	/* Clear NVRAM write protection. */
308 	ret = QLA_FUNCTION_FAILED;
309 	wprot_old = cpu_to_le16(qla2x00_get_nvram_word(ha, 0));
310 	stat = qla2x00_write_nvram_word_tmo(ha, 0,
311 	    __constant_cpu_to_le16(0x1234), 100000);
312 	wprot = cpu_to_le16(qla2x00_get_nvram_word(ha, 0));
313 	if (stat != QLA_SUCCESS || wprot != __constant_cpu_to_le16(0x1234)) {
314 		/* Write enable. */
315 		qla2x00_nv_write(ha, NVR_DATA_OUT);
316 		qla2x00_nv_write(ha, 0);
317 		qla2x00_nv_write(ha, 0);
318 		for (word = 0; word < 8; word++)
319 			qla2x00_nv_write(ha, NVR_DATA_OUT);
320 
321 		qla2x00_nv_deselect(ha);
322 
323 		/* Enable protection register. */
324 		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
325 		qla2x00_nv_write(ha, NVR_PR_ENABLE);
326 		qla2x00_nv_write(ha, NVR_PR_ENABLE);
327 		for (word = 0; word < 8; word++)
328 			qla2x00_nv_write(ha, NVR_DATA_OUT | NVR_PR_ENABLE);
329 
330 		qla2x00_nv_deselect(ha);
331 
332 		/* Clear protection register (ffff is cleared). */
333 		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
334 		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
335 		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
336 		for (word = 0; word < 8; word++)
337 			qla2x00_nv_write(ha, NVR_DATA_OUT | NVR_PR_ENABLE);
338 
339 		qla2x00_nv_deselect(ha);
340 
341 		/* Wait for NVRAM to become ready. */
342 		WRT_REG_WORD(&reg->nvram, NVR_SELECT);
343 		RD_REG_WORD(&reg->nvram);	/* PCI Posting. */
344 		do {
345 			NVRAM_DELAY();
346 			word = RD_REG_WORD(&reg->nvram);
347 		} while ((word & NVR_DATA_IN) == 0);
348 
349 		ret = QLA_SUCCESS;
350 	} else
351 		qla2x00_write_nvram_word(ha, 0, wprot_old);
352 
353 	return ret;
354 }
355 
356 static void
357 qla2x00_set_nvram_protection(scsi_qla_host_t *ha, int stat)
358 {
359 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
360 	uint32_t word;
361 
362 	if (stat != QLA_SUCCESS)
363 		return;
364 
365 	/* Set NVRAM write protection. */
366 	/* Write enable. */
367 	qla2x00_nv_write(ha, NVR_DATA_OUT);
368 	qla2x00_nv_write(ha, 0);
369 	qla2x00_nv_write(ha, 0);
370 	for (word = 0; word < 8; word++)
371 		qla2x00_nv_write(ha, NVR_DATA_OUT);
372 
373 	qla2x00_nv_deselect(ha);
374 
375 	/* Enable protection register. */
376 	qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
377 	qla2x00_nv_write(ha, NVR_PR_ENABLE);
378 	qla2x00_nv_write(ha, NVR_PR_ENABLE);
379 	for (word = 0; word < 8; word++)
380 		qla2x00_nv_write(ha, NVR_DATA_OUT | NVR_PR_ENABLE);
381 
382 	qla2x00_nv_deselect(ha);
383 
384 	/* Enable protection register. */
385 	qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
386 	qla2x00_nv_write(ha, NVR_PR_ENABLE);
387 	qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
388 	for (word = 0; word < 8; word++)
389 		qla2x00_nv_write(ha, NVR_PR_ENABLE);
390 
391 	qla2x00_nv_deselect(ha);
392 
393 	/* Wait for NVRAM to become ready. */
394 	WRT_REG_WORD(&reg->nvram, NVR_SELECT);
395 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
396 	do {
397 		NVRAM_DELAY();
398 		word = RD_REG_WORD(&reg->nvram);
399 	} while ((word & NVR_DATA_IN) == 0);
400 }
401 
402 
403 /*****************************************************************************/
404 /* Flash Manipulation Routines                                               */
405 /*****************************************************************************/
406 
407 static inline uint32_t
408 flash_conf_to_access_addr(uint32_t faddr)
409 {
410 	return FARX_ACCESS_FLASH_CONF | faddr;
411 }
412 
413 static inline uint32_t
414 flash_data_to_access_addr(uint32_t faddr)
415 {
416 	return FARX_ACCESS_FLASH_DATA | faddr;
417 }
418 
419 static inline uint32_t
420 nvram_conf_to_access_addr(uint32_t naddr)
421 {
422 	return FARX_ACCESS_NVRAM_CONF | naddr;
423 }
424 
425 static inline uint32_t
426 nvram_data_to_access_addr(uint32_t naddr)
427 {
428 	return FARX_ACCESS_NVRAM_DATA | naddr;
429 }
430 
431 uint32_t
432 qla24xx_read_flash_dword(scsi_qla_host_t *ha, uint32_t addr)
433 {
434 	int rval;
435 	uint32_t cnt, data;
436 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
437 
438 	WRT_REG_DWORD(&reg->flash_addr, addr & ~FARX_DATA_FLAG);
439 	/* Wait for READ cycle to complete. */
440 	rval = QLA_SUCCESS;
441 	for (cnt = 3000;
442 	    (RD_REG_DWORD(&reg->flash_addr) & FARX_DATA_FLAG) == 0 &&
443 	    rval == QLA_SUCCESS; cnt--) {
444 		if (cnt)
445 			udelay(10);
446 		else
447 			rval = QLA_FUNCTION_TIMEOUT;
448 	}
449 
450 	/* TODO: What happens if we time out? */
451 	data = 0xDEADDEAD;
452 	if (rval == QLA_SUCCESS)
453 		data = RD_REG_DWORD(&reg->flash_data);
454 
455 	return data;
456 }
457 
458 uint32_t *
459 qla24xx_read_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
460     uint32_t dwords)
461 {
462 	uint32_t i;
463 
464 	/* Dword reads to flash. */
465 	for (i = 0; i < dwords; i++, faddr++)
466 		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
467 		    flash_data_to_access_addr(faddr)));
468 
469 	return dwptr;
470 }
471 
472 int
473 qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data)
474 {
475 	int rval;
476 	uint32_t cnt;
477 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
478 
479 	WRT_REG_DWORD(&reg->flash_data, data);
480 	RD_REG_DWORD(&reg->flash_data);		/* PCI Posting. */
481 	WRT_REG_DWORD(&reg->flash_addr, addr | FARX_DATA_FLAG);
482 	/* Wait for Write cycle to complete. */
483 	rval = QLA_SUCCESS;
484 	for (cnt = 500000; (RD_REG_DWORD(&reg->flash_addr) & FARX_DATA_FLAG) &&
485 	    rval == QLA_SUCCESS; cnt--) {
486 		if (cnt)
487 			udelay(10);
488 		else
489 			rval = QLA_FUNCTION_TIMEOUT;
490 	}
491 	return rval;
492 }
493 
494 void
495 qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
496     uint8_t *flash_id)
497 {
498 	uint32_t ids;
499 
500 	ids = qla24xx_read_flash_dword(ha, flash_data_to_access_addr(0xd03ab));
501 	*man_id = LSB(ids);
502 	*flash_id = MSB(ids);
503 }
504 
505 int
506 qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
507     uint32_t dwords)
508 {
509 	int ret;
510 	uint32_t liter;
511 	uint32_t sec_mask, rest_addr, conf_addr;
512 	uint32_t fdata;
513 	uint8_t	man_id, flash_id;
514 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
515 
516 	ret = QLA_SUCCESS;
517 
518 	qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id);
519 	DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__,
520 	    ha->host_no, man_id, flash_id));
521 
522 	conf_addr = flash_conf_to_access_addr(0x03d8);
523 	switch (man_id) {
524 	case 0xbf: /* STT flash. */
525 		rest_addr = 0x1fff;
526 		sec_mask = 0x3e000;
527 		if (flash_id == 0x80)
528 			conf_addr = flash_conf_to_access_addr(0x0352);
529 		break;
530 	case 0x13: /* ST M25P80. */
531 		rest_addr = 0x3fff;
532 		sec_mask = 0x3c000;
533 		break;
534 	default:
535 		/* Default to 64 kb sector size. */
536 		rest_addr = 0x3fff;
537 		sec_mask = 0x3c000;
538 		break;
539 	}
540 
541 	/* Enable flash write. */
542 	WRT_REG_DWORD(&reg->ctrl_status,
543 	    RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
544 	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
545 
546 	/* Disable flash write-protection. */
547 	qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0);
548 
549 	do {    /* Loop once to provide quick error exit. */
550 		for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
551 			/* Are we at the beginning of a sector? */
552 			if ((faddr & rest_addr) == 0) {
553 				fdata = (faddr & sec_mask) << 2;
554 				ret = qla24xx_write_flash_dword(ha, conf_addr,
555 				    (fdata & 0xff00) |((fdata << 16) &
556 				    0xff0000) | ((fdata >> 16) & 0xff));
557 				if (ret != QLA_SUCCESS) {
558 					DEBUG9(printk("%s(%ld) Unable to flash "
559 					    "sector: address=%x.\n", __func__,
560 					    ha->host_no, faddr));
561 					break;
562 				}
563 			}
564 			ret = qla24xx_write_flash_dword(ha,
565 			    flash_data_to_access_addr(faddr),
566 			    cpu_to_le32(*dwptr));
567 			if (ret != QLA_SUCCESS) {
568 				DEBUG9(printk("%s(%ld) Unable to program flash "
569 				    "address=%x data=%x.\n", __func__,
570 				    ha->host_no, faddr, *dwptr));
571 				break;
572 			}
573 		}
574 	} while (0);
575 
576 	/* Disable flash write. */
577 	WRT_REG_DWORD(&reg->ctrl_status,
578 	    RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
579 	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
580 
581 	return ret;
582 }
583 
584 uint8_t *
585 qla2x00_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
586     uint32_t bytes)
587 {
588 	uint32_t i;
589 	uint16_t *wptr;
590 
591 	/* Word reads to NVRAM via registers. */
592 	wptr = (uint16_t *)buf;
593 	qla2x00_lock_nvram_access(ha);
594 	for (i = 0; i < bytes >> 1; i++, naddr++)
595 		wptr[i] = cpu_to_le16(qla2x00_get_nvram_word(ha,
596 		    naddr));
597 	qla2x00_unlock_nvram_access(ha);
598 
599 	return buf;
600 }
601 
602 uint8_t *
603 qla24xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
604     uint32_t bytes)
605 {
606 	uint32_t i;
607 	uint32_t *dwptr;
608 
609 	/* Dword reads to flash. */
610 	dwptr = (uint32_t *)buf;
611 	for (i = 0; i < bytes >> 2; i++, naddr++)
612 		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
613 		    nvram_data_to_access_addr(naddr)));
614 
615 	return buf;
616 }
617 
618 int
619 qla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
620     uint32_t bytes)
621 {
622 	int ret, stat;
623 	uint32_t i;
624 	uint16_t *wptr;
625 
626 	ret = QLA_SUCCESS;
627 
628 	qla2x00_lock_nvram_access(ha);
629 
630 	/* Disable NVRAM write-protection. */
631 	stat = qla2x00_clear_nvram_protection(ha);
632 
633 	wptr = (uint16_t *)buf;
634 	for (i = 0; i < bytes >> 1; i++, naddr++) {
635 		qla2x00_write_nvram_word(ha, naddr,
636 		    cpu_to_le16(*wptr));
637 		wptr++;
638 	}
639 
640 	/* Enable NVRAM write-protection. */
641 	qla2x00_set_nvram_protection(ha, stat);
642 
643 	qla2x00_unlock_nvram_access(ha);
644 
645 	return ret;
646 }
647 
648 int
649 qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
650     uint32_t bytes)
651 {
652 	int ret;
653 	uint32_t i;
654 	uint32_t *dwptr;
655 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
656 
657 	ret = QLA_SUCCESS;
658 
659 	/* Enable flash write. */
660 	WRT_REG_DWORD(&reg->ctrl_status,
661 	    RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
662 	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
663 
664 	/* Disable NVRAM write-protection. */
665 	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
666 	    0);
667 	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
668 	    0);
669 
670 	/* Dword writes to flash. */
671 	dwptr = (uint32_t *)buf;
672 	for (i = 0; i < bytes >> 2; i++, naddr++, dwptr++) {
673 		ret = qla24xx_write_flash_dword(ha,
674 		    nvram_data_to_access_addr(naddr),
675 		    cpu_to_le32(*dwptr));
676 		if (ret != QLA_SUCCESS) {
677 			DEBUG9(printk("%s(%ld) Unable to program "
678 			    "nvram address=%x data=%x.\n", __func__,
679 			    ha->host_no, naddr, *dwptr));
680 			break;
681 		}
682 	}
683 
684 	/* Enable NVRAM write-protection. */
685 	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
686 	    0x8c);
687 
688 	/* Disable flash write. */
689 	WRT_REG_DWORD(&reg->ctrl_status,
690 	    RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
691 	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
692 
693 	return ret;
694 }
695