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
!= (op
->request
->payload_size
- sizeof(*receive
))) {
41 dev_err(dev
, "log request wrong size %d vs %zu\n", len
,
42 (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';
59 * Print with dev_dbg() so that it can be easily turned off using
60 * dynamic debugging (and prevent any DoS)
62 dev_dbg(dev
, "%s", receive
->msg
);
67 static int gb_log_probe(struct gb_bundle
*bundle
,
68 const struct greybus_bundle_id
*id
)
70 struct greybus_descriptor_cport
*cport_desc
;
71 struct gb_connection
*connection
;
75 if (bundle
->num_cports
!= 1)
78 cport_desc
= &bundle
->cport_desc
[0];
79 if (cport_desc
->protocol_id
!= GREYBUS_PROTOCOL_LOG
)
82 log
= kzalloc(sizeof(*log
), GFP_KERNEL
);
86 connection
= gb_connection_create(bundle
, le16_to_cpu(cport_desc
->id
),
87 gb_log_request_handler
);
88 if (IS_ERR(connection
)) {
89 retval
= PTR_ERR(connection
);
93 log
->connection
= connection
;
94 greybus_set_drvdata(bundle
, log
);
96 retval
= gb_connection_enable(connection
);
98 goto error_connection_destroy
;
102 error_connection_destroy
:
103 gb_connection_destroy(connection
);
109 static void gb_log_disconnect(struct gb_bundle
*bundle
)
111 struct gb_log
*log
= greybus_get_drvdata(bundle
);
112 struct gb_connection
*connection
= log
->connection
;
114 gb_connection_disable(connection
);
115 gb_connection_destroy(connection
);
120 static const struct greybus_bundle_id gb_log_id_table
[] = {
121 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LOG
) },
124 MODULE_DEVICE_TABLE(greybus
, gb_log_id_table
);
126 static struct greybus_driver gb_log_driver
= {
128 .probe
= gb_log_probe
,
129 .disconnect
= gb_log_disconnect
,
130 .id_table
= gb_log_id_table
,
132 module_greybus_driver(gb_log_driver
);
134 MODULE_LICENSE("GPL v2");