drivers/infiniband/hw/cxgb4/cm.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/cxgb4/cm.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/cxgb4/cm.c
Extension
.c
Size
121192 bytes
Lines
4477
Domain
Driver Families
Bucket
drivers/infiniband
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!epc->wr_waitp) {
			kfree(epc);
			epc = NULL;
			goto out;
		}
		kref_init(&epc->kref);
		mutex_init(&epc->mutex);
		c4iw_init_wr_wait(epc->wr_waitp);
	}
	pr_debug("alloc ep %p\n", epc);
out:
	return epc;
}

static void remove_ep_tid(struct c4iw_ep *ep)
{
	unsigned long flags;

	xa_lock_irqsave(&ep->com.dev->hwtids, flags);
	__xa_erase(&ep->com.dev->hwtids, ep->hwtid);
	if (xa_empty(&ep->com.dev->hwtids))
		wake_up(&ep->com.dev->wait);
	xa_unlock_irqrestore(&ep->com.dev->hwtids, flags);
}

static int insert_ep_tid(struct c4iw_ep *ep)
{
	unsigned long flags;
	int err;

	xa_lock_irqsave(&ep->com.dev->hwtids, flags);
	err = __xa_insert(&ep->com.dev->hwtids, ep->hwtid, ep, GFP_KERNEL);
	xa_unlock_irqrestore(&ep->com.dev->hwtids, flags);

	return err;
}

/*
 * Atomically lookup the ep ptr given the tid and grab a reference on the ep.
 */
static struct c4iw_ep *get_ep_from_tid(struct c4iw_dev *dev, unsigned int tid)
{
	struct c4iw_ep *ep;
	unsigned long flags;

	xa_lock_irqsave(&dev->hwtids, flags);
	ep = xa_load(&dev->hwtids, tid);
	if (ep)
		c4iw_get_ep(&ep->com);
	xa_unlock_irqrestore(&dev->hwtids, flags);
	return ep;
}

/*
 * Atomically lookup the ep ptr given the stid and grab a reference on the ep.
 */
static struct c4iw_listen_ep *get_ep_from_stid(struct c4iw_dev *dev,
					       unsigned int stid)
{
	struct c4iw_listen_ep *ep;
	unsigned long flags;

	xa_lock_irqsave(&dev->stids, flags);
	ep = xa_load(&dev->stids, stid);
	if (ep)
		c4iw_get_ep(&ep->com);
	xa_unlock_irqrestore(&dev->stids, flags);
	return ep;
}

void _c4iw_free_ep(struct kref *kref)
{
	struct c4iw_ep *ep;

	ep = container_of(kref, struct c4iw_ep, com.kref);
	pr_debug("ep %p state %s\n", ep, states[ep->com.state]);
	if (test_bit(QP_REFERENCED, &ep->com.flags))
		deref_qp(ep);
	if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) {
		if (ep->com.remote_addr.ss_family == AF_INET6) {
			struct sockaddr_in6 *sin6 =
					(struct sockaddr_in6 *)
					&ep->com.local_addr;

			cxgb4_clip_release(
					ep->com.dev->rdev.lldi.ports[0],
					(const u32 *)&sin6->sin6_addr.s6_addr,
					1);
		}
		cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid,

Annotation

Implementation Notes