drivers/net/wireless/purelifi/plfxlc/usb.c
Source file repositories/reference/linux-study-clean/drivers/net/wireless/purelifi/plfxlc/usb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireless/purelifi/plfxlc/usb.c- Extension
.c- Size
- 20659 bytes
- Lines
- 876
- 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.
- 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/kernel.hlinux/init.hlinux/device.hlinux/errno.hlinux/slab.hlinux/skbuff.hlinux/usb.hlinux/workqueue.hlinux/proc_fs.hlinux/fs.hlinux/string.hlinux/module.hnet/mac80211.hlinux/unaligned.hlinux/sysfs.hmac.husb.hchip.h
Detected Declarations
function plfxlc_send_packet_from_data_queuefunction handle_rx_packetfunction rx_urb_completefunction free_rx_urbfunction __lf_x_usb_enable_rxfunction plfxlc_usb_enable_rxfunction __lf_x_usb_disable_rxfunction plfxlc_usb_disable_rxfunction plfxlc_usb_disable_txfunction plfxlc_usb_enable_txfunction plfxlc_tx_urb_completefunction init_usb_rxfunction init_usb_txfunction plfxlc_usb_initfunction plfxlc_usb_releasefunction plfxlc_usb_init_hwfunction get_usb_reqfunction plfxlc_usb_wreq_asyncfunction plfxlc_usb_wreqfunction slif_data_plane_sap_timer_callbfunction sta_queue_cleanup_timer_callbfunction probefunction disconnectfunction plfxlc_usb_resumefunction plfxlc_usb_stopfunction pre_resetfunction post_resetfunction suspendfunction resume
Annotated Snippet
if (tx->submitted_urbs++ < PURELIFI_URB_RETRY_MAX) {
dev_dbg(plfxlc_urb_dev(urb), "urb %p resubmit %d", urb,
tx->submitted_urbs++);
goto resubmit;
} else {
dev_dbg(plfxlc_urb_dev(urb), "urb %p max resubmits reached", urb);
tx->submitted_urbs = 0;
return;
}
}
buffer = urb->transfer_buffer;
length = le32_to_cpu(*(__le32 *)(buffer + sizeof(struct rx_status)))
+ sizeof(u32);
if (urb->actual_length != (PLF_MSG_STATUS_OFFSET + 1)) {
if (usb->initialized && usb->link_up)
handle_rx_packet(usb, buffer, length);
goto resubmit;
}
status = buffer[PLF_MSG_STATUS_OFFSET];
switch (status) {
case STATION_FIFO_ALMOST_FULL_NOT_MESSAGE:
dev_dbg(&usb->intf->dev,
"FIFO full not packet receipt\n");
tx->mac_fifo_full = 1;
for (sidx = 0; sidx < MAX_STA_NUM; sidx++)
tx->station[sidx].flag |= STATION_FIFO_FULL_FLAG;
break;
case STATION_FIFO_ALMOST_FULL_MESSAGE:
dev_dbg(&usb->intf->dev, "FIFO full packet receipt\n");
for (sidx = 0; sidx < MAX_STA_NUM; sidx++)
tx->station[sidx].flag &= STATION_ACTIVE_FLAG;
plfxlc_send_packet_from_data_queue(usb);
break;
case STATION_CONNECT_MESSAGE:
usb->link_up = 1;
dev_dbg(&usb->intf->dev, "ST_CONNECT_MSG packet receipt\n");
break;
case STATION_DISCONNECT_MESSAGE:
usb->link_up = 0;
dev_dbg(&usb->intf->dev, "ST_DISCONN_MSG packet receipt\n");
break;
default:
dev_dbg(&usb->intf->dev, "Unknown packet receipt\n");
break;
}
resubmit:
r = usb_submit_urb(urb, GFP_ATOMIC);
if (r)
dev_dbg(plfxlc_urb_dev(urb), "urb %p resubmit fail (%d)\n", urb, r);
}
static struct urb *alloc_rx_urb(struct plfxlc_usb *usb)
{
struct usb_device *udev = plfxlc_usb_to_usbdev(usb);
struct urb *urb;
void *buffer;
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return NULL;
buffer = usb_alloc_coherent(udev, USB_MAX_RX_SIZE, GFP_KERNEL,
&urb->transfer_dma);
if (!buffer) {
usb_free_urb(urb);
return NULL;
}
usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, EP_DATA_IN),
buffer, USB_MAX_RX_SIZE,
rx_urb_complete, usb);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
return urb;
}
static void free_rx_urb(struct urb *urb)
{
if (!urb)
return;
usb_free_coherent(urb->dev, urb->transfer_buffer_length,
urb->transfer_buffer, urb->transfer_dma);
usb_free_urb(urb);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/init.h`, `linux/device.h`, `linux/errno.h`, `linux/slab.h`, `linux/skbuff.h`, `linux/usb.h`, `linux/workqueue.h`.
- Detected declarations: `function plfxlc_send_packet_from_data_queue`, `function handle_rx_packet`, `function rx_urb_complete`, `function free_rx_urb`, `function __lf_x_usb_enable_rx`, `function plfxlc_usb_enable_rx`, `function __lf_x_usb_disable_rx`, `function plfxlc_usb_disable_rx`, `function plfxlc_usb_disable_tx`, `function plfxlc_usb_enable_tx`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source 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.