linux-can-next-for-4.1-20150401

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJVG8DxAAoJECte4hHFiupUkFkP+QEDROmDdcYQPRqNgVXvbNxo
 +uFBI+Y9ttnm+WCR9tu2v2NDuFsbPaD5ckK/idDypSS9tcQWcZqS8odPq9lFYTqu
 OvfH3lMT82myZf7MT6evn3l6Zwm3UM0fXRxvflpUyFsM8h8quOkhx+ckHK9rjhU7
 vEDRDbg1r2xAvQcAm0ACwTCKIxqtf+xnRKwarR+q/1hiHUOmd455cR6uUc+ydAbt
 94J4ltnUmpZOgBiNmhZBrD29cheKmwqVEsiv5RcFaRbilJmWM8HFOjsocMAbaz8O
 hoV8TQbQY1m2fc+sqBlJUr2YYBGnU1jHzhVP9fgAAvhjZGmRXT5zcEorN4m8sGn2
 6/slVnkeUyy3wgrmqphk81qd86nTd51gMaI5ixs19eG4epjcQ04ORAZs4zkxVQDo
 wUNDS1CLdoGztJUjf4+fEjfU9FXXIrBbyXbpXGiNwogXpFCzSj+NNtEyuzaRlSok
 72mn7ATxSKsrK0t0WJLv/m0mJfOPikQ1YN60g4SxLLlpK+dFarzojQLVyLrJGWxR
 cnseiB0IV2PvuV1RRrBntbXWK+rO4Y2PCMt46Hx63NrxwOzffa0s6MjXg3xLMc3p
 kl0RmoA/lDsIem0iBKF5PysOe7UsjklUO1jgqE53359FQDJDtg5N/BtnpB4wFQh5
 NlfJ6q+TG58jYhiiONFN
 =+qN4
 -----END PGP SIGNATURE-----

Merge tag 'linux-can-next-for-4.1-20150401' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2015-04-01

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

There are two patches for the ems_usb driver by Gerhard Uttenthaler and
me, which fix sparse endianess warnings. Oliver Hartkopp adds two
patches to improve and extend the CAN-ID filter handling on RAW CAN
sockets. The last patch is by me, it silences an uninitialized variable
warning in the peak_usb driver.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2015-04-01 13:58:06 -04:00
commit b9600d2d09
5 changed files with 74 additions and 10 deletions

View File

@ -22,7 +22,8 @@ This file contains
4.1.3 RAW socket option CAN_RAW_LOOPBACK
4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS
4.1.5 RAW socket option CAN_RAW_FD_FRAMES
4.1.6 RAW socket returned message flags
4.1.6 RAW socket option CAN_RAW_JOIN_FILTERS
4.1.7 RAW socket returned message flags
4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
4.2.1 Broadcast Manager operations
4.2.2 Broadcast Manager message flags
@ -601,7 +602,22 @@ solution for a couple of reasons:
CAN FD frames by checking if the device maximum transfer unit is CANFD_MTU.
The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall.
4.1.6 RAW socket returned message flags
4.1.6 RAW socket option CAN_RAW_JOIN_FILTERS
The CAN_RAW socket can set multiple CAN identifier specific filters that
lead to multiple filters in the af_can.c filter processing. These filters
are indenpendent from each other which leads to logical OR'ed filters when
applied (see 4.1.1).
This socket option joines the given CAN filters in the way that only CAN
frames are passed to user space that matched *all* given CAN filters. The
semantic for the applied filters is therefore changed to a logical AND.
This is useful especially when the filterset is a combination of filters
where the CAN_INV_FILTER flag is set in order to notch single CAN IDs or
CAN ID ranges from the incoming traffic.
4.1.7 RAW socket returned message flags
When using recvmsg() call, the msg->msg_flags may contain following flags:

View File

