drivers/rapidio/devices/rio_mport_cdev.c

Source file repositories/reference/linux-study-clean/drivers/rapidio/devices/rio_mport_cdev.c

File Facts

System
Linux kernel
Corpus path
drivers/rapidio/devices/rio_mport_cdev.c
Extension
.c
Size
65929 bytes
Lines
2625
Domain
Driver Families
Bucket
drivers/rapidio
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 mport_fops = {
	.owner		= THIS_MODULE,
	.open		= mport_cdev_open,
	.release	= mport_cdev_release,
	.poll		= mport_cdev_poll,
	.read		= mport_read,
	.write		= mport_write,
	.mmap		= mport_cdev_mmap,
	.fasync		= mport_cdev_fasync,
	.unlocked_ioctl = mport_cdev_ioctl
};

/*
 * Character device management
 */

static void mport_device_release(struct device *dev)
{
	struct mport_dev *md;

	rmcd_debug(EXIT, "%s", dev_name(dev));
	md = container_of(dev, struct mport_dev, dev);
	kfree(md);
}

/*
 * mport_cdev_add() - Create mport_dev from rio_mport
 * @mport:	RapidIO master port
 */
static struct mport_dev *mport_cdev_add(struct rio_mport *mport)
{
	int ret = 0;
	struct mport_dev *md;
	struct rio_mport_attr attr;

	md = kzalloc_obj(*md);
	if (!md) {
		rmcd_error("Unable allocate a device object");
		return NULL;
	}

	md->mport = mport;
	mutex_init(&md->buf_mutex);
	mutex_init(&md->file_mutex);
	INIT_LIST_HEAD(&md->file_list);

	device_initialize(&md->dev);
	md->dev.devt = MKDEV(MAJOR(dev_number), mport->id);
	md->dev.class = &dev_class;
	md->dev.parent = &mport->dev;
	md->dev.release = mport_device_release;
	dev_set_name(&md->dev, DEV_NAME "%d", mport->id);
	atomic_set(&md->active, 1);

	cdev_init(&md->cdev, &mport_fops);
	md->cdev.owner = THIS_MODULE;

	INIT_LIST_HEAD(&md->doorbells);
	spin_lock_init(&md->db_lock);
	INIT_LIST_HEAD(&md->portwrites);
	spin_lock_init(&md->pw_lock);
	INIT_LIST_HEAD(&md->mappings);

	md->properties.id = mport->id;
	md->properties.sys_size = mport->sys_size;
	md->properties.hdid = mport->host_deviceid;
	md->properties.index = mport->index;

	/* The transfer_mode property will be returned through mport query
	 * interface
	 */
#ifdef CONFIG_FSL_RIO /* for now: only on Freescale's SoCs */
	md->properties.transfer_mode |= RIO_TRANSFER_MODE_MAPPED;
#else
	md->properties.transfer_mode |= RIO_TRANSFER_MODE_TRANSFER;
#endif

	ret = cdev_device_add(&md->cdev, &md->dev);
	if (ret) {
		rmcd_error("Failed to register mport %d (err=%d)",
		       mport->id, ret);
		goto err_cdev;
	}
	ret = rio_query_mport(mport, &attr);
	if (!ret) {
		md->properties.flags = attr.flags;
		md->properties.link_speed = attr.link_speed;
		md->properties.link_width = attr.link_width;
		md->properties.dma_max_sge = attr.dma_max_sge;
		md->properties.dma_max_size = attr.dma_max_size;

Annotation

Implementation Notes