1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
|
/*
* Copyright 2003 Digi International (www.digi.com)
* Scott H Kilau <Scott_Kilau at digi dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*/
#ifndef _DGNC_DRIVER_H
#define _DGNC_DRIVER_H
#include <linux/types.h>
#include <linux/tty.h>
#include <linux/interrupt.h>
#include "digi.h" /* Digi specific ioctl header */
/* Driver identification and error statements */
#define PROCSTR "dgnc" /* /proc entries */
#define DEVSTR "/dev/dg/dgnc" /* /dev entries */
#define DRVSTR "dgnc" /* Driver name string */
#define DG_PART "40002369_F" /* RPM part number */
#define TRC_TO_CONSOLE 1
/* Number of boards we support at once. */
#define MAXBOARDS 20
#define MAXPORTS 8
#define MAXTTYNAMELEN 200
/* Serial port types */
#define DGNC_SERIAL 0
#define DGNC_PRINT 1
#define SERIAL_TYPE_NORMAL 1
#define PORT_NUM(dev) ((dev) & 0x7f)
#define IS_PRINT(dev) (((dev) & 0xff) >= 0x80)
/* MAX number of stop characters sent when our read queue is getting full */
#define MAX_STOPS_SENT 5
/* 4 extra for alignment play space */
#define WRITEBUFLEN ((4096) + 4)
#define dgnc_jiffies_from_ms(a) (((a) * HZ) / 1000)
#ifndef _POSIX_VDISABLE
#define _POSIX_VDISABLE '\0'
#endif
/* All the possible states the driver can be while being loaded. */
enum {
DRIVER_INITIALIZED = 0,
DRIVER_READY
};
/* All the possible states the board can be while booting up. */
enum {
BOARD_FAILED = 0,
BOARD_FOUND,
BOARD_READY
};
struct dgnc_board;
struct channel_t;
/**
* struct board_ops - Per board operations.
*/
struct board_ops {
void (*tasklet)(unsigned long data);
irqreturn_t (*intr)(int irq, void *voidbrd);
void (*uart_init)(struct channel_t *ch);
void (*uart_off)(struct channel_t *ch);
int (*drain)(struct tty_struct *tty, uint seconds);
void (*param)(struct tty_struct *tty);
void (*vpd)(struct dgnc_board *brd);
void (*assert_modem_signals)(struct channel_t *ch);
void (*flush_uart_write)(struct channel_t *ch);
void (*flush_uart_read)(struct channel_t *ch);
void (*disable_receiver)(struct channel_t *ch);
void (*enable_receiver)(struct channel_t *ch);
void (*send_break)(struct channel_t *ch, int);
void (*send_start_character)(struct channel_t *ch);
void (*send_stop_character)(struct channel_t *ch);
void (*copy_data_from_queue_to_uart)(struct channel_t *ch);
uint (*get_uart_bytes_left)(struct channel_t *ch);
void (*send_immediate_char)(struct channel_t *ch, unsigned char);
};
/* Device flag definitions for bd_flags. */
#define BD_IS_PCI_EXPRESS 0x0001 /* Is a PCI Express board */
/**
* struct dgnc_board - Per board information.
* @boardnum: Board number (0 - 32).
*
* @type: Type of board.
* @name: Product name.
* @pdev: Pointer to the pci_dev structure.
* @bd_flags: Board flags.
* @vendor: PCI vendor ID.
* @device: PCI device ID.
* @subvendor: PCI subsystem vendor ID.
* @subdevice: PCI subsystem device ID.
* @rev: PCI revision ID.
* @pci_bus: PCI bus value.
* @pci_slot: PCI slot value.
* @maxports: Maximum ports this board can handle.
* @dvid: Board specific device ID.
* @vpd: VPD of this board, if found.
* @serial_num: Serial number of this board, if found in VPD.
* @bd_lock: Used to protect board.
* @bd_intr_lock: Protect poller tasklet and interrupt routine from each other.
* @state: State of the card.
* @state_wait: Queue to sleep on for state change.
* @helper_tasklet: Poll helper tasklet.
* @nasync: Number of ports on card.
* @irq: Interrupt request number.
* @membase: Start of base memory of the card.
* @membase_end: End of base memory of the card.
* @iobase: Start of IO base of the card.
* @iobase_end: End of IO base of the card.
* @bd_uart_offset: Space between each UART.
* @channels: array of pointers to our channels.
* @serial_driver: Pointer to the serial driver.
* @serial_name: Serial driver name.
* @print_dirver: Pointer to the print driver.
* @print_name: Print driver name.
* @dpatype: Board type as defined by DPA.
* @dpastatus: Board status as defined by DPA.
* @bd_dividend: Board/UART's specific dividend.
* @bd_ops: Pointer to board operations structure.
* @proc_entry_pointer: Proc/<board> entry
* @dgnc_board_table: Proc/<board> entry
*/
struct dgnc_board {
int boardnum;
int type;
char *name;
struct pci_dev *pdev;
unsigned long bd_flags;
u16 vendor;
u16 device;
u16 subvendor;
u16 subdevice;
unsigned char rev;
uint pci_bus;
uint pci_slot;
uint maxports;
unsigned char dvid;
unsigned char vpd[128];
unsigned char serial_num[20];
/* used to protect the board */
spinlock_t bd_lock;
/* Protect poller tasklet and interrupt routine from each other. */
spinlock_t bd_intr_lock;
uint state;
wait_queue_head_t state_wait;
struct tasklet_struct helper_tasklet;
uint nasync;
uint irq;
ulong membase;
ulong membase_end;
u8 __iomem *re_map_membase;
ulong iobase;
ulong iobase_end;
uint bd_uart_offset;
struct channel_t *channels[MAXPORTS];
struct tty_driver *serial_driver;
char serial_name[200];
struct tty_driver *print_driver;
char print_name[200];
u16 dpatype;
u16 dpastatus;
uint bd_dividend;
struct board_ops *bd_ops;
struct proc_dir_entry *proc_entry_pointer;
struct dgnc_proc_entry *dgnc_board_table;
};
/* Unit flag definitions for un_flags. */
#define UN_ISOPEN 0x0001 /* Device is open */
#define UN_CLOSING 0x0002 /* Line is being closed */
#define UN_IMM 0x0004 /* Service immediately */
#define UN_BUSY 0x0008 /* Some work this channel */
#define UN_BREAKI 0x0010 /* Input break received */
#define UN_PWAIT 0x0020 /* Printer waiting for terminal */
#define UN_TIME 0x0040 /* Waiting on time */
#define UN_EMPTY 0x0080 /* Waiting output queue empty */
#define UN_LOW 0x0100 /* Waiting output low water mark*/
#define UN_EXCL_OPEN 0x0200 /* Open for exclusive use */
#define UN_WOPEN 0x0400 /* Device waiting for open */
#define UN_WIOCTL 0x0800 /* Device waiting for open */
#define UN_HANGUP 0x8000 /* Carrier lost */
struct device;
/**
* struct un_t - terminal or printer unit
* @un_open_count: Counter of opens to port.
* @un_tty: Pointer to unit tty structure.
* @un_flags: Unit flags.
* @un_flags_wait: Place to sleep to wait on unit.
* @un_dev: Minor device number.
*/
struct un_t {
struct channel_t *un_ch;
ulong un_time;
uint un_type;
uint un_open_count;
struct tty_struct *un_tty;
uint un_flags;
wait_queue_head_t un_flags_wait;
uint un_dev;
struct device *un_sysfs;
};
/* Device flag definitions for ch_flags. */
#define CH_PRON 0x0001 /* Printer on string */
#define CH_STOP 0x0002 /* Output is stopped */
#define CH_STOPI 0x0004 /* Input is stopped */
#define CH_CD 0x0008 /* Carrier is present */
#define CH_FCAR 0x0010 /* Carrier forced on */
#define CH_HANGUP 0x0020 /* Hangup received */
#define CH_RECEIVER_OFF 0x0040 /* Receiver is off */
#define CH_OPENING 0x0080 /* Port in fragile open state */
#define CH_CLOSING 0x0100 /* Port in fragile close state */
#define CH_FIFO_ENABLED 0x0200 /* Port has FIFOs enabled */
#define CH_TX_FIFO_EMPTY 0x0400 /* TX Fifo is completely empty */
#define CH_TX_FIFO_LWM 0x0800 /* TX Fifo is below Low Water */
#define CH_BREAK_SENDING 0x1000 /* Break is being sent */
#define CH_LOOPBACK 0x2000 /* Channel is in lookback mode */
#define CH_BAUD0 0x08000 /* Used for checking B0 transitions */
#define CH_FORCED_STOP 0x20000 /* Output is forcibly stopped */
#define CH_FORCED_STOPI 0x40000 /* Input is forcibly stopped */
/* Our Read/Error/Write queue sizes */
#define RQUEUEMASK 0x1FFF /* 8 K - 1 */
#define EQUEUEMASK 0x1FFF /* 8 K - 1 */
#define WQUEUEMASK 0x0FFF /* 4 K - 1 */
#define RQUEUESIZE (RQUEUEMASK + 1)
#define EQUEUESIZE RQUEUESIZE
#define WQUEUESIZE (WQUEUEMASK + 1)
/**
* struct channel_t - Channel information.
* @dgnc_board: Pointer to board structure.
* @ch_bd: Transparent print structure.
* @ch_tun: Terminal unit information.
* @ch_pun: Printer unit information.
* @ch_lock: Provide for serialization.
* @ch_flags_wait: Channel flags wait queue.
* @ch_portnum: Port number, 0 offset.
* @ch_open_count: Open count.
* @ch_flags: Channel flags.
* @ch_close_delay: How long we should drop RTS/DTR for.
* @ch_cpstime: Time for CPS calculations.
* @ch_c_iflag: Channel iflags.
* @ch_c_cflag: Channel cflags.
* @ch_c_oflag: Channel oflags.
* @ch_c_lflag: Channel lflags.
* @ch_stopc: Stop character.
* @ch_startc: Start character.
* @ch_old_baud: Cache of the current baud rate.
* @ch_custom_speed: Custom baud rate, if set.
* @ch_wopen: Waiting for open process count.
* @ch_mostat: FEP output modem status.
* @ch_mistat: FEP input modem status.
* @chc_neo_uart: Pointer to the mapped neo UART struct
* @ch_cls_uart: Pointer to the mapped cls UART struct
* @ch_cached_lsr: Cached value of the LSR register.
* @ch_rqueue: Read queue buffer, malloc'ed.
* @ch_r_head: Head location of the read queue.
* @ch_r_tail: Tail location of the read queue.
* @ch_equeue: Error queue buffer, malloc'ed.
* @ch_e_head: Head location of the error queue.
* @ch_e_tail: Tail location of the error queue.
* @ch_wqueue: Write queue buffer, malloc'ed.
* @ch_w_head: Head location of the write queue.
* @ch_w_tail: Tail location of the write queue.
* @ch_rxcount: Total of data received so far.
* @ch_txcount: Total of data transmitted so far.
* @ch_r_tlevel: Receive trigger level.
* @ch_t_tlevel: Transmit trigger level.
* @ch_r_watermark: Receive water mark.
* @ch_stop_sending_break: Time we should STOP sending a break.
* @ch_stops_sent: How many times I have send a stop character to try
* to stop the other guy sending.
* @ch_err_parity: Count of parity
* @ch_err_frame: Count of framing errors on channel.
* @ch_err_break: Count of breaks on channel.
* @ch_err_overrun: Count of overruns on channel.
* @ch_xon_sends: Count of xons transmitted.
* @ch_xoff_sends: Count of xoffs transmitted.
* @proc_entry_pointer: Proc/<board>/<channel> entry.
* @dgnc_channel_table: Proc/<board>/<channel> entry.
*/
struct channel_t {
struct dgnc_board *ch_bd;
struct digi_t ch_digi;
struct un_t ch_tun;
struct un_t ch_pun;
spinlock_t ch_lock; /* provide for serialization */
wait_queue_head_t ch_flags_wait;
uint ch_portnum;
uint ch_open_count;
uint ch_flags;
ulong ch_close_delay;
ulong ch_cpstime;
tcflag_t ch_c_iflag;
tcflag_t ch_c_cflag;
tcflag_t ch_c_oflag;
tcflag_t ch_c_lflag;
unsigned char ch_stopc;
unsigned char ch_startc;
uint ch_old_baud;
uint ch_custom_speed;
uint ch_wopen;
unsigned char ch_mostat;
unsigned char ch_mistat;
struct neo_uart_struct __iomem *ch_neo_uart;
struct cls_uart_struct __iomem *ch_cls_uart;
unsigned char ch_cached_lsr;
unsigned char *ch_rqueue;
ushort ch_r_head;
ushort ch_r_tail;
unsigned char *ch_equeue;
ushort ch_e_head;
ushort ch_e_tail;
unsigned char *ch_wqueue;
ushort ch_w_head;
ushort ch_w_tail;
ulong ch_rxcount;
ulong ch_txcount;
unsigned char ch_r_tlevel;
unsigned char ch_t_tlevel;
unsigned char ch_r_watermark;
ulong ch_stop_sending_break;
uint ch_stops_sent;
ulong ch_err_parity;
ulong ch_err_frame;
ulong ch_err_break;
ulong ch_err_overrun;
ulong ch_xon_sends;
ulong ch_xoff_sends;
struct proc_dir_entry *proc_entry_pointer;
struct dgnc_proc_entry *dgnc_channel_table;
};
extern uint dgnc_major; /* Our driver/mgmt major */
extern int dgnc_poll_tick; /* Poll interval - 20 ms */
extern spinlock_t dgnc_global_lock; /* Driver global spinlock */
extern spinlock_t dgnc_poll_lock; /* Poll scheduling lock */
extern uint dgnc_num_boards; /* Total number of boards */
extern struct dgnc_board *dgnc_board[MAXBOARDS];/* Array of boards */
#endif /* _DGNC_DRIVER_H */
|