diff options
author | Christian Pellegrin <chripell@fsfe.org> | 2010-01-14 02:08:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-15 04:39:17 -0500 |
commit | ad72c347e56bf3a0231b9d686e17764157d2961c (patch) | |
tree | 4db03a0abae50edfaf996f43e3f717a57b776fbd /drivers/net/can | |
parent | 1954dc11776ef8c06263ba4cd21bf4d25c79a19c (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>
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/at91_can.c | 1 | ||||
-rw-r--r-- | drivers/net/can/bfin_can.c | 1 | ||||
-rw-r--r-- | drivers/net/can/dev.c | 2 | ||||
-rw-r--r-- | drivers/net/can/mcp251x.c | 11 | ||||
-rw-r--r-- | drivers/net/can/mscan/mscan.c | 1 | ||||
-rw-r--r-- | drivers/net/can/sja1000/sja1000.c | 1 | ||||
-rw-r--r-- | drivers/net/can/ti_hecc.c | 1 | ||||
-rw-r--r-- | drivers/net/can/usb/ems_usb.c | 1 |
8 files changed, 18 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 | ||