static int prism2_enable_aux_port(struct net_device *dev, int enable)
{
	u16 val, reg;
	int i, tries;
	unsigned long flags;
	struct hostap_interface *iface;
	local_info_t *local;

	iface = netdev_priv(dev);
	local = iface->local;

	if (local->no_pri) {
		if (enable) {
			PDEBUG(DEBUG_EXTRA2, "%s: no PRI f/w - assuming Aux "
			       "port is already enabled\n", dev->name);
		}
		return 0;
	}

	spin_lock_irqsave(&local->cmdlock, flags);

	/* wait until busy bit is clear */
	tries = HFA384X_CMD_BUSY_TIMEOUT;
	while (HFA384X_INW(HFA384X_CMD_OFF) & HFA384X_CMD_BUSY && tries > 0) {
		tries--;
		udelay(1);
	}
	if (tries == 0) {
		reg = HFA384X_INW(HFA384X_CMD_OFF);
		spin_unlock_irqrestore(&local->cmdlock, flags);
		printk("%s: prism2_enable_aux_port - timeout - reg=0x%04x\n",
		       dev->name, reg);
		return -ETIMEDOUT;
	}

	val = HFA384X_INW(HFA384X_CONTROL_OFF);

	if (enable) {
		HFA384X_OUTW(HFA384X_AUX_MAGIC0, HFA384X_PARAM0_OFF);
		HFA384X_OUTW(HFA384X_AUX_MAGIC1, HFA384X_PARAM1_OFF);
		HFA384X_OUTW(HFA384X_AUX_MAGIC2, HFA384X_PARAM2_OFF);

		if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_DISABLED)
			printk("prism2_enable_aux_port: was not disabled!?\n");
		val &= ~HFA384X_AUX_PORT_MASK;
		val |= HFA384X_AUX_PORT_ENABLE;
	} else {
		HFA384X_OUTW(0, HFA384X_PARAM0_OFF);
		HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
		HFA384X_OUTW(0, HFA384X_PARAM2_OFF);

		if ((val & HFA384X_AUX_PORT_MASK) != HFA384X_AUX_PORT_ENABLED)
			printk("prism2_enable_aux_port: was not enabled!?\n");
		val &= ~HFA384X_AUX_PORT_MASK;
		val |= HFA384X_AUX_PORT_DISABLE;
	}
	HFA384X_OUTW(val, HFA384X_CONTROL_OFF);

	udelay(5);

	i = 10000;
	while (i > 0) {
		val = HFA384X_INW(HFA384X_CONTROL_OFF);
		val &= HFA384X_AUX_PORT_MASK;

		if ((enable && val == HFA384X_AUX_PORT_ENABLED) ||
		    (!enable && val == HFA384X_AUX_PORT_DISABLED))
			break;

		udelay(10);
		i--;
	}

	spin_unlock_irqrestore(&local->cmdlock, flags);

	if (i == 0) {
		printk("prism2_enable_aux_port(%d) timed out\n",
		       enable);
		return -ETIMEDOUT;
	}

	return 0;
}


static int hfa384x_from_aux(struct net_device *dev, unsigned int addr, int len,
			    void *buf)
{
	u16 page, offset;
	if (addr & 1 || len & 1)
		return -1;

	page = addr >> 7;
	offset = addr & 0x7f;

	HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
	HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);

	udelay(5);

#ifdef PRISM2_PCI
	{
		__le16 *pos = (__le16 *) buf;
		while (len > 0) {
			*pos++ = HFA384X_INW_DATA(HFA384X_AUXDATA_OFF);
			len -= 2;
		}
	}
#else /* PRISM2_PCI */
	HFA384X_INSW(HFA384X_AUXDATA_OFF, buf, len / 2);
#endif /* PRISM2_PCI */

	return 0;
}


static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len,
			  void *buf)
{
	u16 page, offset;
	if (addr & 1 || len & 1)
		return -1;

	page = addr >> 7;
	offset = addr & 0x7f;

	HFA384X_OUTW(page, HFA384X_AUXPAGE_OFF);
	HFA384X_OUTW(offset, HFA384X_AUXOFFSET_OFF);

	udelay(5);

#ifdef PRISM2_PCI
	{
		__le16 *pos = (__le16 *) buf;
		while (len > 0) {
			HFA384X_OUTW_DATA(*pos++, HFA384X_AUXDATA_OFF);
			len -= 2;
		}
	}
#else /* PRISM2_PCI */
	HFA384X_OUTSW(HFA384X_AUXDATA_OFF, buf, len / 2);
#endif /* PRISM2_PCI */

	return 0;
}


