Example #1
0
int gb_connection_bind_protocol(struct gb_connection *connection)
{
	struct gb_protocol *protocol;
	int ret;

	/* If we already have a protocol bound here, just return */
	if (connection->protocol)
		return 0;

	protocol = gb_protocol_get(connection->protocol_id,
				   connection->major,
				   connection->minor);
	if (!protocol)
		return 0;
	connection->protocol = protocol;

	/*
	 * If we have a valid device_id for the interface block, then we have an
	 * active device, so bring up the connection at the same time.
	 */
	if ((!connection->bundle &&
	     protocol->flags & GB_PROTOCOL_NO_BUNDLE) ||
	    connection->bundle->intf->device_id != GB_DEVICE_ID_BAD) {
		ret = gb_connection_init(connection);
		if (ret) {
			gb_protocol_put(protocol);
			connection->protocol = NULL;
			return ret;
		}
	}

	return 0;
}
Example #2
0
static int legacy_connection_create(struct legacy_connection *lc,
					struct gb_bundle *bundle,
					struct greybus_descriptor_cport *desc)
{
	struct gb_connection *connection;
	struct gb_protocol *protocol;
	gb_request_handler_t handler;
	u8 major, minor;
	int ret;

	/*
	 * The legacy protocols have always been looked up using a hard-coded
	 * version of 0.1, despite (or perhaps rather, due to) the fact that
	 * module version negotiation could not take place until after the
	 * protocol was bound.
	 */
	major = 0;
	minor = 1;

	protocol = gb_protocol_get(desc->protocol_id, major, minor);
	if (!protocol) {
		dev_err(&bundle->dev,
				"protocol 0x%02x version %u.%u not found\n",
				desc->protocol_id, major, minor);
		return -EPROTONOSUPPORT;
	}

	if (protocol->request_recv)
		handler = legacy_request_handler;
	else
		handler = NULL;

	connection = gb_connection_create(bundle, le16_to_cpu(desc->id),
						handler);
	if (IS_ERR(connection)) {
		ret = PTR_ERR(connection);
		goto err_protocol_put;
	}

	/*
	 * NOTE: We need to keep a pointer to the protocol in the actual
	 *       connection structure for now.
	 */
	connection->protocol = protocol;

	lc->connection = connection;
	lc->protocol = protocol;

	return 0;

err_protocol_put:
	gb_protocol_put(protocol);

	return ret;
}
Example #3
0
static void legacy_connection_destroy(struct legacy_connection *lc)
{
	if (!lc->connection)
		return;

	lc->connection->protocol = NULL;

	gb_connection_destroy(lc->connection);

	gb_protocol_put(lc->protocol);
}
Example #4
0
/*
 * Tear down a previously set up connection.
 */
void gb_connection_destroy(struct gb_connection *connection)
{
	struct ida *id_map;

	if (WARN_ON(!connection))
		return;

	gb_connection_exit(connection);

	spin_lock_irq(&gb_connections_lock);
	list_del(&connection->bundle_links);
	list_del(&connection->hd_links);
	spin_unlock_irq(&gb_connections_lock);

	if (connection->protocol)
		gb_protocol_put(connection->protocol);
	connection->protocol = NULL;

	id_map = &connection->hd->cport_id_map;
	ida_simple_remove(id_map, connection->hd_cport_id);
	connection->hd_cport_id = CPORT_ID_BAD;

	device_unregister(&connection->dev);
}