drivers/net/usb/lg-vl600.c
Source file repositories/reference/linux-study-clean/drivers/net/usb/lg-vl600.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/usb/lg-vl600.c- Extension
.c- Size
- 9723 bytes
- Lines
- 336
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/etherdevice.hlinux/ethtool.hlinux/mii.hlinux/usb.hlinux/usb/cdc.hlinux/usb/usbnet.hlinux/if_ether.hlinux/if_arp.hlinux/inetdevice.hlinux/module.h
Detected Declarations
struct vl600_frame_hdrstruct vl600_pkt_hdrstruct vl600_statefunction vl600_bindfunction vl600_unbindfunction vl600_rx_fixup
Annotated Snippet
struct vl600_frame_hdr {
__le32 len;
__le32 serial;
__le32 pkt_cnt;
__le32 dummy_flags;
__le32 dummy;
__le32 magic;
} __attribute__((packed));
struct vl600_pkt_hdr {
__le32 dummy[2];
__le32 len;
__be16 h_proto;
} __attribute__((packed));
struct vl600_state {
struct sk_buff *current_rx_buf;
};
static int vl600_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret;
struct vl600_state *s = kzalloc_obj(struct vl600_state);
if (!s)
return -ENOMEM;
ret = usbnet_cdc_bind(dev, intf);
if (ret) {
kfree(s);
return ret;
}
dev->driver_priv = s;
/* ARP packets don't go through, but they're also of no use. The
* subnet has only two hosts anyway: us and the gateway / DHCP
* server (probably simulated by modem firmware or network operator)
* whose address changes every time we connect to the intarwebz and
* who doesn't bother answering ARP requests either. So hardware
* addresses have no meaning, the destination and the source of every
* packet depend only on whether it is on the IN or OUT endpoint. */
dev->net->flags |= IFF_NOARP;
/* IPv6 NDP relies on multicast. Enable it by default. */
dev->net->flags |= IFF_MULTICAST;
return ret;
}
static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf)
{
struct vl600_state *s = dev->driver_priv;
dev_kfree_skb(s->current_rx_buf);
kfree(s);
return usbnet_cdc_unbind(dev, intf);
}
static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
struct vl600_frame_hdr *frame;
struct vl600_pkt_hdr *packet;
struct ethhdr *ethhdr;
int packet_len, count;
struct sk_buff *buf = skb;
struct sk_buff *clone;
struct vl600_state *s = dev->driver_priv;
/* Frame lengths are generally 4B multiplies but every couple of
* hours there's an odd number of bytes sized yet correct frame,
* so don't require this. */
/* Allow a packet (or multiple packets batched together) to be
* split across many frames. We don't allow a new batch to
* begin in the same frame another one is ending however, and no
* leading or trailing pad bytes. */
if (s->current_rx_buf) {
frame = (struct vl600_frame_hdr *) s->current_rx_buf->data;
if (skb->len + s->current_rx_buf->len >
le32_to_cpup(&frame->len)) {
netif_err(dev, ifup, dev->net, "Fragment too long\n");
dev->net->stats.rx_length_errors++;
goto error;
}
buf = s->current_rx_buf;
skb_put_data(buf, skb->data, skb->len);
} else if (skb->len < 4) {
netif_err(dev, ifup, dev->net, "Frame too short\n");
Annotation
- Immediate include surface: `linux/etherdevice.h`, `linux/ethtool.h`, `linux/mii.h`, `linux/usb.h`, `linux/usb/cdc.h`, `linux/usb/usbnet.h`, `linux/if_ether.h`, `linux/if_arp.h`.
- Detected declarations: `struct vl600_frame_hdr`, `struct vl600_pkt_hdr`, `struct vl600_state`, `function vl600_bind`, `function vl600_unbind`, `function vl600_rx_fixup`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.