aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Pellegrin <chripell@fsfe.org>2010-01-14 02:08:34 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-15 04:39:17 -0500
commitad72c347e56bf3a0231b9d686e17764157d2961c (patch)
tree4db03a0abae50edfaf996f43e3f717a57b776fbd
parent1954dc11776ef8c06263ba4cd21bf4d25c79a19c (diff)
can: Proper ctrlmode handling for CAN devices
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> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/can/at91_can.c1
-rw-r--r--drivers/net/can/bfin_can.c1
-rw-r--r--drivers/net/can/dev.c2
-rw-r--r--drivers/net/can/mcp251x.c11
-rw-r--r--drivers/net/can/mscan/mscan.c1
-rw-r--r--drivers/net/can/sja1000/sja1000.c1
-rw-r--r--drivers/net/can/ti_hecc.c1
-rw-r--r--drivers/net/can/usb/ems_usb.c1
-rw-r--r--include/linux/can/dev.h1
9 files changed, 19 insertions, 1 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index f7287497ba6e..a2f29a38798a 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -1073,6 +1073,7 @@ static int __init at91_can_probe(struct platform_device *pdev)
1073 priv->can.bittiming_const = &at91_bittiming_const; 1073 priv->can.bittiming_const = &at91_bittiming_const;
1074 priv->can.do_set_bittiming = at91_set_bittiming; 1074 priv->can.do_set_bittiming = at91_set_bittiming;
1075 priv->can.do_set_mode = at91_set_mode; 1075 priv->can.do_set_mode = at91_set_mode;
1076 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
1076 priv->reg_base = addr; 1077 priv->reg_base = addr;
1077 priv->dev = dev; 1078 priv->dev = dev;
1078 priv->clk = clk; 1079 priv->clk = clk;
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c
index 7e1926e79e98..bf7f9ba2d903 100644
--- a/drivers/net/can/bfin_can.c
+++ b/drivers/net/can/bfin_can.c
@@ -603,6 +603,7 @@ struct net_device *alloc_bfin_candev(void)
603 priv->can.bittiming_const = &bfin_can_bittiming_const; 603 priv->can.bittiming_const = &bfin_can_bittiming_const;
604 priv->can.do_set_bittiming = bfin_can_set_bittiming; 604 priv->can.do_set_bittiming = bfin_can_set_bittiming;
605 priv->can.do_set_mode = bfin_can_set_mode; 605 priv->can.do_set_mode = bfin_can_set_mode;
606 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
606 607
607 return dev; 608 return dev;
608} 609}
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index c1bb29f0322b..f08f1202ff00 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -592,6 +592,8 @@ static int can_changelink(struct net_device *dev,
592 if (dev->flags & IFF_UP) 592 if (dev->flags & IFF_UP)
593 return -EBUSY; 593 return -EBUSY;
594 cm = nla_data(data[IFLA_CAN_CTRLMODE]); 594 cm = nla_data(data[IFLA_CAN_CTRLMODE]);
595 if (cm->flags & ~priv->ctrlmode_supported)
596 return -EOPNOTSUPP;
595 priv->ctrlmode &= ~cm->mask; 597 priv->ctrlmode &= ~cm->mask;
596 priv->ctrlmode |= cm->flags; 598 priv->ctrlmode |= cm->flags;
597 } 599 }
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
index afa2fa45fed9..bbe186b5a0ed 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -539,9 +539,14 @@ static void mcp251x_set_normal_mode(struct spi_device *spi)
539 if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { 539 if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
540 /* Put device into loopback mode */ 540 /* Put device into loopback mode */
541 mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK); 541 mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK);
542 } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
543 /* Put device into listen-only mode */
544 mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY);
542 } else { 545 } else {
543 /* Put device into normal mode */ 546 /* Put device into normal mode */
544 mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL); 547 mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL |
548 (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT ?
549 CANCTRL_OSM : 0));
545 550
546 /* Wait for the device to enter normal mode */ 551 /* Wait for the device to enter normal mode */
547 timeout = jiffies + HZ; 552 timeout = jiffies + HZ;
@@ -948,6 +953,10 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi)
948 priv->can.bittiming_const = &mcp251x_bittiming_const; 953 priv->can.bittiming_const = &mcp251x_bittiming_const;
949 priv->can.do_set_mode = mcp251x_do_set_mode; 954 priv->can.do_set_mode = mcp251x_do_set_mode;
950 priv->can.clock.freq = pdata->oscillator_frequency / 2; 955 priv->can.clock.freq = pdata->oscillator_frequency / 2;
956 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
957 CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
958 if (pdata->model == CAN_MCP251X_MCP2515)
959 priv->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT;
951 priv->net = net; 960 priv->net = net;
952 dev_set_drvdata(&spi->dev, priv); 961 dev_set_drvdata(&spi->dev, priv);
953 962
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 40827c128b65..6b7dd578d417 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -686,6 +686,7 @@ struct net_device *alloc_mscandev(void)
686 priv->can.bittiming_const = &mscan_bittiming_const; 686 priv->can.bittiming_const = &mscan_bittiming_const;
687 priv->can.do_set_bittiming = mscan_do_set_bittiming; 687 priv->can.do_set_bittiming = mscan_do_set_bittiming;
688 priv->can.do_set_mode = mscan_do_set_mode; 688 priv->can.do_set_mode = mscan_do_set_mode;
689 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
689 690
690 for (i = 0; i < TX_QUEUE_SIZE; i++) { 691 for (i = 0; i < TX_QUEUE_SIZE; i++) {
691 priv->tx_queue[i].id = i; 692 priv->tx_queue[i].id = i;
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 345304d779b9..ace103a44833 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -567,6 +567,7 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
567 priv->can.bittiming_const = &sja1000_bittiming_const; 567 priv->can.bittiming_const = &sja1000_bittiming_const;
568 priv->can.do_set_bittiming = sja1000_set_bittiming; 568 priv->can.do_set_bittiming = sja1000_set_bittiming;
569 priv->can.do_set_mode = sja1000_set_mode; 569 priv->can.do_set_mode = sja1000_set_mode;
570 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
570 571
571 if (sizeof_priv) 572 if (sizeof_priv)
572 priv->priv = (void *)priv + sizeof(struct sja1000_priv); 573 priv->priv = (void *)priv + sizeof(struct sja1000_priv);
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index 7d370e32a7a8..8332e242b0be 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -909,6 +909,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
909 priv->can.bittiming_const = &ti_hecc_bittiming_const; 909 priv->can.bittiming_const = &ti_hecc_bittiming_const;
910 priv->can.do_set_mode = ti_hecc_do_set_mode; 910 priv->can.do_set_mode = ti_hecc_do_set_mode;
911 priv->can.do_get_state = ti_hecc_get_state; 911 priv->can.do_get_state = ti_hecc_get_state;
912 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
912 913
913 ndev->irq = irq->start; 914 ndev->irq = irq->start;
914 ndev->flags |= IFF_ECHO; 915 ndev->flags |= IFF_ECHO;
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index ddb17e256656..bfab283ba9b1 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -1022,6 +1022,7 @@ static int ems_usb_probe(struct usb_interface *intf,
1022 dev->can.bittiming_const = &ems_usb_bittiming_const; 1022 dev->can.bittiming_const = &ems_usb_bittiming_const;
1023 dev->can.do_set_bittiming = ems_usb_set_bittiming; 1023 dev->can.do_set_bittiming = ems_usb_set_bittiming;
1024 dev->can.do_set_mode = ems_usb_set_mode; 1024 dev->can.do_set_mode = ems_usb_set_mode;
1025 dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
1025 1026
1026 netdev->flags |= IFF_ECHO; /* we support local echo */ 1027 netdev->flags |= IFF_ECHO; /* we support local echo */
1027 1028
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 7e7c98a3e908..c8c660a79f90 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -38,6 +38,7 @@ struct can_priv {
38 38
39 enum can_state state; 39 enum can_state state;
40 u32 ctrlmode; 40 u32 ctrlmode;
41 u32 ctrlmode_supported;
41 42
42 int restart_ms; 43 int restart_ms;
43 struct timer_list restart_timer; 44 struct timer_list restart_timer;