drivers/net/wireless/intel/ipw2x00/ipw2200.c
Source file repositories/reference/linux-study-clean/drivers/net/wireless/intel/ipw2x00/ipw2200.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireless/intel/ipw2x00/ipw2200.c- Extension
.c- Size
- 328983 bytes
- Lines
- 11974
- Domain
- Driver Families
- Bucket
- drivers/net
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/sched.hlinux/slab.hnet/cfg80211-wext.hipw2200.hipw.h
Detected Declarations
struct fw_chunkstruct ipw_fwstruct ipw_status_codestruct ipw_network_matchfunction snprint_linefunction printk_buffunction snprintk_buffunction ipw_write_reg8function ipw_write_reg16function ipw_write_reg32function _ipw_write8function _ipw_write16function _ipw_write32function _ipw_read8function _ipw_read32function _ipw_write_reg32function _ipw_write_reg8function _ipw_write_reg16function _ipw_read_reg8function _ipw_read_reg32function _ipw_read_indirectfunction _ipw_write_indirectfunction ipw_write_directfunction ipw_set_bitfunction ipw_clear_bitfunction __ipw_enable_interruptsfunction __ipw_disable_interruptsfunction ipw_enable_interruptsfunction ipw_disable_interruptsfunction ipw_dump_error_logfunction ipw_is_initfunction ipw_get_ordinalfunction ipw_init_ordinalsfunction ipw_register_togglefunction ipw_led_link_onfunction ipw_bg_led_link_onfunction ipw_led_link_offfunction ipw_bg_led_link_offfunction __ipw_led_activity_onfunction ipw_led_activity_onfunction ipw_led_activity_offfunction ipw_bg_led_activity_offfunction ipw_led_band_onfunction ipw_led_band_offfunction ipw_led_radio_onfunction ipw_led_radio_offfunction ipw_led_link_upfunction ipw_led_link_down
Annotated Snippet
static ssize_t debug_level_show(struct device_driver *d, char *buf)
{
return sprintf(buf, "0x%08X\n", ipw_debug_level);
}
static ssize_t debug_level_store(struct device_driver *d, const char *buf,
size_t count)
{
unsigned long val;
int result = kstrtoul(buf, 0, &val);
if (result == -EINVAL)
printk(KERN_INFO DRV_NAME
": %s is not in hex or decimal form.\n", buf);
else if (result == -ERANGE)
printk(KERN_INFO DRV_NAME
": %s has overflowed.\n", buf);
else
ipw_debug_level = val;
return count;
}
static DRIVER_ATTR_RW(debug_level);
static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
{
/* length = 1st dword in log */
return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
}
static void ipw_capture_event_log(struct ipw_priv *priv,
u32 log_len, struct ipw_event *log)
{
u32 base;
if (log_len) {
base = ipw_read32(priv, IPW_EVENT_LOG);
ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),
(u8 *) log, sizeof(*log) * log_len);
}
}
static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
{
struct ipw_fw_error *error;
u32 log_len = ipw_get_event_log_len(priv);
u32 base = ipw_read32(priv, IPW_ERROR_LOG);
u32 elem_len = ipw_read_reg32(priv, base);
error = kmalloc(size_add(struct_size(error, elem, elem_len),
array_size(sizeof(*error->log), log_len)),
GFP_ATOMIC);
if (!error) {
IPW_ERROR("Memory allocation for firmware error log "
"failed.\n");
return NULL;
}
error->jiffies = jiffies;
error->status = priv->status;
error->config = priv->config;
error->elem_len = elem_len;
error->log_len = log_len;
error->log = (struct ipw_event *)(error->elem + elem_len);
ipw_capture_event_log(priv, log_len, error->log);
if (elem_len)
ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,
sizeof(*error->elem) * elem_len);
return error;
}
static ssize_t event_log_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct ipw_priv *priv = dev_get_drvdata(d);
u32 log_len = ipw_get_event_log_len(priv);
u32 log_size;
struct ipw_event *log;
u32 len = 0, i;
/* not using min() because of its strict type checking */
log_size = PAGE_SIZE / sizeof(*log) > log_len ?
sizeof(*log) * log_len : PAGE_SIZE;
log = kzalloc(log_size, GFP_KERNEL);
if (!log) {
IPW_ERROR("Unable to allocate memory for log\n");
return 0;
Annotation
- Immediate include surface: `linux/sched.h`, `linux/slab.h`, `net/cfg80211-wext.h`, `ipw2200.h`, `ipw.h`.
- Detected declarations: `struct fw_chunk`, `struct ipw_fw`, `struct ipw_status_code`, `struct ipw_network_match`, `function snprint_line`, `function printk_buf`, `function snprintk_buf`, `function ipw_write_reg8`, `function ipw_write_reg16`, `function ipw_write_reg32`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.