drivers/scsi/snic/snic_scsi.c

Source file repositories/reference/linux-study-clean/drivers/scsi/snic/snic_scsi.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/snic/snic_scsi.c
Extension
.c
Size
67201 bytes
Lines
2638
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

for_each_sg(scsi_sglist(sc), sg, sg_cnt, i) {
			sgd->addr = cpu_to_le64(sg_dma_address(sg));
			sgd->len = cpu_to_le32(sg_dma_len(sg));
			sgd->_resvd = 0;
			sgd++;
		}
	}

	pa = dma_map_single(&snic->pdev->dev,
			    sc->sense_buffer,
			    SCSI_SENSE_BUFFERSIZE,
			    DMA_FROM_DEVICE);
	if (dma_mapping_error(&snic->pdev->dev, pa)) {
		SNIC_HOST_ERR(snic->shost,
			      "QIcmnd:PCI Map Failed for sns buf %p tag %x\n",
			      sc->sense_buffer, snic_cmd_tag(sc));
		ret = -ENOMEM;

		return ret;
	}

	int_to_scsilun(sc->device->lun, &lun);
	if (sc->sc_data_direction == DMA_FROM_DEVICE)
		flags |= SNIC_ICMND_RD;
	if (sc->sc_data_direction == DMA_TO_DEVICE)
		flags |= SNIC_ICMND_WR;

	/* Initialize icmnd */
	snic_icmnd_init(rqi->req,
			snic_cmd_tag(sc),
			snic->config.hid, /* hid */
			(ulong) rqi,
			flags, /* command flags */
			rqi->tgt_id,
			lun.scsi_lun,
			sc->cmnd,
			sc->cmd_len,
			scsi_bufflen(sc),
			sg_cnt,
			(ulong) req_to_sgl(rqi->req),
			pa, /* sense buffer pa */
			SCSI_SENSE_BUFFERSIZE);

	atomic64_inc(&snic->s_stats.io.active);
	ret = snic_queue_wq_desc(snic, rqi->req, rqi->req_len);
	if (ret) {
		atomic64_dec(&snic->s_stats.io.active);
		SNIC_HOST_ERR(snic->shost,
			      "QIcmnd: Queuing Icmnd Failed. ret = %d\n",
			      ret);
	} else
		snic_stats_update_active_ios(&snic->s_stats);

	return ret;
} /* end of snic_queue_icmnd_req */

/*
 * snic_issue_scsi_req : Prepares IO request and Issues to FW.
 */
static int
snic_issue_scsi_req(struct snic *snic,
		      struct snic_tgt *tgt,
		      struct scsi_cmnd *sc)
{
	struct snic_req_info *rqi = NULL;
	int sg_cnt = 0;
	int ret = 0;
	u32 tag = snic_cmd_tag(sc);
	u64 cmd_trc = 0, cmd_st_flags = 0;
	spinlock_t *io_lock = NULL;
	unsigned long flags;

	CMD_STATE(sc) = SNIC_IOREQ_NOT_INITED;
	CMD_FLAGS(sc) = SNIC_NO_FLAGS;
	sg_cnt = scsi_dma_map(sc);
	if (sg_cnt < 0) {
		SNIC_TRC((u16)snic->shost->host_no, tag, (ulong) sc, 0,
			 sc->cmnd[0], sg_cnt, CMD_STATE(sc));

		SNIC_HOST_ERR(snic->shost, "issue_sc:Failed to map SG List.\n");
		ret = -ENOMEM;

		goto issue_sc_end;
	}

	rqi = snic_req_init(snic, sg_cnt);
	if (!rqi) {
		scsi_dma_unmap(sc);
		ret = -ENOMEM;

Annotation

Implementation Notes