2 * Greybus driver for the log protocol
4 * Copyright 2016 Google Inc.
6 * Released under the GPLv2 only.
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/sizes.h>
12 #include <linux/uaccess.h>
17 struct gb_connection
*connection
;
20 static int gb_log_request_handler(struct gb_operation
*op
)
22 struct gb_connection
*connection
= op
->connection
;
23 struct device
*dev
= &connection
->bundle
->dev
;
24 struct gb_log_send_log_request
*receive
;
27 if (op
->type
!= GB_LOG_TYPE_SEND_LOG
) {
28 dev_err(dev
, "unknown request type 0x%02x\n", op
->type
);
32 /* Verify size of payload */
33 if (op
->request
->payload_size
< sizeof(*receive
)) {
34 dev_err(dev
, "log request too small (%zu < %zu)\n",
35 op
->request
->payload_size
, sizeof(*receive
));
38 receive
= op
->request
->payload
;
39 len
= le16_to_cpu(receive
->len
);
40 if (len
!= (int)(op
->request
->payload_size
- sizeof(*receive
))) {
41 dev_err(dev
, "log request wrong size %d vs %d\n", len
,
42 (int)(op
->request
->payload_size
- sizeof(*receive
)));
46 dev_err(dev
, "log request of 0 bytes?\n");
50 if (len
> GB_LOG_MAX_LEN
) {
51 dev_err(dev
, "log request too big: %d\n", len
);
55 /* Ensure the buffer is 0 terminated */
56 receive
->msg
[len
- 1] = '\0';
58 /* Print with dev_dbg() so that it can be easily turned off using
59 * dynamic debugging (and prevent any DoS) */
60 dev_dbg(dev
, "%s", receive
->msg
);
65 static int gb_log_probe(struct gb_bundle
*bundle
,
66 const struct greybus_bundle_id
*id
)
68 struct greybus_descriptor_cport
*cport_desc
;
69 struct gb_connection
*connection
;
73 if (bundle
->num_cports
!= 1)
76 cport_desc
= &bundle
->cport_desc
[0];
77 if (cport_desc
->protocol_id
!= GREYBUS_PROTOCOL_LOG
)
80 log
= kzalloc(sizeof(*log
), GFP_KERNEL
);
84 connection
= gb_connection_create(bundle
, le16_to_cpu(cport_desc
->id
),
85 gb_log_request_handler
);
86 if (IS_ERR(connection
)) {
87 retval
= PTR_ERR(connection
);
91 log
->connection
= connection
;
92 greybus_set_drvdata(bundle
, log
);
94 retval
= gb_connection_enable(connection
);
96 goto error_connection_destroy
;
100 error_connection_destroy
:
101 gb_connection_destroy(connection
);
107 static void gb_log_disconnect(struct gb_bundle
*bundle
)
109 struct gb_log
*log
= greybus_get_drvdata(bundle
);
110 struct gb_connection
*connection
= log
->connection
;
112 gb_connection_disable(connection
);
113 gb_connection_destroy(connection
);
118 static const struct greybus_bundle_id gb_log_id_table
[] = {
119 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LOG
) },
122 MODULE_DEVICE_TABLE(greybus
, gb_log_id_table
);
124 static struct greybus_driver gb_log_driver
= {
126 .probe
= gb_log_probe
,
127 .disconnect
= gb_log_disconnect
,
128 .id_table
= gb_log_id_table
,
130 module_greybus_driver(gb_log_driver
);
132 MODULE_LICENSE("GPL v2");