Commit f14e2243 authored by Marc Kleine-Budde's avatar Marc Kleine-Budde

net: can: peak_usb: Do not do dma on the stack

smatch reports the following warnings:
drivers/net/can/usb/peak_usb/pcan_usb_pro.c:514 pcan_usb_pro_drv_loaded() error: doing dma on the stack (buffer)
drivers/net/can/usb/peak_usb/pcan_usb_pro.c:878 pcan_usb_pro_init() error: doing dma on the stack (&fi)
drivers/net/can/usb/peak_usb/pcan_usb_pro.c:889 pcan_usb_pro_init() error: doing dma on the stack (&bi)

See "Documentation/DMA-API-HOWTO.txt" section "What memory is DMA'able?"

Cc: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent fae37f81
...@@ -504,15 +504,24 @@ static int pcan_usb_pro_restart_async(struct peak_usb_device *dev, ...@@ -504,15 +504,24 @@ static int pcan_usb_pro_restart_async(struct peak_usb_device *dev,
return usb_submit_urb(urb, GFP_ATOMIC); return usb_submit_urb(urb, GFP_ATOMIC);
} }
static void pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded) static int pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded)
{ {
u8 buffer[16]; u8 *buffer;
int err;
buffer = kmalloc(PCAN_USBPRO_FCT_DRVLD_REQ_LEN, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
buffer[0] = 0; buffer[0] = 0;
buffer[1] = !!loaded; buffer[1] = !!loaded;
pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT, err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT,
PCAN_USBPRO_FCT_DRVLD, buffer, sizeof(buffer)); PCAN_USBPRO_FCT_DRVLD, buffer,
PCAN_USBPRO_FCT_DRVLD_REQ_LEN);
kfree(buffer);
return err;
} }
static inline static inline
...@@ -851,21 +860,24 @@ static int pcan_usb_pro_stop(struct peak_usb_device *dev) ...@@ -851,21 +860,24 @@ static int pcan_usb_pro_stop(struct peak_usb_device *dev)
*/ */
static int pcan_usb_pro_init(struct peak_usb_device *dev) static int pcan_usb_pro_init(struct peak_usb_device *dev)
{ {
struct pcan_usb_pro_interface *usb_if;
struct pcan_usb_pro_device *pdev = struct pcan_usb_pro_device *pdev =
container_of(dev, struct pcan_usb_pro_device, dev); container_of(dev, struct pcan_usb_pro_device, dev);
struct pcan_usb_pro_interface *usb_if = NULL;
struct pcan_usb_pro_fwinfo *fi = NULL;
struct pcan_usb_pro_blinfo *bi = NULL;
int err;
/* do this for 1st channel only */ /* do this for 1st channel only */
if (!dev->prev_siblings) { if (!dev->prev_siblings) {
struct pcan_usb_pro_fwinfo fi;
struct pcan_usb_pro_blinfo bi;
int err;
/* allocate netdevices common structure attached to first one */ /* allocate netdevices common structure attached to first one */
usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface), usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface),
GFP_KERNEL); GFP_KERNEL);
if (!usb_if) fi = kmalloc(sizeof(struct pcan_usb_pro_fwinfo), GFP_KERNEL);
return -ENOMEM; bi = kmalloc(sizeof(struct pcan_usb_pro_blinfo), GFP_KERNEL);
if (!usb_if || !fi || !bi) {
err = -ENOMEM;
goto err_out;
}
/* number of ts msgs to ignore before taking one into account */ /* number of ts msgs to ignore before taking one into account */
usb_if->cm_ignore_count = 5; usb_if->cm_ignore_count = 5;
...@@ -877,34 +889,34 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) ...@@ -877,34 +889,34 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
*/ */
err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO, err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
PCAN_USBPRO_INFO_FW, PCAN_USBPRO_INFO_FW,
&fi, sizeof(fi)); fi, sizeof(*fi));
if (err) { if (err) {
kfree(usb_if);
dev_err(dev->netdev->dev.parent, dev_err(dev->netdev->dev.parent,
"unable to read %s firmware info (err %d)\n", "unable to read %s firmware info (err %d)\n",
pcan_usb_pro.name, err); pcan_usb_pro.name, err);
return err; goto err_out;
} }
err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO, err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
PCAN_USBPRO_INFO_BL, PCAN_USBPRO_INFO_BL,
&bi, sizeof(bi)); bi, sizeof(*bi));
if (err) { if (err) {
kfree(usb_if);
dev_err(dev->netdev->dev.parent, dev_err(dev->netdev->dev.parent,
"unable to read %s bootloader info (err %d)\n", "unable to read %s bootloader info (err %d)\n",
pcan_usb_pro.name, err); pcan_usb_pro.name, err);
return err; goto err_out;
} }
/* tell the device the can driver is running */
err = pcan_usb_pro_drv_loaded(dev, 1);
if (err)
goto err_out;
dev_info(dev->netdev->dev.parent, dev_info(dev->netdev->dev.parent,
"PEAK-System %s hwrev %u serial %08X.%08X (%u channels)\n", "PEAK-System %s hwrev %u serial %08X.%08X (%u channels)\n",
pcan_usb_pro.name, pcan_usb_pro.name,
bi.hw_rev, bi.serial_num_hi, bi.serial_num_lo, bi->hw_rev, bi->serial_num_hi, bi->serial_num_lo,
pcan_usb_pro.ctrl_count); pcan_usb_pro.ctrl_count);
/* tell the device the can driver is running */
pcan_usb_pro_drv_loaded(dev, 1);
} else { } else {
usb_if = pcan_usb_pro_dev_if(dev->prev_siblings); usb_if = pcan_usb_pro_dev_if(dev->prev_siblings);
} }
...@@ -916,6 +928,13 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) ...@@ -916,6 +928,13 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev)
pcan_usb_pro_set_led(dev, 0, 1); pcan_usb_pro_set_led(dev, 0, 1);
return 0; return 0;
err_out:
kfree(bi);
kfree(fi);
kfree(usb_if);
return err;
} }
static void pcan_usb_pro_exit(struct peak_usb_device *dev) static void pcan_usb_pro_exit(struct peak_usb_device *dev)
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
/* Vendor Request value for XXX_FCT */ /* Vendor Request value for XXX_FCT */
#define PCAN_USBPRO_FCT_DRVLD 5 /* tell device driver is loaded */ #define PCAN_USBPRO_FCT_DRVLD 5 /* tell device driver is loaded */
#define PCAN_USBPRO_FCT_DRVLD_REQ_LEN 16
/* PCAN_USBPRO_INFO_BL vendor request record type */ /* PCAN_USBPRO_INFO_BL vendor request record type */
struct __packed pcan_usb_pro_blinfo { struct __packed pcan_usb_pro_blinfo {
......
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