diff options
Diffstat (limited to 'drivers/net/can')
23 files changed, 231 insertions, 186 deletions
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index e456b70933c2..3c069472eb8b 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -102,12 +102,9 @@ config CAN_JANZ_ICAN3 This driver can also be built as a module. If so, the module will be called janz-ican3.ko. -config HAVE_CAN_FLEXCAN - bool - config CAN_FLEXCAN tristate "Support for Freescale FLEXCAN based chips" - depends on HAVE_CAN_FLEXCAN + depends on ARM || PPC ---help--- Say Y here if you want to support for Freescale FlexCAN. diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index db52f4414def..dbbe97ae121e 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c @@ -1220,7 +1220,7 @@ static ssize_t at91_sysfs_set_mb0_id(struct device *dev, goto out; } - err = strict_strtoul(buf, 0, &can_id); + err = kstrtoul(buf, 0, &can_id); if (err) { ret = err; goto out; @@ -1264,8 +1264,6 @@ static const struct of_device_id at91_can_dt_ids[] = { } }; MODULE_DEVICE_TABLE(of, at91_can_dt_ids); -#else -#define at91_can_dt_ids NULL #endif static const struct at91_devtype_data *at91_can_get_driver_data(struct platform_device *pdev) @@ -1393,8 +1391,6 @@ static int at91_can_remove(struct platform_device *pdev) unregister_netdev(dev); - platform_set_drvdata(pdev, NULL); - iounmap(priv->reg_base); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1426,7 +1422,7 @@ static struct platform_driver at91_can_driver = { .driver = { .name = KBUILD_MODNAME, .owner = THIS_MODULE, - .of_match_table = at91_can_dt_ids, + .of_match_table = of_match_ptr(at91_can_dt_ids), }, .id_table = at91_can_id_table, }; diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index d4a15e82bfc0..a2700d25ff0e 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -580,7 +580,7 @@ static int bfin_can_probe(struct platform_device *pdev) priv->pin_list = pdata; priv->can.clock.freq = get_sclk(); - dev_set_drvdata(&pdev->dev, dev); + platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); dev->flags |= IFF_ECHO; /* we support local echo */ @@ -613,7 +613,7 @@ exit: static int bfin_can_remove(struct platform_device *pdev) { - struct net_device *dev = dev_get_drvdata(&pdev->dev); + struct net_device *dev = platform_get_drvdata(pdev); struct bfin_can_priv *priv = netdev_priv(dev); struct resource *res; @@ -621,8 +621,6 @@ static int bfin_can_remove(struct platform_device *pdev) unregister_candev(dev); - dev_set_drvdata(&pdev->dev, NULL); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); @@ -635,7 +633,7 @@ static int bfin_can_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg) { - struct net_device *dev = dev_get_drvdata(&pdev->dev); + struct net_device *dev = platform_get_drvdata(pdev); struct bfin_can_priv *priv = netdev_priv(dev); struct bfin_can_regs __iomem *reg = priv->membase; int timeout = BFIN_CAN_TIMEOUT; @@ -658,7 +656,7 @@ static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg) static int bfin_can_resume(struct platform_device *pdev) { - struct net_device *dev = dev_get_drvdata(&pdev->dev); + struct net_device *dev = platform_get_drvdata(pdev); struct bfin_can_priv *priv = netdev_priv(dev); struct bfin_can_regs __iomem *reg = priv->membase; diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index d63b91904f82..c6f838d922a5 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -32,7 +32,6 @@ #include <linux/clk.h> #include <linux/of.h> #include <linux/of_device.h> -#include <linux/pinctrl/consumer.h> #include <linux/can/dev.h> @@ -114,7 +113,6 @@ static int c_can_plat_probe(struct platform_device *pdev) struct c_can_priv *priv; const struct of_device_id *match; const struct platform_device_id *id; - struct pinctrl *pinctrl; struct resource *mem, *res; int irq; struct clk *clk; @@ -131,11 +129,6 @@ static int c_can_plat_probe(struct platform_device *pdev) id = platform_get_device_id(pdev); } - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) - dev_warn(&pdev->dev, - "failed to configure pins from driver\n"); - /* get the appropriate clk */ clk = clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { @@ -201,8 +194,8 @@ static int c_can_plat_probe(struct platform_device *pdev) priv->instance = pdev->id; res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - priv->raminit_ctrlreg = devm_request_and_ioremap(&pdev->dev, res); - if (!priv->raminit_ctrlreg || priv->instance < 0) + priv->raminit_ctrlreg = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0) dev_info(&pdev->dev, "control memory is not used for raminit\n"); else priv->raminit = c_can_hw_raminit; @@ -234,7 +227,6 @@ static int c_can_plat_probe(struct platform_device *pdev) return 0; exit_free_device: - platform_set_drvdata(pdev, NULL); free_c_can_dev(dev); exit_iounmap: iounmap(addr); @@ -255,7 +247,6 @@ static int c_can_plat_remove(struct platform_device *pdev) struct resource *mem; unregister_c_can_dev(dev); - platform_set_drvdata(pdev, NULL); free_c_can_dev(dev); iounmap(priv->base); diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c index 8eaaac81f320..87a47c0cfd49 100644 --- a/drivers/net/can/cc770/cc770_isa.c +++ b/drivers/net/can/cc770/cc770_isa.c @@ -265,7 +265,7 @@ static int cc770_isa_probe(struct platform_device *pdev) else priv->clkout = COR_DEFAULT; - dev_set_drvdata(&pdev->dev, dev); + platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); err = register_cc770dev(dev); @@ -293,12 +293,11 @@ static int cc770_isa_probe(struct platform_device *pdev) static int cc770_isa_remove(struct platform_device *pdev) { - struct net_device *dev = dev_get_drvdata(&pdev->dev); + struct net_device *dev = platform_get_drvdata(pdev); struct cc770_priv *priv = netdev_priv(dev); int idx = pdev->id; unregister_cc770dev(dev); - dev_set_drvdata(&pdev->dev, NULL); if (mem[idx]) { iounmap(priv->reg_base); diff --git a/drivers/net/can/cc770/cc770_platform.c b/drivers/net/can/cc770/cc770_platform.c index d0f6bfc45aea..034bdd816a60 100644 --- a/drivers/net/can/cc770/cc770_platform.c +++ b/drivers/net/can/cc770/cc770_platform.c @@ -216,7 +216,7 @@ static int cc770_platform_probe(struct platform_device *pdev) priv->reg_base, dev->irq, priv->can.clock.freq, priv->cpu_interface, priv->bus_config, priv->clkout); - dev_set_drvdata(&pdev->dev, dev); + platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); err = register_cc770dev(dev); @@ -240,7 +240,7 @@ exit_release_mem: static int cc770_platform_remove(struct platform_device *pdev) { - struct net_device *dev = dev_get_drvdata(&pdev->dev); + struct net_device *dev = platform_get_drvdata(pdev); struct cc770_priv *priv = netdev_priv(dev); struct resource *mem; diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 769d29ed106d..7b0be0910f4b 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -24,7 +24,6 @@ #include <linux/can/dev.h> #include <linux/can/error.h> #include <linux/can/led.h> -#include <linux/can/platform/flexcan.h> #include <linux/clk.h> #include <linux/delay.h> #include <linux/if_arp.h> @@ -37,7 +36,7 @@ #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> -#include <linux/pinctrl/consumer.h> +#include <linux/regulator/consumer.h> #define DRV_NAME "flexcan" @@ -212,6 +211,7 @@ struct flexcan_priv { struct clk *clk_per; struct flexcan_platform_data *pdata; const struct flexcan_devtype_data *devtype_data; + struct regulator *reg_xceiver; }; static struct flexcan_devtype_data fsl_p1010_devtype_data = { @@ -259,15 +259,6 @@ static inline void flexcan_write(u32 val, void __iomem *addr) } #endif -/* - * Swtich transceiver on or off - */ -static void flexcan_transceiver_switch(const struct flexcan_priv *priv, int on) -{ - if (priv->pdata && priv->pdata->transceiver_switch) - priv->pdata->transceiver_switch(on); -} - static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, u32 reg_esr) { @@ -800,7 +791,11 @@ static int flexcan_chip_start(struct net_device *dev) if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) flexcan_write(0x0, ®s->rxfgmask); - flexcan_transceiver_switch(priv, 1); + if (priv->reg_xceiver) { + err = regulator_enable(priv->reg_xceiver); + if (err) + goto out; + } /* synchronize with the can bus */ reg_mcr = flexcan_read(®s->mcr); @@ -843,7 +838,8 @@ static void flexcan_chip_stop(struct net_device *dev) reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT; flexcan_write(reg, ®s->mcr); - flexcan_transceiver_switch(priv, 0); + if (priv->reg_xceiver) + regulator_disable(priv->reg_xceiver); priv->can.state = CAN_STATE_STOPPED; return; @@ -1004,16 +1000,11 @@ static int flexcan_probe(struct platform_device *pdev) struct flexcan_priv *priv; struct resource *mem; struct clk *clk_ipg = NULL, *clk_per = NULL; - struct pinctrl *pinctrl; void __iomem *base; resource_size_t mem_size; int err, irq; u32 clock_freq = 0; - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) - return PTR_ERR(pinctrl); - if (pdev->dev.of_node) of_property_read_u32(pdev->dev.of_node, "clock-frequency", &clock_freq); @@ -1090,6 +1081,10 @@ static int flexcan_probe(struct platform_device *pdev) priv->pdata = pdev->dev.platform_data; priv->devtype_data = devtype_data; + priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); + if (IS_ERR(priv->reg_xceiver)) + priv->reg_xceiver = NULL; + netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT); dev_set_drvdata(&pdev->dev, dev); @@ -1127,7 +1122,6 @@ static int flexcan_remove(struct platform_device *pdev) struct resource *mem; unregister_flexcandev(dev); - platform_set_drvdata(pdev, NULL); iounmap(priv->base); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1138,10 +1132,10 @@ static int flexcan_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int flexcan_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int flexcan_suspend(struct device *device) { - struct net_device *dev = platform_get_drvdata(pdev); + struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); flexcan_chip_disable(priv); @@ -1155,9 +1149,9 @@ static int flexcan_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int flexcan_resume(struct platform_device *pdev) +static int flexcan_resume(struct device *device) { - struct net_device *dev = platform_get_drvdata(pdev); + struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); priv->can.state = CAN_STATE_ERROR_ACTIVE; @@ -1169,21 +1163,19 @@ static int flexcan_resume(struct platform_device *pdev) return 0; } -#else -#define flexcan_suspend NULL -#define flexcan_resume NULL -#endif +#endif /* CONFIG_PM_SLEEP */ + +static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); static struct platform_driver flexcan_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .pm = &flexcan_pm_ops, .of_match_table = flexcan_of_match, }, .probe = flexcan_probe, .remove = flexcan_remove, - .suspend = flexcan_suspend, - .resume = flexcan_resume, .id_table = flexcan_id_table, }; diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c index 17fbc7a09224..6aa737a24393 100644 --- a/drivers/net/can/grcan.c +++ b/drivers/net/can/grcan.c @@ -1646,7 +1646,7 @@ static int grcan_setup_netdev(struct platform_device *ofdev, if (err) goto exit_free_candev; - dev_set_drvdata(&ofdev->dev, dev); + platform_set_drvdata(ofdev, dev); /* Reset device to allow bit-timing to be set. No need to call * grcan_reset at this stage. That is done in grcan_open. @@ -1683,10 +1683,9 @@ static int grcan_probe(struct platform_device *ofdev) } res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); - base = devm_request_and_ioremap(&ofdev->dev, res); - if (!base) { - dev_err(&ofdev->dev, "couldn't map IO resource\n"); - err = -EADDRNOTAVAIL; + base = devm_ioremap_resource(&ofdev->dev, res); + if (IS_ERR(base)) { + err = PTR_ERR(base); goto exit_error; } @@ -1716,13 +1715,12 @@ exit_error: static int grcan_remove(struct platform_device *ofdev) { - struct net_device *dev = dev_get_drvdata(&ofdev->dev); + struct net_device *dev = platform_get_drvdata(ofdev); struct grcan_priv *priv = netdev_priv(dev); unregister_candev(dev); /* Will in turn call grcan_close */ irq_dispose_mapping(dev->irq); - dev_set_drvdata(&ofdev->dev, NULL); netif_napi_del(&priv->napi); free_candev(dev); diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index c4bc1d2e2033..36bd6fa1c7f3 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c @@ -1734,7 +1734,7 @@ static ssize_t ican3_sysfs_set_term(struct device *dev, unsigned long enable; int ret; - if (strict_strtoul(buf, 0, &enable)) + if (kstrtoul(buf, 0, &enable)) return -EINVAL; ret = ican3_set_termination(mod, enable); diff --git a/drivers/net/can/led.c b/drivers/net/can/led.c index f27fca65dc4a..a3d99a8fd2d1 100644 --- a/drivers/net/can/led.c +++ b/drivers/net/can/led.c @@ -88,9 +88,9 @@ EXPORT_SYMBOL_GPL(devm_can_led_init); /* NETDEV rename notifier to rename the associated led triggers too */ static int can_led_notifier(struct notifier_block *nb, unsigned long msg, - void *data) + void *ptr) { - struct net_device *netdev = data; + struct net_device *netdev = netdev_notifier_info_to_dev(ptr); struct can_priv *priv = safe_candev_priv(netdev); char name[CAN_LED_NAME_SZ]; diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index 668850e441dc..5b0ee8ef5885 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -302,7 +302,7 @@ static int mpc5xxx_can_probe(struct platform_device *ofdev) goto exit_free_mscan; } - dev_set_drvdata(&ofdev->dev, dev); + platform_set_drvdata(ofdev, dev); dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n", priv->reg_base, dev->irq, priv->can.clock.freq); @@ -321,11 +321,9 @@ exit_unmap_mem: static int mpc5xxx_can_remove(struct platform_device *ofdev) { - struct net_device *dev = dev_get_drvdata(&ofdev->dev); + struct net_device *dev = platform_get_drvdata(ofdev); struct mscan_priv *priv = netdev_priv(dev); - dev_set_drvdata(&ofdev->dev, NULL); - unregister_mscandev(dev); iounmap(priv->reg_base); irq_dispose_mapping(dev->irq); @@ -338,7 +336,7 @@ static int mpc5xxx_can_remove(struct platform_device *ofdev) static struct mscan_regs saved_regs; static int mpc5xxx_can_suspend(struct platform_device *ofdev, pm_message_t state) { - struct net_device *dev = dev_get_drvdata(&ofdev->dev); + struct net_device *dev = platform_get_drvdata(ofdev); struct mscan_priv *priv = netdev_priv(dev); struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; @@ -349,7 +347,7 @@ static int mpc5xxx_can_suspend(struct platform_device *ofdev, pm_message_t state static int mpc5xxx_can_resume(struct platform_device *ofdev) { - struct net_device *dev = dev_get_drvdata(&ofdev->dev); + struct net_device *dev = platform_get_drvdata(ofdev); struct mscan_priv *priv = netdev_priv(dev); struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; diff --git a/drivers/net/can/sja1000/sja1000_isa.c b/drivers/net/can/sja1000/sja1000_isa.c index 5c8da4661489..06a282397fff 100644 --- a/drivers/net/can/sja1000/sja1000_isa.c +++ b/drivers/net/can/sja1000/sja1000_isa.c @@ -197,7 +197,7 @@ static int sja1000_isa_probe(struct platform_device *pdev) else priv->cdr = CDR_DEFAULT; - dev_set_drvdata(&pdev->dev, dev); + platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); err = register_sja1000dev(dev); @@ -225,12 +225,11 @@ static int sja1000_isa_probe(struct platform_device *pdev) static int sja1000_isa_remove(struct platform_device *pdev) { - struct net_device *dev = dev_get_drvdata(&pdev->dev); + struct net_device *dev = platform_get_drvdata(pdev); struct sja1000_priv *priv = netdev_priv(dev); int idx = pdev->id; unregister_sja1000dev(dev); - dev_set_drvdata(&pdev->dev, NULL); if (mem[idx]) { iounmap(priv->reg_base); diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index 8e0c4a001939..31ad33911167 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -72,13 +72,11 @@ static void sja1000_ofp_write_reg(const struct sja1000_priv *priv, static int sja1000_ofp_remove(struct platform_device *ofdev) { - struct net_device *dev = dev_get_drvdata(&ofdev->dev); + struct net_device *dev = platform_get_drvdata(ofdev); struct sja1000_priv *priv = netdev_priv(dev); struct device_node *np = ofdev->dev.of_node; struct resource res; - dev_set_drvdata(&ofdev->dev, NULL); - unregister_sja1000dev(dev); free_sja1000dev(dev); iounmap(priv->reg_base); @@ -181,7 +179,7 @@ static int sja1000_ofp_probe(struct platform_device *ofdev) priv->reg_base, dev->irq, priv->can.clock.freq, priv->ocr, priv->cdr); - dev_set_drvdata(&ofdev->dev, dev); + platform_set_drvdata(ofdev, dev); SET_NETDEV_DEV(dev, &ofdev->dev); err = register_sja1000dev(dev); diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c index 21619bb5b869..8e259c541036 100644 --- a/drivers/net/can/sja1000/sja1000_platform.c +++ b/drivers/net/can/sja1000/sja1000_platform.c @@ -135,7 +135,7 @@ static int sp_probe(struct platform_device *pdev) break; } - dev_set_drvdata(&pdev->dev, dev); + platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); err = register_sja1000dev(dev); @@ -161,12 +161,11 @@ static int sp_probe(struct platform_device *pdev) static int sp_remove(struct platform_device *pdev) { - struct net_device *dev = dev_get_drvdata(&pdev->dev); + struct net_device *dev = platform_get_drvdata(pdev); struct sja1000_priv *priv = netdev_priv(dev); struct resource *res; unregister_sja1000dev(dev); - dev_set_drvdata(&pdev->dev, NULL); if (priv->reg_base) iounmap(priv->reg_base); diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 06b7e097d36e..874188ba06f7 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -161,7 +161,7 @@ static void slc_bump(struct slcan *sl) sl->rbuff[dlc_pos] = 0; /* terminate can_id string */ - if (strict_strtoul(sl->rbuff+1, 16, &ultmp)) + if (kstrtoul(sl->rbuff+1, 16, &ultmp)) return; cf.can_id = ultmp; diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index 3a2b45601ec2..65eef1eea2e2 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -594,7 +594,7 @@ static ssize_t store_output(struct device *dev, struct device_attribute *attr, unsigned long val; int ret; - ret = strict_strtoul(buf, 0, &val); + ret = kstrtoul(buf, 0, &val); if (ret < 0) return ret; val &= 0xFF; diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index f21fc37ec578..3a349a22d5bc 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -1001,7 +1001,6 @@ static int ti_hecc_remove(struct platform_device *pdev) iounmap(priv->base); release_mem_region(res->start, resource_size(res)); free_candev(ndev); - platform_set_drvdata(pdev, NULL); return 0; } diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index 9b74d1e3ad44..ac6177d3befc 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -412,10 +412,20 @@ static void esd_usb2_read_bulk_callback(struct urb *urb) switch (msg->msg.hdr.cmd) { case CMD_CAN_RX: + if (msg->msg.rx.net >= dev->net_count) { + dev_err(dev->udev->dev.parent, "format error\n"); + break; + } + esd_usb2_rx_can_msg(dev->nets[msg->msg.rx.net], msg); break; case CMD_CAN_TX: + if (msg->msg.txdone.net >= dev->net_count) { + dev_err(dev->udev->dev.parent, "format error\n"); + break; + } + esd_usb2_tx_done_msg(dev->nets[msg->msg.txdone.net], msg); break; @@ -612,9 +622,15 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv) { struct esd_usb2 *dev = priv->usb2; struct net_device *netdev = priv->netdev; - struct esd_usb2_msg msg; + struct esd_usb2_msg *msg; int err, i; + msg = kmalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) { + err = -ENOMEM; + goto out; + } + /* * Enable all IDs * The IDADD message takes up to 64 32 bit bitmasks (2048 bits). @@ -628,33 +644,32 @@ static int esd_usb2_start(struct esd_usb2_net_priv *priv) * the number of the starting bitmask (0..64) to the filter.option * field followed by only some bitmasks. */ - msg.msg.hdr.cmd = CMD_IDADD; - msg.msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; - msg.msg.filter.net = priv->index; - msg.msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ + msg->msg.hdr.cmd = CMD_IDADD; + msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; + msg->msg.filter.net = priv->index; + msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ for (i = 0; i < ESD_MAX_ID_SEGMENT; i++) - msg.msg.filter.mask[i] = cpu_to_le32(0xffffffff); + msg->msg.filter.mask[i] = cpu_to_le32(0xffffffff); /* enable 29bit extended IDs */ - msg.msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001); + msg->msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001); - err = esd_usb2_send_msg(dev, &msg); + err = esd_usb2_send_msg(dev, msg); if (err) - goto failed; + goto out; err = esd_usb2_setup_rx_urbs(dev); if (err) - goto failed; + goto out; priv->can.state = CAN_STATE_ERROR_ACTIVE; - return 0; - -failed: +out: if (err == -ENODEV) netif_device_detach(netdev); + if (err) + netdev_err(netdev, "couldn't start device: %d\n", err); - netdev_err(netdev, "couldn't start device: %d\n", err); - + kfree(msg); return err; } @@ -833,26 +848,30 @@ nourbmem: static int esd_usb2_close(struct net_device *netdev) { struct esd_usb2_net_priv *priv = netdev_priv(netdev); - struct esd_usb2_msg msg; + struct esd_usb2_msg *msg; int i; + msg = kmalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) + return -ENOMEM; + /* Disable all IDs (see esd_usb2_start()) */ - msg.msg.hdr.cmd = CMD_IDADD; - msg.msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; - msg.msg.filter.net = priv->index; - msg.msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ + msg->msg.hdr.cmd = CMD_IDADD; + msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT; + msg->msg.filter.net = priv->index; + msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */ for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++) - msg.msg.filter.mask[i] = 0; - if (esd_usb2_send_msg(priv->usb2, &msg) < 0) + msg->msg.filter.mask[i] = 0; + if (esd_usb2_send_msg(priv->usb2, msg) < 0) netdev_err(netdev, "sending idadd message failed\n"); /* set CAN controller to reset mode */ - msg.msg.hdr.len = 2; - msg.msg.hdr.cmd = CMD_SETBAUD; - msg.msg.setbaud.net = priv->index; - msg.msg.setbaud.rsvd = 0; - msg.msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE); - if (esd_usb2_send_msg(priv->usb2, &msg) < 0) + msg->msg.hdr.len = 2; + msg->msg.hdr.cmd = CMD_SETBAUD; + msg->msg.setbaud.net = priv->index; + msg->msg.setbaud.rsvd = 0; + msg->msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE); + if (esd_usb2_send_msg(priv->usb2, msg) < 0) netdev_err(netdev, "sending setbaud message failed\n"); priv->can.state = CAN_STATE_STOPPED; @@ -861,6 +880,8 @@ static int esd_usb2_close(struct net_device *netdev) close_candev(netdev); + kfree(msg); + return 0; } @@ -886,7 +907,8 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) { struct esd_usb2_net_priv *priv = netdev_priv(netdev); struct can_bittiming *bt = &priv->can.bittiming; - struct esd_usb2_msg msg; + struct esd_usb2_msg *msg; + int err; u32 canbtr; int sjw_shift; @@ -912,15 +934,22 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) canbtr |= ESD_USB2_3_SAMPLES; - msg.msg.hdr.len = 2; - msg.msg.hdr.cmd = CMD_SETBAUD; - msg.msg.setbaud.net = priv->index; - msg.msg.setbaud.rsvd = 0; - msg.msg.setbaud.baud = cpu_to_le32(canbtr); + msg = kmalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) + return -ENOMEM; + + msg->msg.hdr.len = 2; + msg->msg.hdr.cmd = CMD_SETBAUD; + msg->msg.setbaud.net = priv->index; + msg->msg.setbaud.rsvd = 0; + msg->msg.setbaud.baud = cpu_to_le32(canbtr); netdev_info(netdev, "setting BTR=%#x\n", canbtr); - return esd_usb2_send_msg(priv->usb2, &msg); + err = esd_usb2_send_msg(priv->usb2, msg); + + kfree(msg); + return err; } static int esd_usb2_get_berr_counter(const struct net_device *netdev, @@ -1022,7 +1051,7 @@ static int esd_usb2_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct esd_usb2 *dev; - struct esd_usb2_msg msg; + struct esd_usb2_msg *msg; int i, err; dev = kzalloc(sizeof(*dev), GFP_KERNEL); @@ -1037,27 +1066,33 @@ static int esd_usb2_probe(struct usb_interface *intf, usb_set_intfdata(intf, dev); + msg = kmalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) { + err = -ENOMEM; + goto free_msg; + } + /* query number of CAN interfaces (nets) */ - msg.msg.hdr.cmd = CMD_VERSION; - msg.msg.hdr.len = 2; - msg.msg.version.rsvd = 0; - msg.msg.version.flags = 0; - msg.msg.version.drv_version = 0; + msg->msg.hdr.cmd = CMD_VERSION; + msg->msg.hdr.len = 2; + msg->msg.version.rsvd = 0; + msg->msg.version.flags = 0; + msg->msg.version.drv_version = 0; - err = esd_usb2_send_msg(dev, &msg); + err = esd_usb2_send_msg(dev, msg); if (err < 0) { dev_err(&intf->dev, "sending version message failed\n"); - goto free_dev; + goto free_msg; } - err = esd_usb2_wait_msg(dev, &msg); + err = esd_usb2_wait_msg(dev, msg); if (err < 0) { dev_err(&intf->dev, "no version message answer\n"); - goto free_dev; + goto free_msg; } - dev->net_count = (int)msg.msg.version_reply.nets; - dev->version = le32_to_cpu(msg.msg.version_reply.version); + dev->net_count = (int)msg->msg.version_reply.nets; + dev->version = le32_to_cpu(msg->msg.version_reply.version); if (device_create_file(&intf->dev, &dev_attr_firmware)) dev_err(&intf->dev, @@ -1075,10 +1110,10 @@ static int esd_usb2_probe(struct usb_interface *intf, for (i = 0; i < dev->net_count; i++) esd_usb2_probe_one_net(intf, i); - return 0; - -free_dev: - kfree(dev); +free_msg: + kfree(msg); + if (err) + kfree(dev); done: return err; } diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 45cb9f3c1324..3b9546588240 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -136,6 +136,9 @@ #define KVASER_CTRL_MODE_SELFRECEPTION 3 #define KVASER_CTRL_MODE_OFF 4 +/* log message */ +#define KVASER_EXTENDED_FRAME BIT(31) + struct kvaser_msg_simple { u8 tid; u8 channel; @@ -817,8 +820,13 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, priv = dev->nets[channel]; stats = &priv->netdev->stats; - if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME | MSG_FLAG_NERR | - MSG_FLAG_OVERRUN)) { + if ((msg->u.rx_can.flag & MSG_FLAG_ERROR_FRAME) && + (msg->id == CMD_LOG_MESSAGE)) { + kvaser_usb_rx_error(dev, msg); + return; + } else if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME | + MSG_FLAG_NERR | + MSG_FLAG_OVERRUN)) { kvaser_usb_rx_can_err(priv, msg); return; } else if (msg->u.rx_can.flag & ~MSG_FLAG_REMOTE_FRAME) { @@ -834,22 +842,40 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, return; } - cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) | - (msg->u.rx_can.msg[1] & 0x3f); - cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]); + if (msg->id == CMD_LOG_MESSAGE) { + cf->can_id = le32_to_cpu(msg->u.log_message.id); + if (cf->can_id & KVASER_EXTENDED_FRAME) + cf->can_id &= CAN_EFF_MASK | CAN_EFF_FLAG; + else + cf->can_id &= CAN_SFF_MASK; - if (msg->id == CMD_RX_EXT_MESSAGE) { - cf->can_id <<= 18; - cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) | - ((msg->u.rx_can.msg[3] & 0xff) << 6) | - (msg->u.rx_can.msg[4] & 0x3f); - cf->can_id |= CAN_EFF_FLAG; - } + cf->can_dlc = get_can_dlc(msg->u.log_message.dlc); - if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME) - cf->can_id |= CAN_RTR_FLAG; - else - memcpy(cf->data, &msg->u.rx_can.msg[6], cf->can_dlc); + if (msg->u.log_message.flags & MSG_FLAG_REMOTE_FRAME) + cf->can_id |= CAN_RTR_FLAG; + else + memcpy(cf->data, &msg->u.log_message.data, + cf->can_dlc); + } else { + cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) | + (msg->u.rx_can.msg[1] & 0x3f); + + if (msg->id == CMD_RX_EXT_MESSAGE) { + cf->can_id <<= 18; + cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) | + ((msg->u.rx_can.msg[3] & 0xff) << 6) | + (msg->u.rx_can.msg[4] & 0x3f); + cf->can_id |= CAN_EFF_FLAG; + } + + cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]); + + if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME) + cf->can_id |= CAN_RTR_FLAG; + else + memcpy(cf->data, &msg->u.rx_can.msg[6], + cf->can_dlc); + } netif_rx(skb); @@ -911,6 +937,7 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev, case CMD_RX_STD_MESSAGE: case CMD_RX_EXT_MESSAGE: + case CMD_LOG_MESSAGE: kvaser_usb_rx_can_msg(dev, msg); break; @@ -919,11 +946,6 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev, kvaser_usb_rx_error(dev, msg); break; - case CMD_LOG_MESSAGE: - if (msg->u.log_message.flags & MSG_FLAG_ERROR_FRAME) - kvaser_usb_rx_error(dev, msg); - break; - case CMD_TX_ACKNOWLEDGE: kvaser_usb_tx_acknowledge(dev, msg); break; diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index 25723d8ee201..925ab8ec9329 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -649,7 +649,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) if ((mc->ptr + rec_len) > mc->end) goto decode_failed; - memcpy(cf->data, mc->ptr, rec_len); + memcpy(cf->data, mc->ptr, cf->can_dlc); mc->ptr += rec_len; } diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 30d79bfa5b10..8ee9d1556e6e 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -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) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h index a869918c5620..32275af547e0 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h @@ -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 { diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c index 6e15ef08f301..8becd3d838b5 100644 --- a/drivers/net/can/usb/usb_8dev.c +++ b/drivers/net/can/usb/usb_8dev.c @@ -779,6 +779,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) usb_unanchor_urb(urb); usb_free_coherent(priv->udev, RX_BUFFER_SIZE, buf, urb->transfer_dma); + usb_free_urb(urb); break; } @@ -977,7 +978,7 @@ static int usb_8dev_probe(struct usb_interface *intf, err = usb_8dev_cmd_version(priv, &version); if (err) { netdev_err(netdev, "can't get firmware version\n"); - goto cleanup_cmd_msg_buffer; + goto cleanup_unregister_candev; } else { netdev_info(netdev, "firmware: %d.%d, hardware: %d.%d\n", @@ -989,6 +990,9 @@ static int usb_8dev_probe(struct usb_interface *intf, return 0; +cleanup_unregister_candev: + unregister_netdev(priv->netdev); + cleanup_cmd_msg_buffer: kfree(priv->cmd_msg_buffer); |
