drivers/greybus/connection.c

Source file repositories/reference/linux-study-clean/drivers/greybus/connection.c

File Facts

System
Linux kernel
Corpus path
drivers/greybus/connection.c
Extension
.c
Size
23120 bytes
Lines
940
Domain
Driver Families
Bucket
drivers/greybus
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (connection->hd_cport_id == cport_id) {
			gb_connection_get(connection);
			goto found;
		}
	connection = NULL;
found:
	spin_unlock_irqrestore(&gb_connections_lock, flags);

	return connection;
}

/*
 * Callback from the host driver to let us know that data has been
 * received on the bundle.
 */
void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id,
		       u8 *data, size_t length)
{
	struct gb_connection *connection;

	trace_gb_hd_in(hd);

	connection = gb_connection_hd_find(hd, cport_id);
	if (!connection) {
		dev_err(&hd->dev,
			"nonexistent connection (%zu bytes dropped)\n", length);
		return;
	}
	gb_connection_recv(connection, data, length);
	gb_connection_put(connection);
}
EXPORT_SYMBOL_GPL(greybus_data_rcvd);

static void gb_connection_kref_release(struct kref *kref)
{
	struct gb_connection *connection;

	connection = container_of(kref, struct gb_connection, kref);

	trace_gb_connection_release(connection);

	kfree(connection);
}

static void gb_connection_init_name(struct gb_connection *connection)
{
	u16 hd_cport_id = connection->hd_cport_id;
	u16 cport_id = 0;
	u8 intf_id = 0;

	if (connection->intf) {
		intf_id = connection->intf->interface_id;
		cport_id = connection->intf_cport_id;
	}

	snprintf(connection->name, sizeof(connection->name),
		 "%u/%u:%u", hd_cport_id, intf_id, cport_id);
}

/*
 * _gb_connection_create() - create a Greybus connection
 * @hd:			host device of the connection
 * @hd_cport_id:	host-device cport id, or -1 for dynamic allocation
 * @intf:		remote interface, or NULL for static connections
 * @bundle:		remote-interface bundle (may be NULL)
 * @cport_id:		remote-interface cport id, or 0 for static connections
 * @handler:		request handler (may be NULL)
 * @flags:		connection flags
 *
 * Create a Greybus connection, representing the bidirectional link
 * between a CPort on a (local) Greybus host device and a CPort on
 * another Greybus interface.
 *
 * A connection also maintains the state of operations sent over the
 * connection.
 *
 * Serialised against concurrent create and destroy using the
 * gb_connection_mutex.
 *
 * Return: A pointer to the new connection if successful, or an ERR_PTR
 * otherwise.
 */
static struct gb_connection *
_gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
		      struct gb_interface *intf,
		      struct gb_bundle *bundle, int cport_id,
		      gb_request_handler_t handler,
		      unsigned long flags)
{
	struct gb_connection *connection;

Annotation

Implementation Notes