net/qrtr/mhi.c
Source file repositories/reference/linux-study-clean/net/qrtr/mhi.c
File Facts
- System
- Linux kernel
- Corpus path
net/qrtr/mhi.c- Extension
.c- Size
- 5458 bytes
- Lines
- 231
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: implementation source
- Status
- source implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- 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/mhi.hlinux/mod_devicetable.hlinux/module.hlinux/skbuff.hnet/sock.hqrtr.h
Detected Declarations
struct qrtr_mhi_devfunction qcom_mhi_qrtr_dl_callbackfunction qcom_mhi_qrtr_ul_callbackfunction qcom_mhi_qrtr_sendfunction qcom_mhi_qrtr_queue_dl_buffersfunction qcom_mhi_qrtr_probefunction qcom_mhi_qrtr_removefunction qcom_mhi_qrtr_pm_suspend_latefunction qcom_mhi_qrtr_pm_resume_early
Annotated Snippet
struct qrtr_mhi_dev {
struct qrtr_endpoint ep;
struct mhi_device *mhi_dev;
struct device *dev;
};
/* From MHI to QRTR */
static void qcom_mhi_qrtr_dl_callback(struct mhi_device *mhi_dev,
struct mhi_result *mhi_res)
{
struct qrtr_mhi_dev *qdev = dev_get_drvdata(&mhi_dev->dev);
int rc;
if (!qdev || (mhi_res->transaction_status && mhi_res->transaction_status != -ENOTCONN))
return;
/* Channel got reset. So just free the buffer */
if (mhi_res->transaction_status == -ENOTCONN) {
devm_kfree(&mhi_dev->dev, mhi_res->buf_addr);
return;
}
rc = qrtr_endpoint_post(&qdev->ep, mhi_res->buf_addr,
mhi_res->bytes_xferd);
if (rc == -EINVAL)
dev_err(qdev->dev, "invalid ipcrouter packet\n");
/* Done with the buffer, now recycle it for future use */
rc = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, mhi_res->buf_addr,
mhi_dev->mhi_cntrl->buffer_len, MHI_EOT);
if (rc)
dev_err(&mhi_dev->dev, "Failed to recycle the buffer: %d\n", rc);
}
/* From QRTR to MHI */
static void qcom_mhi_qrtr_ul_callback(struct mhi_device *mhi_dev,
struct mhi_result *mhi_res)
{
struct sk_buff *skb = mhi_res->buf_addr;
if (skb->sk)
sock_put(skb->sk);
consume_skb(skb);
}
/* Send data over MHI */
static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
{
struct qrtr_mhi_dev *qdev = container_of(ep, struct qrtr_mhi_dev, ep);
int rc;
if (skb->sk)
sock_hold(skb->sk);
rc = skb_linearize(skb);
if (rc)
goto free_skb;
rc = mhi_queue_skb(qdev->mhi_dev, DMA_TO_DEVICE, skb, skb->len,
MHI_EOT);
if (rc)
goto free_skb;
return rc;
free_skb:
if (skb->sk)
sock_put(skb->sk);
kfree_skb(skb);
return rc;
}
static int qcom_mhi_qrtr_queue_dl_buffers(struct mhi_device *mhi_dev)
{
u32 free_desc;
void *buf;
int ret;
free_desc = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE);
while (free_desc--) {
buf = devm_kmalloc(&mhi_dev->dev, mhi_dev->mhi_cntrl->buffer_len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, buf, mhi_dev->mhi_cntrl->buffer_len,
MHI_EOT);
if (ret) {
dev_err(&mhi_dev->dev, "Failed to queue buffer: %d\n", ret);
return ret;
Annotation
- Immediate include surface: `linux/mhi.h`, `linux/mod_devicetable.h`, `linux/module.h`, `linux/skbuff.h`, `net/sock.h`, `qrtr.h`.
- Detected declarations: `struct qrtr_mhi_dev`, `function qcom_mhi_qrtr_dl_callback`, `function qcom_mhi_qrtr_ul_callback`, `function qcom_mhi_qrtr_send`, `function qcom_mhi_qrtr_queue_dl_buffers`, `function qcom_mhi_qrtr_probe`, `function qcom_mhi_qrtr_remove`, `function qcom_mhi_qrtr_pm_suspend_late`, `function qcom_mhi_qrtr_pm_resume_early`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- 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.