Loading MAINTAINERS +2 −1 Original line number Original line Diff line number Diff line Loading @@ -4304,6 +4304,7 @@ F: drivers/video/aty/aty128fb.c RALINK RT2X00 WIRELESS LAN DRIVER RALINK RT2X00 WIRELESS LAN DRIVER P: rt2x00 project P: rt2x00 project M: Ivo van Doorn <IvDoorn@gmail.com> M: Ivo van Doorn <IvDoorn@gmail.com> M: Gertjan van Wingerde <gwingerde@gmail.com> L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org L: users@rt2x00.serialmonkey.com (moderated for non-subscribers) L: users@rt2x00.serialmonkey.com (moderated for non-subscribers) W: http://rt2x00.serialmonkey.com/ W: http://rt2x00.serialmonkey.com/ Loading Loading @@ -4391,7 +4392,7 @@ RFKILL M: Johannes Berg <johannes@sipsolutions.net> M: Johannes Berg <johannes@sipsolutions.net> L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org S: Maintained S: Maintained F Documentation/rfkill.txt F: Documentation/rfkill.txt F: net/rfkill/ F: net/rfkill/ RISCOM8 DRIVER RISCOM8 DRIVER Loading drivers/isdn/hardware/mISDN/hfcmulti.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -5481,7 +5481,7 @@ HFCmulti_init(void) if (err) { if (err) { printk(KERN_ERR "error registering embedded driver: " printk(KERN_ERR "error registering embedded driver: " "%x\n", err); "%x\n", err); return -err; return err; } } HFC_cnt++; HFC_cnt++; printk(KERN_INFO "%d devices registered\n", HFC_cnt); printk(KERN_INFO "%d devices registered\n", HFC_cnt); Loading drivers/isdn/i4l/isdn_ppp.c +163 −189 Original line number Original line Diff line number Diff line Loading @@ -1535,10 +1535,8 @@ static int isdn_ppp_mp_bundle_array_init(void) int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL ) if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL ) return -ENOMEM; return -ENOMEM; for (i = 0; i < ISDN_MAX_CHANNELS; i++) { for( i = 0; i < ISDN_MAX_CHANNELS; i++ ) spin_lock_init(&isdn_ppp_bundle_arr[i].lock); spin_lock_init(&isdn_ppp_bundle_arr[i].lock); skb_queue_head_init(&isdn_ppp_bundle_arr[i].frags); } return 0; return 0; } } Loading Loading @@ -1571,7 +1569,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) return -ENOMEM; return -ENOMEM; lp->next = lp->last = lp; /* nobody else in a queue */ lp->next = lp->last = lp; /* nobody else in a queue */ skb_queue_head_init(&lp->netdev->pb->frags); lp->netdev->pb->frags = NULL; lp->netdev->pb->frames = 0; lp->netdev->pb->frames = 0; lp->netdev->pb->seq = UINT_MAX; lp->netdev->pb->seq = UINT_MAX; } } Loading @@ -1583,24 +1581,23 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) static u32 isdn_ppp_mp_get_seq( int short_seq, static u32 isdn_ppp_mp_get_seq( int short_seq, struct sk_buff * skb, u32 last_seq ); struct sk_buff * skb, u32 last_seq ); static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, struct sk_buff *to); struct sk_buff * from, struct sk_buff * to ); static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *from, struct sk_buff *to, struct sk_buff * from, struct sk_buff * to ); u32 lastseq); static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb ); static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb ); static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb) struct sk_buff *skb) { { struct sk_buff *newfrag, *frag, *start, *nextf; u32 newseq, minseq, thisseq; isdn_mppp_stats *stats; struct ippp_struct *is; struct ippp_struct *is; unsigned long flags; isdn_net_local * lpq; isdn_net_local * lpq; ippp_bundle * mp; ippp_bundle * mp; isdn_mppp_stats * stats; struct sk_buff * newfrag, * frag, * start, *nextf; u32 newseq, minseq, thisseq; unsigned long flags; int slot; int slot; spin_lock_irqsave(&net_dev->pb->lock, flags); spin_lock_irqsave(&net_dev->pb->lock, flags); Loading @@ -1625,6 +1622,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, skb, is->last_link_seqno); skb, is->last_link_seqno); /* if this packet seq # is less than last already processed one, /* if this packet seq # is less than last already processed one, * toss it right away, but check for sequence start case first * toss it right away, but check for sequence start case first */ */ Loading Loading @@ -1659,31 +1657,22 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * packets */ * packets */ newfrag = skb; newfrag = skb; /* Insert new fragment into the proper sequence slot. */ /* if this new fragment is before the first one, then enqueue it now. */ skb_queue_walk(&mp->frags, frag) { if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) { if (MP_SEQ(frag) == newseq) { newfrag->next = frag; isdn_ppp_mp_free_skb(mp, newfrag); mp->frags = frag = newfrag; newfrag = NULL; newfrag = NULL; break; } } if (MP_LT(newseq, MP_SEQ(frag))) { __skb_queue_before(&mp->frags, frag, newfrag); newfrag = NULL; break; } } if (newfrag) __skb_queue_tail(&mp->frags, newfrag); frag = skb_peek(&mp->frags); start = MP_FLAGS(frag) & MP_BEGIN_FRAG && start = ((MP_FLAGS(frag) & MP_BEGIN_FRAG) && MP_SEQ(frag) == mp->seq ? frag : NULL; (MP_SEQ(frag) == mp->seq)) ? frag : NULL; if (!start) goto check_overflow; /* main fragment traversing loop /* * main fragment traversing loop * * * try to accomplish several tasks: * try to accomplish several tasks: * - insert new fragment into the proper sequence slot (once that's done * newfrag will be set to NULL) * - reassemble any complete fragment sequence (non-null 'start' * - reassemble any complete fragment sequence (non-null 'start' * indicates there is a continguous sequence present) * indicates there is a continguous sequence present) * - discard any incomplete sequences that are below minseq -- due * - discard any incomplete sequences that are below minseq -- due Loading @@ -1692,45 +1681,70 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * come to complete such sequence and it should be discarded * come to complete such sequence and it should be discarded * * * loop completes when we accomplished the following tasks: * loop completes when we accomplished the following tasks: * - new fragment is inserted in the proper sequence ('newfrag' is * set to NULL) * - we hit a gap in the sequence, so no reassembly/processing is * - we hit a gap in the sequence, so no reassembly/processing is * possible ('start' would be set to NULL) * possible ('start' would be set to NULL) * * * algorithm for this code is derived from code in the book * algorithm for this code is derived from code in the book * 'PPP Design And Debugging' by James Carlson (Addison-Wesley) * 'PPP Design And Debugging' by James Carlson (Addison-Wesley) */ */ skb_queue_walk_safe(&mp->frags, frag, nextf) { while (start != NULL || newfrag != NULL) { thisseq = MP_SEQ(frag); thisseq = MP_SEQ(frag); nextf = frag->next; /* drop any duplicate fragments */ if (newfrag != NULL && thisseq == newseq) { isdn_ppp_mp_free_skb(mp, newfrag); newfrag = NULL; } /* insert new fragment before next element if possible. */ if (newfrag != NULL && (nextf == NULL || MP_LT(newseq, MP_SEQ(nextf)))) { newfrag->next = nextf; frag->next = nextf = newfrag; newfrag = NULL; } if (start != NULL) { /* check for misplaced start */ /* check for misplaced start */ if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { printk(KERN_WARNING"isdn_mppp(seq %d): new " printk(KERN_WARNING"isdn_mppp(seq %d): new " "BEGIN flag with no prior END", thisseq); "BEGIN flag with no prior END", thisseq); stats->seqerrs++; stats->seqerrs++; stats->frame_drops++; stats->frame_drops++; isdn_ppp_mp_discard(mp, start, frag); start = isdn_ppp_mp_discard(mp, start,frag); start = frag; nextf = frag->next; } } else if (MP_LE(thisseq, minseq)) { } else if (MP_LE(thisseq, minseq)) { if (MP_FLAGS(frag) & MP_BEGIN_FRAG) if (MP_FLAGS(frag) & MP_BEGIN_FRAG) start = frag; start = frag; else { else { if (MP_FLAGS(frag) & MP_END_FRAG) if (MP_FLAGS(frag) & MP_END_FRAG) stats->frame_drops++; stats->frame_drops++; __skb_unlink(skb, &mp->frags); if( mp->frags == frag ) mp->frags = nextf; isdn_ppp_mp_free_skb(mp, frag); isdn_ppp_mp_free_skb(mp, frag); frag = nextf; continue; continue; } } } } /* if we have end fragment, then we have full reassembly /* if start is non-null and we have end fragment, then * sequence -- reassemble and process packet now * we have full reassembly sequence -- reassemble * and process packet now */ */ if (MP_FLAGS(frag) & MP_END_FRAG) { if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) { minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; /* Reassemble the packet then dispatch it */ /* Reassemble the packet then dispatch it */ isdn_ppp_mp_reassembly(net_dev, lp, start, frag, thisseq); isdn_ppp_mp_reassembly(net_dev, lp, start, nextf); start = NULL; start = NULL; frag = NULL; frag = NULL; mp->frags = nextf; } } /* check if need to update start pointer: if we just /* check if need to update start pointer: if we just Loading @@ -1742,24 +1756,25 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * below low watermark and set start to the next frag or * below low watermark and set start to the next frag or * clear start ptr. * clear start ptr. */ */ if (nextf != (struct sk_buff *)&mp->frags && if (nextf != NULL && ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) { ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) { /* if we just reassembled and the next one is here, /* if we just reassembled and the next one is here, * then start another reassembly. * then start another reassembly. */ */ if (frag == NULL) { if (frag == NULL) { if (MP_FLAGS(nextf) & MP_BEGIN_FRAG) if (MP_FLAGS(nextf) & MP_BEGIN_FRAG) start = nextf; start = nextf; else { else { printk(KERN_WARNING"isdn_mppp(seq %d):" printk(KERN_WARNING"isdn_mppp(seq %d):" " END flag with no following " " END flag with no following " "BEGIN", thisseq); "BEGIN", thisseq); stats->seqerrs++; stats->seqerrs++; } } } } } else { } else { if (nextf != (struct sk_buff *)&mp->frags && if ( nextf != NULL && frag != NULL && frag != NULL && MP_LT(thisseq, minseq)) { MP_LT(thisseq, minseq)) { /* we've got a break in the sequence /* we've got a break in the sequence * and we not at the end yet * and we not at the end yet Loading @@ -1769,26 +1784,26 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * discard all the frames below low watermark * discard all the frames below low watermark * and start over */ * and start over */ stats->frame_drops++; stats->frame_drops++; isdn_ppp_mp_discard(mp, start, nextf); mp->frags = isdn_ppp_mp_discard(mp,start,nextf); } } /* break in the sequence, no reassembly */ /* break in the sequence, no reassembly */ start = NULL; start = NULL; } } if (!start) break; } check_overflow: frag = nextf; } /* while -- main loop */ if (mp->frags == NULL) mp->frags = frag; /* rather straighforward way to deal with (not very) possible /* rather straighforward way to deal with (not very) possible * queue overflow * queue overflow */ */ if (mp->frames > MP_MAX_QUEUE_LEN) { if (mp->frames > MP_MAX_QUEUE_LEN) { stats->overflows++; stats->overflows++; skb_queue_walk_safe(&mp->frags, frag, nextf) { while (mp->frames > MP_MAX_QUEUE_LEN) { if (mp->frames <= MP_MAX_QUEUE_LEN) frag = mp->frags->next; break; isdn_ppp_mp_free_skb(mp, mp->frags); __skb_unlink(frag, &mp->frags); mp->frags = frag; isdn_ppp_mp_free_skb(mp, frag); } } } } spin_unlock_irqrestore(&mp->lock, flags); spin_unlock_irqrestore(&mp->lock, flags); Loading @@ -1796,12 +1811,14 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, static void isdn_ppp_mp_cleanup( isdn_net_local * lp ) static void isdn_ppp_mp_cleanup( isdn_net_local * lp ) { { struct sk_buff *skb, *tmp; struct sk_buff * frag = lp->netdev->pb->frags; struct sk_buff * nextfrag; skb_queue_walk_safe(&lp->netdev->pb->frags, skb, tmp) { while( frag ) { __skb_unlink(skb, &lp->netdev->pb->frags); nextfrag = frag->next; isdn_ppp_mp_free_skb(lp->netdev->pb, skb); isdn_ppp_mp_free_skb(lp->netdev->pb, frag); frag = nextfrag; } } lp->netdev->pb->frags = NULL; } } static u32 isdn_ppp_mp_get_seq( int short_seq, static u32 isdn_ppp_mp_get_seq( int short_seq, Loading Loading @@ -1838,110 +1855,67 @@ static u32 isdn_ppp_mp_get_seq( int short_seq, return seq; return seq; } } static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, struct sk_buff *to) { if (from) { struct sk_buff *skb, *tmp; int freeing = 0; skb_queue_walk_safe(&mp->frags, skb, tmp) { if (skb == to) break; if (skb == from) freeing = 1; if (!freeing) continue; __skb_unlink(skb, &mp->frags); isdn_ppp_mp_free_skb(mp, skb); } } } static unsigned int calc_tot_len(struct sk_buff_head *queue, struct sk_buff * from, struct sk_buff * to ) struct sk_buff * from, struct sk_buff * to ) { { unsigned int tot_len = 0; if( from ) struct sk_buff *skb; while (from != to) { int found_start = 0; struct sk_buff * next = from->next; isdn_ppp_mp_free_skb(mp, from); skb_queue_walk(queue, skb) { from = next; if (skb == from) found_start = 1; if (!found_start) continue; tot_len += skb->len - MP_HEADER_LEN; if (skb == to) break; } } return tot_len; return from; } } /* Reassemble packet using fragments in the reassembly queue from void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, * 'from' until 'to', inclusive. struct sk_buff * from, struct sk_buff * to ) */ static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *from, struct sk_buff *to, u32 lastseq) { { ippp_bundle * mp = net_dev->pb; ippp_bundle * mp = net_dev->pb; unsigned int tot_len; struct sk_buff *skb; int proto; int proto; struct sk_buff * skb; unsigned int tot_len; if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", __func__, lp->ppp_slot); __func__, lp->ppp_slot); return; return; } } tot_len = calc_tot_len(&mp->frags, from, to); if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) { if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) { if( ippp_table[lp->ppp_slot]->debug & 0x40 ) if( ippp_table[lp->ppp_slot]->debug & 0x40 ) printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, " printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, " "len %d\n", MP_SEQ(from), from->len ); "len %d\n", MP_SEQ(from), from->len ); skb = from; skb = from; skb_pull(skb, MP_HEADER_LEN); skb_pull(skb, MP_HEADER_LEN); __skb_unlink(skb, &mp->frags); mp->frames--; mp->frames--; } else { } else { struct sk_buff *walk, *tmp; struct sk_buff * frag; int found_start = 0; int n; for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++) tot_len += frag->len - MP_HEADER_LEN; if( ippp_table[lp->ppp_slot]->debug & 0x40 ) if( ippp_table[lp->ppp_slot]->debug & 0x40 ) printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " "to %d, len %d\n", MP_SEQ(from), lastseq, "to %d, len %d\n", MP_SEQ(from), tot_len); (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len ); if( (skb = dev_alloc_skb(tot_len)) == NULL ) { skb = dev_alloc_skb(tot_len); if (!skb) printk(KERN_ERR "isdn_mppp: cannot allocate sk buff " printk(KERN_ERR "isdn_mppp: cannot allocate sk buff " "of size %d\n", tot_len); "of size %d\n", tot_len); isdn_ppp_mp_discard(mp, from, to); return; } found_start = 0; while( from != to ) { skb_queue_walk_safe(&mp->frags, walk, tmp) { unsigned int len = from->len - MP_HEADER_LEN; if (walk == from) found_start = 1; if (!found_start) continue; if (skb) { skb_copy_from_linear_data_offset(from, MP_HEADER_LEN, unsigned int len = walk->len - MP_HEADER_LEN; skb_copy_from_linear_data_offset(walk, MP_HEADER_LEN, skb_put(skb,len), skb_put(skb,len), len); len); } frag = from->next; __skb_unlink(walk, &mp->frags); isdn_ppp_mp_free_skb(mp, from); isdn_ppp_mp_free_skb(mp, walk); from = frag; if (walk == to) break; } } } } if (!skb) return; proto = isdn_ppp_strip_proto(skb); proto = isdn_ppp_strip_proto(skb); isdn_ppp_push_higher(net_dev, lp, skb, proto); isdn_ppp_push_higher(net_dev, lp, skb, proto); } } Loading drivers/net/can/Kconfig +5 −55 Original line number Original line Diff line number Diff line Loading @@ -35,63 +35,9 @@ config CAN_CALC_BITTIMING arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". If unsure, say Y. If unsure, say Y. config CAN_SJA1000 depends on CAN_DEV && HAS_IOMEM tristate "Philips SJA1000" ---help--- Driver for the SJA1000 CAN controllers from Philips or NXP config CAN_SJA1000_ISA depends on CAN_SJA1000 && ISA tristate "ISA Bus based legacy SJA1000 driver" ---help--- This driver adds legacy support for SJA1000 chips connected to the ISA bus using I/O port, memory mapped or indirect access. config CAN_SJA1000_PLATFORM depends on CAN_SJA1000 tristate "Generic Platform Bus based SJA1000 driver" ---help--- This driver adds support for the SJA1000 chips connected to the "platform bus" (Linux abstraction for directly to the processor attached devices). Which can be found on various boards from Phytec (http://www.phytec.de) like the PCM027, PCM038. config CAN_SJA1000_OF_PLATFORM depends on CAN_SJA1000 && PPC_OF tristate "Generic OF Platform Bus based SJA1000 driver" ---help--- This driver adds support for the SJA1000 chips connected to the OpenFirmware "platform bus" found on embedded systems with OpenFirmware bindings, e.g. if you have a PowerPC based system you may want to enable this option. config CAN_EMS_PCI tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card" depends on PCI && CAN_SJA1000 ---help--- This driver is for the one, two or four channel CPC-PCI, CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de). config CAN_EMS_USB tristate "EMS CPC-USB/ARM7 CAN/USB interface" depends on USB && CAN_DEV ---help--- This driver is for the one channel CPC-USB/ARM7 CAN/USB interface from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de). config CAN_KVASER_PCI tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards" depends on PCI && CAN_SJA1000 ---help--- This driver is for the the PCIcanx and PCIcan cards (1, 2 or 4 channel) from Kvaser (http://www.kvaser.com). config CAN_AT91 config CAN_AT91 tristate "Atmel AT91 onchip CAN controller" tristate "Atmel AT91 onchip CAN controller" depends on CAN && CAN_DEV && ARCH_AT91SAM9263 depends on CAN_DEV && ARCH_AT91SAM9263 ---help--- ---help--- This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. Loading Loading @@ -127,6 +73,10 @@ config CAN_MPC52XX This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module will be called mpc5xxx_can. will be called mpc5xxx_can. source "drivers/net/can/sja1000/Kconfig" source "drivers/net/can/usb/Kconfig" config CAN_DEBUG_DEVICES config CAN_DEBUG_DEVICES bool "CAN devices debugging messages" bool "CAN devices debugging messages" depends on CAN depends on CAN Loading drivers/net/can/dev.c +6 −0 Original line number Original line Diff line number Diff line Loading @@ -677,6 +677,11 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) return -EMSGSIZE; return -EMSGSIZE; } } static size_t can_get_xstats_size(const struct net_device *dev) { return sizeof(struct can_device_stats); } static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) { { struct can_priv *priv = netdev_priv(dev); struct can_priv *priv = netdev_priv(dev); Loading Loading @@ -705,6 +710,7 @@ static struct rtnl_link_ops can_link_ops __read_mostly = { .changelink = can_changelink, .changelink = can_changelink, .get_size = can_get_size, .get_size = can_get_size, .fill_info = can_fill_info, .fill_info = can_fill_info, .get_xstats_size = can_get_xstats_size, .fill_xstats = can_fill_xstats, .fill_xstats = can_fill_xstats, }; }; Loading Loading
MAINTAINERS +2 −1 Original line number Original line Diff line number Diff line Loading @@ -4304,6 +4304,7 @@ F: drivers/video/aty/aty128fb.c RALINK RT2X00 WIRELESS LAN DRIVER RALINK RT2X00 WIRELESS LAN DRIVER P: rt2x00 project P: rt2x00 project M: Ivo van Doorn <IvDoorn@gmail.com> M: Ivo van Doorn <IvDoorn@gmail.com> M: Gertjan van Wingerde <gwingerde@gmail.com> L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org L: users@rt2x00.serialmonkey.com (moderated for non-subscribers) L: users@rt2x00.serialmonkey.com (moderated for non-subscribers) W: http://rt2x00.serialmonkey.com/ W: http://rt2x00.serialmonkey.com/ Loading Loading @@ -4391,7 +4392,7 @@ RFKILL M: Johannes Berg <johannes@sipsolutions.net> M: Johannes Berg <johannes@sipsolutions.net> L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org S: Maintained S: Maintained F Documentation/rfkill.txt F: Documentation/rfkill.txt F: net/rfkill/ F: net/rfkill/ RISCOM8 DRIVER RISCOM8 DRIVER Loading
drivers/isdn/hardware/mISDN/hfcmulti.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -5481,7 +5481,7 @@ HFCmulti_init(void) if (err) { if (err) { printk(KERN_ERR "error registering embedded driver: " printk(KERN_ERR "error registering embedded driver: " "%x\n", err); "%x\n", err); return -err; return err; } } HFC_cnt++; HFC_cnt++; printk(KERN_INFO "%d devices registered\n", HFC_cnt); printk(KERN_INFO "%d devices registered\n", HFC_cnt); Loading
drivers/isdn/i4l/isdn_ppp.c +163 −189 Original line number Original line Diff line number Diff line Loading @@ -1535,10 +1535,8 @@ static int isdn_ppp_mp_bundle_array_init(void) int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL ) if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL ) return -ENOMEM; return -ENOMEM; for (i = 0; i < ISDN_MAX_CHANNELS; i++) { for( i = 0; i < ISDN_MAX_CHANNELS; i++ ) spin_lock_init(&isdn_ppp_bundle_arr[i].lock); spin_lock_init(&isdn_ppp_bundle_arr[i].lock); skb_queue_head_init(&isdn_ppp_bundle_arr[i].frags); } return 0; return 0; } } Loading Loading @@ -1571,7 +1569,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) return -ENOMEM; return -ENOMEM; lp->next = lp->last = lp; /* nobody else in a queue */ lp->next = lp->last = lp; /* nobody else in a queue */ skb_queue_head_init(&lp->netdev->pb->frags); lp->netdev->pb->frags = NULL; lp->netdev->pb->frames = 0; lp->netdev->pb->frames = 0; lp->netdev->pb->seq = UINT_MAX; lp->netdev->pb->seq = UINT_MAX; } } Loading @@ -1583,24 +1581,23 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) static u32 isdn_ppp_mp_get_seq( int short_seq, static u32 isdn_ppp_mp_get_seq( int short_seq, struct sk_buff * skb, u32 last_seq ); struct sk_buff * skb, u32 last_seq ); static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, struct sk_buff *to); struct sk_buff * from, struct sk_buff * to ); static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *from, struct sk_buff *to, struct sk_buff * from, struct sk_buff * to ); u32 lastseq); static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb ); static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb ); static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb) struct sk_buff *skb) { { struct sk_buff *newfrag, *frag, *start, *nextf; u32 newseq, minseq, thisseq; isdn_mppp_stats *stats; struct ippp_struct *is; struct ippp_struct *is; unsigned long flags; isdn_net_local * lpq; isdn_net_local * lpq; ippp_bundle * mp; ippp_bundle * mp; isdn_mppp_stats * stats; struct sk_buff * newfrag, * frag, * start, *nextf; u32 newseq, minseq, thisseq; unsigned long flags; int slot; int slot; spin_lock_irqsave(&net_dev->pb->lock, flags); spin_lock_irqsave(&net_dev->pb->lock, flags); Loading @@ -1625,6 +1622,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, skb, is->last_link_seqno); skb, is->last_link_seqno); /* if this packet seq # is less than last already processed one, /* if this packet seq # is less than last already processed one, * toss it right away, but check for sequence start case first * toss it right away, but check for sequence start case first */ */ Loading Loading @@ -1659,31 +1657,22 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * packets */ * packets */ newfrag = skb; newfrag = skb; /* Insert new fragment into the proper sequence slot. */ /* if this new fragment is before the first one, then enqueue it now. */ skb_queue_walk(&mp->frags, frag) { if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) { if (MP_SEQ(frag) == newseq) { newfrag->next = frag; isdn_ppp_mp_free_skb(mp, newfrag); mp->frags = frag = newfrag; newfrag = NULL; newfrag = NULL; break; } } if (MP_LT(newseq, MP_SEQ(frag))) { __skb_queue_before(&mp->frags, frag, newfrag); newfrag = NULL; break; } } if (newfrag) __skb_queue_tail(&mp->frags, newfrag); frag = skb_peek(&mp->frags); start = MP_FLAGS(frag) & MP_BEGIN_FRAG && start = ((MP_FLAGS(frag) & MP_BEGIN_FRAG) && MP_SEQ(frag) == mp->seq ? frag : NULL; (MP_SEQ(frag) == mp->seq)) ? frag : NULL; if (!start) goto check_overflow; /* main fragment traversing loop /* * main fragment traversing loop * * * try to accomplish several tasks: * try to accomplish several tasks: * - insert new fragment into the proper sequence slot (once that's done * newfrag will be set to NULL) * - reassemble any complete fragment sequence (non-null 'start' * - reassemble any complete fragment sequence (non-null 'start' * indicates there is a continguous sequence present) * indicates there is a continguous sequence present) * - discard any incomplete sequences that are below minseq -- due * - discard any incomplete sequences that are below minseq -- due Loading @@ -1692,45 +1681,70 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * come to complete such sequence and it should be discarded * come to complete such sequence and it should be discarded * * * loop completes when we accomplished the following tasks: * loop completes when we accomplished the following tasks: * - new fragment is inserted in the proper sequence ('newfrag' is * set to NULL) * - we hit a gap in the sequence, so no reassembly/processing is * - we hit a gap in the sequence, so no reassembly/processing is * possible ('start' would be set to NULL) * possible ('start' would be set to NULL) * * * algorithm for this code is derived from code in the book * algorithm for this code is derived from code in the book * 'PPP Design And Debugging' by James Carlson (Addison-Wesley) * 'PPP Design And Debugging' by James Carlson (Addison-Wesley) */ */ skb_queue_walk_safe(&mp->frags, frag, nextf) { while (start != NULL || newfrag != NULL) { thisseq = MP_SEQ(frag); thisseq = MP_SEQ(frag); nextf = frag->next; /* drop any duplicate fragments */ if (newfrag != NULL && thisseq == newseq) { isdn_ppp_mp_free_skb(mp, newfrag); newfrag = NULL; } /* insert new fragment before next element if possible. */ if (newfrag != NULL && (nextf == NULL || MP_LT(newseq, MP_SEQ(nextf)))) { newfrag->next = nextf; frag->next = nextf = newfrag; newfrag = NULL; } if (start != NULL) { /* check for misplaced start */ /* check for misplaced start */ if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { printk(KERN_WARNING"isdn_mppp(seq %d): new " printk(KERN_WARNING"isdn_mppp(seq %d): new " "BEGIN flag with no prior END", thisseq); "BEGIN flag with no prior END", thisseq); stats->seqerrs++; stats->seqerrs++; stats->frame_drops++; stats->frame_drops++; isdn_ppp_mp_discard(mp, start, frag); start = isdn_ppp_mp_discard(mp, start,frag); start = frag; nextf = frag->next; } } else if (MP_LE(thisseq, minseq)) { } else if (MP_LE(thisseq, minseq)) { if (MP_FLAGS(frag) & MP_BEGIN_FRAG) if (MP_FLAGS(frag) & MP_BEGIN_FRAG) start = frag; start = frag; else { else { if (MP_FLAGS(frag) & MP_END_FRAG) if (MP_FLAGS(frag) & MP_END_FRAG) stats->frame_drops++; stats->frame_drops++; __skb_unlink(skb, &mp->frags); if( mp->frags == frag ) mp->frags = nextf; isdn_ppp_mp_free_skb(mp, frag); isdn_ppp_mp_free_skb(mp, frag); frag = nextf; continue; continue; } } } } /* if we have end fragment, then we have full reassembly /* if start is non-null and we have end fragment, then * sequence -- reassemble and process packet now * we have full reassembly sequence -- reassemble * and process packet now */ */ if (MP_FLAGS(frag) & MP_END_FRAG) { if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) { minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; /* Reassemble the packet then dispatch it */ /* Reassemble the packet then dispatch it */ isdn_ppp_mp_reassembly(net_dev, lp, start, frag, thisseq); isdn_ppp_mp_reassembly(net_dev, lp, start, nextf); start = NULL; start = NULL; frag = NULL; frag = NULL; mp->frags = nextf; } } /* check if need to update start pointer: if we just /* check if need to update start pointer: if we just Loading @@ -1742,24 +1756,25 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * below low watermark and set start to the next frag or * below low watermark and set start to the next frag or * clear start ptr. * clear start ptr. */ */ if (nextf != (struct sk_buff *)&mp->frags && if (nextf != NULL && ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) { ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) { /* if we just reassembled and the next one is here, /* if we just reassembled and the next one is here, * then start another reassembly. * then start another reassembly. */ */ if (frag == NULL) { if (frag == NULL) { if (MP_FLAGS(nextf) & MP_BEGIN_FRAG) if (MP_FLAGS(nextf) & MP_BEGIN_FRAG) start = nextf; start = nextf; else { else { printk(KERN_WARNING"isdn_mppp(seq %d):" printk(KERN_WARNING"isdn_mppp(seq %d):" " END flag with no following " " END flag with no following " "BEGIN", thisseq); "BEGIN", thisseq); stats->seqerrs++; stats->seqerrs++; } } } } } else { } else { if (nextf != (struct sk_buff *)&mp->frags && if ( nextf != NULL && frag != NULL && frag != NULL && MP_LT(thisseq, minseq)) { MP_LT(thisseq, minseq)) { /* we've got a break in the sequence /* we've got a break in the sequence * and we not at the end yet * and we not at the end yet Loading @@ -1769,26 +1784,26 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * discard all the frames below low watermark * discard all the frames below low watermark * and start over */ * and start over */ stats->frame_drops++; stats->frame_drops++; isdn_ppp_mp_discard(mp, start, nextf); mp->frags = isdn_ppp_mp_discard(mp,start,nextf); } } /* break in the sequence, no reassembly */ /* break in the sequence, no reassembly */ start = NULL; start = NULL; } } if (!start) break; } check_overflow: frag = nextf; } /* while -- main loop */ if (mp->frags == NULL) mp->frags = frag; /* rather straighforward way to deal with (not very) possible /* rather straighforward way to deal with (not very) possible * queue overflow * queue overflow */ */ if (mp->frames > MP_MAX_QUEUE_LEN) { if (mp->frames > MP_MAX_QUEUE_LEN) { stats->overflows++; stats->overflows++; skb_queue_walk_safe(&mp->frags, frag, nextf) { while (mp->frames > MP_MAX_QUEUE_LEN) { if (mp->frames <= MP_MAX_QUEUE_LEN) frag = mp->frags->next; break; isdn_ppp_mp_free_skb(mp, mp->frags); __skb_unlink(frag, &mp->frags); mp->frags = frag; isdn_ppp_mp_free_skb(mp, frag); } } } } spin_unlock_irqrestore(&mp->lock, flags); spin_unlock_irqrestore(&mp->lock, flags); Loading @@ -1796,12 +1811,14 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, static void isdn_ppp_mp_cleanup( isdn_net_local * lp ) static void isdn_ppp_mp_cleanup( isdn_net_local * lp ) { { struct sk_buff *skb, *tmp; struct sk_buff * frag = lp->netdev->pb->frags; struct sk_buff * nextfrag; skb_queue_walk_safe(&lp->netdev->pb->frags, skb, tmp) { while( frag ) { __skb_unlink(skb, &lp->netdev->pb->frags); nextfrag = frag->next; isdn_ppp_mp_free_skb(lp->netdev->pb, skb); isdn_ppp_mp_free_skb(lp->netdev->pb, frag); frag = nextfrag; } } lp->netdev->pb->frags = NULL; } } static u32 isdn_ppp_mp_get_seq( int short_seq, static u32 isdn_ppp_mp_get_seq( int short_seq, Loading Loading @@ -1838,110 +1855,67 @@ static u32 isdn_ppp_mp_get_seq( int short_seq, return seq; return seq; } } static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, struct sk_buff *to) { if (from) { struct sk_buff *skb, *tmp; int freeing = 0; skb_queue_walk_safe(&mp->frags, skb, tmp) { if (skb == to) break; if (skb == from) freeing = 1; if (!freeing) continue; __skb_unlink(skb, &mp->frags); isdn_ppp_mp_free_skb(mp, skb); } } } static unsigned int calc_tot_len(struct sk_buff_head *queue, struct sk_buff * from, struct sk_buff * to ) struct sk_buff * from, struct sk_buff * to ) { { unsigned int tot_len = 0; if( from ) struct sk_buff *skb; while (from != to) { int found_start = 0; struct sk_buff * next = from->next; isdn_ppp_mp_free_skb(mp, from); skb_queue_walk(queue, skb) { from = next; if (skb == from) found_start = 1; if (!found_start) continue; tot_len += skb->len - MP_HEADER_LEN; if (skb == to) break; } } return tot_len; return from; } } /* Reassemble packet using fragments in the reassembly queue from void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, * 'from' until 'to', inclusive. struct sk_buff * from, struct sk_buff * to ) */ static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *from, struct sk_buff *to, u32 lastseq) { { ippp_bundle * mp = net_dev->pb; ippp_bundle * mp = net_dev->pb; unsigned int tot_len; struct sk_buff *skb; int proto; int proto; struct sk_buff * skb; unsigned int tot_len; if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", __func__, lp->ppp_slot); __func__, lp->ppp_slot); return; return; } } tot_len = calc_tot_len(&mp->frags, from, to); if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) { if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) { if( ippp_table[lp->ppp_slot]->debug & 0x40 ) if( ippp_table[lp->ppp_slot]->debug & 0x40 ) printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, " printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, " "len %d\n", MP_SEQ(from), from->len ); "len %d\n", MP_SEQ(from), from->len ); skb = from; skb = from; skb_pull(skb, MP_HEADER_LEN); skb_pull(skb, MP_HEADER_LEN); __skb_unlink(skb, &mp->frags); mp->frames--; mp->frames--; } else { } else { struct sk_buff *walk, *tmp; struct sk_buff * frag; int found_start = 0; int n; for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++) tot_len += frag->len - MP_HEADER_LEN; if( ippp_table[lp->ppp_slot]->debug & 0x40 ) if( ippp_table[lp->ppp_slot]->debug & 0x40 ) printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " "to %d, len %d\n", MP_SEQ(from), lastseq, "to %d, len %d\n", MP_SEQ(from), tot_len); (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len ); if( (skb = dev_alloc_skb(tot_len)) == NULL ) { skb = dev_alloc_skb(tot_len); if (!skb) printk(KERN_ERR "isdn_mppp: cannot allocate sk buff " printk(KERN_ERR "isdn_mppp: cannot allocate sk buff " "of size %d\n", tot_len); "of size %d\n", tot_len); isdn_ppp_mp_discard(mp, from, to); return; } found_start = 0; while( from != to ) { skb_queue_walk_safe(&mp->frags, walk, tmp) { unsigned int len = from->len - MP_HEADER_LEN; if (walk == from) found_start = 1; if (!found_start) continue; if (skb) { skb_copy_from_linear_data_offset(from, MP_HEADER_LEN, unsigned int len = walk->len - MP_HEADER_LEN; skb_copy_from_linear_data_offset(walk, MP_HEADER_LEN, skb_put(skb,len), skb_put(skb,len), len); len); } frag = from->next; __skb_unlink(walk, &mp->frags); isdn_ppp_mp_free_skb(mp, from); isdn_ppp_mp_free_skb(mp, walk); from = frag; if (walk == to) break; } } } } if (!skb) return; proto = isdn_ppp_strip_proto(skb); proto = isdn_ppp_strip_proto(skb); isdn_ppp_push_higher(net_dev, lp, skb, proto); isdn_ppp_push_higher(net_dev, lp, skb, proto); } } Loading
drivers/net/can/Kconfig +5 −55 Original line number Original line Diff line number Diff line Loading @@ -35,63 +35,9 @@ config CAN_CALC_BITTIMING arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". If unsure, say Y. If unsure, say Y. config CAN_SJA1000 depends on CAN_DEV && HAS_IOMEM tristate "Philips SJA1000" ---help--- Driver for the SJA1000 CAN controllers from Philips or NXP config CAN_SJA1000_ISA depends on CAN_SJA1000 && ISA tristate "ISA Bus based legacy SJA1000 driver" ---help--- This driver adds legacy support for SJA1000 chips connected to the ISA bus using I/O port, memory mapped or indirect access. config CAN_SJA1000_PLATFORM depends on CAN_SJA1000 tristate "Generic Platform Bus based SJA1000 driver" ---help--- This driver adds support for the SJA1000 chips connected to the "platform bus" (Linux abstraction for directly to the processor attached devices). Which can be found on various boards from Phytec (http://www.phytec.de) like the PCM027, PCM038. config CAN_SJA1000_OF_PLATFORM depends on CAN_SJA1000 && PPC_OF tristate "Generic OF Platform Bus based SJA1000 driver" ---help--- This driver adds support for the SJA1000 chips connected to the OpenFirmware "platform bus" found on embedded systems with OpenFirmware bindings, e.g. if you have a PowerPC based system you may want to enable this option. config CAN_EMS_PCI tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card" depends on PCI && CAN_SJA1000 ---help--- This driver is for the one, two or four channel CPC-PCI, CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de). config CAN_EMS_USB tristate "EMS CPC-USB/ARM7 CAN/USB interface" depends on USB && CAN_DEV ---help--- This driver is for the one channel CPC-USB/ARM7 CAN/USB interface from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de). config CAN_KVASER_PCI tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards" depends on PCI && CAN_SJA1000 ---help--- This driver is for the the PCIcanx and PCIcan cards (1, 2 or 4 channel) from Kvaser (http://www.kvaser.com). config CAN_AT91 config CAN_AT91 tristate "Atmel AT91 onchip CAN controller" tristate "Atmel AT91 onchip CAN controller" depends on CAN && CAN_DEV && ARCH_AT91SAM9263 depends on CAN_DEV && ARCH_AT91SAM9263 ---help--- ---help--- This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. Loading Loading @@ -127,6 +73,10 @@ config CAN_MPC52XX This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module will be called mpc5xxx_can. will be called mpc5xxx_can. source "drivers/net/can/sja1000/Kconfig" source "drivers/net/can/usb/Kconfig" config CAN_DEBUG_DEVICES config CAN_DEBUG_DEVICES bool "CAN devices debugging messages" bool "CAN devices debugging messages" depends on CAN depends on CAN Loading
drivers/net/can/dev.c +6 −0 Original line number Original line Diff line number Diff line Loading @@ -677,6 +677,11 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) return -EMSGSIZE; return -EMSGSIZE; } } static size_t can_get_xstats_size(const struct net_device *dev) { return sizeof(struct can_device_stats); } static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) { { struct can_priv *priv = netdev_priv(dev); struct can_priv *priv = netdev_priv(dev); Loading Loading @@ -705,6 +710,7 @@ static struct rtnl_link_ops can_link_ops __read_mostly = { .changelink = can_changelink, .changelink = can_changelink, .get_size = can_get_size, .get_size = can_get_size, .fill_info = can_fill_info, .fill_info = can_fill_info, .get_xstats_size = can_get_xstats_size, .fill_xstats = can_fill_xstats, .fill_xstats = can_fill_xstats, }; }; Loading