static int prism2_pda_ok(u8 *buf)
{
	__le16 *pda = (__le16 *) buf;
	int pos;
	u16 len, pdr;

	if (buf[0] == 0xff && buf[1] == 0x00 && buf[2] == 0xff &&
	    buf[3] == 0x00)
		return 0;

	pos = 0;
	while (pos + 1 < PRISM2_PDA_SIZE / 2) {
		len = le16_to_cpu(pda[pos]);
		pdr = le16_to_cpu(pda[pos + 1]);
		if (len == 0 || pos + len > PRISM2_PDA_SIZE / 2)
			return 0;

		if (pdr == 0x0000 && len == 2) {
			/* PDA end found */
			return 1;
		}

		pos += len + 1;
	}

	return 0;
}


#define prism2_download_aux_dump_npages 65536

struct prism2_download_aux_dump {
	local_info_t *local;
	u16 page[0x80];
};

static int prism2_download_aux_dump_proc_show(struct seq_file *m, void *v)
{
	struct prism2_download_aux_dump *ctx = m->private;

	hfa384x_from_aux(ctx->local->dev, (unsigned long)v - 1, 0x80, ctx->page);
	seq_write(m, ctx->page, 0x80);
	return 0;
}

static void *prism2_download_aux_dump_proc_start(struct seq_file *m, loff_t *_pos)
{
	struct prism2_download_aux_dump *ctx = m->private;
	prism2_enable_aux_port(ctx->local->dev, 1);
	if (*_pos >= prism2_download_aux_dump_npages)
		return NULL;
	return (void *)((unsigned long)*_pos + 1);
}

static void *prism2_download_aux_dump_proc_next(struct seq_file *m, void *v, loff_t *_pos)
{
	++*_pos;
	if (*_pos >= prism2_download_aux_dump_npages)
		return NULL;
	return (void *)((unsigned long)*_pos + 1);
}

static void prism2_download_aux_dump_proc_stop(struct seq_file *m, void *v)
{
	struct prism2_download_aux_dump *ctx = m->private;
	prism2_enable_aux_port(ctx->local->dev, 0);
}

static const struct seq_operations prism2_download_aux_dump_proc_seqops = {
	.start	= prism2_download_aux_dump_proc_start,
	.next	= prism2_download_aux_dump_proc_next,
	.stop	= prism2_download_aux_dump_proc_stop,
	.show	= prism2_download_aux_dump_proc_show,
};

static int prism2_download_aux_dump_proc_open(struct inode *inode, struct file *file)
{
	int ret = seq_open_private(file, &prism2_download_aux_dump_proc_seqops,
				   sizeof(struct prism2_download_aux_dump));
	if (ret == 0) {
		struct seq_file *m = file->private_data;
		m->private = PDE_DATA(inode);
	}
	return ret;
}

static const struct file_operations prism2_download_aux_dump_proc_fops = {
	.open		= prism2_download_aux_dump_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release_private,
};


static u8 * prism2_read_pda(struct net_device *dev)
{
	u8 *buf;
	int res, i, found = 0;
#define NUM_PDA_ADDRS 4
	unsigned int pda_addr[NUM_PDA_ADDRS] = {
		0x7f0000 /* others than HFA3841 */,
		0x3f0000 /* HFA3841 */,
		0x390000 /* apparently used in older cards */,
		0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */,
	};

	buf = kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
	if (buf == NULL)
		return NULL;

	/* Note: wlan card should be in initial state (just after init cmd)
	 * and no other operations should be performed concurrently. */

	prism2_enable_aux_port(dev, 1);

	for (i = 0; i < NUM_PDA_ADDRS; i++) {
		PDEBUG(DEBUG_EXTRA2, "%s: trying to read PDA from 0x%08x",
		       dev->name, pda_addr[i]);
		res = hfa384x_from_aux(dev, pda_addr[i], PRISM2_PDA_SIZE, buf);
		if (res)
			continue;
		if (res == 0 && prism2_pda_ok(buf)) {
			PDEBUG2(DEBUG_EXTRA2, ": OK\n");
			found = 1;
			break;
		} else {
			PDEBUG2(DEBUG_EXTRA2, ": failed\n");
		}
	}

	prism2_enable_aux_port(dev, 0);

	if (!found) {
		printk(KERN_DEBUG "%s: valid PDA not found\n", dev->name);
		kfree(buf);
		buf = NULL;
	}

	return buf;
}


