Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hostap_download.c
Go to the documentation of this file.
1 static int prism2_enable_aux_port(struct net_device *dev, int enable)
2 {
3  u16 val, reg;
4  int i, tries;
5  unsigned long flags;
6  struct hostap_interface *iface;
7  local_info_t *local;
8 
9  iface = netdev_priv(dev);
10  local = iface->local;
11 
12  if (local->no_pri) {
13  if (enable) {
14  PDEBUG(DEBUG_EXTRA2, "%s: no PRI f/w - assuming Aux "
15  "port is already enabled\n", dev->name);
16  }
17  return 0;
18  }
19 
20  spin_lock_irqsave(&local->cmdlock, flags);
21 
22  /* wait until busy bit is clear */
24  while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
25  tries--;
26  udelay(1);
27  }
28  if (tries == 0) {
29  reg = HFA384X_INW(HFA384X_CMD_OFF);
30  spin_unlock_irqrestore(&local->cmdlock, flags);
31  printk("%s: prism2_enable_aux_port - timeout - reg=0x%04x\n",
32  dev->name, reg);
33  return -ETIMEDOUT;
34  }
35 
36  val = HFA384X_INW(HFA384X_CONTROL_OFF);
37 
38  if (enable) {
39  HFA384X_OUTW(HFA384X_AUX_MAGIC0, HFA384X_PARAM0_OFF);
40  HFA384X_OUTW(HFA384X_AUX_MAGIC1, HFA384X_PARAM1_OFF);
41  HFA384X_OUTW(HFA384X_AUX_MAGIC2, HFA384X_PARAM2_OFF);
42 
44  printk("prism2_enable_aux_port: was not disabled!?\n");
45  val &= ~HFA384X_AUX_PORT_MASK;
47  } else {
48  HFA384X_OUTW(0, HFA384X_PARAM0_OFF);
49  HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
50  HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
51 
53  printk("prism2_enable_aux_port: was not enabled!?\n");
54  val &= ~HFA384X_AUX_PORT_MASK;
56  }
57  HFA384X_OUTW(val, HFA384X_CONTROL_OFF);
58 
59  udelay(5);
60 
61  i = 10000;
62  while (i > 0) {
63  val = HFA384X_INW(HFA384X_CONTROL_OFF);
64  val &= HFA384X_AUX_PORT_MASK;
65 
66  if ((enable && val == HFA384X_AUX_PORT_ENABLED) ||
67  (!enable && val == HFA384X_AUX_PORT_DISABLED))
68  break;
69 
70  udelay(10);
71  i--;
72  }
73 
74  spin_unlock_irqrestore(&local->cmdlock, flags);
75 
76  if (i == 0) {
77  printk("prism2_enable_aux_port(%d) timed out\n",
78  enable);
79  return -ETIMEDOUT;
80  }
81 
82  return 0;
83 }
84 
85 
86 static int hfa384x_from_aux(struct net_device *dev, unsigned int addr, int len,
87  void *buf)
88 {
89  u16 page, offset;
90  if (addr & 1 || len & 1)
91  return -1;
92 
93  page = addr >> 7;
94  offset = addr & 0x7f;
95 
96  HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
97  HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
98 
99  udelay(5);
100 
101 #ifdef PRISM2_PCI
102  {
103  __le16 *pos = (__le16 *) buf;
104  while (len > 0) {
105  *pos++ = HFA384X_INW_DATA(HFA384X_AUXDATA_OFF);
106  len -= 2;
107  }
108  }
109 #else /* PRISM2_PCI */
110  HFA384X_INSW(HFA384X_AUXDATA_OFF, buf, len / 2);
111 #endif /* PRISM2_PCI */
112 
113  return 0;
114 }
115 
116 
117 static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len,
118  void *buf)
119 {
120  u16 page, offset;
121  if (addr & 1 || len & 1)
122  return -1;
123 
124  page = addr >> 7;
125  offset = addr & 0x7f;
126 
127  HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
128  HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);
129 
130  udelay(5);
131 
132 #ifdef PRISM2_PCI
133  {
134  __le16 *pos = (__le16 *) buf;
135  while (len > 0) {
136  HFA384X_OUTW_DATA(*pos++, HFA384X_AUXDATA_OFF);
137  len -= 2;
138  }
139  }
140 #else /* PRISM2_PCI */
141  HFA384X_OUTSW(HFA384X_AUXDATA_OFF, buf, len / 2);
142 #endif /* PRISM2_PCI */
143 
144  return 0;
145 }
146 
147 
148 static int prism2_pda_ok(u8 *buf)
149 {
150  __le16 *pda = (__le16 *) buf;
151  int pos;
152  u16 len, pdr;
153 
154  if (buf[0] == 0xff && buf[1] == 0x00 && buf[2] == 0xff &&
155  buf[3] == 0x00)
156  return 0;
157 
158  pos = 0;
159  while (pos + 1 < PRISM2_PDA_SIZE / 2) {
160  len = le16_to_cpu(pda[pos]);
161  pdr = le16_to_cpu(pda[pos + 1]);
162  if (len == 0 || pos + len > PRISM2_PDA_SIZE / 2)
163  return 0;
164 
165  if (pdr == 0x0000 && len == 2) {
166  /* PDA end found */
167  return 1;
168  }
169 
170  pos += len + 1;
171  }
172 
173  return 0;
174 }
175 
176 
177 static int prism2_download_aux_dump(struct net_device *dev,
178  unsigned int addr, int len, u8 *buf)
179 {
180  int res;
181 
182  prism2_enable_aux_port(dev, 1);
183  res = hfa384x_from_aux(dev, addr, len, buf);
184  prism2_enable_aux_port(dev, 0);
185  if (res)
186  return -1;
187 
188  return 0;
189 }
190 
191 
192 static u8 * prism2_read_pda(struct net_device *dev)
193 {
194  u8 *buf;
195  int res, i, found = 0;
196 #define NUM_PDA_ADDRS 4
197  unsigned int pda_addr[NUM_PDA_ADDRS] = {
198  0x7f0000 /* others than HFA3841 */,
199  0x3f0000 /* HFA3841 */,
200  0x390000 /* apparently used in older cards */,
201  0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */,
202  };
203 
205  if (buf == NULL)
206  return NULL;
207 
208  /* Note: wlan card should be in initial state (just after init cmd)
209  * and no other operations should be performed concurrently. */
210 
211  prism2_enable_aux_port(dev, 1);
212 
213  for (i = 0; i < NUM_PDA_ADDRS; i++) {
214  PDEBUG(DEBUG_EXTRA2, "%s: trying to read PDA from 0x%08x",
215  dev->name, pda_addr[i]);
216  res = hfa384x_from_aux(dev, pda_addr[i], PRISM2_PDA_SIZE, buf);
217  if (res)
218  continue;
219  if (res == 0 && prism2_pda_ok(buf)) {
220  PDEBUG2(DEBUG_EXTRA2, ": OK\n");
221  found = 1;
222  break;
223  } else {
224  PDEBUG2(DEBUG_EXTRA2, ": failed\n");
225  }
226  }
227 
228  prism2_enable_aux_port(dev, 0);
229 
230  if (!found) {
231  printk(KERN_DEBUG "%s: valid PDA not found\n", dev->name);
232  kfree(buf);
233  buf = NULL;
234  }
235 
236  return buf;
237 }
238 
239 
240 static int prism2_download_volatile(local_info_t *local,
241  struct prism2_download_data *param)
242 {
243  struct net_device *dev = local->dev;
244  int ret = 0, i;
245  u16 param0, param1;
246 
247  if (local->hw_downloading) {
248  printk(KERN_WARNING "%s: Already downloading - aborting new "
249  "request\n", dev->name);
250  return -1;
251  }
252 
253  local->hw_downloading = 1;
254  if (local->pri_only) {
255  hfa384x_disable_interrupts(dev);
256  } else {
257  prism2_hw_shutdown(dev, 0);
258 
259  if (prism2_hw_init(dev, 0)) {
260  printk(KERN_WARNING "%s: Could not initialize card for"
261  " download\n", dev->name);
262  ret = -1;
263  goto out;
264  }
265  }
266 
267  if (prism2_enable_aux_port(dev, 1)) {
268  printk(KERN_WARNING "%s: Could not enable AUX port\n",
269  dev->name);
270  ret = -1;
271  goto out;
272  }
273 
274  param0 = param->start_addr & 0xffff;
275  param1 = param->start_addr >> 16;
276 
277  HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
278  HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
279  if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
281  param0)) {
282  printk(KERN_WARNING "%s: Download command execution failed\n",
283  dev->name);
284  ret = -1;
285  goto out;
286  }
287 
288  for (i = 0; i < param->num_areas; i++) {
289  PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
290  dev->name, param->data[i].len, param->data[i].addr);
291  if (hfa384x_to_aux(dev, param->data[i].addr,
292  param->data[i].len, param->data[i].data)) {
293  printk(KERN_WARNING "%s: RAM download at 0x%08x "
294  "(len=%d) failed\n", dev->name,
295  param->data[i].addr, param->data[i].len);
296  ret = -1;
297  goto out;
298  }
299  }
300 
301  HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
302  HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
303  if (hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
304  (HFA384X_PROGMODE_DISABLE << 8), param0)) {
305  printk(KERN_WARNING "%s: Download command execution failed\n",
306  dev->name);
307  ret = -1;
308  goto out;
309  }
310  /* ProgMode disable causes the hardware to restart itself from the
311  * given starting address. Give hw some time and ACK command just in
312  * case restart did not happen. */
313  mdelay(5);
314  HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);
315 
316  if (prism2_enable_aux_port(dev, 0)) {
317  printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
318  dev->name);
319  /* continue anyway.. restart should have taken care of this */
320  }
321 
322  mdelay(5);
323  local->hw_downloading = 0;
324  if (prism2_hw_config(dev, 2)) {
325  printk(KERN_WARNING "%s: Card configuration after RAM "
326  "download failed\n", dev->name);
327  ret = -1;
328  goto out;
329  }
330 
331  out:
332  local->hw_downloading = 0;
333  return ret;
334 }
335 
336 
337 static int prism2_enable_genesis(local_info_t *local, int hcr)
338 {
339  struct net_device *dev = local->dev;
340  u8 initseq[4] = { 0x00, 0xe1, 0xa1, 0xff };
341  u8 readbuf[4];
342 
343  printk(KERN_DEBUG "%s: test Genesis mode with HCR 0x%02x\n",
344  dev->name, hcr);
345  local->func->cor_sreset(local);
346  hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
347  local->func->genesis_reset(local, hcr);
348 
349  /* Readback test */
350  hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
351  hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
352  hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
353 
354  if (memcmp(initseq, readbuf, sizeof(initseq)) == 0) {
355  printk(KERN_DEBUG "Readback test succeeded, HCR 0x%02x\n",
356  hcr);
357  return 0;
358  } else {
359  printk(KERN_DEBUG "Readback test failed, HCR 0x%02x "
360  "write %02x %02x %02x %02x read %02x %02x %02x %02x\n",
361  hcr, initseq[0], initseq[1], initseq[2], initseq[3],
362  readbuf[0], readbuf[1], readbuf[2], readbuf[3]);
363  return 1;
364  }
365 }
366 
367 
368 static int prism2_get_ram_size(local_info_t *local)
369 {
370  int ret;
371 
372  /* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */
373  if (prism2_enable_genesis(local, 0x1f) == 0)
374  ret = 8;
375  else if (prism2_enable_genesis(local, 0x0f) == 0)
376  ret = 16;
377  else
378  ret = -1;
379 
380  /* Disable genesis mode */
381  local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17);
382 
383  return ret;
384 }
385 
386 
387 static int prism2_download_genesis(local_info_t *local,
388  struct prism2_download_data *param)
389 {
390  struct net_device *dev = local->dev;
391  int ram16 = 0, i;
392  int ret = 0;
393 
394  if (local->hw_downloading) {
395  printk(KERN_WARNING "%s: Already downloading - aborting new "
396  "request\n", dev->name);
397  return -EBUSY;
398  }
399 
400  if (!local->func->genesis_reset || !local->func->cor_sreset) {
401  printk(KERN_INFO "%s: Genesis mode downloading not supported "
402  "with this hwmodel\n", dev->name);
403  return -EOPNOTSUPP;
404  }
405 
406  local->hw_downloading = 1;
407 
408  if (prism2_enable_aux_port(dev, 1)) {
409  printk(KERN_DEBUG "%s: failed to enable AUX port\n",
410  dev->name);
411  ret = -EIO;
412  goto out;
413  }
414 
415  if (local->sram_type == -1) {
416  /* 0x1F for x8 SRAM or 0x0F for x16 SRAM */
417  if (prism2_enable_genesis(local, 0x1f) == 0) {
418  ram16 = 0;
419  PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 "
420  "SRAM\n", dev->name);
421  } else if (prism2_enable_genesis(local, 0x0f) == 0) {
422  ram16 = 1;
423  PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 "
424  "SRAM\n", dev->name);
425  } else {
426  printk(KERN_DEBUG "%s: Could not initiate genesis "
427  "mode\n", dev->name);
428  ret = -EIO;
429  goto out;
430  }
431  } else {
432  if (prism2_enable_genesis(local, local->sram_type == 8 ?
433  0x1f : 0x0f)) {
434  printk(KERN_DEBUG "%s: Failed to set Genesis "
435  "mode (sram_type=%d)\n", dev->name,
436  local->sram_type);
437  ret = -EIO;
438  goto out;
439  }
440  ram16 = local->sram_type != 8;
441  }
442 
443  for (i = 0; i < param->num_areas; i++) {
444  PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
445  dev->name, param->data[i].len, param->data[i].addr);
446  if (hfa384x_to_aux(dev, param->data[i].addr,
447  param->data[i].len, param->data[i].data)) {
448  printk(KERN_WARNING "%s: RAM download at 0x%08x "
449  "(len=%d) failed\n", dev->name,
450  param->data[i].addr, param->data[i].len);
451  ret = -EIO;
452  goto out;
453  }
454  }
455 
456  PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n");
457  local->func->genesis_reset(local, ram16 ? 0x07 : 0x17);
458  if (prism2_enable_aux_port(dev, 0)) {
459  printk(KERN_DEBUG "%s: Failed to disable AUX port\n",
460  dev->name);
461  }
462 
463  mdelay(5);
464  local->hw_downloading = 0;
465 
466  PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n");
467  /*
468  * Make sure the INIT command does not generate a command completion
469  * event by disabling interrupts.
470  */
471  hfa384x_disable_interrupts(dev);
472  if (prism2_hw_init(dev, 1)) {
473  printk(KERN_DEBUG "%s: Initialization after genesis mode "
474  "download failed\n", dev->name);
475  ret = -EIO;
476  goto out;
477  }
478 
479  PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n");
480  if (prism2_hw_init2(dev, 1)) {
481  printk(KERN_DEBUG "%s: Initialization(2) after genesis mode "
482  "download failed\n", dev->name);
483  ret = -EIO;
484  goto out;
485  }
486 
487  out:
488  local->hw_downloading = 0;
489  return ret;
490 }
491 
492 
493 #ifdef PRISM2_NON_VOLATILE_DOWNLOAD
494 /* Note! Non-volatile downloading functionality has not yet been tested
495  * thoroughly and it may corrupt flash image and effectively kill the card that
496  * is being updated. You have been warned. */
497 
498 static inline int prism2_download_block(struct net_device *dev,
499  u32 addr, u8 *data,
500  u32 bufaddr, int rest_len)
501 {
502  u16 param0, param1;
503  int block_len;
504 
505  block_len = rest_len < 4096 ? rest_len : 4096;
506 
507  param0 = addr & 0xffff;
508  param1 = addr >> 16;
509 
510  HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF);
511  HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
512 
513  if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
515  param0)) {
516  printk(KERN_WARNING "%s: Flash download command execution "
517  "failed\n", dev->name);
518  return -1;
519  }
520 
521  if (hfa384x_to_aux(dev, bufaddr, block_len, data)) {
522  printk(KERN_WARNING "%s: flash download at 0x%08x "
523  "(len=%d) failed\n", dev->name, addr, block_len);
524  return -1;
525  }
526 
527  HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
528  HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
529  if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
531  0)) {
532  printk(KERN_WARNING "%s: Flash write command execution "
533  "failed\n", dev->name);
534  return -1;
535  }
536 
537  return block_len;
538 }
539 
540 
541 static int prism2_download_nonvolatile(local_info_t *local,
542  struct prism2_download_data *dl)
543 {
544  struct net_device *dev = local->dev;
545  int ret = 0, i;
546  struct {
547  __le16 page;
548  __le16 offset;
549  __le16 len;
550  } dlbuffer;
551  u32 bufaddr;
552 
553  if (local->hw_downloading) {
554  printk(KERN_WARNING "%s: Already downloading - aborting new "
555  "request\n", dev->name);
556  return -1;
557  }
558 
559  ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER,
560  &dlbuffer, 6, 0);
561 
562  if (ret < 0) {
563  printk(KERN_WARNING "%s: Could not read download buffer "
564  "parameters\n", dev->name);
565  goto out;
566  }
567 
568  printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",
569  le16_to_cpu(dlbuffer.len),
570  le16_to_cpu(dlbuffer.page),
571  le16_to_cpu(dlbuffer.offset));
572 
573  bufaddr = (le16_to_cpu(dlbuffer.page) << 7) + le16_to_cpu(dlbuffer.offset);
574 
575  local->hw_downloading = 1;
576 
577  if (!local->pri_only) {
578  prism2_hw_shutdown(dev, 0);
579 
580  if (prism2_hw_init(dev, 0)) {
581  printk(KERN_WARNING "%s: Could not initialize card for"
582  " download\n", dev->name);
583  ret = -1;
584  goto out;
585  }
586  }
587 
588  hfa384x_disable_interrupts(dev);
589 
590  if (prism2_enable_aux_port(dev, 1)) {
591  printk(KERN_WARNING "%s: Could not enable AUX port\n",
592  dev->name);
593  ret = -1;
594  goto out;
595  }
596 
597  printk(KERN_DEBUG "%s: starting flash download\n", dev->name);
598  for (i = 0; i < dl->num_areas; i++) {
599  int rest_len = dl->data[i].len;
600  int data_off = 0;
601 
602  while (rest_len > 0) {
603  int block_len;
604 
605  block_len = prism2_download_block(
606  dev, dl->data[i].addr + data_off,
607  dl->data[i].data + data_off, bufaddr,
608  rest_len);
609 
610  if (block_len < 0) {
611  ret = -1;
612  goto out;
613  }
614 
615  rest_len -= block_len;
616  data_off += block_len;
617  }
618  }
619 
620  HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
621  HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
622  if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
623  (HFA384X_PROGMODE_DISABLE << 8), 0)) {
624  printk(KERN_WARNING "%s: Download command execution failed\n",
625  dev->name);
626  ret = -1;
627  goto out;
628  }
629 
630  if (prism2_enable_aux_port(dev, 0)) {
631  printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
632  dev->name);
633  /* continue anyway.. restart should have taken care of this */
634  }
635 
636  mdelay(5);
637 
638  local->func->hw_reset(dev);
639  local->hw_downloading = 0;
640  if (prism2_hw_config(dev, 2)) {
641  printk(KERN_WARNING "%s: Card configuration after flash "
642  "download failed\n", dev->name);
643  ret = -1;
644  } else {
645  printk(KERN_INFO "%s: Card initialized successfully after "
646  "flash download\n", dev->name);
647  }
648 
649  out:
650  local->hw_downloading = 0;
651  return ret;
652 }
653 #endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
654 
655 
656 static void prism2_download_free_data(struct prism2_download_data *dl)
657 {
658  int i;
659 
660  if (dl == NULL)
661  return;
662 
663  for (i = 0; i < dl->num_areas; i++)
664  kfree(dl->data[i].data);
665  kfree(dl);
666 }
667 
668 
669 static int prism2_download(local_info_t *local,
670  struct prism2_download_param *param)
671 {
672  int ret = 0;
673  int i;
674  u32 total_len = 0;
675  struct prism2_download_data *dl = NULL;
676 
677  printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x "
678  "num_areas=%d\n",
679  param->dl_cmd, param->start_addr, param->num_areas);
680 
681  if (param->num_areas > 100) {
682  ret = -EINVAL;
683  goto out;
684  }
685 
686  dl = kzalloc(sizeof(*dl) + param->num_areas *
687  sizeof(struct prism2_download_data_area), GFP_KERNEL);
688  if (dl == NULL) {
689  ret = -ENOMEM;
690  goto out;
691  }
692  dl->dl_cmd = param->dl_cmd;
693  dl->start_addr = param->start_addr;
694  dl->num_areas = param->num_areas;
695  for (i = 0; i < param->num_areas; i++) {
696  PDEBUG(DEBUG_EXTRA2,
697  " area %d: addr=0x%08x len=%d ptr=0x%p\n",
698  i, param->data[i].addr, param->data[i].len,
699  param->data[i].ptr);
700 
701  dl->data[i].addr = param->data[i].addr;
702  dl->data[i].len = param->data[i].len;
703 
704  total_len += param->data[i].len;
705  if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN ||
706  total_len > PRISM2_MAX_DOWNLOAD_LEN) {
707  ret = -E2BIG;
708  goto out;
709  }
710 
711  dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL);
712  if (dl->data[i].data == NULL) {
713  ret = -ENOMEM;
714  goto out;
715  }
716 
717  if (copy_from_user(dl->data[i].data, param->data[i].ptr,
718  param->data[i].len)) {
719  ret = -EFAULT;
720  goto out;
721  }
722  }
723 
724  switch (param->dl_cmd) {
727  ret = prism2_download_volatile(local, dl);
728  break;
731  ret = prism2_download_genesis(local, dl);
732  break;
734 #ifdef PRISM2_NON_VOLATILE_DOWNLOAD
735  ret = prism2_download_nonvolatile(local, dl);
736 #else /* PRISM2_NON_VOLATILE_DOWNLOAD */
737  printk(KERN_INFO "%s: non-volatile downloading not enabled\n",
738  local->dev->name);
739  ret = -EOPNOTSUPP;
740 #endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
741  break;
742  default:
743  printk(KERN_DEBUG "%s: unsupported download command %d\n",
744  local->dev->name, param->dl_cmd);
745  ret = -EINVAL;
746  break;
747  }
748 
749  out:
750  if (ret == 0 && dl &&
752  prism2_download_free_data(local->dl_pri);
753  local->dl_pri = dl;
754  } else if (ret == 0 && dl &&
756  prism2_download_free_data(local->dl_sec);
757  local->dl_sec = dl;
758  } else
759  prism2_download_free_data(dl);
760 
761  return ret;
762 }