arch/powerpc/platforms/pseries/papr-rtas-common.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/pseries/papr-rtas-common.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/pseries/papr-rtas-common.c
Extension
.c
Size
7799 bytes
Lines
295
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

const struct file_operations *fops,
				char *name)
{
	const struct papr_rtas_blob *blob;
	int fd;

	blob = papr_rtas_retrieve(seq);
	if (IS_ERR(blob))
		return PTR_ERR(blob);

	fd = FD_ADD(O_RDONLY | O_CLOEXEC,
		   anon_inode_getfile_fmode(name, fops, (void *)blob, O_RDONLY,
					    FMODE_LSEEK | FMODE_PREAD));
	if (fd < 0)
		papr_rtas_blob_free(blob);
	return fd;
}

/*
 * papr_rtas_sequence_should_stop() - Determine whether RTAS retrieval
 *                                    sequence should continue.
 *
 * Examines the sequence error state and outputs of the last call to
 * the specific RTAS to determine whether the sequence in progress
 * should continue or stop.
 *
 * Return: True if the sequence has encountered an error or if all data
 *         for this sequence has been retrieved. False otherwise.
 */
bool papr_rtas_sequence_should_stop(const struct papr_rtas_sequence *seq,
				s32 status, bool init_state)
{
	bool done;

	if (seq->error)
		return true;

	switch (status) {
	case RTAS_SEQ_COMPLETE:
		if (init_state)
			done = false; /* Initial state. */
		else
			done = true; /* All data consumed. */
		break;
	case RTAS_SEQ_MORE_DATA:
		done = false; /* More data available. */
		break;
	default:
		done = true; /* Error encountered. */
		break;
	}

	return done;
}

/*
 * User space read to retrieve data for the corresponding RTAS call.
 * papr_rtas_blob is filled with the data using the corresponding RTAS
 * call sequence API.
 */
ssize_t papr_rtas_common_handle_read(struct file *file,
	       char __user *buf, size_t size, loff_t *off)
{
	const struct papr_rtas_blob *blob = file->private_data;

	/* We should not instantiate a handle without any data attached. */
	if (!papr_rtas_blob_has_data(blob)) {
		pr_err_once("handle without data\n");
		return -EIO;
	}

	return simple_read_from_buffer(buf, size, off, blob->data, blob->len);
}

int papr_rtas_common_handle_release(struct inode *inode,
		struct file *file)
{
	const struct papr_rtas_blob *blob = file->private_data;

	papr_rtas_blob_free(blob);

	return 0;
}

loff_t papr_rtas_common_handle_seek(struct file *file, loff_t off,
					int whence)
{
	const struct papr_rtas_blob *blob = file->private_data;

	return fixed_size_llseek(file, off, whence, blob->len);

Annotation

Implementation Notes