1 /****************************************************************************** 2 * QLOGIC LINUX SOFTWARE 3 * 4 * QLogic ISP2x00 device driver for Linux 2.6.x 5 * Copyright (C) 2003-2004 QLogic Corporation 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 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); 28 29 /* 30 * NVRAM support routines 31 */ 32 33 /** 34 * qla2x00_lock_nvram_access() - 35 * @ha: HA context 36 */ 37 void 38 qla2x00_lock_nvram_access(scsi_qla_host_t *ha) 39 { 40 uint16_t data; 41 device_reg_t __iomem *reg = ha->iobase; 42 43 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) { 44 data = RD_REG_WORD(®->nvram); 45 while (data & NVR_BUSY) { 46 udelay(100); 47 data = RD_REG_WORD(®->nvram); 48 } 49 50 /* Lock resource */ 51 WRT_REG_WORD(®->u.isp2300.host_semaphore, 0x1); 52 RD_REG_WORD(®->u.isp2300.host_semaphore); 53 udelay(5); 54 data = RD_REG_WORD(®->u.isp2300.host_semaphore); 55 while ((data & BIT_0) == 0) { 56 /* Lock failed */ 57 udelay(100); 58 WRT_REG_WORD(®->u.isp2300.host_semaphore, 0x1); 59 RD_REG_WORD(®->u.isp2300.host_semaphore); 60 udelay(5); 61 data = RD_REG_WORD(®->u.isp2300.host_semaphore); 62 } 63 } 64 } 65 66 /** 67 * qla2x00_unlock_nvram_access() - 68 * @ha: HA context 69 */ 70 void 71 qla2x00_unlock_nvram_access(scsi_qla_host_t *ha) 72 { 73 device_reg_t __iomem *reg = ha->iobase; 74 75 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) { 76 WRT_REG_WORD(®->u.isp2300.host_semaphore, 0); 77 RD_REG_WORD(®->u.isp2300.host_semaphore); 78 } 79 } 80 81 /** 82 * qla2x00_release_nvram_protection() - 83 * @ha: HA context 84 */ 85 void 86 qla2x00_release_nvram_protection(scsi_qla_host_t *ha) 87 { 88 device_reg_t __iomem *reg; 89 uint32_t word; 90 91 reg = ha->iobase; 92 93 /* Release NVRAM write protection. */ 94 if (IS_QLA2322(ha) || IS_QLA6322(ha)) { 95 /* Write enable. */ 96 qla2x00_nv_write(ha, NVR_DATA_OUT); 97 qla2x00_nv_write(ha, 0); 98 qla2x00_nv_write(ha, 0); 99 for (word = 0; word < 8; word++) 100 qla2x00_nv_write(ha, NVR_DATA_OUT); 101 102 qla2x00_nv_deselect(ha); 103 104 /* Enable protection register. */ 105 qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT); 106 qla2x00_nv_write(ha, NVR_PR_ENABLE); 107 qla2x00_nv_write(ha, NVR_PR_ENABLE); 108 for (word = 0; word < 8; word++) 109 qla2x00_nv_write(ha, NVR_DATA_OUT | NVR_PR_ENABLE); 110 111 qla2x00_nv_deselect(ha); 112 113 /* Clear protection register (ffff is cleared). */ 114 qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT); 115 qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT); 116 qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT); 117 for (word = 0; word < 8; word++) 118 qla2x00_nv_write(ha, NVR_DATA_OUT | NVR_PR_ENABLE); 119 120 qla2x00_nv_deselect(ha); 121 122 /* Wait for NVRAM to become ready. */ 123 WRT_REG_WORD(®->nvram, NVR_SELECT); 124 do { 125 NVRAM_DELAY(); 126 word = RD_REG_WORD(®->nvram); 127 } while ((word & NVR_DATA_IN) == 0); 128 } 129 } 130 131 /** 132 * qla2x00_get_nvram_word() - Calculates word position in NVRAM and calls the 133 * request routine to get the word from NVRAM. 134 * @ha: HA context 135 * @addr: Address in NVRAM to read 136 * 137 * Returns the word read from nvram @addr. 138 */ 139 uint16_t 140 qla2x00_get_nvram_word(scsi_qla_host_t *ha, uint32_t addr) 141 { 142 uint16_t data; 143 uint32_t nv_cmd; 144 145 nv_cmd = addr << 16; 146 nv_cmd |= NV_READ_OP; 147 data = qla2x00_nvram_request(ha, nv_cmd); 148 149 return (data); 150 } 151 152 /** 153 * qla2x00_write_nvram_word() - Write NVRAM data. 154 * @ha: HA context 155 * @addr: Address in NVRAM to write 156 * @data: word to program 157 */ 158 void 159 qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data) 160 { 161 int count; 162 uint16_t word; 163 uint32_t nv_cmd; 164 device_reg_t __iomem *reg = ha->iobase; 165 166 qla2x00_nv_write(ha, NVR_DATA_OUT); 167 qla2x00_nv_write(ha, 0); 168 qla2x00_nv_write(ha, 0); 169 170 for (word = 0; word < 8; word++) 171 qla2x00_nv_write(ha, NVR_DATA_OUT); 172 173 qla2x00_nv_deselect(ha); 174 175 /* Write data */ 176 nv_cmd = (addr << 16) | NV_WRITE_OP; 177 nv_cmd |= data; 178 nv_cmd <<= 5; 179 for (count = 0; count < 27; count++) { 180 if (nv_cmd & BIT_31) 181 qla2x00_nv_write(ha, NVR_DATA_OUT); 182 else 183 qla2x00_nv_write(ha, 0); 184 185 nv_cmd <<= 1; 186 } 187 188 qla2x00_nv_deselect(ha); 189 190 /* Wait for NVRAM to become ready */ 191 WRT_REG_WORD(®->nvram, NVR_SELECT); 192 do { 193 NVRAM_DELAY(); 194 word = RD_REG_WORD(®->nvram); 195 } while ((word & NVR_DATA_IN) == 0); 196 197 qla2x00_nv_deselect(ha); 198 199 /* Disable writes */ 200 qla2x00_nv_write(ha, NVR_DATA_OUT); 201 for (count = 0; count < 10; count++) 202 qla2x00_nv_write(ha, 0); 203 204 qla2x00_nv_deselect(ha); 205 } 206 207 /** 208 * qla2x00_nvram_request() - Sends read command to NVRAM and gets data from 209 * NVRAM. 210 * @ha: HA context 211 * @nv_cmd: NVRAM command 212 * 213 * Bit definitions for NVRAM command: 214 * 215 * Bit 26 = start bit 216 * Bit 25, 24 = opcode 217 * Bit 23-16 = address 218 * Bit 15-0 = write data 219 * 220 * Returns the word read from nvram @addr. 221 */ 222 static uint16_t 223 qla2x00_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd) 224 { 225 uint8_t cnt; 226 device_reg_t __iomem *reg = ha->iobase; 227 uint16_t data = 0; 228 uint16_t reg_data; 229 230 /* Send command to NVRAM. */ 231 nv_cmd <<= 5; 232 for (cnt = 0; cnt < 11; cnt++) { 233 if (nv_cmd & BIT_31) 234 qla2x00_nv_write(ha, NVR_DATA_OUT); 235 else 236 qla2x00_nv_write(ha, 0); 237 nv_cmd <<= 1; 238 } 239 240 /* Read data from NVRAM. */ 241 for (cnt = 0; cnt < 16; cnt++) { 242 WRT_REG_WORD(®->nvram, NVR_SELECT | NVR_CLOCK); 243 NVRAM_DELAY(); 244 data <<= 1; 245 reg_data = RD_REG_WORD(®->nvram); 246 if (reg_data & NVR_DATA_IN) 247 data |= BIT_0; 248 WRT_REG_WORD(®->nvram, NVR_SELECT); 249 RD_REG_WORD(®->nvram); /* PCI Posting. */ 250 NVRAM_DELAY(); 251 } 252 253 /* Deselect chip. */ 254 WRT_REG_WORD(®->nvram, NVR_DESELECT); 255 RD_REG_WORD(®->nvram); /* PCI Posting. */ 256 NVRAM_DELAY(); 257 258 return (data); 259 } 260 261 /** 262 * qla2x00_nv_write() - Clean NVRAM operations. 263 * @ha: HA context 264 */ 265 static void 266 qla2x00_nv_deselect(scsi_qla_host_t *ha) 267 { 268 device_reg_t __iomem *reg = ha->iobase; 269 270 WRT_REG_WORD(®->nvram, NVR_DESELECT); 271 RD_REG_WORD(®->nvram); /* PCI Posting. */ 272 NVRAM_DELAY(); 273 } 274 275 /** 276 * qla2x00_nv_write() - Prepare for NVRAM read/write operation. 277 * @ha: HA context 278 * @data: Serial interface selector 279 */ 280 static void 281 qla2x00_nv_write(scsi_qla_host_t *ha, uint16_t data) 282 { 283 device_reg_t __iomem *reg = ha->iobase; 284 285 WRT_REG_WORD(®->nvram, data | NVR_SELECT | NVR_WRT_ENABLE); 286 RD_REG_WORD(®->nvram); /* PCI Posting. */ 287 NVRAM_DELAY(); 288 WRT_REG_WORD(®->nvram, data | NVR_SELECT| NVR_CLOCK | 289 NVR_WRT_ENABLE); 290 RD_REG_WORD(®->nvram); /* PCI Posting. */ 291 NVRAM_DELAY(); 292 WRT_REG_WORD(®->nvram, data | NVR_SELECT | NVR_WRT_ENABLE); 293 RD_REG_WORD(®->nvram); /* PCI Posting. */ 294 NVRAM_DELAY(); 295 } 296 297