static int prism2_download_volatile(local_info_t *local,
				    struct prism2_download_data *param)
{
	struct net_device *dev = local->dev;
	int ret = 0, i;
	u16 param0, param1;

	if (local->hw_downloading) {
		printk(KERN_WARNING "%s: Already downloading - aborting new "
		       "request\n", dev->name);
		return -1;
	}

	local->hw_downloading = 1;
	if (local->pri_only) {
		hfa384x_disable_interrupts(dev);
	} else {
		prism2_hw_shutdown(dev, 0);

		if (prism2_hw_init(dev, 0)) {
			printk(KERN_WARNING "%s: Could not initialize card for"
			       " download\n", dev->name);
			ret = -1;
			goto out;
		}
	}

	if (prism2_enable_aux_port(dev, 1)) {
		printk(KERN_WARNING "%s: Could not enable AUX port\n",
		       dev->name);
		ret = -1;
		goto out;
	}

	param0 = param->start_addr & 0xffff;
	param1 = param->start_addr >> 16;

	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
	HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
			     (HFA384X_PROGMODE_ENABLE_VOLATILE << 8),
			     param0)) {
		printk(KERN_WARNING "%s: Download command execution failed\n",
		       dev->name);
		ret = -1;
		goto out;
	}

	for (i = 0; i < param->num_areas; i++) {
		PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
		       dev->name, param->data[i].len, param->data[i].addr);
		if (hfa384x_to_aux(dev, param->data[i].addr,
				   param->data[i].len, param->data[i].data)) {
			printk(KERN_WARNING "%s: RAM download at 0x%08x "
			       "(len=%d) failed\n", dev->name,
			       param->data[i].addr, param->data[i].len);
			ret = -1;
			goto out;
		}
	}

	HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);
	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
	if (hfa384x_cmd_no_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
				(HFA384X_PROGMODE_DISABLE << 8), param0)) {
		printk(KERN_WARNING "%s: Download command execution failed\n",
		       dev->name);
		ret = -1;
		goto out;
	}
	/* ProgMode disable causes the hardware to restart itself from the
	 * given starting address. Give hw some time and ACK command just in
	 * case restart did not happen. */
	mdelay(5);
	HFA384X_OUTW(HFA384X_EV_CMD, HFA384X_EVACK_OFF);

	if (prism2_enable_aux_port(dev, 0)) {
		printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
		       dev->name);
		/* continue anyway.. restart should have taken care of this */
	}

	mdelay(5);
	local->hw_downloading = 0;
	if (prism2_hw_config(dev, 2)) {
		printk(KERN_WARNING "%s: Card configuration after RAM "
		       "download failed\n", dev->name);
		ret = -1;
		goto out;
	}

 out:
	local->hw_downloading = 0;
	return ret;
}


static int prism2_enable_genesis(local_info_t *local, int hcr)
{
	struct net_device *dev = local->dev;
	u8 initseq[4] = { 0x00, 0xe1, 0xa1, 0xff };
	u8 readbuf[4];

	printk(KERN_DEBUG "%s: test Genesis mode with HCR 0x%02x\n",
	       dev->name, hcr);
	local->func->cor_sreset(local);
	hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
	local->func->genesis_reset(local, hcr);

	/* Readback test */
	hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);
	hfa384x_to_aux(dev, 0x7e0038, sizeof(initseq), initseq);
	hfa384x_from_aux(dev, 0x7e0038, sizeof(readbuf), readbuf);

	if (memcmp(initseq, readbuf, sizeof(initseq)) == 0) {
		printk(KERN_DEBUG "Readback test succeeded, HCR 0x%02x\n",
		       hcr);
		return 0;
	} else {
		printk(KERN_DEBUG "Readback test failed, HCR 0x%02x "
		       "write %02x %02x %02x %02x read %02x %02x %02x %02x\n",
		       hcr, initseq[0], initseq[1], initseq[2], initseq[3],
		       readbuf[0], readbuf[1], readbuf[2], readbuf[3]);
		return 1;
	}
}


