/* * drivers/char/vs_serial_server.c * * Copyright (c) 2012-2018 General Dynamics * Copyright (c) 2014 Open Kernel Labs, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Serial vService server driver * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "vs_serial_common.h" #define server_state_to_port(state) \ container_of(state, struct vtty_port, u.vs_server) static struct vs_mbuf *vs_serial_server_alloc_msg_buf(struct vtty_port *port, struct vs_pbuf *pbuf, gfp_t gfp_flags) { return vs_server_serial_serial_alloc_msg(&port->u.vs_server, pbuf, gfp_flags); } static void vs_serial_server_free_msg_buf(struct vtty_port *port, struct vs_mbuf *mbuf, struct vs_pbuf *pbuf) { vs_server_serial_serial_free_msg(&port->u.vs_server, pbuf, mbuf); } static int vs_serial_server_send_msg_buf(struct vtty_port *port, struct vs_mbuf *mbuf, struct vs_pbuf *pbuf) { return vs_server_serial_serial_send_msg(&port->u.vs_server, *pbuf, mbuf); } static bool vs_serial_server_is_vservices_running(struct vtty_port *port) { return VSERVICE_BASE_STATE_IS_RUNNING(port->u.vs_server.state.base); } static struct vtty_port_ops server_port_ops = { .alloc_msg_buf = vs_serial_server_alloc_msg_buf, .free_msg_buf = vs_serial_server_free_msg_buf, .send_msg_buf = vs_serial_server_send_msg_buf, .is_running = vs_serial_server_is_vservices_running, }; static struct vs_server_serial_state * vs_serial_server_alloc(struct vs_service_device *service) { struct vtty_port *port; port = vs_serial_alloc_port(service, &server_port_ops); if (!port) return NULL; dev_set_drvdata(&service->dev, port); return &port->u.vs_server; } static void vs_serial_server_release(struct vs_server_serial_state *_state) { vs_serial_release(server_state_to_port(_state)); } static void vs_serial_server_closed(struct vs_server_serial_state *_state) { vs_serial_reset(server_state_to_port(_state)); } static int vs_serial_server_handle_message(struct vs_server_serial_state *_state, struct vs_pbuf data, struct vs_mbuf *mbuf) { return vs_serial_handle_message(server_state_to_port(_state), mbuf, &data); } static vs_server_response_type_t vs_serial_server_req_open(struct vs_server_serial_state *_state) { struct vtty_port *port = server_state_to_port(_state); dev_dbg(&port->service->dev, "req_open\n"); /* FIXME: Jira ticket SDK-3521 - ryanm. */ port->max_transfer_size = vs_service_max_mbuf_size(port->service) - 8; _state->packet_size = port->max_transfer_size; return VS_SERVER_RESP_SUCCESS; } static vs_server_response_type_t vs_serial_server_req_close(struct vs_server_serial_state *_state) { struct vtty_port *port = server_state_to_port(_state); dev_dbg(&port->service->dev, "req_close\n"); return VS_SERVER_RESP_SUCCESS; } static struct vs_server_serial vs_server_serial_driver = { .rx_atomic = true, .alloc = vs_serial_server_alloc, .release = vs_serial_server_release, .closed = vs_serial_server_closed, .open = vs_serial_server_req_open, .close = vs_serial_server_req_close, .serial = { .msg_msg = vs_serial_server_handle_message, }, /* Large default quota for batching data messages */ .in_quota_best = 16, .out_quota_best = 16, }; static int __init vs_serial_server_init(void) { return vservice_serial_server_register(&vs_server_serial_driver, "vserial"); } static void __exit vs_serial_server_exit(void) { vservice_serial_server_unregister(&vs_server_serial_driver); } module_init(vs_serial_server_init); module_exit(vs_serial_server_exit); MODULE_DESCRIPTION("OKL4 Virtual Services Serial Server Driver"); MODULE_AUTHOR("Open Kernel Labs, Inc");