Merge master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6] / drivers / scsi / qla2xxx / qla_sup.c
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         /* Enable flash write-protection. */
577         qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c);
578
579         /* Disable flash write. */
580         WRT_REG_DWORD(&reg->ctrl_status,
581             RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
582         RD_REG_DWORD(&reg->ctrl_status);        /* PCI Posting. */
583
584         return ret;
585 }
586
587 uint8_t *
588 qla2x00_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
589     uint32_t bytes)
590 {
591         uint32_t i;
592         uint16_t *wptr;
593
594         /* Word reads to NVRAM via registers. */
595         wptr = (uint16_t *)buf;
596         qla2x00_lock_nvram_access(ha);
597         for (i = 0; i < bytes >> 1; i++, naddr++)
598                 wptr[i] = cpu_to_le16(qla2x00_get_nvram_word(ha,
599                     naddr));
600         qla2x00_unlock_nvram_access(ha);
601
602         return buf;
603 }
604
605 uint8_t *
606 qla24xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
607     uint32_t bytes)
608 {
609         uint32_t i;
610         uint32_t *dwptr;
611
612         /* Dword reads to flash. */
613         dwptr = (uint32_t *)buf;
614         for (i = 0; i < bytes >> 2; i++, naddr++)
615                 dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
616                     nvram_data_to_access_addr(naddr)));
617
618         return buf;
619 }
620
621 int
622 qla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
623     uint32_t bytes)
624 {
625         int ret, stat;
626         uint32_t i;
627         uint16_t *wptr;
628
629         ret = QLA_SUCCESS;
630
631         qla2x00_lock_nvram_access(ha);
632
633         /* Disable NVRAM write-protection. */
634         stat = qla2x00_clear_nvram_protection(ha);
635
636         wptr = (uint16_t *)buf;
637         for (i = 0; i < bytes >> 1; i++, naddr++) {
638                 qla2x00_write_nvram_word(ha, naddr,
639                     cpu_to_le16(*wptr));
640                 wptr++;
641         }
642
643         /* Enable NVRAM write-protection. */
644         qla2x00_set_nvram_protection(ha, stat);
645
646         qla2x00_unlock_nvram_access(ha);
647
648         return ret;
649 }
650
651 int
652 qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
653     uint32_t bytes)
654 {
655         int ret;
656         uint32_t i;
657         uint32_t *dwptr;
658         struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
659
660         ret = QLA_SUCCESS;
661
662         /* Enable flash write. */
663         WRT_REG_DWORD(&reg->ctrl_status,
664             RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
665         RD_REG_DWORD(&reg->ctrl_status);        /* PCI Posting. */
666
667         /* Disable NVRAM write-protection. */
668         qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
669             0);
670         qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
671             0);
672
673         /* Dword writes to flash. */
674         dwptr = (uint32_t *)buf;
675         for (i = 0; i < bytes >> 2; i++, naddr++, dwptr++) {
676                 ret = qla24xx_write_flash_dword(ha,
677                     nvram_data_to_access_addr(naddr),
678                     cpu_to_le32(*dwptr));
679                 if (ret != QLA_SUCCESS) {
680                         DEBUG9(printk("%s(%ld) Unable to program "
681                             "nvram address=%x data=%x.\n", __func__,
682                             ha->host_no, naddr, *dwptr));
683                         break;
684                 }
685         }
686
687         /* Enable NVRAM write-protection. */
688         qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
689             0x8c);
690
691         /* Disable flash write. */
692         WRT_REG_DWORD(&reg->ctrl_status,
693             RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
694         RD_REG_DWORD(&reg->ctrl_status);        /* PCI Posting. */
695
696         return ret;
697 }