@ -123,7 +123,7 @@ MODULE_LICENSE("GPL v2");
* CPC_MSG_TYPE_EXT_CAN_FRAME or CPC_MSG_TYPE_EXT_RTR_FRAME.
*/
struct cpc_can_msg {
u32 id;
__le32 id;
u8 length;
u8 msg[8];
};
@ -200,8 +200,8 @@ struct __packed ems_cpc_msg {
u8 type; /* type of message */
u8 length; /* length of data within union 'msg' */
u8 msgid; /* confirmation handle */
u32 ts_sec; /* timestamp in seconds */
u32 ts_nsec; /* timestamp in nano seconds */
__le32 ts_sec; /* timestamp in seconds */
__le32 ts_nsec; /* timestamp in nano seconds */
union {
u8 generic[64];
@ -765,7 +765,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE];
msg->msg.can_msg.id = cf->can_id & CAN_ERR_MASK;
msg->msg.can_msg.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK);
msg->msg.can_msg.length = cf->can_dlc;
if (cf->can_id & CAN_RTR_FLAG) {
@ -783,9 +783,6 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc;
}
/* Respect byte order */
msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id);
for (i = 0; i < MAX_TX_URBS; i++) {
if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) {
context = &dev->tx_contexts[i];

View File

@ -182,7 +182,7 @@ static inline void *pcan_usb_fd_cmd_buffer(struct peak_usb_device *dev)
static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail)
{
void *cmd_head = pcan_usb_fd_cmd_buffer(dev);
int err;
int err = 0;
u8 *packet_ptr;
int i, n = 1, packet_len;
ptrdiff_t cmd_len;

View File

@ -57,6 +57,7 @@ enum {
CAN_RAW_LOOPBACK, /* local loopback (default:on) */
CAN_RAW_RECV_OWN_MSGS, /* receive my own msgs (default:off) */
CAN_RAW_FD_FRAMES, /* allow CAN FD frames (default:off) */
CAN_RAW_JOIN_FILTERS, /* all filters must match to trigger */
};
#endif /* !_UAPI_CAN_RAW_H */

View File

@ -74,6 +74,12 @@ MODULE_ALIAS("can-proto-1");
* storing the single filter in dfilter, to avoid using dynamic memory.
*/
struct uniqframe {
ktime_t tstamp;
const struct sk_buff *skb;
unsigned int join_rx_count;
};
struct raw_sock {
struct sock sk;
int bound;
@ -82,10 +88,12 @@ struct raw_sock {
int loopback;
int recv_own_msgs;
int fd_frames;
int join_filters;
int count; /* number of active filters */
struct can_filter dfilter; /* default/single filter */
struct can_filter *filter; /* pointer to filter(s) */
can_err_mask_t err_mask;
struct uniqframe __percpu *uniq;
};
/*
@ -123,6 +131,26 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
if (!ro->fd_frames && oskb->len != CAN_MTU)
return;
/* eliminate multiple filter matches for the same skb */
if (this_cpu_ptr(ro->uniq)->skb == oskb &&
ktime_equal(this_cpu_ptr(ro->uniq)->tstamp, oskb->tstamp)) {
if (ro->join_filters) {
this_cpu_inc(ro->uniq->join_rx_count);
/* drop frame until all enabled filters matched */
if (this_cpu_ptr(ro->uniq)->join_rx_count < ro->count)
return;
} else {
return;
}
} else {
this_cpu_ptr(ro->uniq)->skb = oskb;
this_cpu_ptr(ro->uniq)->tstamp = oskb->tstamp;
this_cpu_ptr(ro->uniq)->join_rx_count = 1;
/* drop first frame to check all enabled filters? */
if (ro->join_filters && ro->count > 1)
return;
}
/* clone the given skb to be able to enqueue it into the rcv queue */
skb = skb_clone(oskb, GFP_ATOMIC);
if (!skb)
@ -296,6 +324,12 @@ static int raw_init(struct sock *sk)
ro->loopback = 1;
ro->recv_own_msgs = 0;
ro->fd_frames = 0;
ro->join_filters = 0;
/* alloc_percpu provides zero'ed memory */
ro->uniq = alloc_percpu(struct uniqframe);
if (unlikely(!ro->uniq))
return -ENOMEM;
/* set notifier */
ro->notifier.notifier_call = raw_notifier;
@ -339,6 +373,7 @@ static int raw_release(struct socket *sock)
ro->ifindex = 0;
ro->bound = 0;
ro->count = 0;
free_percpu(ro->uniq);
sock_orphan(sk);
sock->sk = NULL;
@ -583,6 +618,15 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
break;
case CAN_RAW_JOIN_FILTERS:
if (optlen != sizeof(ro->join_filters))
return -EINVAL;
if (copy_from_user(&ro->join_filters, optval, optlen))
return -EFAULT;
break;
default:
return -ENOPROTOOPT;
}
@ -647,6 +691,12 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,
val = &ro->fd_frames;
break;
case CAN_RAW_JOIN_FILTERS:
if (len > sizeof(int))
len = sizeof(int);
val = &ro->join_filters;
break;
default:
return -ENOPROTOOPT;
}