drivers/scsi/megaraid/megaraid_mm.c

Source file repositories/reference/linux-study-clean/drivers/scsi/megaraid/megaraid_mm.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/megaraid/megaraid_mm.c
Extension
.c
Size
26480 bytes
Lines
1227
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations lsi_fops = {
	.open	= mraid_mm_open,
	.unlocked_ioctl = mraid_mm_unlocked_ioctl,
	.compat_ioctl = compat_ptr_ioctl,
	.owner	= THIS_MODULE,
	.llseek = noop_llseek,
};

static struct miscdevice megaraid_mm_dev = {
	.minor	= MISC_DYNAMIC_MINOR,
	.name   = "megadev0",
	.fops   = &lsi_fops,
};

/**
 * mraid_mm_open - open routine for char node interface
 * @inode	: unused
 * @filep	: unused
 *
 * Allow ioctl operations by apps only if they have superuser privilege.
 */
static int
mraid_mm_open(struct inode *inode, struct file *filep)
{
	/*
	 * Only allow superuser to access private ioctl interface
	 */
	if (!capable(CAP_SYS_ADMIN)) return (-EACCES);

	return 0;
}

/**
 * mraid_mm_ioctl - module entry-point for ioctls
 * @filep	: file operations pointer (ignored)
 * @cmd		: ioctl command
 * @arg		: user ioctl packet
 */
static int
mraid_mm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
	uioc_t		*kioc;
	char		signature[EXT_IOCTL_SIGN_SZ]	= {0};
	int		rval;
	mraid_mmadp_t	*adp;
	uint8_t		old_ioctl;
	int		drvrcmd_rval;
	void __user *argp = (void __user *)arg;

	/*
	 * Make sure only USCSICMD are issued through this interface.
	 * MIMD application would still fire different command.
	 */

	if ((_IOC_TYPE(cmd) != MEGAIOC_MAGIC) && (cmd != USCSICMD)) {
		return (-EINVAL);
	}

	/*
	 * Look for signature to see if this is the new or old ioctl format.
	 */
	if (copy_from_user(signature, argp, EXT_IOCTL_SIGN_SZ)) {
		con_log(CL_ANN, (KERN_WARNING
			"megaraid cmm: copy from usr addr failed\n"));
		return (-EFAULT);
	}

	if (memcmp(signature, EXT_IOCTL_SIGN, EXT_IOCTL_SIGN_SZ) == 0)
		old_ioctl = 0;
	else
		old_ioctl = 1;

	/*
	 * At present, we don't support the new ioctl packet
	 */
	if (!old_ioctl )
		return (-EINVAL);

	/*
	 * If it is a driver ioctl (as opposed to fw ioctls), then we can
	 * handle the command locally. rval > 0 means it is not a drvr cmd
	 */
	rval = handle_drvrcmd(argp, old_ioctl, &drvrcmd_rval);

	if (rval < 0)
		return rval;
	else if (rval == 0)
		return drvrcmd_rval;

	rval = 0;

Annotation

Implementation Notes