drivers/target/iscsi/cxgbit/cxgbit_cm.c

Source file repositories/reference/linux-study-clean/drivers/target/iscsi/cxgbit/cxgbit_cm.c

File Facts

System
Linux kernel
Corpus path
drivers/target/iscsi/cxgbit/cxgbit_cm.c
Extension
.c
Size
48372 bytes
Lines
2019
Domain
Driver Families
Bucket
drivers/target
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 (p->cnp == cnp) {
			stid = p->stid;
			break;
		}
	}
	spin_unlock(&cdev->np_lock);

	return stid;
}

static int cxgbit_np_hash_del(struct cxgbit_device *cdev, struct cxgbit_np *cnp)
{
	int stid = -1, bucket = cxgbit_np_hashfn(cnp);
	struct np_info *p, **prev = &cdev->np_hash_tab[bucket];

	spin_lock(&cdev->np_lock);
	for (p = *prev; p; prev = &p->next, p = p->next) {
		if (p->cnp == cnp) {
			stid = p->stid;
			*prev = p->next;
			kfree(p);
			break;
		}
	}
	spin_unlock(&cdev->np_lock);

	return stid;
}

void _cxgbit_free_cnp(struct kref *kref)
{
	struct cxgbit_np *cnp;

	cnp = container_of(kref, struct cxgbit_np, kref);
	kfree(cnp);
}

static int
cxgbit_create_server6(struct cxgbit_device *cdev, unsigned int stid,
		      struct cxgbit_np *cnp)
{
	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)
				     &cnp->com.local_addr;
	int addr_type;
	int ret;

	pr_debug("%s: dev = %s; stid = %u; sin6_port = %u\n",
		 __func__, cdev->lldi.ports[0]->name, stid, sin6->sin6_port);

	addr_type = ipv6_addr_type((const struct in6_addr *)
				   &sin6->sin6_addr);
	if (addr_type != IPV6_ADDR_ANY) {
		ret = cxgb4_clip_get(cdev->lldi.ports[0],
				     (const u32 *)&sin6->sin6_addr.s6_addr, 1);
		if (ret) {
			pr_err("Unable to find clip table entry. laddr %pI6. Error:%d.\n",
			       sin6->sin6_addr.s6_addr, ret);
			return -ENOMEM;
		}
	}

	cxgbit_get_cnp(cnp);
	cxgbit_init_wr_wait(&cnp->com.wr_wait);

	ret = cxgb4_create_server6(cdev->lldi.ports[0],
				   stid, &sin6->sin6_addr,
				   sin6->sin6_port,
				   cdev->lldi.rxq_ids[0]);
	if (!ret)
		ret = cxgbit_wait_for_reply(cdev, &cnp->com.wr_wait,
					    0, 10, __func__);
	else if (ret > 0)
		ret = net_xmit_errno(ret);
	else
		cxgbit_put_cnp(cnp);

	if (ret) {
		if (ret != -ETIMEDOUT)
			cxgb4_clip_release(cdev->lldi.ports[0],
				   (const u32 *)&sin6->sin6_addr.s6_addr, 1);

		pr_err("create server6 err %d stid %d laddr %pI6 lport %d\n",
		       ret, stid, sin6->sin6_addr.s6_addr,
		       ntohs(sin6->sin6_port));
	}

	return ret;
}

static int

Annotation

Implementation Notes