o wl3501: tidy up wl3501_ioctl

. check if the device is present, bail out if not
. move the buffer to the place where it is used
. check the size of the firmware buffer passed from userspace
. make wl3501_write_flash return -EIO on failure, 0 on success
parent 63c0f605
...@@ -334,7 +334,7 @@ int wl3501_flash_writeb(struct wl3501_card *this, u16 page, u16 addr, ...@@ -334,7 +334,7 @@ int wl3501_flash_writeb(struct wl3501_card *this, u16 page, u16 addr,
static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf, static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf,
int len) int len)
{ {
int i; int i, rc = -EIO;
u32 bf_addr = *(u32 *)bf; u32 bf_addr = *(u32 *)bf;
int running = wl3501_hold_sutro(this); int running = wl3501_hold_sutro(this);
u16 flash_id = wl3501_get_flash_id(this); u16 flash_id = wl3501_get_flash_id(this);
...@@ -351,7 +351,7 @@ static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf, ...@@ -351,7 +351,7 @@ static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf,
"wl3501_flash_erase_sector(0) failed\n"); "wl3501_flash_erase_sector(0) failed\n");
if (running) if (running)
wl3501_unhold_sutro(this); wl3501_unhold_sutro(this);
return 0; goto out;
} }
} }
} else if (flash_id != 0xf51d) { } else if (flash_id != 0xf51d) {
...@@ -360,7 +360,7 @@ static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf, ...@@ -360,7 +360,7 @@ static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf,
flash_id); flash_id);
if (running) if (running)
wl3501_unhold_sutro(this); wl3501_unhold_sutro(this);
return 0; goto out;
} }
/* Programming flash ROM byte by byte */ /* Programming flash ROM byte by byte */
...@@ -370,7 +370,7 @@ static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf, ...@@ -370,7 +370,7 @@ static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf,
"wl3501_flash_writeb(buf[%d]) failed!\n", i); "wl3501_flash_writeb(buf[%d]) failed!\n", i);
if (running) if (running)
wl3501_unhold_sutro(this); wl3501_unhold_sutro(this);
return 0; goto out;
} }
bf++; bf++;
} }
...@@ -384,7 +384,9 @@ static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf, ...@@ -384,7 +384,9 @@ static int wl3501_write_flash(struct wl3501_card *this, unsigned char *bf,
if (running) if (running)
wl3501_unhold_sutro(this); wl3501_unhold_sutro(this);
#endif #endif
return 1; rc = 0;
out:
return rc;
} }
/** /**
...@@ -1699,12 +1701,13 @@ static void wl3501_set_multicast_list(struct net_device *dev) ...@@ -1699,12 +1701,13 @@ static void wl3501_set_multicast_list(struct net_device *dev)
*/ */
static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{ {
int rc = 0; int rc = -ENODEV;
struct wl3501_card *this = (struct wl3501_card *)dev->priv; struct wl3501_card *this = (struct wl3501_card *)dev->priv;
struct wl3501_ioctl_parm parm; struct wl3501_ioctl_parm parm;
struct wl3501_ioctl_blk *blk = (struct wl3501_ioctl_blk *) struct wl3501_ioctl_blk *blk = (struct wl3501_ioctl_blk *)&rq->ifr_data;
&rq->ifr_data;
unsigned char bf[1028]; if (!netif_device_present(dev))
goto out;
switch (blk->cmd) { switch (blk->cmd) {
case WL3501_IOCTL_CMD_SET_RESET: /* Reset drv - needed after set */ case WL3501_IOCTL_CMD_SET_RESET: /* Reset drv - needed after set */
...@@ -1713,14 +1716,20 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -1713,14 +1716,20 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
break; break;
rc = wl3501_reset(dev); rc = wl3501_reset(dev);
break; break;
case WL3501_IOCTL_CMD_WRITE_FLASH: /* Write firmware into Flash */ case WL3501_IOCTL_CMD_WRITE_FLASH: { /* Write firmware into Flash */
unsigned char bf[1028];
rc = -EPERM; rc = -EPERM;
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
break; break;
rc = -EFBIG;
if (blk->len > sizeof(bf))
break;
rc = -EFAULT; rc = -EFAULT;
if (copy_from_user(bf, blk->data, blk->len)) if (copy_from_user(bf, blk->data, blk->len))
break; break;
rc = wl3501_write_flash(this, bf, blk->len) ? 0 : -EIO; rc = wl3501_write_flash(this, bf, blk->len);
}
break; break;
case WL3501_IOCTL_CMD_GET_PARAMETER: case WL3501_IOCTL_CMD_GET_PARAMETER:
parm.def_chan = this->def_chan; parm.def_chan = this->def_chan;
...@@ -1753,6 +1762,7 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -1753,6 +1762,7 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
default: default:
rc = -EOPNOTSUPP; rc = -EOPNOTSUPP;
} }
out:
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment