drivers/s390/char/sclp_sdias.c

Source file repositories/reference/linux-study-clean/drivers/s390/char/sclp_sdias.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/char/sclp_sdias.c
Extension
.c
Size
6694 bytes
Lines
277
Domain
Driver Families
Bucket
drivers/s390
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 (rc) {
			/* not initiated, wait some time and retry */
			set_current_state(TASK_INTERRUPTIBLE);
			TRACE("add request failed: rc = %i\n",rc);
			schedule_timeout(msecs_to_jiffies(500));
			continue;
		}
		/* initiated, wait for completion of service call */
		wait_for_completion(&evbuf_accepted);
		if (req->status == SCLP_REQ_FAILED) {
			TRACE("sclp request failed\n");
			continue;
		}
		/* if not accepted, retry */
		if (!(sccb->evbuf.hdr.flags & 0x80)) {
			TRACE("sclp request failed: flags=%x\n",
			      sccb->evbuf.hdr.flags);
			continue;
		}
		/*
		 * for the sync interface the response is in the initial sccb
		 */
		if (!sclp_sdias_register.receiver_fn) {
			memcpy(&sdias_evbuf, &sccb->evbuf, sizeof(sdias_evbuf));
			TRACE("sync request done\n");
			return 0;
		}
		/* otherwise we wait for completion */
		wait_for_completion(&evbuf_done);
		TRACE("request done\n");
		return 0;
	}
	return -EIO;
}

/*
 * Get number of blocks (4K) available in the HSA
 */
int sclp_sdias_blk_count(void)
{
	struct sdias_sccb *sccb = sclp_sdias_sccb;
	struct sclp_req request;
	int rc;

	mutex_lock(&sdias_mutex);

	memset(sccb, 0, sizeof(*sccb));
	memset(&request, 0, sizeof(request));

	sccb->hdr.length = sizeof(*sccb);
	sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf);
	sccb->evbuf.hdr.type = EVTYP_SDIAS;
	sccb->evbuf.event_qual = SDIAS_EQ_SIZE;
	sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP;
	sccb->evbuf.event_id = 4712;
	sccb->evbuf.dbs = 1;

	request.sccb = sccb;
	request.command = SCLP_CMDW_WRITE_EVENT_DATA;
	request.status = SCLP_REQ_FILLED;
	request.callback = sdias_callback;

	rc = sdias_sclp_send(&request);
	if (rc) {
		pr_err("sclp_send failed for get_nr_blocks\n");
		goto out;
	}
	if (sccb->hdr.response_code != 0x0020) {
		TRACE("send failed: %x\n", sccb->hdr.response_code);
		rc = -EIO;
		goto out;
	}

	switch (sdias_evbuf.event_status) {
		case 0:
			rc = sdias_evbuf.blk_cnt;
			break;
		default:
			pr_err("SCLP error: %x\n", sdias_evbuf.event_status);
			rc = -EIO;
			goto out;
	}
	TRACE("%i blocks\n", rc);
out:
	mutex_unlock(&sdias_mutex);
	return rc;
}

/*
 * Copy from HSA to absolute storage (not reentrant):

Annotation

Implementation Notes