drivers/firewire/core-card.c
Source file repositories/reference/linux-study-clean/drivers/firewire/core-card.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/firewire/core-card.c- Extension
.c- Size
- 26102 bytes
- Lines
- 838
- Domain
- Driver Families
- Bucket
- drivers/firewire
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bug.hlinux/completion.hlinux/crc-itu-t.hlinux/device.hlinux/errno.hlinux/firewire.hlinux/firewire-constants.hlinux/jiffies.hlinux/kernel.hlinux/kref.hlinux/list.hlinux/module.hlinux/mutex.hlinux/spinlock.hlinux/workqueue.hlinux/atomic.hasm/byteorder.hcore.htrace/events/firewire.h
Detected Declarations
enum bm_contention_outcomefunction fw_compute_block_crcfunction generate_config_romfunction update_config_romsfunction list_for_each_entryfunction required_spacefunction fw_core_add_descriptorfunction fw_core_remove_descriptorfunction reset_busfunction fw_schedule_bus_resetfunction br_workfunction time_is_after_jiffies64function allocate_broadcast_channelfunction fw_schedule_bm_workfunction contend_for_bmfunction bm_workfunction fw_card_initializefunction fw_card_addfunction scoped_guardfunction handledfunction dummy_update_phy_regfunction dummy_send_requestfunction dummy_send_responsefunction dummy_cancel_packetfunction dummy_enable_phys_dmafunction dummy_read_csrfunction dummy_write_csrfunction dummy_set_iso_channelsfunction dummy_queue_isofunction dummy_flush_queue_isofunction fw_card_releasefunction fw_core_remove_cardfunction fw_card_read_cycle_timeexport fw_core_add_descriptorexport fw_core_remove_descriptorexport fw_schedule_bus_resetexport fw_card_initializeexport fw_card_addexport fw_card_releaseexport fw_core_remove_cardexport fw_card_read_cycle_time
Annotated Snippet
time_is_after_jiffies64(card->reset_jiffies + secs_to_jiffies(2))) {
trace_bus_reset_postpone(card->index, card->generation, card->br_short);
if (!queue_delayed_work(fw_workqueue, &card->br_work, secs_to_jiffies(2)))
fw_card_put(card);
return;
}
fw_send_phy_config(card, FW_PHY_CONFIG_NO_NODE_ID, card->generation,
FW_PHY_CONFIG_CURRENT_GAP_COUNT);
reset_bus(card, card->br_short);
fw_card_put(card);
}
static void allocate_broadcast_channel(struct fw_card *card, int generation)
{
int channel, bandwidth = 0;
if (!card->broadcast_channel_allocated) {
fw_iso_resource_manage(card, generation, 1ULL << 31,
&channel, &bandwidth, true);
if (channel != 31) {
fw_notice(card, "failed to allocate broadcast channel\n");
return;
}
card->broadcast_channel_allocated = true;
}
device_for_each_child(card->device, (void *)(long)generation,
fw_device_set_broadcast_channel);
}
void fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
{
fw_card_get(card);
if (!schedule_delayed_work(&card->bm_work, delay))
fw_card_put(card);
}
enum bm_contention_outcome {
// The bus management contention window is not expired.
BM_CONTENTION_OUTCOME_WITHIN_WINDOW = 0,
// The IRM node has link off.
BM_CONTENTION_OUTCOME_IRM_HAS_LINK_OFF,
// The IRM node complies IEEE 1394:1994 only.
BM_CONTENTION_OUTCOME_IRM_COMPLIES_1394_1995_ONLY,
// Another bus reset, BM work has been rescheduled.
BM_CONTENTION_OUTCOME_AT_NEW_GENERATION,
// We have been unable to send the lock request to IRM node due to some local problem.
BM_CONTENTION_OUTCOME_LOCAL_PROBLEM_AT_TRANSACTION,
// The lock request failed, maybe the IRM isn't really IRM capable after all.
BM_CONTENTION_OUTCOME_IRM_IS_NOT_CAPABLE_FOR_IRM,
// Somebody else is BM.
BM_CONTENTION_OUTCOME_IRM_HOLDS_ANOTHER_NODE_AS_BM,
// The local node succeeds after contending for bus manager.
BM_CONTENTION_OUTCOME_IRM_HOLDS_LOCAL_NODE_AS_BM,
};
static enum bm_contention_outcome contend_for_bm(struct fw_card *card)
__must_hold(&card->lock)
{
int generation = card->generation;
int local_id = card->local_node->node_id;
__be32 data[2] = {
cpu_to_be32(BUS_MANAGER_ID_NOT_REGISTERED),
cpu_to_be32(local_id),
};
bool grace = time_is_before_jiffies64(card->reset_jiffies + msecs_to_jiffies(125));
struct fw_node *irm_node;
struct fw_device *irm_device;
int irm_node_id, irm_device_quirks = 0;
int rcode;
lockdep_assert_held(&card->lock);
if (!grace) {
if (!is_next_generation(generation, card->bm_generation) || card->bm_abdicate)
return BM_CONTENTION_OUTCOME_WITHIN_WINDOW;
}
irm_node = card->irm_node;
if (!irm_node->link_on) {
fw_notice(card, "IRM has link off, making local node (%02x) root\n", local_id);
return BM_CONTENTION_OUTCOME_IRM_HAS_LINK_OFF;
}
// NOTE: It is likely that the quirk detection for IRM device has not done yet.
irm_device = fw_node_get_device(irm_node);
if (irm_device)
irm_device_quirks = READ_ONCE(irm_device->quirks);
Annotation
- Immediate include surface: `linux/bug.h`, `linux/completion.h`, `linux/crc-itu-t.h`, `linux/device.h`, `linux/errno.h`, `linux/firewire.h`, `linux/firewire-constants.h`, `linux/jiffies.h`.
- Detected declarations: `enum bm_contention_outcome`, `function fw_compute_block_crc`, `function generate_config_rom`, `function update_config_roms`, `function list_for_each_entry`, `function required_space`, `function fw_core_add_descriptor`, `function fw_core_remove_descriptor`, `function reset_bus`, `function fw_schedule_bus_reset`.
- Atlas domain: Driver Families / drivers/firewire.
- 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.