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