drivers/net/ipa/ipa_qmi.c
Source file repositories/reference/linux-study-clean/drivers/net/ipa/ipa_qmi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ipa/ipa_qmi.c- Extension
.c- Size
- 17804 bytes
- Lines
- 534
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/qrtr.hlinux/string.hlinux/types.hipa.hipa_mem.hipa_modem.hipa_qmi_msg.h
Detected Declarations
function sofunction ipa_qmi_indicationfunction everythingfunction ipa_server_byefunction ipa_server_indication_registerfunction ipa_server_driver_init_completefunction ipa_client_init_driverfunction init_modem_driver_reqfunction ipa_client_init_driver_workfunction ipa_client_new_serverfunction ipa_qmi_setupfunction ipa_qmi_teardown
Annotated Snippet
if (mem->size) {
req.hw_stats_quota_base_addr_valid = 1;
req.hw_stats_quota_base_addr =
ipa->mem_offset + mem->offset;
req.hw_stats_quota_size_valid = 1;
req.hw_stats_quota_size = ipa->mem_offset + mem->size;
}
/* If the DROP stats region is defined, include it */
mem = ipa_mem_find(ipa, IPA_MEM_STATS_DROP);
if (mem && mem->size) {
req.hw_stats_drop_base_addr_valid = 1;
req.hw_stats_drop_base_addr =
ipa->mem_offset + mem->offset;
req.hw_stats_drop_size_valid = 1;
req.hw_stats_drop_size = ipa->mem_offset + mem->size;
}
}
return &req;
}
/* Send an INIT_DRIVER request to the modem, and wait for it to complete. */
static void ipa_client_init_driver_work(struct work_struct *work)
{
unsigned long timeout = msecs_to_jiffies(QMI_INIT_DRIVER_TIMEOUT);
const struct ipa_init_modem_driver_req *req;
struct ipa_qmi *ipa_qmi;
struct qmi_handle *qmi;
struct qmi_txn txn;
struct device *dev;
struct ipa *ipa;
int ret;
ipa_qmi = container_of(work, struct ipa_qmi, init_driver_work);
qmi = &ipa_qmi->client_handle;
ipa = container_of(ipa_qmi, struct ipa, qmi);
dev = ipa->dev;
ret = qmi_txn_init(qmi, &txn, NULL, NULL);
if (ret < 0) {
dev_err(dev, "error %d preparing init driver request\n", ret);
return;
}
/* Send the request, and if successful wait for its response */
req = init_modem_driver_req(ipa_qmi);
ret = qmi_send_request(qmi, &ipa_qmi->modem_sq, &txn,
IPA_QMI_INIT_DRIVER, IPA_QMI_INIT_DRIVER_REQ_SZ,
ipa_init_modem_driver_req_ei, req);
if (ret)
dev_err(dev, "error %d sending init driver request\n", ret);
else if ((ret = qmi_txn_wait(&txn, timeout)))
dev_err(dev, "error %d awaiting init driver response\n", ret);
if (!ret) {
ipa_qmi->modem_ready = true;
ipa_qmi_ready(ipa_qmi); /* We might be ready now */
} else {
/* If any error occurs we need to cancel the transaction */
qmi_txn_cancel(&txn);
}
}
/* The modem server is now available. We will send an INIT_DRIVER request
* to the modem, but can't wait for it to complete in this callback thread.
* Schedule a worker on the global workqueue to do that for us.
*/
static int
ipa_client_new_server(struct qmi_handle *qmi, struct qmi_service *svc)
{
struct ipa_qmi *ipa_qmi;
ipa_qmi = container_of(qmi, struct ipa_qmi, client_handle);
ipa_qmi->modem_sq.sq_family = AF_QIPCRTR;
ipa_qmi->modem_sq.sq_node = svc->node;
ipa_qmi->modem_sq.sq_port = svc->port;
schedule_work(&ipa_qmi->init_driver_work);
return 0;
}
static const struct qmi_ops ipa_client_ops = {
.new_server = ipa_client_new_server,
};
/* Set up for QMI message exchange */
Annotation
- Immediate include surface: `linux/qrtr.h`, `linux/string.h`, `linux/types.h`, `ipa.h`, `ipa_mem.h`, `ipa_modem.h`, `ipa_qmi_msg.h`.
- Detected declarations: `function so`, `function ipa_qmi_indication`, `function everything`, `function ipa_server_bye`, `function ipa_server_indication_register`, `function ipa_server_driver_init_complete`, `function ipa_client_init_driver`, `function init_modem_driver_req`, `function ipa_client_init_driver_work`, `function ipa_client_new_server`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
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.