#include "greybus.h"
#include "audio.h"
-#define GB_I2S_MGMT_VERSION_MAJOR 0x00
-#define GB_I2S_MGMT_VERSION_MINOR 0x01
-
-#define GB_I2S_DATA_VERSION_MAJOR 0x00
-#define GB_I2S_DATA_VERSION_MINOR 0x01
-
/***********************************
* GB I2S helper functions
***********************************/
-int gb_i2s_mgmt_get_version(struct gb_connection *connection)
-{
- struct gb_protocol_version_response response;
-
- memset(&response, 0, sizeof(response));
- return gb_protocol_get_version(connection,
- GB_I2S_MGMT_TYPE_PROTOCOL_VERSION,
- NULL, 0, &response,
- GB_I2S_MGMT_VERSION_MAJOR);
-}
-
-int gb_i2s_data_get_version(struct gb_connection *connection)
-{
- struct gb_protocol_version_response response;
-
- memset(&response, 0, sizeof(response));
- return gb_protocol_get_version(connection,
- GB_I2S_DATA_TYPE_PROTOCOL_VERSION,
- NULL, 0, &response,
- GB_I2S_DATA_VERSION_MAJOR);
-}
-
int gb_i2s_mgmt_activate_cport(struct gb_connection *connection,
uint16_t cport)
{
goto out_card;
}
- ret = gb_i2s_data_get_version(connection);
- if (ret) {
- pr_err("i2s data get_version() failed: %d\n", ret);
- goto out_get_ver;
- }
-
#if USE_RT5645
rt5647_info.addr = RT5647_I2C_ADDR;
strlcpy(rt5647_info.type, "rt5647", I2C_NAME_SIZE);
return 0;
+#if USE_RT5645
out_get_ver:
platform_device_unregister(&snd_dev->card);
+#endif
out_card:
platform_device_unregister(&snd_dev->cpu_dai);
out_dai:
connection->private = snd_dev;
spin_unlock_irqrestore(&snd_dev->lock, flags);
- ret = gb_i2s_mgmt_get_version(connection);
- if (ret) {
- pr_err("i2s mgmt get_version() failed: %d\n", ret);
- goto err_free_snd_dev;
- }
-
ret = gb_i2s_mgmt_get_cfgs(snd_dev, connection);
if (ret) {
pr_err("can't get i2s configurations: %d\n", ret);
}
if (op->request->payload_size < sizeof(*req)) {
- dev_err(&connection->dev, "Short request received: %zu, %zu\n",
+ dev_err(&connection->dev, "Short request received (%zu < %zu)\n",
op->request->payload_size, sizeof(*req));
return -EINVAL;
}
/*
* GB I2S cmd functions
*/
-int gb_i2s_mgmt_get_version(struct gb_connection *connection);
-int gb_i2s_data_get_version(struct gb_connection *connection);
int gb_i2s_mgmt_activate_cport(struct gb_connection *connection,
uint16_t cport);
int gb_i2s_mgmt_deactivate_cport(struct gb_connection *connection,
// updates from the SVC "on the fly" so we don't have to always go ask
// the battery for some information. Hopefully...
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
};
#define GB_BATTERY_VERSION_MINOR 0x01
/* Greybus battery request types */
-#define GB_BATTERY_TYPE_INVALID 0x00
-#define GB_BATTERY_TYPE_PROTOCOL_VERSION 0x01
#define GB_BATTERY_TYPE_TECHNOLOGY 0x02
#define GB_BATTERY_TYPE_STATUS 0x03
#define GB_BATTERY_TYPE_MAX_VOLTAGE 0x04
__le32 voltage;
};
-/* Define get_version() routine */
-define_get_version(gb_battery, BATTERY);
-
static int get_tech(struct gb_battery *gb)
{
struct gb_battery_technology_response tech_response;
gb->connection = connection;
connection->private = gb;
- /* Check the version */
- retval = get_version(gb);
- if (retval)
- goto out;
retval = init_and_register(connection, gb);
-out:
if (retval)
kfree(gb);
static struct gb_protocol battery_protocol = {
.name = "battery",
.id = GREYBUS_PROTOCOL_BATTERY,
- .major = 0,
- .minor = 1,
+ .major = GB_BATTERY_VERSION_MAJOR,
+ .minor = GB_BATTERY_VERSION_MINOR,
.connection_init = gb_battery_connection_init,
.connection_exit = gb_battery_connection_exit,
.request_recv = NULL, /* no incoming requests */
device_unregister(&connection->dev);
}
+static void gb_connection_disconnected(struct gb_connection *connection)
+{
+ struct gb_control *control;
+ int cport_id = connection->intf_cport_id;
+ int ret;
+
+ /*
+ * Inform Interface about In-active CPorts. We don't need to do this
+ * operation for control cport.
+ */
+ if ((cport_id == GB_CONTROL_CPORT_ID) ||
+ (connection->hd_cport_id == GB_SVC_CPORT_ID))
+ return;
+
+ control = connection->bundle->intf->control;
+
+ ret = gb_control_disconnected_operation(control, cport_id);
+ if (ret)
+ dev_warn(&connection->dev,
+ "Failed to disconnect CPort-%d (%d)\n", cport_id, ret);
+}
+
int gb_connection_init(struct gb_connection *connection)
{
int cport_id = connection->intf_cport_id;
connection->state = GB_CONNECTION_STATE_ENABLED;
spin_unlock_irq(&connection->lock);
- ret = connection->protocol->connection_init(connection);
- if (ret) {
- spin_lock_irq(&connection->lock);
- connection->state = GB_CONNECTION_STATE_ERROR;
- spin_unlock_irq(&connection->lock);
+ /*
+ * Request protocol version supported by the module. We don't need to do
+ * this for SVC as that is initiated by the SVC.
+ */
+ if (connection->hd_cport_id != GB_SVC_CPORT_ID) {
+ ret = gb_protocol_get_version(connection, NULL, 0);
+ if (ret) {
+ dev_err(&connection->dev,
+ "Failed to get version CPort-%d (%d)\n",
+ cport_id, ret);
+ goto disconnect;
+ }
}
+ ret = connection->protocol->connection_init(connection);
+ if (!ret)
+ return 0;
+
+disconnect:
+ spin_lock_irq(&connection->lock);
+ connection->state = GB_CONNECTION_STATE_ERROR;
+ spin_unlock_irq(&connection->lock);
+
+ gb_connection_disconnected(connection);
return ret;
}
void gb_connection_exit(struct gb_connection *connection)
{
- int cport_id = connection->intf_cport_id;
-
if (!connection->protocol) {
dev_warn(&connection->dev, "exit without protocol.\n");
return;
gb_connection_cancel_operations(connection, -ESHUTDOWN);
connection->protocol->connection_exit(connection);
-
- /*
- * Inform Interface about In-active CPorts. We don't need to do this
- * operation for control cport.
- */
- if (cport_id != GB_CONTROL_CPORT_ID &&
- connection->hd_cport_id != GB_SVC_CPORT_ID) {
- struct gb_control *control = connection->bundle->intf->control;
- int ret;
-
- ret = gb_control_disconnected_operation(control, cport_id);
- if (ret)
- dev_warn(&connection->dev,
- "Failed to disconnect CPort-%d (%d)\n",
- cport_id, ret);
- }
+ gb_connection_disconnected(connection);
}
void gb_hd_connections_exit(struct greybus_host_device *hd)
u8 protocol_id;
u8 major;
u8 minor;
+ u8 module_major;
+ u8 module_minor;
spinlock_t lock;
enum gb_connection_state state;
#include <linux/slab.h>
#include "greybus.h"
-/* Define get_version() routine */
-define_get_version(gb_control, CONTROL);
-
/* Get Manifest's size from the interface */
int gb_control_get_manifest_size_operation(struct gb_interface *intf)
{
static int gb_control_connection_init(struct gb_connection *connection)
{
struct gb_control *control;
- int ret;
control = kzalloc(sizeof(*control), GFP_KERNEL);
if (!control)
control->connection = connection;
connection->private = control;
- ret = get_version(control);
- if (ret)
- kfree(control);
-
/* Set interface's control connection */
connection->bundle->intf->control = control;
- return ret;
+ return 0;
}
static void gb_control_connection_exit(struct gb_connection *connection)
struct gb_control {
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
};
int gb_control_connected_operation(struct gb_control *control, u16 cport_id);
struct gb_gpio_controller {
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
u8 line_max; /* max line number */
struct gb_gpio_line *lines;
container_of(chip, struct gb_gpio_controller, chip)
#define irq_data_to_gpio_chip(d) (d->domain->host_data)
-/* Define get_version() routine */
-define_get_version(gb_gpio_controller, GPIO);
-
static int gb_gpio_line_count_operation(struct gb_gpio_controller *ggc)
{
struct gb_gpio_line_count_response response;
{
int ret;
- /* First thing we need to do is check the version */
- ret = get_version(ggc);
- if (ret)
- return ret;
-
/* Now find out how many lines there are */
ret = gb_gpio_line_count_operation(ggc);
if (ret)
static struct gb_protocol gpio_protocol = {
.name = "gpio",
.id = GREYBUS_PROTOCOL_GPIO,
- .major = 0,
- .minor = 1,
+ .major = GB_GPIO_VERSION_MAJOR,
+ .minor = GB_GPIO_VERSION_MINOR,
.connection_init = gb_gpio_connection_init,
.connection_exit = gb_gpio_connection_exit,
.request_recv = gb_gpio_request_recv,
};
+/* Generic request numbers supported by all modules */
+#define GB_REQUEST_TYPE_INVALID 0x00
+#define GB_REQUEST_TYPE_PROTOCOL_VERSION 0x01
+
/* Control Protocol */
/* version request has no payload */
/* Greybus HID device's structure */
struct gb_hid {
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
struct hid_device *hid;
struct gb_hid_desc_response hdesc;
static DEFINE_MUTEX(gb_hid_open_mutex);
-/* Routines to get controller's infomation over greybus */
-
-/* Define get_version() routine */
-define_get_version(gb_hid, HID);
+/* Routines to get controller's information over greybus */
/* Operations performed on greybus */
static int gb_hid_get_desc(struct gb_hid *ghid)
struct hid_device *hid = ghid->hid;
int ret;
- ret = get_version(ghid);
- if (ret)
- return ret;
-
ret = gb_hid_get_desc(ghid);
if (ret)
return ret;
static struct gb_protocol hid_protocol = {
.name = "hid",
.id = GREYBUS_PROTOCOL_HID,
- .major = 0,
- .minor = 1,
+ .major = GB_HID_VERSION_MAJOR,
+ .minor = GB_HID_VERSION_MINOR,
.connection_init = gb_hid_connection_init,
.connection_exit = gb_hid_connection_exit,
.request_recv = gb_hid_irq_handler,
struct gb_i2c_device {
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
u32 functionality;
u16 timeout_msec;
struct i2c_adapter adapter;
};
-/* Define get_version() routine */
-define_get_version(gb_i2c_device, I2C);
-
/*
* Map Greybus i2c functionality bits into Linux ones
*/
{
int ret;
- /* First thing we need to do is check the version */
- ret = get_version(gb_i2c_dev);
- if (ret)
- return ret;
-
/* Assume the functionality never changes, just get it once */
ret = gb_i2c_functionality_operation(gb_i2c_dev);
if (ret)
static struct gb_protocol i2c_protocol = {
.name = "i2c",
.id = GREYBUS_PROTOCOL_I2C,
- .major = 0,
- .minor = 1,
+ .major = GB_I2C_VERSION_MAJOR,
+ .minor = GB_I2C_VERSION_MINOR,
.connection_init = gb_i2c_connection_init,
.connection_exit = gb_i2c_connection_exit,
.request_recv = NULL, /* no incoming requests */
struct gb_loopback {
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
struct kfifo kfifo;
struct mutex mutex;
#define GB_LOOPBACK_MS_WAIT_MAX 1000
-/* Define get_version() routine */
-define_get_version(gb_loopback, LOOPBACK);
-
/* interface sysfs attributes */
#define gb_loopback_ro_attr(field) \
static ssize_t field##_show(struct device *dev, \
goto out_sysfs;
}
- /* Check the version */
- retval = get_version(gb);
- if (retval)
- goto out_minor;
-
/* Calculate maximum payload */
gb->size_max = gb_operation_get_payload_size_max(connection);
if (gb->size_max <= sizeof(struct gb_loopback_transfer_request)) {
return protocol;
}
-int gb_protocol_get_version(struct gb_connection *connection, int type,
- void *request, int request_size,
- struct gb_protocol_version_response *response,
- __u8 major)
+int gb_protocol_get_version(struct gb_connection *connection, void *request,
+ int request_size)
{
+ struct gb_protocol_version_response response;
int retval;
- retval = gb_operation_sync(connection, type, request, request_size,
- response, sizeof(*response));
+ retval = gb_operation_sync(connection, GB_REQUEST_TYPE_PROTOCOL_VERSION,
+ request, request_size, &response,
+ sizeof(response));
if (retval)
return retval;
- if (response->major > major) {
+ if (response.major > connection->protocol->major) {
dev_err(&connection->dev,
"unsupported major version (%hhu > %hhu)\n",
- response->major, major);
+ response.major, connection->protocol->major);
return -ENOTSUPP;
}
+ connection->module_major = response.major;
+ connection->module_minor = response.minor;
+
dev_dbg(&connection->dev, "version_major = %u version_minor = %u\n",
- response->major, response->minor);
+ response.major, response.minor);
return 0;
}
__gb_protocol_register(protocol, THIS_MODULE)
struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor);
-int gb_protocol_get_version(struct gb_connection *connection, int type,
- void *request, int request_size,
- struct gb_protocol_version_response *response,
- __u8 major);
+int gb_protocol_get_version(struct gb_connection *connection, void *request,
+ int request_size);
void gb_protocol_put(struct gb_protocol *protocol);
gb_protocol_deregister(&__protocol); \
} \
-/*
- * Macro to create get_version() routine for protocols
- * @__device: name of the device struct
- * @__protocol: name of protocol in CAPITALS
- */
-#define define_get_version(__device, __protocol) \
-static int get_version(struct __device *dev) \
-{ \
- struct gb_protocol_version_response response; \
- int retval; \
- \
- retval = gb_protocol_get_version(dev->connection, \
- GB_##__protocol##_TYPE_PROTOCOL_VERSION,\
- NULL, 0, &response, \
- GB_##__protocol##_VERSION_MAJOR); \
- if (retval) \
- return retval; \
- \
- dev->version_major = response.major; \
- dev->version_minor = response.minor; \
- return 0; \
-}
-
#endif /* __PROTOCOL_H */
struct gb_pwm_chip {
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
u8 pwm_max; /* max pwm number */
struct pwm_chip chip;
container_of(chip, struct gb_pwm_chip, chip)
-/* Define get_version() routine */
-define_get_version(gb_pwm_chip, PWM);
-
static int gb_pwm_count_operation(struct gb_pwm_chip *pwmc)
{
struct gb_pwm_count_response response;
pwmc->connection = connection;
connection->private = pwmc;
- /* Check for compatible protocol version */
- ret = get_version(pwmc);
- if (ret)
- goto out_err;
-
/* Query number of pwms present */
ret = gb_pwm_count_operation(pwmc);
if (ret)
static struct gb_protocol pwm_protocol = {
.name = "pwm",
.id = GREYBUS_PROTOCOL_PWM,
- .major = 0,
- .minor = 1,
+ .major = GB_PWM_VERSION_MAJOR,
+ .minor = GB_PWM_VERSION_MINOR,
.connection_init = gb_pwm_connection_init,
.connection_exit = gb_pwm_connection_exit,
.request_recv = NULL, /* no incoming requests */
struct gb_raw {
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
struct list_head list;
int list_data;
#define GB_RAW_VERSION_MINOR 0x01
/* Greybus raw request types */
-#define GB_RAW_TYPE_INVALID 0x00
-#define GB_RAW_TYPE_PROTOCOL_VERSION 0x01
#define GB_RAW_TYPE_SEND 0x02
-/* Define get_version() routine */
-define_get_version(gb_raw, RAW);
-
struct gb_raw_send_request {
__le32 len;
__u8 data[0];
raw->connection = connection;
connection->private = raw;
- /* Check the protocol version */
- retval = get_version(raw);
- if (retval)
- goto error_free;
-
INIT_LIST_HEAD(&raw->list);
mutex_init(&raw->list_lock);
struct gb_sdio_host {
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
struct mmc_host *mmc;
struct mmc_request *mrq;
struct mutex lock; /* lock for this host */
static struct workqueue_struct *gb_sdio_mrq_workqueue;
-/* Define get_version() routine */
-define_get_version(gb_sdio_host, SDIO);
-
#define GB_SDIO_RSP_R1_R5_R6_R7 (GB_SDIO_RSP_PRESENT | GB_SDIO_RSP_CRC | \
GB_SDIO_RSP_OPCODE)
#define GB_SDIO_RSP_R3_R4 (GB_SDIO_RSP_PRESENT)
request = op->request;
- if (request->payload_size != sizeof(*payload)) {
- dev_err(mmc_dev(host->mmc), "wrong event size received\n");
+ if (request->payload_size < sizeof(*payload)) {
+ dev_err(mmc_dev(host->mmc), "wrong event size received (%zu < %zu)\n",
+ request->payload_size, sizeof(*payload));
return -EINVAL;
}
host->connection = connection;
connection->private = host;
- ret = get_version(host);
- if (ret < 0)
- goto free_mmc;
-
ret = gb_sdio_get_caps(host);
if (ret < 0)
goto free_mmc;
struct gb_spi {
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
/* Modes supported by spi controller */
u16 mode;
/* Routines to get controller infomation */
-/* Define get_version() routine */
-define_get_version(gb_spi, SPI);
-
/*
* Map Greybus spi mode bits/flags/bpw into Linux ones.
* All bits are same for now and so these macro's return same values.
{
int ret;
- /* First thing we need to do is check the version */
- ret = get_version(spi);
- if (ret)
- return ret;
-
/* mode never changes, just get it once */
ret = gb_spi_mode_operation(spi);
if (ret)
static struct gb_protocol spi_protocol = {
.name = "spi",
.id = GREYBUS_PROTOCOL_SPI,
- .major = 0,
- .minor = 1,
+ .major = GB_SPI_VERSION_MAJOR,
+ .minor = GB_SPI_VERSION_MINOR,
.connection_init = gb_spi_connection_init,
.connection_exit = gb_spi_connection_exit,
.request_recv = NULL,
struct gb_svc {
struct gb_connection *connection;
- u8 version_major;
- u8 version_minor;
};
struct svc_hotplug {
return -ENOTSUPP;
}
+ connection->module_major = version->major;
+ connection->module_minor = version->minor;
+
if (!gb_operation_response_alloc(op, sizeof(*version), GFP_KERNEL)) {
dev_err(dev, "%s: error allocating response\n",
__func__);
* SVC sends information about the endo and interface-id on the hello
* request, use that to create an endo.
*/
- if (op->request->payload_size != sizeof(*hello_request)) {
- dev_err(dev, "%s: Illegal size of hello request (%zu %zu)\n",
+ if (op->request->payload_size < sizeof(*hello_request)) {
+ dev_err(dev, "%s: Illegal size of hello request (%zu < %zu)\n",
__func__, op->request->payload_size,
sizeof(*hello_request));
return -EINVAL;
ara_vend_id = le32_to_cpu(hotplug->data.ara_vend_id);
ara_prod_id = le32_to_cpu(hotplug->data.ara_prod_id);
- // FIXME May require firmware download
intf = gb_interface_create(hd, intf_id);
if (!intf) {
dev_err(dev, "%s: Failed to create interface with id %hhu\n",
struct async_icount oldcount;
wait_queue_head_t wioctl;
struct mutex mutex;
- u8 version_major;
- u8 version_minor;
u8 ctrlin; /* input control lines */
u8 ctrlout; /* output control lines */
struct gb_tty_line_coding line_coding;
static DEFINE_MUTEX(table_lock);
static atomic_t reference_count = ATOMIC_INIT(0);
-/* Define get_version() routine */
-define_get_version(gb_tty, UART);
-
static int gb_uart_receive_data(struct gb_tty *gb_tty,
struct gb_connection *connection,
struct gb_uart_recv_data_request *receive_data)
gb_tty->connection = connection;
connection->private = gb_tty;
- /* Check for compatible protocol version */
- retval = get_version(gb_tty);
- if (retval)
- goto error_version;
-
minor = alloc_minor(gb_tty);
if (minor < 0) {
if (minor == -ENOSPC) {
dev_err(&connection->dev,
"no more free minor numbers\n");
retval = -ENODEV;
- goto error_version;
+ goto error_minor;
}
retval = minor;
- goto error_version;
+ goto error_minor;
}
gb_tty->minor = minor;
error:
tty_port_destroy(&gb_tty->port);
release_minor(gb_tty);
-error_version:
+error_minor:
connection->private = NULL;
kfree(gb_tty->buffer);
error_payload:
static struct gb_protocol uart_protocol = {
.name = "uart",
.id = GREYBUS_PROTOCOL_UART,
- .major = 0,
- .minor = 1,
+ .major = GB_UART_VERSION_MAJOR,
+ .minor = GB_UART_VERSION_MINOR,
.connection_init = gb_uart_connection_init,
.connection_exit = gb_uart_connection_exit,
.request_recv = gb_uart_request_recv,
#define GB_USB_VERSION_MINOR 0x01
/* Greybus USB request types */
-#define GB_USB_TYPE_INVALID 0x00
-#define GB_USB_TYPE_PROTOCOL_VERSION 0x01
#define GB_USB_TYPE_HCD_START 0x02
#define GB_USB_TYPE_HCD_STOP 0x03
#define GB_USB_TYPE_HUB_CONTROL 0x04
struct gb_usb_device {
struct gb_connection *connection;
-
- u8 version_major;
- u8 version_minor;
};
static inline struct gb_usb_device *to_gb_usb_device(struct usb_hcd *hcd)
return container_of((void *)dev, struct usb_hcd, hcd_priv);
}
-/* Define get_version() routine */
-define_get_version(gb_usb_device, USB);
-
static void hcd_stop(struct usb_hcd *hcd)
{
struct gb_usb_device *dev = to_gb_usb_device(hcd);
gb_usb_dev->connection = connection;
connection->private = gb_usb_dev;
- /* Check for compatible protocol version */
- retval = get_version(gb_usb_dev);
- if (retval)
- goto err_put_hcd;
-
hcd->has_tt = 1;
/*
static struct gb_protocol usb_protocol = {
.name = "usb",
.id = GREYBUS_PROTOCOL_USB,
- .major = 0,
- .minor = 1,
+ .major = GB_USB_VERSION_MAJOR,
+ .minor = GB_USB_VERSION_MINOR,
.connection_init = gb_usb_connection_init,
.connection_exit = gb_usb_connection_exit,
.request_recv = NULL, /* FIXME we have requests!!! */
struct gb_connection *connection;
struct device *dev;
int minor; /* vibrator minor number */
- u8 version_major;
- u8 version_minor;
};
/* Version of the Greybus vibrator protocol we support */
#define GB_VIBRATOR_VERSION_MINOR 0x01
/* Greybus Vibrator operation types */
-#define GB_VIBRATOR_TYPE_INVALID 0x00
-#define GB_VIBRATOR_TYPE_PROTOCOL_VERSION 0x01
#define GB_VIBRATOR_TYPE_ON 0x02
#define GB_VIBRATOR_TYPE_OFF 0x03
__le16 timeout_ms;
};
-/* Define get_version() routine */
-define_get_version(gb_vibrator_device, VIBRATOR);
-
static int turn_on(struct gb_vibrator_device *vib, u16 timeout_ms)
{
struct gb_vibrator_on_request request;
vib->connection = connection;
connection->private = vib;
- retval = get_version(vib);
- if (retval)
- goto error;
-
/*
* For now we create a device in sysfs for the vibrator, but odds are
* there is a "real" device somewhere in the kernel for this, but I
static struct gb_protocol vibrator_protocol = {
.name = "vibrator",
.id = GREYBUS_PROTOCOL_VIBRATOR,
- .major = 0,
- .minor = 1,
+ .major = GB_VIBRATOR_VERSION_MAJOR,
+ .minor = GB_VIBRATOR_VERSION_MINOR,
.connection_init = gb_vibrator_connection_init,
.connection_exit = gb_vibrator_connection_exit,
.request_recv = NULL, /* no incoming requests */