static int prism2_get_ram_size(local_info_t *local)
{
	int ret;

	/* Try to enable genesis mode; 0x1F for x8 SRAM or 0x0F for x16 SRAM */
	if (prism2_enable_genesis(local, 0x1f) == 0)
		ret = 8;
	else if (prism2_enable_genesis(local, 0x0f) == 0)
		ret = 16;
	else
		ret = -1;

	/* Disable genesis mode */
	local->func->genesis_reset(local, ret == 16 ? 0x07 : 0x17);

	return ret;
}


static int prism2_download_genesis(local_info_t *local,
				   struct prism2_download_data *param)
{
	struct net_device *dev = local->dev;
	int ram16 = 0, i;
	int ret = 0;

	if (local->hw_downloading) {
		printk(KERN_WARNING "%s: Already downloading - aborting new "
		       "request\n", dev->name);
		return -EBUSY;
	}

	if (!local->func->genesis_reset || !local->func->cor_sreset) {
		printk(KERN_INFO "%s: Genesis mode downloading not supported "
		       "with this hwmodel\n", dev->name);
		return -EOPNOTSUPP;
	}

	local->hw_downloading = 1;

	if (prism2_enable_aux_port(dev, 1)) {
		printk(KERN_DEBUG "%s: failed to enable AUX port\n",
		       dev->name);
		ret = -EIO;
		goto out;
	}

	if (local->sram_type == -1) {
		/* 0x1F for x8 SRAM or 0x0F for x16 SRAM */
		if (prism2_enable_genesis(local, 0x1f) == 0) {
			ram16 = 0;
			PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x8 "
			       "SRAM\n", dev->name);
		} else if (prism2_enable_genesis(local, 0x0f) == 0) {
			ram16 = 1;
			PDEBUG(DEBUG_EXTRA2, "%s: Genesis mode OK using x16 "
			       "SRAM\n", dev->name);
		} else {
			printk(KERN_DEBUG "%s: Could not initiate genesis "
			       "mode\n", dev->name);
			ret = -EIO;
			goto out;
		}
	} else {
		if (prism2_enable_genesis(local, local->sram_type == 8 ?
					  0x1f : 0x0f)) {
			printk(KERN_DEBUG "%s: Failed to set Genesis "
			       "mode (sram_type=%d)\n", dev->name,
			       local->sram_type);
			ret = -EIO;
			goto out;
		}
		ram16 = local->sram_type != 8;
	}

	for (i = 0; i < param->num_areas; i++) {
		PDEBUG(DEBUG_EXTRA2, "%s: Writing %d bytes at 0x%08x\n",
		       dev->name, param->data[i].len, param->data[i].addr);
		if (hfa384x_to_aux(dev, param->data[i].addr,
				   param->data[i].len, param->data[i].data)) {
			printk(KERN_WARNING "%s: RAM download at 0x%08x "
			       "(len=%d) failed\n", dev->name,
			       param->data[i].addr, param->data[i].len);
			ret = -EIO;
			goto out;
		}
	}

	PDEBUG(DEBUG_EXTRA2, "Disable genesis mode\n");
	local->func->genesis_reset(local, ram16 ? 0x07 : 0x17);
	if (prism2_enable_aux_port(dev, 0)) {
		printk(KERN_DEBUG "%s: Failed to disable AUX port\n",
		       dev->name);
	}

	mdelay(5);
	local->hw_downloading = 0;

	PDEBUG(DEBUG_EXTRA2, "Trying to initialize card\n");
	/*
	 * Make sure the INIT command does not generate a command completion
	 * event by disabling interrupts.
	 */
	hfa384x_disable_interrupts(dev);
	if (prism2_hw_init(dev, 1)) {
		printk(KERN_DEBUG "%s: Initialization after genesis mode "
		       "download failed\n", dev->name);
		ret = -EIO;
		goto out;
	}

	PDEBUG(DEBUG_EXTRA2, "Card initialized - running PRI only\n");
	if (prism2_hw_init2(dev, 1)) {
		printk(KERN_DEBUG "%s: Initialization(2) after genesis mode "
		       "download failed\n", dev->name);
		ret = -EIO;
		goto out;
	}

 out:
	local->hw_downloading = 0;
	return ret;
}


