Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+40 −21
Original line number Diff line number Diff line
@@ -504,15 +504,24 @@ static int pcan_usb_pro_restart_async(struct peak_usb_device *dev,
	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[1] = !!loaded;

	pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT,
			      PCAN_USBPRO_FCT_DRVLD, buffer, sizeof(buffer));
	err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT,
				    PCAN_USBPRO_FCT_DRVLD, buffer,
				    PCAN_USBPRO_FCT_DRVLD_REQ_LEN);
	kfree(buffer);

	return err;
}

static inline
@@ -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)
{
	struct pcan_usb_pro_interface *usb_if;
	struct pcan_usb_pro_device *pdev =
			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 */
	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 */
		usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface),
				 GFP_KERNEL);
		if (!usb_if)
			return -ENOMEM;
		fi = kmalloc(sizeof(struct pcan_usb_pro_fwinfo), GFP_KERNEL);
		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 */
		usb_if->cm_ignore_count = 5;
@@ -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,
					    PCAN_USBPRO_INFO_FW,
					    &fi, sizeof(fi));
					    fi, sizeof(*fi));
		if (err) {
			kfree(usb_if);
			dev_err(dev->netdev->dev.parent,
				"unable to read %s firmware info (err %d)\n",
				pcan_usb_pro.name, err);
			return err;
			goto err_out;
		}

		err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
					    PCAN_USBPRO_INFO_BL,
					    &bi, sizeof(bi));
					    bi, sizeof(*bi));
		if (err) {
			kfree(usb_if);
			dev_err(dev->netdev->dev.parent,
				"unable to read %s bootloader info (err %d)\n",
				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,
		     "PEAK-System %s hwrev %u serial %08X.%08X (%u channels)\n",
		     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);

		/* tell the device the can driver is running */
		pcan_usb_pro_drv_loaded(dev, 1);
	} else {
		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)
	pcan_usb_pro_set_led(dev, 0, 1);

	return 0;

 err_out:
	kfree(bi);
	kfree(fi);
	kfree(usb_if);

	return err;
}

static void pcan_usb_pro_exit(struct peak_usb_device *dev)
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@

/* Vendor Request value for XXX_FCT */
#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 */
struct __packed pcan_usb_pro_blinfo {