drivers/scsi/elx/efct/efct_scsi.c

Source file repositories/reference/linux-study-clean/drivers/scsi/elx/efct/efct_scsi.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/elx/efct/efct_scsi.c
Extension
.c
Size
29241 bytes
Lines
1158
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

switch (ext_status) {
		case SLI4_FC_LOCAL_REJECT_INVALID_RELOFFSET:
		case SLI4_FC_LOCAL_REJECT_ABORT_REQUESTED:
			scsi_stat = EFCT_SCSI_STATUS_ABORTED;
			break;
		case SLI4_FC_LOCAL_REJECT_INVALID_RPI:
			scsi_stat = EFCT_SCSI_STATUS_NEXUS_LOST;
			break;
		case SLI4_FC_LOCAL_REJECT_NO_XRI:
			scsi_stat = EFCT_SCSI_STATUS_NO_IO;
			break;
		default:
			/*we have seen 0x0d(TX_DMA_FAILED err)*/
			scsi_stat = EFCT_SCSI_STATUS_ERROR;
			break;
		}
		break;

	case SLI4_FC_WCQE_STATUS_TARGET_WQE_TIMEOUT:
		/* target IO timed out */
		scsi_stat = EFCT_SCSI_STATUS_TIMEDOUT_AND_ABORTED;
		break;

	case SLI4_FC_WCQE_STATUS_SHUTDOWN:
		/* Target IO cancelled by HW */
		scsi_stat = EFCT_SCSI_STATUS_SHUTDOWN;
		break;

	default:
		scsi_stat = EFCT_SCSI_STATUS_ERROR;
		break;
	}

	cb(io, scsi_stat, flags, io->scsi_tgt_cb_arg);

	efct_scsi_check_pending(efct);
}

static int
efct_scsi_build_sgls(struct efct_hw *hw, struct efct_hw_io *hio,
		     struct efct_scsi_sgl *sgl, u32 sgl_count,
		     enum efct_hw_io_type type)
{
	int rc;
	u32 i;
	struct efct *efct = hw->os;

	/* Initialize HW SGL */
	rc = efct_hw_io_init_sges(hw, hio, type);
	if (rc) {
		efc_log_err(efct, "efct_hw_io_init_sges failed: %d\n", rc);
		return -EIO;
	}

	for (i = 0; i < sgl_count; i++) {
		/* Add data SGE */
		rc = efct_hw_io_add_sge(hw, hio, sgl[i].addr, sgl[i].len);
		if (rc) {
			efc_log_err(efct, "add sge failed cnt=%d rc=%d\n",
				    sgl_count, rc);
			return rc;
		}
	}

	return 0;
}

static void efc_log_sgl(struct efct_io *io)
{
	struct efct_hw_io *hio = io->hio;
	struct sli4_sge *data = NULL;
	u32 *dword = NULL;
	u32 i;
	u32 n_sge;

	scsi_io_trace(io, "def_sgl at 0x%x 0x%08x\n",
		      upper_32_bits(hio->def_sgl.phys),
		      lower_32_bits(hio->def_sgl.phys));
	n_sge = (hio->sgl == &hio->def_sgl) ? hio->n_sge : hio->def_sgl_count;
	for (i = 0, data = hio->def_sgl.virt; i < n_sge; i++, data++) {
		dword = (u32 *)data;

		scsi_io_trace(io, "SGL %2d 0x%08x 0x%08x 0x%08x 0x%08x\n",
			      i, dword[0], dword[1], dword[2], dword[3]);

		if (dword[2] & (1U << 31))
			break;
	}
}

Annotation

Implementation Notes