connection->interface = interface; /* XXX refcount? */
connection->interface_cport_id = cport_id;
connection->protocol = protocol;
+ connection->state = GB_CONNECTION_STATE_DISABLED;
spin_lock_irq(&gb_connections_lock);
_gb_hd_connection_insert(hd, connection);
*/
int gb_connection_init(struct gb_connection *connection)
{
+ int ret;
+
+ /* Need to enable the connection to initialize it */
+ connection->state = GB_CONNECTION_STATE_ENABLED;
switch (connection->protocol) {
case GREYBUS_PROTOCOL_I2C:
- return gb_i2c_device_init(connection);
+ ret = gb_i2c_device_init(connection);
+ break;
case GREYBUS_PROTOCOL_GPIO:
- return gb_gpio_controller_init(connection);
+ ret = gb_gpio_controller_init(connection);
+ break;
case GREYBUS_PROTOCOL_BATTERY:
- return gb_battery_device_init(connection);
+ ret = gb_battery_device_init(connection);
+ break;
case GREYBUS_PROTOCOL_CONTROL:
case GREYBUS_PROTOCOL_AP:
case GREYBUS_PROTOCOL_UART:
default:
gb_connection_err(connection, "unimplemented protocol %u",
(u32)connection->protocol);
+ ret = -ENXIO;
break;
}
- return -ENXIO;
+
+ if (ret)
+ connection->state = GB_CONNECTION_STATE_ERROR;
+
+ return ret;
}
void gb_connection_exit(struct gb_connection *connection)
{
+ connection->state = GB_CONNECTION_STATE_DESTROYING;
+
switch (connection->protocol) {
case GREYBUS_PROTOCOL_I2C:
gb_i2c_device_exit(connection);
#include "greybus.h"
+enum gb_connection_state {
+ GB_CONNECTION_STATE_INVALID = 0,
+ GB_CONNECTION_STATE_DISABLED = 1,
+ GB_CONNECTION_STATE_ENABLED = 2,
+ GB_CONNECTION_STATE_ERROR = 3,
+ GB_CONNECTION_STATE_DESTROYING = 4,
+};
+
struct gb_connection {
struct greybus_host_device *hd;
struct gb_interface *interface;
struct rb_node hd_node;
struct list_head interface_links;
enum greybus_protocol protocol;
+ enum gb_connection_state state;
struct list_head operations;
struct rb_root pending; /* awaiting reponse */
{
int ret;
+ if (operation->connection->state != GB_CONNECTION_STATE_ENABLED)
+ return -ENOTCONN;
+
/*
* XXX
* I think the order of operations is going to be
struct gbuf *gbuf;
u16 msg_size;
+ if (connection->state != GB_CONNECTION_STATE_ENABLED)
+ return;
+
if (size > GB_OPERATION_MESSAGE_SIZE_MAX) {
gb_connection_err(connection, "message too big");
return;