Commit 7ef70aab authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-fixes-for-4.0-20150322' of...

Merge tag 'linux-can-fixes-for-4.0-20150322' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can

Marc Kleine-Budde says:

====================
pull-request: can 2015-03-22

this is a pull-request of 7 patches for net/master.

Ahmed S. Darwish fixes another two problems in the kvaser_usb driver. A patch
by Colin Ian King for the gs_usb driver adds a missing check for kzalloc
allocation failures. Two patches by Stephane Grosjean for the peak_usb driver
add missing support for ISO / non-ISO mode switching. Andri Yngvason
contributes a patch to fix the state handling in the flexcan driver. The last
patch by Andreas Werner for the flexcan driver add missing EPROBE_DEFER
handling for the transceiver regulator.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 90a5a895 555828ef
...@@ -592,13 +592,12 @@ static int flexcan_poll_state(struct net_device *dev, u32 reg_esr) ...@@ -592,13 +592,12 @@ static int flexcan_poll_state(struct net_device *dev, u32 reg_esr)
rx_state = unlikely(reg_esr & FLEXCAN_ESR_RX_WRN) ? rx_state = unlikely(reg_esr & FLEXCAN_ESR_RX_WRN) ?
CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE; CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE;
new_state = max(tx_state, rx_state); new_state = max(tx_state, rx_state);
} else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE)) { } else {
__flexcan_get_berr_counter(dev, &bec); __flexcan_get_berr_counter(dev, &bec);
new_state = CAN_STATE_ERROR_PASSIVE; new_state = flt == FLEXCAN_ESR_FLT_CONF_PASSIVE ?
CAN_STATE_ERROR_PASSIVE : CAN_STATE_BUS_OFF;
rx_state = bec.rxerr >= bec.txerr ? new_state : 0; rx_state = bec.rxerr >= bec.txerr ? new_state : 0;
tx_state = bec.rxerr <= bec.txerr ? new_state : 0; tx_state = bec.rxerr <= bec.txerr ? new_state : 0;
} else {
new_state = CAN_STATE_BUS_OFF;
} }
/* state hasn't changed */ /* state hasn't changed */
...@@ -1158,12 +1157,19 @@ static int flexcan_probe(struct platform_device *pdev) ...@@ -1158,12 +1157,19 @@ static int flexcan_probe(struct platform_device *pdev)
const struct flexcan_devtype_data *devtype_data; const struct flexcan_devtype_data *devtype_data;
struct net_device *dev; struct net_device *dev;
struct flexcan_priv *priv; struct flexcan_priv *priv;
struct regulator *reg_xceiver;
struct resource *mem; struct resource *mem;
struct clk *clk_ipg = NULL, *clk_per = NULL; struct clk *clk_ipg = NULL, *clk_per = NULL;
void __iomem *base; void __iomem *base;
int err, irq; int err, irq;
u32 clock_freq = 0; u32 clock_freq = 0;
reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver");
if (PTR_ERR(reg_xceiver) == -EPROBE_DEFER)
return -EPROBE_DEFER;
else if (IS_ERR(reg_xceiver))
reg_xceiver = NULL;
if (pdev->dev.of_node) if (pdev->dev.of_node)
of_property_read_u32(pdev->dev.of_node, of_property_read_u32(pdev->dev.of_node,
"clock-frequency", &clock_freq); "clock-frequency", &clock_freq);
...@@ -1224,9 +1230,7 @@ static int flexcan_probe(struct platform_device *pdev) ...@@ -1224,9 +1230,7 @@ static int flexcan_probe(struct platform_device *pdev)
priv->pdata = dev_get_platdata(&pdev->dev); priv->pdata = dev_get_platdata(&pdev->dev);
priv->devtype_data = devtype_data; priv->devtype_data = devtype_data;
priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); priv->reg_xceiver = reg_xceiver;
if (IS_ERR(priv->reg_xceiver))
priv->reg_xceiver = NULL;
netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT); netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
......
...@@ -901,6 +901,8 @@ static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id * ...@@ -901,6 +901,8 @@ static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id *
} }
dev = kzalloc(sizeof(*dev), GFP_KERNEL); dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
init_usb_anchor(&dev->rx_submitted); init_usb_anchor(&dev->rx_submitted);
atomic_set(&dev->active_channels, 0); atomic_set(&dev->active_channels, 0);
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <linux/can/dev.h> #include <linux/can/dev.h>
#include <linux/can/error.h> #include <linux/can/error.h>
#define MAX_TX_URBS 16
#define MAX_RX_URBS 4 #define MAX_RX_URBS 4
#define START_TIMEOUT 1000 /* msecs */ #define START_TIMEOUT 1000 /* msecs */
#define STOP_TIMEOUT 1000 /* msecs */ #define STOP_TIMEOUT 1000 /* msecs */
...@@ -443,6 +442,7 @@ struct kvaser_usb_error_summary { ...@@ -443,6 +442,7 @@ struct kvaser_usb_error_summary {
}; };
}; };
/* Context for an outstanding, not yet ACKed, transmission */
struct kvaser_usb_tx_urb_context { struct kvaser_usb_tx_urb_context {
struct kvaser_usb_net_priv *priv; struct kvaser_usb_net_priv *priv;
u32 echo_index; u32 echo_index;
...@@ -456,8 +456,13 @@ struct kvaser_usb { ...@@ -456,8 +456,13 @@ struct kvaser_usb {
struct usb_endpoint_descriptor *bulk_in, *bulk_out; struct usb_endpoint_descriptor *bulk_in, *bulk_out;
struct usb_anchor rx_submitted; struct usb_anchor rx_submitted;
/* @max_tx_urbs: Firmware-reported maximum number of oustanding,
* not yet ACKed, transmissions on this device. This value is
* also used as a sentinel for marking free tx contexts.
*/
u32 fw_version; u32 fw_version;
unsigned int nchannels; unsigned int nchannels;
unsigned int max_tx_urbs;
enum kvaser_usb_family family; enum kvaser_usb_family family;
bool rxinitdone; bool rxinitdone;
...@@ -467,19 +472,18 @@ struct kvaser_usb { ...@@ -467,19 +472,18 @@ struct kvaser_usb {
struct kvaser_usb_net_priv { struct kvaser_usb_net_priv {
struct can_priv can; struct can_priv can;
struct can_berr_counter bec;
spinlock_t tx_contexts_lock;
int active_tx_contexts;
struct kvaser_usb_tx_urb_context tx_contexts[MAX_TX_URBS];
struct usb_anchor tx_submitted;
struct completion start_comp, stop_comp;
struct kvaser_usb *dev; struct kvaser_usb *dev;
struct net_device *netdev; struct net_device *netdev;
int channel; int channel;
struct can_berr_counter bec; struct completion start_comp, stop_comp;
struct usb_anchor tx_submitted;
spinlock_t tx_contexts_lock;
int active_tx_contexts;
struct kvaser_usb_tx_urb_context tx_contexts[];
}; };
static const struct usb_device_id kvaser_usb_table[] = { static const struct usb_device_id kvaser_usb_table[] = {
...@@ -592,8 +596,8 @@ static int kvaser_usb_wait_msg(const struct kvaser_usb *dev, u8 id, ...@@ -592,8 +596,8 @@ static int kvaser_usb_wait_msg(const struct kvaser_usb *dev, u8 id,
* for further details. * for further details.
*/ */
if (tmp->len == 0) { if (tmp->len == 0) {
pos = round_up(pos, pos = round_up(pos, le16_to_cpu(dev->bulk_in->
dev->bulk_in->wMaxPacketSize); wMaxPacketSize));
continue; continue;
} }
...@@ -657,9 +661,13 @@ static int kvaser_usb_get_software_info(struct kvaser_usb *dev) ...@@ -657,9 +661,13 @@ static int kvaser_usb_get_software_info(struct kvaser_usb *dev)
switch (dev->family) { switch (dev->family) {
case KVASER_LEAF: case KVASER_LEAF:
dev->fw_version = le32_to_cpu(msg.u.leaf.softinfo.fw_version); dev->fw_version = le32_to_cpu(msg.u.leaf.softinfo.fw_version);
dev->max_tx_urbs =
le16_to_cpu(msg.u.leaf.softinfo.max_outstanding_tx);
break; break;
case KVASER_USBCAN: case KVASER_USBCAN:
dev->fw_version = le32_to_cpu(msg.u.usbcan.softinfo.fw_version); dev->fw_version = le32_to_cpu(msg.u.usbcan.softinfo.fw_version);
dev->max_tx_urbs =
le16_to_cpu(msg.u.usbcan.softinfo.max_outstanding_tx);
break; break;
} }
...@@ -715,7 +723,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, ...@@ -715,7 +723,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev,
stats = &priv->netdev->stats; stats = &priv->netdev->stats;
context = &priv->tx_contexts[tid % MAX_TX_URBS]; context = &priv->tx_contexts[tid % dev->max_tx_urbs];
/* Sometimes the state change doesn't come after a bus-off event */ /* Sometimes the state change doesn't come after a bus-off event */
if (priv->can.restart_ms && if (priv->can.restart_ms &&
...@@ -744,7 +752,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, ...@@ -744,7 +752,7 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev,
spin_lock_irqsave(&priv->tx_contexts_lock, flags); spin_lock_irqsave(&priv->tx_contexts_lock, flags);
can_get_echo_skb(priv->netdev, context->echo_index); can_get_echo_skb(priv->netdev, context->echo_index);
context->echo_index = MAX_TX_URBS; context->echo_index = dev->max_tx_urbs;
--priv->active_tx_contexts; --priv->active_tx_contexts;
netif_wake_queue(priv->netdev); netif_wake_queue(priv->netdev);
...@@ -1329,7 +1337,8 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb) ...@@ -1329,7 +1337,8 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb)
* number of events in case of a heavy rx load on the bus. * number of events in case of a heavy rx load on the bus.
*/ */
if (msg->len == 0) { if (msg->len == 0) {
pos = round_up(pos, dev->bulk_in->wMaxPacketSize); pos = round_up(pos, le16_to_cpu(dev->bulk_in->
wMaxPacketSize));
continue; continue;
} }
...@@ -1512,11 +1521,13 @@ static int kvaser_usb_open(struct net_device *netdev) ...@@ -1512,11 +1521,13 @@ static int kvaser_usb_open(struct net_device *netdev)
static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv) static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv)
{ {
int i; int i, max_tx_urbs;
max_tx_urbs = priv->dev->max_tx_urbs;
priv->active_tx_contexts = 0; priv->active_tx_contexts = 0;
for (i = 0; i < MAX_TX_URBS; i++) for (i = 0; i < max_tx_urbs; i++)
priv->tx_contexts[i].echo_index = MAX_TX_URBS; priv->tx_contexts[i].echo_index = max_tx_urbs;
} }
/* This method might sleep. Do not call it in the atomic context /* This method might sleep. Do not call it in the atomic context
...@@ -1702,14 +1713,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, ...@@ -1702,14 +1713,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
*msg_tx_can_flags |= MSG_FLAG_REMOTE_FRAME; *msg_tx_can_flags |= MSG_FLAG_REMOTE_FRAME;
spin_lock_irqsave(&priv->tx_contexts_lock, flags); spin_lock_irqsave(&priv->tx_contexts_lock, flags);
for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++) { for (i = 0; i < dev->max_tx_urbs; i++) {
if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) { if (priv->tx_contexts[i].echo_index == dev->max_tx_urbs) {
context = &priv->tx_contexts[i]; context = &priv->tx_contexts[i];
context->echo_index = i; context->echo_index = i;
can_put_echo_skb(skb, netdev, context->echo_index); can_put_echo_skb(skb, netdev, context->echo_index);
++priv->active_tx_contexts; ++priv->active_tx_contexts;
if (priv->active_tx_contexts >= MAX_TX_URBS) if (priv->active_tx_contexts >= dev->max_tx_urbs)
netif_stop_queue(netdev); netif_stop_queue(netdev);
break; break;
...@@ -1743,7 +1754,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, ...@@ -1743,7 +1754,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
spin_lock_irqsave(&priv->tx_contexts_lock, flags); spin_lock_irqsave(&priv->tx_contexts_lock, flags);
can_free_echo_skb(netdev, context->echo_index); can_free_echo_skb(netdev, context->echo_index);
context->echo_index = MAX_TX_URBS; context->echo_index = dev->max_tx_urbs;
--priv->active_tx_contexts; --priv->active_tx_contexts;
netif_wake_queue(netdev); netif_wake_queue(netdev);
...@@ -1881,7 +1892,9 @@ static int kvaser_usb_init_one(struct usb_interface *intf, ...@@ -1881,7 +1892,9 @@ static int kvaser_usb_init_one(struct usb_interface *intf,
if (err) if (err)
return err; return err;
netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); netdev = alloc_candev(sizeof(*priv) +
dev->max_tx_urbs * sizeof(*priv->tx_contexts),
dev->max_tx_urbs);
if (!netdev) { if (!netdev) {
dev_err(&intf->dev, "Cannot alloc candev\n"); dev_err(&intf->dev, "Cannot alloc candev\n");
return -ENOMEM; return -ENOMEM;
...@@ -2009,6 +2022,13 @@ static int kvaser_usb_probe(struct usb_interface *intf, ...@@ -2009,6 +2022,13 @@ static int kvaser_usb_probe(struct usb_interface *intf,
return err; return err;
} }
dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n",
((dev->fw_version >> 24) & 0xff),
((dev->fw_version >> 16) & 0xff),
(dev->fw_version & 0xffff));
dev_dbg(&intf->dev, "Max oustanding tx = %d URBs\n", dev->max_tx_urbs);
err = kvaser_usb_get_card_info(dev); err = kvaser_usb_get_card_info(dev);
if (err) { if (err) {
dev_err(&intf->dev, dev_err(&intf->dev,
...@@ -2016,11 +2036,6 @@ static int kvaser_usb_probe(struct usb_interface *intf, ...@@ -2016,11 +2036,6 @@ static int kvaser_usb_probe(struct usb_interface *intf,
return err; return err;
} }
dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n",
((dev->fw_version >> 24) & 0xff),
((dev->fw_version >> 16) & 0xff),
(dev->fw_version & 0xffff));
for (i = 0; i < dev->nchannels; i++) { for (i = 0; i < dev->nchannels; i++) {
err = kvaser_usb_init_one(intf, id, i); err = kvaser_usb_init_one(intf, id, i);
if (err) { if (err) {
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
#define PUCAN_CMD_FILTER_STD 0x008 #define PUCAN_CMD_FILTER_STD 0x008
#define PUCAN_CMD_TX_ABORT 0x009 #define PUCAN_CMD_TX_ABORT 0x009
#define PUCAN_CMD_WR_ERR_CNT 0x00a #define PUCAN_CMD_WR_ERR_CNT 0x00a
#define PUCAN_CMD_RX_FRAME_ENABLE 0x00b #define PUCAN_CMD_SET_EN_OPTION 0x00b
#define PUCAN_CMD_RX_FRAME_DISABLE 0x00c #define PUCAN_CMD_CLR_DIS_OPTION 0x00c
#define PUCAN_CMD_END_OF_COLLECTION 0x3ff #define PUCAN_CMD_END_OF_COLLECTION 0x3ff
/* uCAN received messages list */ /* uCAN received messages list */
...@@ -101,14 +101,15 @@ struct __packed pucan_wr_err_cnt { ...@@ -101,14 +101,15 @@ struct __packed pucan_wr_err_cnt {
u16 unused; u16 unused;
}; };
/* uCAN RX_FRAME_ENABLE command fields */ /* uCAN SET_EN/CLR_DIS _OPTION command fields */
#define PUCAN_FLTEXT_ERROR 0x0001 #define PUCAN_OPTION_ERROR 0x0001
#define PUCAN_FLTEXT_BUSLOAD 0x0002 #define PUCAN_OPTION_BUSLOAD 0x0002
#define PUCAN_OPTION_CANDFDISO 0x0004
struct __packed pucan_filter_ext { struct __packed pucan_options {
__le16 opcode_channel; __le16 opcode_channel;
__le16 ext_mask; __le16 options;
u32 unused; u32 unused;
}; };
......
...@@ -110,13 +110,13 @@ struct __packed pcan_ufd_led { ...@@ -110,13 +110,13 @@ struct __packed pcan_ufd_led {
u8 unused[5]; u8 unused[5];
}; };
/* Extended usage of uCAN commands CMD_RX_FRAME_xxxABLE for PCAN-USB Pro FD */ /* Extended usage of uCAN commands CMD_xxx_xx_OPTION for PCAN-USB Pro FD */
#define PCAN_UFD_FLTEXT_CALIBRATION 0x8000 #define PCAN_UFD_FLTEXT_CALIBRATION 0x8000
struct __packed pcan_ufd_filter_ext { struct __packed pcan_ufd_options {
__le16 opcode_channel; __le16 opcode_channel;
__le16 ext_mask; __le16 ucan_mask;
u16 unused; u16 unused;
__le16 usb_mask; __le16 usb_mask;
}; };
...@@ -251,6 +251,27 @@ static int pcan_usb_fd_build_restart_cmd(struct peak_usb_device *dev, u8 *buf) ...@@ -251,6 +251,27 @@ static int pcan_usb_fd_build_restart_cmd(struct peak_usb_device *dev, u8 *buf)
/* moves the pointer forward */ /* moves the pointer forward */
pc += sizeof(struct pucan_wr_err_cnt); pc += sizeof(struct pucan_wr_err_cnt);
/* add command to switch from ISO to non-ISO mode, if fw allows it */
if (dev->can.ctrlmode_supported & CAN_CTRLMODE_FD_NON_ISO) {
struct pucan_options *puo = (struct pucan_options *)pc;
puo->opcode_channel =
(dev->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) ?
pucan_cmd_opcode_channel(dev,
PUCAN_CMD_CLR_DIS_OPTION) :
pucan_cmd_opcode_channel(dev, PUCAN_CMD_SET_EN_OPTION);
puo->options = cpu_to_le16(PUCAN_OPTION_CANDFDISO);
/* to be sure that no other extended bits will be taken into
* account
*/
puo->unused = 0;
/* moves the pointer forward */
pc += sizeof(struct pucan_options);
}
/* next, go back to operational mode */ /* next, go back to operational mode */
cmd = (struct pucan_command *)pc; cmd = (struct pucan_command *)pc;
cmd->opcode_channel = pucan_cmd_opcode_channel(dev, cmd->opcode_channel = pucan_cmd_opcode_channel(dev,
...@@ -321,21 +342,21 @@ static int pcan_usb_fd_set_filter_std(struct peak_usb_device *dev, int idx, ...@@ -321,21 +342,21 @@ static int pcan_usb_fd_set_filter_std(struct peak_usb_device *dev, int idx,
return pcan_usb_fd_send_cmd(dev, cmd); return pcan_usb_fd_send_cmd(dev, cmd);
} }
/* set/unset notifications filter: /* set/unset options
* *
* onoff sets(1)/unset(0) notifications * onoff set(1)/unset(0) options
* mask each bit defines a kind of notification to set/unset * mask each bit defines a kind of options to set/unset
*/ */
static int pcan_usb_fd_set_filter_ext(struct peak_usb_device *dev, static int pcan_usb_fd_set_options(struct peak_usb_device *dev,
bool onoff, u16 ext_mask, u16 usb_mask) bool onoff, u16 ucan_mask, u16 usb_mask)
{ {
struct pcan_ufd_filter_ext *cmd = pcan_usb_fd_cmd_buffer(dev); struct pcan_ufd_options *cmd = pcan_usb_fd_cmd_buffer(dev);
cmd->opcode_channel = pucan_cmd_opcode_channel(dev, cmd->opcode_channel = pucan_cmd_opcode_channel(dev,
(onoff) ? PUCAN_CMD_RX_FRAME_ENABLE : (onoff) ? PUCAN_CMD_SET_EN_OPTION :
PUCAN_CMD_RX_FRAME_DISABLE); PUCAN_CMD_CLR_DIS_OPTION);
cmd->ext_mask = cpu_to_le16(ext_mask); cmd->ucan_mask = cpu_to_le16(ucan_mask);
cmd->usb_mask = cpu_to_le16(usb_mask); cmd->usb_mask = cpu_to_le16(usb_mask);
/* send the command */ /* send the command */
...@@ -770,8 +791,8 @@ static int pcan_usb_fd_start(struct peak_usb_device *dev) ...@@ -770,8 +791,8 @@ static int pcan_usb_fd_start(struct peak_usb_device *dev)
&pcan_usb_pro_fd); &pcan_usb_pro_fd);
/* enable USB calibration messages */ /* enable USB calibration messages */
err = pcan_usb_fd_set_filter_ext(dev, 1, err = pcan_usb_fd_set_options(dev, 1,
PUCAN_FLTEXT_ERROR, PUCAN_OPTION_ERROR,
PCAN_UFD_FLTEXT_CALIBRATION); PCAN_UFD_FLTEXT_CALIBRATION);
} }
...@@ -806,8 +827,8 @@ static int pcan_usb_fd_stop(struct peak_usb_device *dev) ...@@ -806,8 +827,8 @@ static int pcan_usb_fd_stop(struct peak_usb_device *dev)
/* turn off special msgs for that interface if no other dev opened */ /* turn off special msgs for that interface if no other dev opened */
if (pdev->usb_if->dev_opened_count == 1) if (pdev->usb_if->dev_opened_count == 1)
pcan_usb_fd_set_filter_ext(dev, 0, pcan_usb_fd_set_options(dev, 0,
PUCAN_FLTEXT_ERROR, PUCAN_OPTION_ERROR,
PCAN_UFD_FLTEXT_CALIBRATION); PCAN_UFD_FLTEXT_CALIBRATION);
pdev->usb_if->dev_opened_count--; pdev->usb_if->dev_opened_count--;
...@@ -860,8 +881,14 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev) ...@@ -860,8 +881,14 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
pdev->usb_if->fw_info.fw_version[2], pdev->usb_if->fw_info.fw_version[2],
dev->adapter->ctrl_count); dev->adapter->ctrl_count);
/* the currently supported hw is non-ISO */ /* check for ability to switch between ISO/non-ISO modes */
dev->can.ctrlmode = CAN_CTRLMODE_FD_NON_ISO; if (pdev->usb_if->fw_info.fw_version[0] >= 2) {
/* firmware >= 2.x supports ISO/non-ISO switching */
dev->can.ctrlmode_supported |= CAN_CTRLMODE_FD_NON_ISO;
} else {
/* firmware < 2.x only supports fixed(!) non-ISO */
dev->can.ctrlmode |= CAN_CTRLMODE_FD_NON_ISO;
}
/* tell the hardware the can driver is running */ /* tell the hardware the can driver is running */
err = pcan_usb_fd_drv_loaded(dev, 1); err = pcan_usb_fd_drv_loaded(dev, 1);
...@@ -937,8 +964,8 @@ static void pcan_usb_fd_exit(struct peak_usb_device *dev) ...@@ -937,8 +964,8 @@ static void pcan_usb_fd_exit(struct peak_usb_device *dev)
if (dev->ctrl_idx == 0) { if (dev->ctrl_idx == 0) {
/* turn off calibration message if any device were opened */ /* turn off calibration message if any device were opened */
if (pdev->usb_if->dev_opened_count > 0) if (pdev->usb_if->dev_opened_count > 0)
pcan_usb_fd_set_filter_ext(dev, 0, pcan_usb_fd_set_options(dev, 0,
PUCAN_FLTEXT_ERROR, PUCAN_OPTION_ERROR,
PCAN_UFD_FLTEXT_CALIBRATION); PCAN_UFD_FLTEXT_CALIBRATION);
/* tell USB adapter that the driver is being unloaded */ /* tell USB adapter that the driver is being unloaded */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment