drivers/misc/mei/pxp/mei_pxp.c

Source file repositories/reference/linux-study-clean/drivers/misc/mei/pxp/mei_pxp.c

File Facts

System
Linux kernel
Corpus path
drivers/misc/mei/pxp/mei_pxp.c
Extension
.c
Size
9175 bytes
Lines
345
Domain
Driver Families
Bucket
drivers/misc
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 (byte) {
		case -ENOMEM:
			fallthrough;
		case -ENODEV:
			fallthrough;
		case -ETIME:
			ret = mei_pxp_reenable(dev, cldev);
			if (ret)
				byte = ret;
			break;
		}
		return byte;
	}

	return 0;
}

/**
 * mei_pxp_receive_message() - Receives a PXP message from ME FW.
 * @dev: device corresponding to the mei_cl_device
 * @buffer: a message buffer to contain the received message
 * @size: size of the buffer
 * @timeout_ms: timeout in milliseconds, zero means wait indefinitely.
 *
 * Returns: number of bytes send on Success, <0 on Failure with the following defined failures.
 *         -ENODEV: Client was not connected.
 *                  Caller may attempt to try again from send immediately.
 *         -ENOMEM: Internal memory allocation failure experienced.
 *                  Caller may sleep to allow kernel reclaim before retrying.
 *         -EINTR : Calling thread received a signal. Caller will need to repeat calling
 *                  (with a different owning thread) to retrieve existing unclaimed response
 *                  (and may discard it).
 *         -ETIME : Request is timed out.
 *                  Caller may attempt to try again from send immediately.
 */
static int
mei_pxp_receive_message(struct device *dev, void *buffer, size_t size, unsigned long timeout_ms)
{
	struct mei_cl_device *cldev;
	ssize_t byte;
	bool retry = false;
	int ret;

	if (!dev || !buffer)
		return -EINVAL;

	cldev = to_mei_cl_device(dev);

retry:
	byte = mei_cldev_recv_timeout(cldev, buffer, size, timeout_ms);
	if (byte < 0) {
		dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
		switch (byte) {
		case -ENOMEM:
			/* Retry the read when pages are reclaimed */
			msleep(20);
			if (!retry) {
				retry = true;
				goto retry;
			}
			fallthrough;
		case -ENODEV:
			fallthrough;
		case -ETIME:
			ret = mei_pxp_reenable(dev, cldev);
			if (ret)
				byte = ret;
			break;
		}
	}

	return byte;
}

/**
 * mei_pxp_gsc_command() - sends a gsc command, by sending
 * a sgl mei message to gsc and receiving reply from gsc
 *
 * @dev: device corresponding to the mei_cl_device
 * @client_id: client id to send the command to
 * @fence_id: fence id to send the command to
 * @sg_in: scatter gather list containing addresses for rx message buffer
 * @total_in_len: total length of data in 'in' sg, can be less than the sum of buffers sizes
 * @sg_out: scatter gather list containing addresses for tx message buffer
 *
 * Return: bytes sent on Success, <0 on Failure
 */
static ssize_t mei_pxp_gsc_command(struct device *dev, u8 client_id, u32 fence_id,
				   struct scatterlist *sg_in, size_t total_in_len,
				   struct scatterlist *sg_out)

Annotation

Implementation Notes