#ifdef PRISM2_NON_VOLATILE_DOWNLOAD
/* Note! Non-volatile downloading functionality has not yet been tested
 * thoroughly and it may corrupt flash image and effectively kill the card that
 * is being updated. You have been warned. */

static inline int prism2_download_block(struct net_device *dev,
					u32 addr, u8 *data,
					u32 bufaddr, int rest_len)
{
	u16 param0, param1;
	int block_len;

	block_len = rest_len < 4096 ? rest_len : 4096;

	param0 = addr & 0xffff;
	param1 = addr >> 16;

	HFA384X_OUTW(block_len, HFA384X_PARAM2_OFF);
	HFA384X_OUTW(param1, HFA384X_PARAM1_OFF);

	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
			     (HFA384X_PROGMODE_ENABLE_NON_VOLATILE << 8),
			     param0)) {
		printk(KERN_WARNING "%s: Flash download command execution "
		       "failed\n", dev->name);
		return -1;
	}

	if (hfa384x_to_aux(dev, bufaddr, block_len, data)) {
		printk(KERN_WARNING "%s: flash download at 0x%08x "
		       "(len=%d) failed\n", dev->name, addr, block_len);
		return -1;
	}

	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
	HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
			     (HFA384X_PROGMODE_PROGRAM_NON_VOLATILE << 8),
			     0)) {
		printk(KERN_WARNING "%s: Flash write command execution "
		       "failed\n", dev->name);
		return -1;
	}

	return block_len;
}


static int prism2_download_nonvolatile(local_info_t *local,
				       struct prism2_download_data *dl)
{
	struct net_device *dev = local->dev;
	int ret = 0, i;
	struct {
		__le16 page;
		__le16 offset;
		__le16 len;
	} dlbuffer;
	u32 bufaddr;

	if (local->hw_downloading) {
		printk(KERN_WARNING "%s: Already downloading - aborting new "
		       "request\n", dev->name);
		return -1;
	}

	ret = local->func->get_rid(dev, HFA384X_RID_DOWNLOADBUFFER,
				   &dlbuffer, 6, 0);

	if (ret < 0) {
		printk(KERN_WARNING "%s: Could not read download buffer "
		       "parameters\n", dev->name);
		goto out;
	}

	printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",
	       le16_to_cpu(dlbuffer.len),
	       le16_to_cpu(dlbuffer.page),
	       le16_to_cpu(dlbuffer.offset));

	bufaddr = (le16_to_cpu(dlbuffer.page) << 7) + le16_to_cpu(dlbuffer.offset);

	local->hw_downloading = 1;

	if (!local->pri_only) {
		prism2_hw_shutdown(dev, 0);

		if (prism2_hw_init(dev, 0)) {
			printk(KERN_WARNING "%s: Could not initialize card for"
			       " download\n", dev->name);
			ret = -1;
			goto out;
		}
	}

	hfa384x_disable_interrupts(dev);

	if (prism2_enable_aux_port(dev, 1)) {
		printk(KERN_WARNING "%s: Could not enable AUX port\n",
		       dev->name);
		ret = -1;
		goto out;
	}

	printk(KERN_DEBUG "%s: starting flash download\n", dev->name);
	for (i = 0; i < dl->num_areas; i++) {
		int rest_len = dl->data[i].len;
		int data_off = 0;

		while (rest_len > 0) {
			int block_len;

			block_len = prism2_download_block(
				dev, dl->data[i].addr + data_off,
				dl->data[i].data + data_off, bufaddr,
				rest_len);

			if (block_len < 0) {
				ret = -1;
				goto out;
			}

			rest_len -= block_len;
			data_off += block_len;
		}
	}

	HFA384X_OUTW(0, HFA384X_PARAM1_OFF);
	HFA384X_OUTW(0, HFA384X_PARAM2_OFF);
	if (hfa384x_cmd_wait(dev, HFA384X_CMDCODE_DOWNLOAD |
				(HFA384X_PROGMODE_DISABLE << 8), 0)) {
		printk(KERN_WARNING "%s: Download command execution failed\n",
		       dev->name);
		ret = -1;
		goto out;
	}

	if (prism2_enable_aux_port(dev, 0)) {
		printk(KERN_DEBUG "%s: Disabling AUX port failed\n",
		       dev->name);
		/* continue anyway.. restart should have taken care of this */
	}

	mdelay(5);

	local->func->hw_reset(dev);
	local->hw_downloading = 0;
	if (prism2_hw_config(dev, 2)) {
		printk(KERN_WARNING "%s: Card configuration after flash "
		       "download failed\n", dev->name);
		ret = -1;
	} else {
		printk(KERN_INFO "%s: Card initialized successfully after "
		       "flash download\n", dev->name);
	}

 out:
	local->hw_downloading = 0;
	return ret;
}
#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */


