drivers/usb/gadget/function/f_phonet.c
Source file repositories/reference/linux-study-clean/drivers/usb/gadget/function/f_phonet.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/usb/gadget/function/f_phonet.c- Extension
.c- Size
- 17682 bytes
- Lines
- 743
- Domain
- Driver Families
- Bucket
- drivers/usb
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/mm.hlinux/slab.hlinux/kernel.hlinux/module.hlinux/device.hlinux/netdevice.hlinux/if_ether.hlinux/if_phonet.hlinux/if_arp.hlinux/usb/ch9.hlinux/usb/cdc.hlinux/usb/composite.hu_phonet.hu_ether.h
Detected Declarations
struct phonet_portstruct f_phonetfunction pn_net_openfunction pn_net_closefunction pn_tx_completefunction pn_net_xmitfunction pn_net_setupfunction pn_rx_submitfunction pn_rx_completefunction __pn_resetfunction pn_set_altfunction pn_get_altfunction pn_disconnectfunction pn_bindfunction phonet_attr_releasefunction f_phonet_ifname_showfunction phonet_free_instfunction phonet_freefunction pn_unbindfunction gphonet_set_gadgetfunction gphonet_register_netdevfunction gphonet_cleanup
Annotated Snippet
static const struct net_device_ops pn_netdev_ops = {
.ndo_open = pn_net_open,
.ndo_stop = pn_net_close,
.ndo_start_xmit = pn_net_xmit,
};
static void pn_net_setup(struct net_device *dev)
{
const u8 addr = PN_MEDIA_USB;
dev->features = 0;
dev->type = ARPHRD_PHONET;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
dev->mtu = PHONET_DEV_MTU;
dev->min_mtu = PHONET_MIN_MTU;
dev->max_mtu = PHONET_MAX_MTU;
dev->hard_header_len = 1;
dev->addr_len = 1;
dev_addr_set(dev, &addr);
dev->tx_queue_len = 1;
dev->netdev_ops = &pn_netdev_ops;
dev->needs_free_netdev = true;
dev->header_ops = &phonet_header_ops;
}
/*-------------------------------------------------------------------------*/
/*
* Queue buffer for data from the host
*/
static int
pn_rx_submit(struct f_phonet *fp, struct usb_request *req, gfp_t gfp_flags)
{
struct page *page;
int err;
page = __dev_alloc_page(gfp_flags | __GFP_NOMEMALLOC);
if (!page)
return -ENOMEM;
req->buf = page_address(page);
req->length = PAGE_SIZE;
req->context = page;
err = usb_ep_queue(fp->out_ep, req, gfp_flags);
if (unlikely(err))
put_page(page);
return err;
}
static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)
{
struct f_phonet *fp = ep->driver_data;
struct net_device *dev = fp->dev;
struct page *page = req->context;
struct sk_buff *skb;
unsigned long flags;
int status = req->status;
switch (status) {
case 0:
spin_lock_irqsave(&fp->rx.lock, flags);
skb = fp->rx.skb;
if (!skb)
skb = fp->rx.skb = netdev_alloc_skb(dev, 12);
if (req->actual < req->length) /* Last fragment */
fp->rx.skb = NULL;
spin_unlock_irqrestore(&fp->rx.lock, flags);
if (unlikely(!skb))
break;
if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) {
/* Frame count from host exceeds frags[] capacity */
dev_kfree_skb_any(skb);
if (fp->rx.skb == skb)
fp->rx.skb = NULL;
dev->stats.rx_length_errors++;
break;
}
if (skb->len == 0) { /* First fragment */
skb->protocol = htons(ETH_P_PHONET);
skb_reset_mac_header(skb);
/* Can't use pskb_pull() on page in IRQ */
skb_put_data(skb, page_address(page), 1);
}
Annotation
- Immediate include surface: `linux/mm.h`, `linux/slab.h`, `linux/kernel.h`, `linux/module.h`, `linux/device.h`, `linux/netdevice.h`, `linux/if_ether.h`, `linux/if_phonet.h`.
- Detected declarations: `struct phonet_port`, `struct f_phonet`, `function pn_net_open`, `function pn_net_close`, `function pn_tx_complete`, `function pn_net_xmit`, `function pn_net_setup`, `function pn_rx_submit`, `function pn_rx_complete`, `function __pn_reset`.
- Atlas domain: Driver Families / drivers/usb.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.