1#ifndef _FIREWIRE_FWSERIAL_H
2#define _FIREWIRE_FWSERIAL_H
3
4#include <linux/kernel.h>
5#include <linux/tty.h>
6#include <linux/tty_driver.h>
7#include <linux/tty_flip.h>
8#include <linux/list.h>
9#include <linux/firewire.h>
10#include <linux/firewire-constants.h>
11#include <linux/spinlock.h>
12#include <linux/rcupdate.h>
13#include <linux/mutex.h>
14#include <linux/serial.h>
15#include <linux/serial_reg.h>
16#include <linux/module.h>
17#include <linux/seq_file.h>
18#include <linux/debugfs.h>
19
20#include "dma_fifo.h"
21
22#ifdef FWTTY_PROFILING
23#define DISTRIBUTION_MAX_SIZE 8192
24#define DISTRIBUTION_MAX_INDEX (ilog2(DISTRIBUTION_MAX_SIZE) + 1)
25static inline void profile_size_distrib(unsigned stat[], unsigned val)
26{
27 int n = (val) ? min(ilog2(val) + 1, DISTRIBUTION_MAX_INDEX) : 0;
28 ++stat[n];
29}
30#else
31#define DISTRIBUTION_MAX_INDEX 0
32#define profile_size_distrib(st, n)
33#endif
34
35
36struct virt_plug_params {
37 __be32 status_hi;
38 __be32 status_lo;
39 __be32 fifo_hi;
40 __be32 fifo_lo;
41 __be32 fifo_len;
42};
43
44struct peer_work_params {
45 union {
46 struct virt_plug_params plug_req;
47 };
48};
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75struct fwtty_peer {
76 struct fw_unit *unit;
77 struct fw_serial *serial;
78 u64 guid;
79 int generation;
80 int node_id;
81 unsigned speed;
82 int max_payload;
83 u64 mgmt_addr;
84
85
86 u64 status_addr;
87 u64 fifo_addr;
88 int fifo_len;
89
90 struct list_head list;
91 struct rcu_head rcu;
92
93 spinlock_t lock;
94 struct work_struct work;
95 struct peer_work_params work_params;
96 struct timer_list timer;
97 int state;
98 struct delayed_work connect;
99 int connect_retries;
100
101 struct fwtty_port *port;
102};
103
104#define to_peer(ptr, field) (container_of(ptr, struct fwtty_peer, field))
105
106
107enum fwtty_peer_state {
108 FWPS_GONE,
109 FWPS_NOT_ATTACHED,
110 FWPS_ATTACHED,
111 FWPS_PLUG_PENDING,
112 FWPS_PLUG_RESPONDING,
113 FWPS_UNPLUG_PENDING,
114 FWPS_UNPLUG_RESPONDING,
115
116 FWPS_NO_MGMT_ADDR = -1,
117};
118
119#define CONNECT_RETRY_DELAY HZ
120#define MAX_CONNECT_RETRIES 10
121
122
123static inline void peer_set_state(struct fwtty_peer *peer, int new)
124{
125 peer->state = new;
126}
127
128static inline struct fwtty_port *peer_revert_state(struct fwtty_peer *peer)
129{
130 struct fwtty_port *port = peer->port;
131
132 peer->port = NULL;
133 peer_set_state(peer, FWPS_NOT_ATTACHED);
134 return port;
135}
136
137struct fwserial_mgmt_pkt {
138 struct {
139 __be16 len;
140 __be16 code;
141 } hdr;
142 union {
143 struct virt_plug_params plug_req;
144 struct virt_plug_params plug_rsp;
145 };
146} __packed;
147
148
149#define FWSC_RSP_OK 0x0000
150#define FWSC_RSP_NACK 0x8000
151#define FWSC_CODE_MASK 0x0fff
152
153#define FWSC_VIRT_CABLE_PLUG 1
154#define FWSC_VIRT_CABLE_UNPLUG 2
155#define FWSC_VIRT_CABLE_PLUG_RSP 3
156#define FWSC_VIRT_CABLE_UNPLUG_RSP 4
157
158
159#define VIRT_CABLE_PLUG_TIMEOUT (60 * HZ)
160
161struct stats {
162 unsigned xchars;
163 unsigned dropped;
164 unsigned tx_stall;
165 unsigned fifo_errs;
166 unsigned sent;
167 unsigned lost;
168 unsigned throttled;
169 unsigned watermark;
170 unsigned reads[DISTRIBUTION_MAX_INDEX + 1];
171 unsigned writes[DISTRIBUTION_MAX_INDEX + 1];
172 unsigned txns[DISTRIBUTION_MAX_INDEX + 1];
173 unsigned unthrottle[DISTRIBUTION_MAX_INDEX + 1];
174};
175
176struct fwconsole_ops {
177 void (*notify)(int code, void *data);
178 void (*stats)(struct stats *stats, void *data);
179 void (*proc_show)(struct seq_file *m, void *data);
180};
181
182
183#define FWCON_NOTIFY_ATTACH 1
184#define FWCON_NOTIFY_DETACH 2
185
186struct buffered_rx {
187 struct list_head list;
188 size_t n;
189 unsigned char data[0];
190};
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248struct fwtty_port {
249 struct tty_port port;
250 struct device *device;
251 unsigned index;
252 struct fw_serial *serial;
253 struct fw_address_handler rx_handler;
254
255 struct fwconsole_ops *fwcon_ops;
256 void *con_data;
257
258 wait_queue_head_t wait_tx;
259 struct delayed_work emit_breaks;
260 unsigned cps;
261 unsigned long break_last;
262
263 struct work_struct hangup;
264
265 unsigned mstatus;
266
267 spinlock_t lock;
268 unsigned mctrl;
269 struct delayed_work drain;
270 struct work_struct push;
271 struct list_head buf_list;
272 int buffered;
273 struct dma_fifo tx_fifo;
274 int max_payload;
275 unsigned status_mask;
276 unsigned ignore_mask;
277 unsigned break_ctl:1,
278 write_only:1,
279 overrun:1,
280 loopback:1;
281 unsigned long flags;
282
283 struct fwtty_peer __rcu *peer;
284
285 struct async_icount icount;
286 struct stats stats;
287};
288
289#define to_port(ptr, field) (container_of(ptr, struct fwtty_port, field))
290
291
292#define IN_TX 0
293#define STOP_TX 1
294#define BUFFERING_RX 2
295
296
297#define OOB_RX_THROTTLE 0x00010000
298#define MCTRL_RSRVD 0x000e0000
299#define OOB_TX_THROTTLE 0x00100000
300#define MSTATUS_RSRVD 0x00e00000
301
302#define MCTRL_MASK (TIOCM_DTR | TIOCM_RTS | TIOCM_OUT1 | TIOCM_OUT2 | \
303 TIOCM_LOOP | OOB_RX_THROTTLE | MCTRL_RSRVD)
304
305
306
307#define FREQ_BREAKS (HZ / 50)
308
309
310#define MAX_CARD_PORTS 32
311#define MAX_TOTAL_PORTS 64
312
313
314#define FWTTY_PORT_TXFIFO_LEN 4096
315#define FWTTY_PORT_MAX_PEND_DMA 8
316#define DRAIN_THRESHOLD 1024
317#define MAX_ASYNC_PAYLOAD 4096
318#define WRITER_MINIMUM 128
319
320#define HIGH_WATERMARK 32768
321
322
323
324
325
326#define FWTTY_PORT_RXFIFO_LEN MAX_ASYNC_PAYLOAD
327
328
329
330
331
332
333
334
335
336
337
338struct fw_serial {
339 struct fw_card *card;
340 struct kref kref;
341
342 struct dentry *debugfs;
343 struct fwtty_peer *self;
344
345 struct list_head list;
346 struct list_head peer_list;
347
348 struct fwtty_port *ports[MAX_CARD_PORTS];
349};
350
351#define to_serial(ptr, field) (container_of(ptr, struct fw_serial, field))
352
353#define TTY_DEV_NAME "fwtty"
354static const char tty_dev_name[] = TTY_DEV_NAME;
355static const char loop_dev_name[] = "fwloop";
356
357extern struct tty_driver *fwtty_driver;
358
359struct fwtty_port *fwtty_port_get(unsigned index);
360void fwtty_port_put(struct fwtty_port *port);
361
362static inline void fwtty_bind_console(struct fwtty_port *port,
363 struct fwconsole_ops *fwcon_ops,
364 void *data)
365{
366 port->con_data = data;
367 port->fwcon_ops = fwcon_ops;
368}
369
370
371
372
373
374
375
376
377
378static inline int link_speed_to_max_payload(unsigned speed)
379{
380
381 return min(512 << speed, 4096);
382}
383
384#endif
385