drivers/scsi/qla2xxx/qla_init.c

Source file repositories/reference/linux-study-clean/drivers/scsi/qla2xxx/qla_init.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/qla2xxx/qla_init.c
Extension
.c
Size
276702 bytes
Lines
10285
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 (qpair->req->outstanding_cmds[handle] == sp) {
			qpair->req->outstanding_cmds[handle] = NULL;
			sp_found = 1;
			qla_put_fw_resources(qpair, &sp->iores);
			break;
		}
	}
	spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);

	if (cmdsp_found && sp->cmd_sp) {
		/*
		 * This done function should take care of
		 * original command ref: INIT
		 */
		sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
	}

	if (sp_found) {
		abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
		sp->done(sp, QLA_OS_TIMER_EXPIRED);
	}
}

static void qla24xx_abort_sp_done(srb_t *sp, int res)
{
	struct srb_iocb *abt = &sp->u.iocb_cmd;
	srb_t *orig_sp = sp->cmd_sp;

	if (orig_sp)
		qla_wait_nvme_release_cmd_kref(orig_sp);

	if (sp->flags & SRB_WAKEUP_ON_COMP)
		complete(&abt->u.abt.comp);
	else
		/* ref: INIT */
		kref_put(&sp->cmd_kref, qla2x00_sp_release);
}

int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
{
	scsi_qla_host_t *vha = cmd_sp->vha;
	struct srb_iocb *abt_iocb;
	srb_t *sp;
	int rval = QLA_FUNCTION_FAILED;

	/* ref: INIT for ABTS command */
	sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
				  GFP_ATOMIC);
	if (!sp)
		return QLA_MEMORY_ALLOC_FAILED;

	qla_vha_mark_busy(vha);
	abt_iocb = &sp->u.iocb_cmd;
	sp->type = SRB_ABT_CMD;
	sp->name = "abort";
	sp->qpair = cmd_sp->qpair;
	sp->cmd_sp = cmd_sp;
	if (wait)
		sp->flags = SRB_WAKEUP_ON_COMP;

	init_completion(&abt_iocb->u.abt.comp);
	/* FW can send 2 x ABTS's timeout/20s */
	qla2x00_init_async_sp(sp, 42, qla24xx_abort_sp_done);
	sp->u.iocb_cmd.timeout = qla24xx_abort_iocb_timeout;

	abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
	abt_iocb->u.abt.req_que_no = cpu_to_le16(cmd_sp->qpair->req->id);

	ql_dbg(ql_dbg_async, vha, 0x507c,
	       "Abort command issued - hdl=%x, type=%x\n", cmd_sp->handle,
	       cmd_sp->type);

	rval = qla2x00_start_sp(sp);
	if (rval != QLA_SUCCESS) {
		/* ref: INIT */
		kref_put(&sp->cmd_kref, qla2x00_sp_release);
		return rval;
	}

	if (wait) {
		wait_for_completion(&abt_iocb->u.abt.comp);
		rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
			QLA_SUCCESS : QLA_ERR_FROM_FW;
		/* ref: INIT */
		kref_put(&sp->cmd_kref, qla2x00_sp_release);
	}

	return rval;
}

Annotation

Implementation Notes