1 // SPDX-License-Identifier: GPL-2.0
3 * Greybus driver for the log protocol
5 * Copyright 2016 Google Inc.
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/slab.h>
10 #include <linux/sizes.h>
11 #include <linux/uaccess.h>
16 struct gb_connection
*connection
;
19 static int gb_log_request_handler(struct gb_operation
*op
)
21 struct gb_connection
*connection
= op
->connection
;
22 struct device
*dev
= &connection
->bundle
->dev
;
23 struct gb_log_send_log_request
*receive
;
26 if (op
->type
!= GB_LOG_TYPE_SEND_LOG
) {
27 dev_err(dev
, "unknown request type 0x%02x\n", op
->type
);
31 /* Verify size of payload */
32 if (op
->request
->payload_size
< sizeof(*receive
)) {
33 dev_err(dev
, "log request too small (%zu < %zu)\n",
34 op
->request
->payload_size
, sizeof(*receive
));
37 receive
= op
->request
->payload
;
38 len
= le16_to_cpu(receive
->len
);
39 if (len
!= (op
->request
->payload_size
- sizeof(*receive
))) {
40 dev_err(dev
, "log request wrong size %d vs %zu\n", len
,
41 (op
->request
->payload_size
- sizeof(*receive
)));
45 dev_err(dev
, "log request of 0 bytes?\n");
49 if (len
> GB_LOG_MAX_LEN
) {
50 dev_err(dev
, "log request too big: %d\n", len
);
54 /* Ensure the buffer is 0 terminated */
55 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)
61 dev_dbg(dev
, "%s", receive
->msg
);
66 static int gb_log_probe(struct gb_bundle
*bundle
,
67 const struct greybus_bundle_id
*id
)
69 struct greybus_descriptor_cport
*cport_desc
;
70 struct gb_connection
*connection
;
74 if (bundle
->num_cports
!= 1)
77 cport_desc
= &bundle
->cport_desc
[0];
78 if (cport_desc
->protocol_id
!= GREYBUS_PROTOCOL_LOG
)
81 log
= kzalloc(sizeof(*log
), GFP_KERNEL
);
85 connection
= gb_connection_create(bundle
, le16_to_cpu(cport_desc
->id
),
86 gb_log_request_handler
);
87 if (IS_ERR(connection
)) {
88 retval
= PTR_ERR(connection
);
92 log
->connection
= connection
;
93 greybus_set_drvdata(bundle
, log
);
95 retval
= gb_connection_enable(connection
);
97 goto error_connection_destroy
;
101 error_connection_destroy
:
102 gb_connection_destroy(connection
);
108 static void gb_log_disconnect(struct gb_bundle
*bundle
)
110 struct gb_log
*log
= greybus_get_drvdata(bundle
);
111 struct gb_connection
*connection
= log
->connection
;
113 gb_connection_disable(connection
);
114 gb_connection_destroy(connection
);
119 static const struct greybus_bundle_id gb_log_id_table
[] = {
120 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LOG
) },
123 MODULE_DEVICE_TABLE(greybus
, gb_log_id_table
);
125 static struct greybus_driver gb_log_driver
= {
127 .probe
= gb_log_probe
,
128 .disconnect
= gb_log_disconnect
,
129 .id_table
= gb_log_id_table
,
131 module_greybus_driver(gb_log_driver
);
133 MODULE_LICENSE("GPL v2");