static void prism2_download_free_data(struct prism2_download_data *dl)
{
	int i;

	if (dl == NULL)
		return;

	for (i = 0; i < dl->num_areas; i++)
		kfree(dl->data[i].data);
	kfree(dl);
}


static int prism2_download(local_info_t *local,
			   struct prism2_download_param *param)
{
	int ret = 0;
	int i;
	u32 total_len = 0;
	struct prism2_download_data *dl = NULL;

	printk(KERN_DEBUG "prism2_download: dl_cmd=%d start_addr=0x%08x "
	       "num_areas=%d\n",
	       param->dl_cmd, param->start_addr, param->num_areas);

	if (param->num_areas > 100) {
		ret = -EINVAL;
		goto out;
	}

	dl = kzalloc(sizeof(*dl) + param->num_areas *
		     sizeof(struct prism2_download_data_area), GFP_KERNEL);
	if (dl == NULL) {
		ret = -ENOMEM;
		goto out;
	}
	dl->dl_cmd = param->dl_cmd;
	dl->start_addr = param->start_addr;
	dl->num_areas = param->num_areas;
	for (i = 0; i < param->num_areas; i++) {
		PDEBUG(DEBUG_EXTRA2,
		       "  area %d: addr=0x%08x len=%d ptr=0x%p\n",
		       i, param->data[i].addr, param->data[i].len,
		       param->data[i].ptr);

		dl->data[i].addr = param->data[i].addr;
		dl->data[i].len = param->data[i].len;

		total_len += param->data[i].len;
		if (param->data[i].len > PRISM2_MAX_DOWNLOAD_AREA_LEN ||
		    total_len > PRISM2_MAX_DOWNLOAD_LEN) {
			ret = -E2BIG;
			goto out;
		}

		dl->data[i].data = kmalloc(dl->data[i].len, GFP_KERNEL);
		if (dl->data[i].data == NULL) {
			ret = -ENOMEM;
			goto out;
		}

		if (copy_from_user(dl->data[i].data, param->data[i].ptr,
				   param->data[i].len)) {
			ret = -EFAULT;
			goto out;
		}
	}

	switch (param->dl_cmd) {
	case PRISM2_DOWNLOAD_VOLATILE:
	case PRISM2_DOWNLOAD_VOLATILE_PERSISTENT:
		ret = prism2_download_volatile(local, dl);
		break;
	case PRISM2_DOWNLOAD_VOLATILE_GENESIS:
	case PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT:
		ret = prism2_download_genesis(local, dl);
		break;
	case PRISM2_DOWNLOAD_NON_VOLATILE:
#ifdef PRISM2_NON_VOLATILE_DOWNLOAD
		ret = prism2_download_nonvolatile(local, dl);
#else /* PRISM2_NON_VOLATILE_DOWNLOAD */
		printk(KERN_INFO "%s: non-volatile downloading not enabled\n",
		       local->dev->name);
		ret = -EOPNOTSUPP;
#endif /* PRISM2_NON_VOLATILE_DOWNLOAD */
		break;
	default:
		printk(KERN_DEBUG "%s: unsupported download command %d\n",
		       local->dev->name, param->dl_cmd);
		ret = -EINVAL;
		break;
	}

 out:
	if (ret == 0 && dl &&
	    param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_GENESIS_PERSISTENT) {
		prism2_download_free_data(local->dl_pri);
		local->dl_pri = dl;
	} else if (ret == 0 && dl &&
		   param->dl_cmd == PRISM2_DOWNLOAD_VOLATILE_PERSISTENT) {
		prism2_download_free_data(local->dl_sec);
		local->dl_sec = dl;
	} else
		prism2_download_free_data(dl);

	return ret;
}
