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 ******************************************************************************/
23 static uint16_t qla2x00_nvram_request(scsi_qla_host_t *, uint32_t);
24 static void qla2x00_nv_deselect(scsi_qla_host_t *);
25 static void qla2x00_nv_write(scsi_qla_host_t *, uint16_t);
29 * NVRAM support routines
33 * qla2x00_lock_nvram_access() -
37 qla2x00_lock_nvram_access(scsi_qla_host_t *ha)
44 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) {
45 data = RD_REG_WORD(®->nvram);
46 while (data & NVR_BUSY) {
48 data = RD_REG_WORD(®->nvram);
52 WRT_REG_WORD(®->u.isp2300.host_semaphore, 0x1);
54 data = RD_REG_WORD(®->u.isp2300.host_semaphore);
55 while ((data & BIT_0) == 0) {
58 WRT_REG_WORD(®->u.isp2300.host_semaphore, 0x1);
60 data = RD_REG_WORD(®->u.isp2300.host_semaphore);
66 * qla2x00_unlock_nvram_access() -
70 qla2x00_unlock_nvram_access(scsi_qla_host_t *ha)
76 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha))
77 WRT_REG_WORD(®->u.isp2300.host_semaphore, 0);
81 * qla2x00_get_nvram_word() - Calculates word position in NVRAM and calls the
82 * request routine to get the word from NVRAM.
84 * @addr: Address in NVRAM to read
86 * Returns the word read from nvram @addr.
89 qla2x00_get_nvram_word(scsi_qla_host_t *ha, uint32_t addr)
96 data = qla2x00_nvram_request(ha, nv_cmd);
102 * qla2x00_write_nvram_word() - Write NVRAM data.
104 * @addr: Address in NVRAM to write
105 * @data: word to program
108 qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data)
113 device_reg_t *reg = ha->iobase;
115 qla2x00_nv_write(ha, NVR_DATA_OUT);
116 qla2x00_nv_write(ha, 0);
117 qla2x00_nv_write(ha, 0);
119 for (word = 0; word < 8; word++)
120 qla2x00_nv_write(ha, NVR_DATA_OUT);
122 qla2x00_nv_deselect(ha);
125 nv_cmd = (addr << 16) | NV_ERASE_OP;
127 for (count = 0; count < 11; count++) {
129 qla2x00_nv_write(ha, NVR_DATA_OUT);
131 qla2x00_nv_write(ha, 0);
136 qla2x00_nv_deselect(ha);
138 /* Wait for Erase to Finish */
139 WRT_REG_WORD(®->nvram, NVR_SELECT);
142 word = RD_REG_WORD(®->nvram);
143 } while ((word & NVR_DATA_IN) == 0);
145 qla2x00_nv_deselect(ha);
148 nv_cmd = (addr << 16) | NV_WRITE_OP;
151 for (count = 0; count < 27; count++) {
153 qla2x00_nv_write(ha, NVR_DATA_OUT);
155 qla2x00_nv_write(ha, 0);
160 qla2x00_nv_deselect(ha);
162 /* Wait for NVRAM to become ready */
163 WRT_REG_WORD(®->nvram, NVR_SELECT);
166 word = RD_REG_WORD(®->nvram);
167 } while ((word & NVR_DATA_IN) == 0);
169 qla2x00_nv_deselect(ha);
172 qla2x00_nv_write(ha, NVR_DATA_OUT);
173 for (count = 0; count < 10; count++)
174 qla2x00_nv_write(ha, 0);
176 qla2x00_nv_deselect(ha);
180 * qla2x00_nvram_request() - Sends read command to NVRAM and gets data from
183 * @nv_cmd: NVRAM command
185 * Bit definitions for NVRAM command:
188 * Bit 25, 24 = opcode
189 * Bit 23-16 = address
190 * Bit 15-0 = write data
192 * Returns the word read from nvram @addr.
195 qla2x00_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd)
198 device_reg_t *reg = ha->iobase;
202 /* Send command to NVRAM. */
204 for (cnt = 0; cnt < 11; cnt++) {
206 qla2x00_nv_write(ha, NVR_DATA_OUT);
208 qla2x00_nv_write(ha, 0);
212 /* Read data from NVRAM. */
213 for (cnt = 0; cnt < 16; cnt++) {
214 WRT_REG_WORD(®->nvram, NVR_SELECT | NVR_CLOCK);
217 reg_data = RD_REG_WORD(®->nvram);
218 if (reg_data & NVR_DATA_IN)
220 WRT_REG_WORD(®->nvram, NVR_SELECT);
222 RD_REG_WORD(®->nvram); /* PCI Posting. */
226 WRT_REG_WORD(®->nvram, NVR_DESELECT);
228 RD_REG_WORD(®->nvram); /* PCI Posting. */
234 * qla2x00_nv_write() - Clean NVRAM operations.
238 qla2x00_nv_deselect(scsi_qla_host_t *ha)
240 device_reg_t *reg = ha->iobase;
242 WRT_REG_WORD(®->nvram, NVR_DESELECT);
244 RD_REG_WORD(®->nvram); /* PCI Posting. */
248 * qla2x00_nv_write() - Prepare for NVRAM read/write operation.
250 * @data: Serial interface selector
253 qla2x00_nv_write(scsi_qla_host_t *ha, uint16_t data)
255 device_reg_t *reg = ha->iobase;
257 WRT_REG_WORD(®->nvram, data | NVR_SELECT);
259 RD_REG_WORD(®->nvram); /* PCI Posting. */
260 WRT_REG_WORD(®->nvram, data | NVR_SELECT | NVR_CLOCK);
262 RD_REG_WORD(®->nvram); /* PCI Posting. */
263 WRT_REG_WORD(®->nvram, data | NVR_SELECT);
265 RD_REG_WORD(®->nvram); /* PCI Posting. */