drivers/rapidio/rio_cm.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rapidio/rio_cm.c
Extension
.c
Size
54955 bytes
Lines
2372
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 riocm_cdev_fops = {
	.owner		= THIS_MODULE,
	.open		= riocm_cdev_open,
	.release	= riocm_cdev_release,
	.unlocked_ioctl = riocm_cdev_ioctl,
};

/*
 * riocm_add_dev - add new remote RapidIO device into channel management core
 * @dev: device object associated with RapidIO device
 * @sif: subsystem interface
 *
 * Adds the specified RapidIO device (if applicable) into peers list of
 * the corresponding channel management device (cm_dev).
 */
static int riocm_add_dev(struct device *dev, struct subsys_interface *sif)
{
	struct cm_peer *peer;
	struct rio_dev *rdev = to_rio_dev(dev);
	struct cm_dev *cm;

	/* Check if the remote device has capabilities required to support CM */
	if (!dev_cm_capable(rdev))
		return 0;

	riocm_debug(RDEV, "(%s)", rio_name(rdev));

	peer = kmalloc_obj(*peer);
	if (!peer)
		return -ENOMEM;

	/* Find a corresponding cm_dev object */
	down_write(&rdev_sem);
	list_for_each_entry(cm, &cm_dev_list, list) {
		if (cm->mport == rdev->net->hport)
			goto found;
	}

	up_write(&rdev_sem);
	kfree(peer);
	return -ENODEV;

found:
	peer->rdev = rdev;
	list_add_tail(&peer->node, &cm->peers);
	cm->npeers++;

	up_write(&rdev_sem);
	return 0;
}

/*
 * riocm_remove_dev - remove remote RapidIO device from channel management core
 * @dev: device object associated with RapidIO device
 * @sif: subsystem interface
 *
 * Removes the specified RapidIO device (if applicable) from peers list of
 * the corresponding channel management device (cm_dev).
 */
static void riocm_remove_dev(struct device *dev, struct subsys_interface *sif)
{
	struct rio_dev *rdev = to_rio_dev(dev);
	struct cm_dev *cm;
	struct cm_peer *peer;
	struct rio_channel *ch, *_c;
	unsigned int i;
	bool found = false;
	LIST_HEAD(list);

	/* Check if the remote device has capabilities required to support CM */
	if (!dev_cm_capable(rdev))
		return;

	riocm_debug(RDEV, "(%s)", rio_name(rdev));

	/* Find matching cm_dev object */
	down_write(&rdev_sem);
	list_for_each_entry(cm, &cm_dev_list, list) {
		if (cm->mport == rdev->net->hport) {
			found = true;
			break;
		}
	}

	if (!found) {
		up_write(&rdev_sem);
		return;
	}

	/* Remove remote device from the list of peers */

Annotation

Implementation Notes