Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

orinoco: Add function to execute Hermes initialisation commands synchronously

The current synchronous execution function doesn't work
for certain Hermes commands which clear the MAGIC number from
SWSUPPORT0. These commands seem to be related to initialisation or
programming, for example HERMES_CMD_INIT.

Replicate hermes_docmd_wait for commands which clear the MAGIC number
from SWSUPPORT0. This version accepts two extra arguments which are
passed straight to the firmware.

Functionality copied out of hermes_init.

Signed-off-by: David Kilroy <kilroyd@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

David Kilroy and committed by
John W. Linville
fc5a62d8 82a06ee5

+60 -37
+57 -37
drivers/net/wireless/hermes.c
··· 116 116 * Function definitions 117 117 */ 118 118 119 + /* For doing cmds that wipe the magic constant in SWSUPPORT0 */ 120 + int hermes_doicmd_wait(hermes_t *hw, u16 cmd, 121 + u16 parm0, u16 parm1, u16 parm2, 122 + struct hermes_response *resp) 123 + { 124 + int err = 0; 125 + int k; 126 + u16 status, reg; 127 + 128 + err = hermes_issue_cmd(hw, cmd, parm0, parm1, parm2); 129 + if (err) 130 + return err; 131 + 132 + reg = hermes_read_regn(hw, EVSTAT); 133 + k = CMD_INIT_TIMEOUT; 134 + while ((!(reg & HERMES_EV_CMD)) && k) { 135 + k--; 136 + udelay(10); 137 + reg = hermes_read_regn(hw, EVSTAT); 138 + } 139 + 140 + hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC); 141 + 142 + if (!hermes_present(hw)) { 143 + DEBUG(0, "hermes @ 0x%x: Card removed during reset.\n", 144 + hw->iobase); 145 + err = -ENODEV; 146 + goto out; 147 + } 148 + 149 + if (!(reg & HERMES_EV_CMD)) { 150 + printk(KERN_ERR "hermes @ %p: " 151 + "Timeout waiting for card to reset (reg=0x%04x)!\n", 152 + hw->iobase, reg); 153 + err = -ETIMEDOUT; 154 + goto out; 155 + } 156 + 157 + status = hermes_read_regn(hw, STATUS); 158 + if (resp) { 159 + resp->status = status; 160 + resp->resp0 = hermes_read_regn(hw, RESP0); 161 + resp->resp1 = hermes_read_regn(hw, RESP1); 162 + resp->resp2 = hermes_read_regn(hw, RESP2); 163 + } 164 + 165 + hermes_write_regn(hw, EVACK, HERMES_EV_CMD); 166 + 167 + if (status & HERMES_STATUS_RESULT) 168 + err = -EIO; 169 + out: 170 + return err; 171 + } 172 + EXPORT_SYMBOL(hermes_doicmd_wait); 173 + 119 174 void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing) 120 175 { 121 176 hw->iobase = address; ··· 181 126 182 127 int hermes_init(hermes_t *hw) 183 128 { 184 - u16 status, reg; 129 + u16 reg; 185 130 int err = 0; 186 131 int k; 187 132 ··· 219 164 220 165 /* We don't use hermes_docmd_wait here, because the reset wipes 221 166 the magic constant in SWSUPPORT0 away, and it gets confused */ 222 - err = hermes_issue_cmd(hw, HERMES_CMD_INIT, 0, 0, 0); 223 - if (err) 224 - return err; 167 + err = hermes_doicmd_wait(hw, HERMES_CMD_INIT, 0, 0, 0, NULL); 225 168 226 - reg = hermes_read_regn(hw, EVSTAT); 227 - k = CMD_INIT_TIMEOUT; 228 - while ( (! (reg & HERMES_EV_CMD)) && k) { 229 - k--; 230 - udelay(10); 231 - reg = hermes_read_regn(hw, EVSTAT); 232 - } 233 - 234 - hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC); 235 - 236 - if (! hermes_present(hw)) { 237 - DEBUG(0, "hermes @ 0x%x: Card removed during reset.\n", 238 - hw->iobase); 239 - err = -ENODEV; 240 - goto out; 241 - } 242 - 243 - if (! (reg & HERMES_EV_CMD)) { 244 - printk(KERN_ERR "hermes @ %p: " 245 - "Timeout waiting for card to reset (reg=0x%04x)!\n", 246 - hw->iobase, reg); 247 - err = -ETIMEDOUT; 248 - goto out; 249 - } 250 - 251 - status = hermes_read_regn(hw, STATUS); 252 - 253 - hermes_write_regn(hw, EVACK, HERMES_EV_CMD); 254 - 255 - if (status & HERMES_STATUS_RESULT) 256 - err = -EIO; 257 - 258 - out: 259 169 return err; 260 170 } 261 171 EXPORT_SYMBOL(hermes_init);
+3
drivers/net/wireless/hermes.h
··· 353 353 int hermes_init(hermes_t *hw); 354 354 int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, 355 355 struct hermes_response *resp); 356 + int hermes_doicmd_wait(hermes_t *hw, u16 cmd, 357 + u16 parm0, u16 parm1, u16 parm2, 358 + struct hermes_response *resp); 356 359 int hermes_allocate(hermes_t *hw, u16 size, u16 *fid); 357 360 358 361 int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,