drivers/scsi/libsas/sas_scsi_host.c

Source file repositories/reference/linux-study-clean/drivers/scsi/libsas/sas_scsi_host.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/libsas/sas_scsi_host.c
Extension
.c
Size
32445 bytes
Lines
1245
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (ts->stat) {
		case SAS_DEV_NO_RESPONSE:
		case SAS_INTERRUPTED:
		case SAS_PHY_DOWN:
		case SAS_NAK_R_ERR:
		case SAS_OPEN_TO:
			hs = DID_NO_CONNECT;
			break;
		case SAS_DATA_UNDERRUN:
			scsi_set_resid(sc, ts->residual);
			if (scsi_bufflen(sc) - scsi_get_resid(sc) < sc->underflow)
				hs = DID_ERROR;
			break;
		case SAS_DATA_OVERRUN:
			hs = DID_ERROR;
			break;
		case SAS_QUEUE_FULL:
			hs = DID_SOFT_ERROR; /* retry */
			break;
		case SAS_DEVICE_UNKNOWN:
			hs = DID_BAD_TARGET;
			break;
		case SAS_OPEN_REJECT:
			if (ts->open_rej_reason == SAS_OREJ_RSVD_RETRY)
				hs = DID_SOFT_ERROR; /* retry */
			else
				hs = DID_ERROR;
			break;
		case SAS_PROTO_RESPONSE:
			pr_notice("LLDD:%s sent SAS_PROTO_RESP for an SSP task; please report this\n",
				  task->dev->port->ha->sas_ha_name);
			break;
		case SAS_ABORTED_TASK:
			hs = DID_ABORT;
			break;
		case SAS_SAM_STAT_CHECK_CONDITION:
			memcpy(sc->sense_buffer, ts->buf,
			       min(SCSI_SENSE_BUFFERSIZE, ts->buf_valid_size));
			stat = SAS_SAM_STAT_CHECK_CONDITION;
			break;
		default:
			stat = ts->stat;
			break;
		}
	}

	sc->result = (hs << 16) | stat;
	ASSIGN_SAS_TASK(sc, NULL);
	sas_free_task(task);
}

static void sas_scsi_task_done(struct sas_task *task)
{
	struct scsi_cmnd *sc = task->uldd_task;
	struct domain_device *dev = task->dev;
	struct sas_ha_struct *ha = dev->port->ha;
	unsigned long flags;

	spin_lock_irqsave(&dev->done_lock, flags);
	if (test_bit(SAS_HA_FROZEN, &ha->state))
		task = NULL;
	else
		ASSIGN_SAS_TASK(sc, NULL);
	spin_unlock_irqrestore(&dev->done_lock, flags);

	if (unlikely(!task)) {
		/* task will be completed by the error handler */
		pr_debug("task done but aborted\n");
		return;
	}

	if (unlikely(!sc)) {
		pr_debug("task_done called with non existing SCSI cmnd!\n");
		sas_free_task(task);
		return;
	}

	sas_end_task(sc, task);
	scsi_done(sc);
}

static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
					       struct domain_device *dev,
					       gfp_t gfp_flags)
{
	struct sas_task *task = sas_alloc_task(gfp_flags);
	struct scsi_lun lun;

	if (!task)
		return NULL;

Annotation

Implementation Notes