blob: b9dc775dc9f46bb0dc405fab2c3a28497e65d36d [file] [log] [blame]
Carl van Schaik6d7b2ff2018-07-06 22:00:55 +10001/*
2 * include/vservices/session.h
3 *
4 * Copyright (c) 2012-2018 General Dynamics
5 * Copyright (c) 2014 Open Kernel Labs, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This file defines the device type for a vServices session attached to a
12 * transport. This should only be used by transport drivers, the vServices
13 * session code, and the inline transport-access functions defined in
14 * vservices/service.h.
15 *
16 * Drivers for these devices are defined internally by the vServices
17 * framework. Other drivers should not attach to these devices.
18 */
19
20#ifndef _VSERVICES_SESSION_H_
21#define _VSERVICES_SESSION_H_
22
23#include <linux/types.h>
24#include <linux/device.h>
25#include <linux/spinlock.h>
26#include <linux/completion.h>
27#include <linux/mutex.h>
28#include <linux/list.h>
29#include <linux/idr.h>
30
31#include <vservices/types.h>
32
33struct vs_service_device;
34struct vs_mbuf;
35
36struct notifier_block;
37
38/**
39 * enum vs_notify_event_t - vService notifier events
40 *
41 * @VS_SESSION_NOTIFY_ADD: vService session added. Argument is a pointer to
42 * the vs_session_device. This notification is sent after the session has been
43 * added.
44 *
45 * @VS_SESSION_NOTIFY_REMOVE: vService session about to be removed. Argument is
46 * a pointer to the vs_session_device. This notification is sent before the
47 * session is removed.
48 */
49enum vs_notify_event_t {
50 VS_SESSION_NOTIFY_ADD,
51 VS_SESSION_NOTIFY_REMOVE,
52};
53
54/**
55 * struct vs_session_device - Session device
56 * @name: The unique human-readable name of this session.
57 * @is_server: True if this session is a server, false if client
58 * @transport: The transport device for this session
59 * @session_num: Unique ID for this session. Used for sysfs
60 * @session_lock: Mutex which protects any change to service presence or
61 * readiness
62 * @core_service: The core service, if one has ever been registered. Once set,
63 * this must remain valid and unchanged until the session driver is
64 * removed. Writes are protected by the service_ids_lock.
65 * @services: Dynamic array of the services on this session. Protected by
66 * service_ids_lock.
67 * @alloc_service_ids: Size of the session services array
68 * @service_ids_lock: Mutex protecting service array updates
69 * @activation_work: work structure for handling session activation & reset
70 * @activation_state: true if transport is currently active
71 * @fatal_error_work: work structure for handling fatal session failures
72 * @debug_mask: Debug level mask
73 * @list: Entry in the global session list
74 * @sysfs_entry: Kobject pointer pointing to session device in sysfs under
75 * sys/vservices
76 * @dev: Device structure for the Linux device model
77 */
78struct vs_session_device {
79 char *name;
80 bool is_server;
81 struct vs_transport *transport;
82 int session_num;
83
84 struct mutex session_lock;
85
86 /*
87 * The service_idr maintains the list of currently allocated services
88 * on a session, and allows for recycling of service ids. The lock also
89 * protects core_service.
90 */
91 struct idr service_idr;
92 struct mutex service_idr_lock;
93 struct vs_service_device *core_service;
94
95 struct work_struct activation_work;
96 atomic_t activation_state;
97
98 struct work_struct fatal_error_work;
99
100 unsigned long debug_mask;
101
102 struct list_head list;
103 struct kobject *sysfs_entry;
104
105 struct device dev;
106};
107
108#define to_vs_session_device(d) \
109 container_of(d, struct vs_session_device, dev)
110
111extern struct vs_session_device *
112vs_session_register(struct vs_transport *transport, struct device *parent,
113 bool server, const char *transport_name);
114extern void vs_session_start(struct vs_session_device *session);
115extern void vs_session_unregister(struct vs_session_device *session);
116
117extern int vs_session_handle_message(struct vs_session_device *session,
118 struct vs_mbuf *mbuf, vs_service_id_t service_id);
119
120extern void vs_session_quota_available(struct vs_session_device *session,
121 vs_service_id_t service_id, unsigned count,
122 bool send_tx_ready);
123
124extern void vs_session_handle_notify(struct vs_session_device *session,
125 unsigned long flags, vs_service_id_t service_id);
126
127extern void vs_session_handle_reset(struct vs_session_device *session);
128extern void vs_session_handle_activate(struct vs_session_device *session);
129
130extern struct vs_service_device *
131vs_server_create_service(struct vs_session_device *session,
132 struct vs_service_device *parent, const char *name,
133 const char *protocol, const void *plat_data);
134extern int vs_server_destroy_service(struct vs_service_device *service,
135 struct vs_service_device *parent);
136
137extern void vs_session_register_notify(struct notifier_block *nb);
138extern void vs_session_unregister_notify(struct notifier_block *nb);
139
140extern int vs_session_unbind_driver(struct vs_service_device *service);
141
142extern void vs_session_for_each_service(struct vs_session_device *session,
143 void (*func)(struct vs_service_device *, void *), void *data);
144
145extern struct mutex vs_session_lock;
146extern int vs_session_for_each_locked(
147 int (*fn)(struct vs_session_device *session, void *data),
148 void *data);
149
150static inline int vs_session_for_each(
151 int (*fn)(struct vs_session_device *session, void *data),
152 void *data)
153{
154 int r;
155 mutex_lock(&vs_session_lock);
156 r = vs_session_for_each_locked(fn, data);
157 mutex_unlock(&vs_session_lock);
158 return r;
159}
160
161#endif /* _VSERVICES_SESSION_H_ */