drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
Source file repositories/reference/linux-study-clean/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c- Extension
.c- Size
- 22296 bytes
- Lines
- 892
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/module.hlinux/slab.hlinux/usb.hlinux/bug.hrt2x00.hrt2x00usb.h
Detected Declarations
struct rt2x00_async_read_datafunction rt2x00usb_check_usb_errorfunction rt2x00usb_vendor_requestfunction rt2x00usb_vendor_req_buff_lockfunction rt2x00usb_vendor_request_bufffunction rt2x00usb_regbusy_readfunction rt2x00usb_register_read_async_cbfunction rt2x00usb_register_read_asyncfunction rt2x00usb_work_txdone_entryfunction rt2x00usb_work_txdonefunction tx_queue_for_eachfunction rt2x00usb_interrupt_txdonefunction rt2x00usb_kick_tx_entryfunction rt2x00usb_work_rxdonefunction rt2x00usb_interrupt_rxdonefunction rt2x00usb_kick_rx_entryfunction rt2x00usb_kick_queuefunction rt2x00usb_flush_entryfunction rt2x00usb_flush_queuefunction rt2x00usb_watchdog_tx_dmafunction rt2x00usb_dma_timeoutfunction rt2x00usb_watchdogfunction tx_queue_for_eachfunction rt2x00usb_disable_radiofunction rt2x00usb_clear_entryfunction rt2x00usb_assign_endpointfunction rt2x00usb_find_endpointsfunction rt2x00usb_alloc_entriesfunction rt2x00usb_free_entriesfunction rt2x00usb_initializefunction rt2x00usb_uninitializefunction rt2x00usb_free_regfunction rt2x00usb_alloc_regfunction rt2x00usb_probefunction rt2x00usb_disconnectfunction rt2x00usb_suspendfunction rt2x00usb_resumeexport rt2x00usb_vendor_requestexport rt2x00usb_vendor_req_buff_lockexport rt2x00usb_vendor_request_buffexport rt2x00usb_regbusy_readexport rt2x00usb_register_read_asyncexport rt2x00usb_kick_queueexport rt2x00usb_flush_queueexport rt2x00usb_watchdogexport rt2x00usb_disable_radioexport rt2x00usb_clear_entryexport rt2x00usb_initialize
Annotated Snippet
struct rt2x00_async_read_data {
__le32 reg;
struct usb_ctrlrequest cr;
struct rt2x00_dev *rt2x00dev;
bool (*callback)(struct rt2x00_dev *, int, u32);
};
static void rt2x00usb_register_read_async_cb(struct urb *urb)
{
struct rt2x00_async_read_data *rd = urb->context;
if (rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg))) {
usb_anchor_urb(urb, rd->rt2x00dev->anchor);
if (usb_submit_urb(urb, GFP_ATOMIC) < 0) {
usb_unanchor_urb(urb);
kfree(rd);
}
} else
kfree(rd);
}
void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
bool (*callback)(struct rt2x00_dev*, int, u32))
{
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
struct urb *urb;
struct rt2x00_async_read_data *rd;
rd = kmalloc_obj(*rd, GFP_ATOMIC);
if (!rd)
return;
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
kfree(rd);
return;
}
rd->rt2x00dev = rt2x00dev;
rd->callback = callback;
rd->cr.bRequestType = USB_VENDOR_REQUEST_IN;
rd->cr.bRequest = USB_MULTI_READ;
rd->cr.wValue = 0;
rd->cr.wIndex = cpu_to_le16(offset);
rd->cr.wLength = cpu_to_le16(sizeof(u32));
usb_fill_control_urb(urb, usb_dev, usb_rcvctrlpipe(usb_dev, 0),
(u8 *)(&rd->cr), &rd->reg, sizeof(rd->reg),
rt2x00usb_register_read_async_cb, rd);
usb_anchor_urb(urb, rt2x00dev->anchor);
if (usb_submit_urb(urb, GFP_ATOMIC) < 0) {
usb_unanchor_urb(urb);
kfree(rd);
}
usb_free_urb(urb);
}
EXPORT_SYMBOL_GPL(rt2x00usb_register_read_async);
/*
* TX data handlers.
*/
static void rt2x00usb_work_txdone_entry(struct queue_entry *entry)
{
/*
* If the transfer to hardware succeeded, it does not mean the
* frame was send out correctly. It only means the frame
* was successfully pushed to the hardware, we have no
* way to determine the transmission status right now.
* (Only indirectly by looking at the failed TX counters
* in the register).
*/
if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
else
rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
}
static void rt2x00usb_work_txdone(struct work_struct *work)
{
struct rt2x00_dev *rt2x00dev =
container_of(work, struct rt2x00_dev, txdone_work);
struct data_queue *queue;
struct queue_entry *entry;
tx_queue_for_each(rt2x00dev, queue) {
while (!rt2x00queue_empty(queue)) {
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/slab.h`, `linux/usb.h`, `linux/bug.h`, `rt2x00.h`, `rt2x00usb.h`.
- Detected declarations: `struct rt2x00_async_read_data`, `function rt2x00usb_check_usb_error`, `function rt2x00usb_vendor_request`, `function rt2x00usb_vendor_req_buff_lock`, `function rt2x00usb_vendor_request_buff`, `function rt2x00usb_regbusy_read`, `function rt2x00usb_register_read_async_cb`, `function rt2x00usb_register_read_async`, `function rt2x00usb_work_txdone_entry`, `function rt2x00usb_work_txdone`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: integration 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.