greybus: Drop protocol specific _PROTOCOL_VERSION and _INVALID macros
[cascardo/linux.git] / drivers / staging / greybus / control.c
1 /*
2  * Greybus CPort control protocol.
3  *
4  * Copyright 2015 Google Inc.
5  * Copyright 2015 Linaro Ltd.
6  *
7  * Released under the GPLv2 only.
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/slab.h>
13 #include "greybus.h"
14
15 /* Get Manifest's size from the interface */
16 int gb_control_get_manifest_size_operation(struct gb_interface *intf)
17 {
18         struct gb_control_get_manifest_size_response response;
19         struct gb_connection *connection = intf->control->connection;
20         int ret;
21
22         ret = gb_operation_sync(connection, GB_CONTROL_TYPE_GET_MANIFEST_SIZE,
23                                 NULL, 0, &response, sizeof(response));
24         if (ret) {
25                 dev_err(&connection->dev,
26                         "%s: Manifest size get operation failed (%d)\n",
27                         __func__, ret);
28                 return ret;
29         }
30
31         return le16_to_cpu(response.size);
32 }
33
34 /* Reads Manifest from the interface */
35 int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest,
36                                       size_t size)
37 {
38         struct gb_connection *connection = intf->control->connection;
39
40         return gb_operation_sync(connection, GB_CONTROL_TYPE_GET_MANIFEST,
41                                 NULL, 0, manifest, size);
42 }
43
44 int gb_control_connected_operation(struct gb_control *control, u16 cport_id)
45 {
46         struct gb_control_connected_request request;
47
48         request.cport_id = cpu_to_le16(cport_id);
49         return gb_operation_sync(control->connection, GB_CONTROL_TYPE_CONNECTED,
50                                  &request, sizeof(request), NULL, 0);
51 }
52
53 int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id)
54 {
55         struct gb_control_disconnected_request request;
56
57         request.cport_id = cpu_to_le16(cport_id);
58         return gb_operation_sync(control->connection,
59                                  GB_CONTROL_TYPE_DISCONNECTED, &request,
60                                  sizeof(request), NULL, 0);
61 }
62
63 static int gb_control_request_recv(u8 type, struct gb_operation *op)
64 {
65         struct gb_connection *connection = op->connection;
66         struct gb_protocol_version_response *version;
67
68         switch (type) {
69         case GB_CONTROL_TYPE_PROBE_AP:
70                 // TODO
71                 // Send authenticated block of data, confirming this module is
72                 // an AP.
73                 break;
74         case GB_REQUEST_TYPE_PROTOCOL_VERSION:
75                 if (!gb_operation_response_alloc(op, sizeof(*version),
76                                                  GFP_KERNEL)) {
77                         dev_err(&connection->dev,
78                                 "%s: error allocating response\n", __func__);
79                         return -ENOMEM;
80                 }
81
82                 version = op->response->payload;
83                 version->major = GB_CONTROL_VERSION_MAJOR;
84                 version->minor = GB_CONTROL_VERSION_MINOR;
85                 break;
86         case GB_CONTROL_TYPE_CONNECTED:
87         case GB_CONTROL_TYPE_DISCONNECTED:
88                 break;
89         default:
90                 WARN_ON(1);
91                 break;
92         }
93
94         return 0;
95 }
96
97 static int gb_control_connection_init(struct gb_connection *connection)
98 {
99         struct gb_control *control;
100
101         control = kzalloc(sizeof(*control), GFP_KERNEL);
102         if (!control)
103                 return -ENOMEM;
104
105         control->connection = connection;
106         connection->private = control;
107
108         /* Set interface's control connection */
109         connection->bundle->intf->control = control;
110
111         return 0;
112 }
113
114 static void gb_control_connection_exit(struct gb_connection *connection)
115 {
116         struct gb_control *control = connection->private;
117
118         if (WARN_ON(connection->bundle->intf->control != control))
119                 return;
120
121         connection->bundle->intf->control = NULL;
122         kfree(control);
123 }
124
125 static struct gb_protocol control_protocol = {
126         .name                   = "control",
127         .id                     = GREYBUS_PROTOCOL_CONTROL,
128         .major                  = 0,
129         .minor                  = 1,
130         .connection_init        = gb_control_connection_init,
131         .connection_exit        = gb_control_connection_exit,
132         .request_recv           = gb_control_request_recv,
133 };
134 gb_builtin_protocol_driver(control_protocol);