drivers/scsi/qla2xxx/qla_inline.h

Source file repositories/reference/linux-study-clean/drivers/scsi/qla2xxx/qla_inline.h

File Facts

System
Linux kernel
Corpus path
drivers/scsi/qla2xxx/qla_inline.h
Extension
.h
Size
14762 bytes
Lines
641
Domain
Driver Families
Bucket
drivers/scsi
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 ((iores->iocb_cnt + iocbs_used) >= qp->fwres.iocbs_limit) {
			iores->res_type = RESOURCE_NONE;
			return -ENOSPC;
		}
	}

	if (iores->res_type & RESOURCE_EXCH) {
		exch_used = ha->base_qpair->fwres.exch_used;
		for (i = 0; i < ha->max_qpairs; i++) {
			if (ha->queue_pair_map[i])
				exch_used += ha->queue_pair_map[i]->fwres.exch_used;
		}

		if ((exch_used + iores->exch_cnt) >= qp->fwres.exch_limit) {
			iores->res_type = RESOURCE_NONE;
			return -ENOSPC;
		}
	}

	if (ql2xenforce_iocb_limit == 2) {
		if ((iores->iocb_cnt + atomic_read(&ha->fwres.iocb_used)) >=
		    ha->fwres.iocb_limit) {
			iores->res_type = RESOURCE_NONE;
			return -ENOSPC;
		}

		if (iores->res_type & RESOURCE_EXCH) {
			if ((iores->exch_cnt + atomic_read(&ha->fwres.exch_used)) >=
			    ha->fwres.exch_limit) {
				iores->res_type = RESOURCE_NONE;
				return -ENOSPC;
			}
		}
	}

force:
	qp->fwres.iocbs_used += iores->iocb_cnt;
	qp->fwres.exch_used += iores->exch_cnt;
	if (ql2xenforce_iocb_limit == 2) {
		atomic_add(iores->iocb_cnt, &ha->fwres.iocb_used);
		atomic_add(iores->exch_cnt, &ha->fwres.exch_used);
		iores->res_type |= RESOURCE_HA;
	}
	return 0;
}

/*
 * decrement to zero.  This routine will not decrement below zero
 * @v:  pointer of type atomic_t
 * @amount: amount to decrement from v
 */
static void qla_atomic_dtz(atomic_t *v, int amount)
{
	int c, old, dec;

	c = atomic_read(v);
	for (;;) {
		dec = c - amount;
		if (unlikely(dec < 0))
			dec = 0;

		old = atomic_cmpxchg((v), c, dec);
		if (likely(old == c))
			break;
		c = old;
	}
}

static inline void
qla_put_fw_resources(struct qla_qpair *qp, struct iocb_resource *iores)
{
	struct qla_hw_data *ha = qp->hw;

	if (iores->res_type & RESOURCE_HA) {
		if (iores->res_type & RESOURCE_IOCB)
			qla_atomic_dtz(&ha->fwres.iocb_used, iores->iocb_cnt);

		if (iores->res_type & RESOURCE_EXCH)
			qla_atomic_dtz(&ha->fwres.exch_used, iores->exch_cnt);
	}

	if (iores->res_type & RESOURCE_IOCB) {
		if (qp->fwres.iocbs_used >= iores->iocb_cnt) {
			qp->fwres.iocbs_used -= iores->iocb_cnt;
		} else {
			/* should not happen */
			qp->fwres.iocbs_used = 0;
		}
	}

Annotation

Implementation Notes