]> rtime.felk.cvut.cz Git - socketcan-devel.git/commitdiff
can: Proper ctrlmode handling for CAN devices
authorwolf <wolf@030b6a49-0b11-0410-94ab-b0dab22257f2>
Fri, 5 Feb 2010 19:47:46 +0000 (19:47 +0000)
committerwolf <wolf@030b6a49-0b11-0410-94ab-b0dab22257f2>
Fri, 5 Feb 2010 19:47:46 +0000 (19:47 +0000)
From net-next-2.6 commit ad72c347e56bf3a0231b9d686e17764157d2961c

This patch adds error checking of ctrlmode values for CAN devices. As
an example all availabe bits are implemented in the mcp251x driver.

Signed-off-by: Christian Pellegrin <chripell@fsfe.org>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
git-svn-id: svn://svn.berlios.de//socketcan/trunk@1123 030b6a49-0b11-0410-94ab-b0dab22257f2

kernel/2.6/drivers/net/can/at91_can.c
kernel/2.6/drivers/net/can/cc770/cc770.c
kernel/2.6/drivers/net/can/dev.c
kernel/2.6/drivers/net/can/esd_pci331.c
kernel/2.6/drivers/net/can/mcp251x.c
kernel/2.6/drivers/net/can/mscan/mscan.c
kernel/2.6/drivers/net/can/sja1000/sja1000.c
kernel/2.6/drivers/net/can/softing/softing_main.c
kernel/2.6/drivers/net/can/usb/ems_usb.c
kernel/2.6/include/socketcan/can/dev.h

index 02f9f778dded300b3fac94d8142194ec818f260e..07cbf3e89a000a24b322a64a37f6a3d4a349e8b3 100644 (file)
@@ -1094,6 +1094,7 @@ static int __init at91_can_probe(struct platform_device *pdev)
        priv->can.bittiming_const = &at91_bittiming_const;
        priv->can.do_set_bittiming = at91_set_bittiming;
        priv->can.do_set_mode = at91_set_mode;
+       priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
        priv->reg_base = addr;
        priv->dev = dev;
        priv->clk = clk;
index 259492386180dfad6f52abc1275ec7b3c9f0a64b..090ab54238434a58c911bf2dd46514ef0556b517 100644 (file)
@@ -863,6 +863,7 @@ struct net_device *alloc_cc770dev(int sizeof_priv)
        priv->can.bittiming_const = &cc770_bittiming_const;
        priv->can.do_set_bittiming = cc770_set_bittiming;
        priv->can.do_set_mode = cc770_set_mode;
+       priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
        memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags));
 
index ac81d20b846182be71485d0daa80b11c847b97c3..643693d1310cf10dc7c178454457a5c412eb0545 100644 (file)
@@ -667,6 +667,8 @@ static int can_changelink(struct net_device *dev,
                if (dev->flags & IFF_UP)
                        return -EBUSY;
                cm = nla_data(data[IFLA_CAN_CTRLMODE]);
+               if (cm->flags & ~priv->ctrlmode_supported)
+                       return -EOPNOTSUPP;
                priv->ctrlmode &= ~cm->mask;
                priv->ctrlmode |= cm->flags;
        }
index 7099811d265112582b379316b4827415e63203e4..26cb5ec0f4e04144dae588084f68ee1fdb960592 100644 (file)
@@ -784,6 +784,7 @@ static struct net_device *__devinit esd331_pci_add_chan(struct pci_dev *pdev,
 
        priv->can.do_set_bittiming = esd331_set_bittiming;
        priv->can.do_set_mode = esd331_set_mode;
+       priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
        err = register_candev(dev);
        if (err) {
index 19e4733fe63e8b877df5ac4936fc8c0e8a6ae540..b84d8a0f96013790b6378d79a588bcb8826a4a27 100644 (file)
@@ -533,7 +533,10 @@ static void mcp251x_set_normal_mode(struct spi_device *spi)
        if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
                /* Put device into loopback mode */
                mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK);
-       } else {
+       } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+               /* Put device into listen-only mode */
+               mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY);
+       } else {
                /* Put device into normal mode */
                mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL |
                                  ((pdata->model == CAN_MCP251X_MCP2515 &&
@@ -946,6 +949,10 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi)
        priv->can.bittiming_const = &mcp251x_bittiming_const;
        priv->can.do_set_mode = mcp251x_do_set_mode;
        priv->can.clock.freq = pdata->oscillator_frequency / 2;
+       priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+               CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
+       if (pdata->model == CAN_MCP251X_MCP2515)
+               priv->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT;
        priv->net = net;
        dev_set_drvdata(&spi->dev, priv);
 
index bbdc633ba42aea4f1c6d478b20e02953c048e056..a28a01c451acff52c33f62be5300700a7539622e 100644 (file)
@@ -767,6 +767,7 @@ struct net_device *alloc_mscandev(void)
        priv->can.bittiming_const = &mscan_bittiming_const;
        priv->can.do_set_bittiming = mscan_do_set_bittiming;
        priv->can.do_set_mode = mscan_do_set_mode;
+       priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
        for (i = 0; i < TX_QUEUE_SIZE; i++) {
                priv->tx_queue[i].id = i;
index df2690ea89f94343e8fc71661d0c11ad8f86965d..f81d0188a3b51a103baa992f7bbe256c1d3ef7fb 100644 (file)
@@ -602,6 +602,7 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
        priv->can.bittiming_const = &sja1000_bittiming_const;
        priv->can.do_set_bittiming = sja1000_set_bittiming;
        priv->can.do_set_mode = sja1000_set_mode;
+       priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
        if (sizeof_priv)
                priv->priv = (void *)priv + sizeof(struct sja1000_priv);
index 9bb3642d20b00fc883e0a90612155d6d19f1c64c..90b0d8569f55ca6ee55e834bbdb17794c19d84e7 100644 (file)
@@ -671,6 +671,7 @@ static struct softing_priv *mk_netdev(struct softing *card, u16 chip_id)
        ndev->hard_start_xmit   = netdev_start_xmit;
 #endif
        priv->can.do_set_mode   = candev_set_mode;
+       priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
        return priv;
 }
index 613852b5b1c60266081e183a0939eceb0c9a686a..f3a8192f7285bafb50e64cc3d4b184e19e67ba86 100644 (file)
@@ -1031,6 +1031,7 @@ static int ems_usb_probe(struct usb_interface *intf,
        dev->can.bittiming_const = &ems_usb_bittiming_const;
        dev->can.do_set_bittiming = ems_usb_set_bittiming;
        dev->can.do_set_mode = ems_usb_set_mode;
+       dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
        netdev->flags |= IFF_ECHO; /* we support local echo */
 
index 4e6da7f6cf2627a1dc12f32fb9a3b84879e25233..74f87e03235fb59b994714a717d21ff4a050e192 100644 (file)
@@ -44,6 +44,7 @@ struct can_priv {
 
        enum can_state state;
        u32 ctrlmode;
+       u32 ctrlmode_supported;
 
        int restart_ms;
        struct timer_list restart_timer;