1 /******************************************************************************
2 * QLOGIC LINUX SOFTWARE
4 * QLogic ISP2x00 device driver for Linux 2.6.x
5 * Copyright (C) 2003-2004 QLogic Corporation
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
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.
18 ******************************************************************************/
22 #include <linux/delay.h>
23 #include <asm/uaccess.h>
25 static uint16_t qla2x00_nvram_request(scsi_qla_host_t *, uint32_t);
26 static void qla2x00_nv_deselect(scsi_qla_host_t *);
27 static void qla2x00_nv_write(scsi_qla_host_t *, uint16_t);
31 * NVRAM support routines
35 * qla2x00_lock_nvram_access() -
39 qla2x00_lock_nvram_access(scsi_qla_host_t *ha)
46 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) {
47 data = RD_REG_WORD(®->nvram);
48 while (data & NVR_BUSY) {
50 data = RD_REG_WORD(®->nvram);
54 WRT_REG_WORD(®->u.isp2300.host_semaphore, 0x1);
56 data = RD_REG_WORD(®->u.isp2300.host_semaphore);
57 while ((data & BIT_0) == 0) {
60 WRT_REG_WORD(®->u.isp2300.host_semaphore, 0x1);
62 data = RD_REG_WORD(®->u.isp2300.host_semaphore);
68 * qla2x00_unlock_nvram_access() -
72 qla2x00_unlock_nvram_access(scsi_qla_host_t *ha)
78 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha))
79 WRT_REG_WORD(®->u.isp2300.host_semaphore, 0);
83 * qla2x00_get_nvram_word() - Calculates word position in NVRAM and calls the
84 * request routine to get the word from NVRAM.
86 * @addr: Address in NVRAM to read
88 * Returns the word read from nvram @addr.
91 qla2x00_get_nvram_word(scsi_qla_host_t *ha, uint32_t addr)
98 data = qla2x00_nvram_request(ha, nv_cmd);
104 * qla2x00_write_nvram_word() - Write NVRAM data.
106 * @addr: Address in NVRAM to write
107 * @data: word to program
110 qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data)
115 device_reg_t *reg = ha->iobase;
117 qla2x00_nv_write(ha, NVR_DATA_OUT);
118 qla2x00_nv_write(ha, 0);
119 qla2x00_nv_write(ha, 0);
121 for (word = 0; word < 8; word++)
122 qla2x00_nv_write(ha, NVR_DATA_OUT);
124 qla2x00_nv_deselect(ha);
127 nv_cmd = (addr << 16) | NV_ERASE_OP;
129 for (count = 0; count < 11; count++) {
131 qla2x00_nv_write(ha, NVR_DATA_OUT);
133 qla2x00_nv_write(ha, 0);
138 qla2x00_nv_deselect(ha);
140 /* Wait for Erase to Finish */
141 WRT_REG_WORD(®->nvram, NVR_SELECT);
144 word = RD_REG_WORD(®->nvram);
145 } while ((word & NVR_DATA_IN) == 0);
147 qla2x00_nv_deselect(ha);
150 nv_cmd = (addr << 16) | NV_WRITE_OP;
153 for (count = 0; count < 27; count++) {
155 qla2x00_nv_write(ha, NVR_DATA_OUT);
157 qla2x00_nv_write(ha, 0);
162 qla2x00_nv_deselect(ha);
164 /* Wait for NVRAM to become ready */
165 WRT_REG_WORD(®->nvram, NVR_SELECT);
168 word = RD_REG_WORD(®->nvram);
169 } while ((word & NVR_DATA_IN) == 0);
171 qla2x00_nv_deselect(ha);
174 qla2x00_nv_write(ha, NVR_DATA_OUT);
175 for (count = 0; count < 10; count++)
176 qla2x00_nv_write(ha, 0);
178 qla2x00_nv_deselect(ha);
182 * qla2x00_nvram_request() - Sends read command to NVRAM and gets data from
185 * @nv_cmd: NVRAM command
187 * Bit definitions for NVRAM command:
190 * Bit 25, 24 = opcode
191 * Bit 23-16 = address
192 * Bit 15-0 = write data
194 * Returns the word read from nvram @addr.
197 qla2x00_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd)
200 device_reg_t *reg = ha->iobase;
204 /* Send command to NVRAM. */
206 for (cnt = 0; cnt < 11; cnt++) {
208 qla2x00_nv_write(ha, NVR_DATA_OUT);
210 qla2x00_nv_write(ha, 0);
214 /* Read data from NVRAM. */
215 for (cnt = 0; cnt < 16; cnt++) {
216 WRT_REG_WORD(®->nvram, NVR_SELECT | NVR_CLOCK);
219 reg_data = RD_REG_WORD(®->nvram);
220 if (reg_data & NVR_DATA_IN)
222 WRT_REG_WORD(®->nvram, NVR_SELECT);
224 RD_REG_WORD(®->nvram); /* PCI Posting. */
228 WRT_REG_WORD(®->nvram, NVR_DESELECT);
230 RD_REG_WORD(®->nvram); /* PCI Posting. */
236 * qla2x00_nv_write() - Clean NVRAM operations.
240 qla2x00_nv_deselect(scsi_qla_host_t *ha)
242 device_reg_t *reg = ha->iobase;
244 WRT_REG_WORD(®->nvram, NVR_DESELECT);
246 RD_REG_WORD(®->nvram); /* PCI Posting. */
250 * qla2x00_nv_write() - Prepare for NVRAM read/write operation.
252 * @data: Serial interface selector
255 qla2x00_nv_write(scsi_qla_host_t *ha, uint16_t data)
257 device_reg_t *reg = ha->iobase;
259 WRT_REG_WORD(®->nvram, data | NVR_SELECT);
261 RD_REG_WORD(®->nvram); /* PCI Posting. */
262 WRT_REG_WORD(®->nvram, data | NVR_SELECT | NVR_CLOCK);
264 RD_REG_WORD(®->nvram); /* PCI Posting. */
265 WRT_REG_WORD(®->nvram, data | NVR_SELECT);
267 RD_REG_WORD(®->nvram); /* PCI Posting. */