drivers/cdx/controller/mcdi.c
Source file repositories/reference/linux-study-clean/drivers/cdx/controller/mcdi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/cdx/controller/mcdi.c- Extension
.c- Size
- 23274 bytes
- Lines
- 871
- Domain
- Driver Families
- Bucket
- drivers/cdx
- 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/delay.hlinux/slab.hlinux/io.hlinux/spinlock.hlinux/netdevice.hlinux/etherdevice.hlinux/ethtool.hlinux/if_vlan.hlinux/timer.hlinux/list.hlinux/pci.hlinux/device.hlinux/rwsem.hlinux/vmalloc.hnet/netevent.hlinux/log2.hlinux/net_tstamp.hlinux/wait.hlinux/cdx/bitfield.hlinux/cdx/mcdi.hmcdid.h
Detected Declarations
struct cdx_mcdi_blocking_datafunction cdx_cmd_cancelledfunction cdx_mcdi_cmd_releasefunction cdx_mcdi_cmd_handlefunction _cdx_mcdi_remove_cmdfunction cdx_mcdi_remove_cmdfunction cdx_mcdi_rpc_timeoutfunction cdx_mcdi_initfunction MCDIfunction cdx_mcdi_flushedfunction cdx_mcdi_wait_for_cleanupfunction cdx_mcdi_wait_for_quiescencefunction cdx_mcdi_payload_csumfunction cdx_mcdi_send_requestfunction cdx_mcdi_errnofunction cdx_mcdi_process_cleanup_listfunction _cdx_mcdi_cancel_cmdfunction list_for_each_entryfunction cdx_mcdi_cancel_cmdfunction cdx_mcdi_blocking_data_releasefunction cdx_mcdi_rpc_completerfunction cdx_mcdi_rpc_syncfunction cdx_mcdi_get_seqfunction cdx_mcdi_rpc_async_internalfunction cdx_mcdi_cmd_start_or_queuefunction cdx_mcdi_start_or_queuefunction cdx_mcdi_process_cmdfunction cdx_mcdi_cmd_workfunction cdx_mcdi_complete_cmdfunction cdx_mcdi_timeout_cmdfunction cdx_mcdi_rpcfunction cdx_mcdi_rpc_asyncfunction _cdx_mcdi_display_errorfunction cdx_mcdi_mode_failexport cdx_mcdi_initexport cdx_mcdi_finishexport cdx_mcdi_process_cmdexport cdx_mcdi_rpc
Annotated Snippet
struct cdx_mcdi_blocking_data {
struct kref ref;
bool done;
wait_queue_head_t wq;
int rc;
struct cdx_dword *outbuf;
size_t outlen;
size_t outlen_actual;
};
static void cdx_mcdi_blocking_data_release(struct kref *ref)
{
kfree(container_of(ref, struct cdx_mcdi_blocking_data, ref));
}
static void cdx_mcdi_rpc_completer(struct cdx_mcdi *cdx, unsigned long cookie,
int rc, struct cdx_dword *outbuf,
size_t outlen_actual)
{
struct cdx_mcdi_blocking_data *wait_data =
(struct cdx_mcdi_blocking_data *)cookie;
wait_data->rc = rc;
memcpy(wait_data->outbuf, outbuf,
min(outlen_actual, wait_data->outlen));
wait_data->outlen_actual = outlen_actual;
/* memory barrier */
smp_wmb();
wait_data->done = true;
wake_up(&wait_data->wq);
kref_put(&wait_data->ref, cdx_mcdi_blocking_data_release);
}
static int cdx_mcdi_rpc_sync(struct cdx_mcdi *cdx, unsigned int cmd,
const struct cdx_dword *inbuf, size_t inlen,
struct cdx_dword *outbuf, size_t outlen,
size_t *outlen_actual, bool quiet)
{
struct cdx_mcdi_blocking_data *wait_data;
struct cdx_mcdi_cmd *cmd_item;
unsigned int handle;
int rc;
if (outlen_actual)
*outlen_actual = 0;
wait_data = kmalloc_obj(*wait_data);
if (!wait_data)
return -ENOMEM;
cmd_item = kmalloc_obj(*cmd_item);
if (!cmd_item) {
kfree(wait_data);
return -ENOMEM;
}
kref_init(&wait_data->ref);
wait_data->done = false;
init_waitqueue_head(&wait_data->wq);
wait_data->outbuf = outbuf;
wait_data->outlen = outlen;
kref_init(&cmd_item->ref);
cmd_item->quiet = quiet;
cmd_item->cookie = (unsigned long)wait_data;
cmd_item->completer = &cdx_mcdi_rpc_completer;
cmd_item->cmd = cmd;
cmd_item->inlen = inlen;
cmd_item->inbuf = inbuf;
/* Claim an extra reference for the completer to put. */
kref_get(&wait_data->ref);
rc = cdx_mcdi_rpc_async_internal(cdx, cmd_item, &handle);
if (rc) {
kref_put(&wait_data->ref, cdx_mcdi_blocking_data_release);
goto out;
}
if (!wait_event_timeout(wait_data->wq, wait_data->done,
cdx_mcdi_rpc_timeout(cdx, cmd)) &&
!wait_data->done) {
pr_err("MC command 0x%x inlen %zu timed out (sync)\n",
cmd, inlen);
cdx_mcdi_cancel_cmd(cdx, cmd_item);
wait_data->rc = -ETIMEDOUT;
wait_data->outlen_actual = 0;
}
Annotation
- Immediate include surface: `linux/delay.h`, `linux/slab.h`, `linux/io.h`, `linux/spinlock.h`, `linux/netdevice.h`, `linux/etherdevice.h`, `linux/ethtool.h`, `linux/if_vlan.h`.
- Detected declarations: `struct cdx_mcdi_blocking_data`, `function cdx_cmd_cancelled`, `function cdx_mcdi_cmd_release`, `function cdx_mcdi_cmd_handle`, `function _cdx_mcdi_remove_cmd`, `function cdx_mcdi_remove_cmd`, `function cdx_mcdi_rpc_timeout`, `function cdx_mcdi_init`, `function MCDI`, `function cdx_mcdi_flushed`.
- Atlas domain: Driver Families / drivers/cdx.
- 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.