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
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
|
/*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
*
*************************************************************************
*
* Driver includes
*
*************************************************************************/
#ifndef __DGNC_DRIVER_H
#define __DGNC_DRIVER_H
#include <linux/types.h> /* To pick up the varions Linux types */
#include <linux/tty.h> /* To pick up the various tty structs/defines */
#include <linux/interrupt.h> /* For irqreturn_t type */
#include "dgnc_types.h" /* Additional types needed by the Digi header files */
#include "digi.h" /* Digi specific ioctl header */
#include "dgnc_kcompat.h" /* Kernel 2.4/2.6 compat includes */
#include "dgnc_sysfs.h" /* Support for SYSFS */
/*************************************************************************
*
* Driver defines
*
*************************************************************************/
/*
* Driver identification, error and debugging statments
*
* In theory, you can change all occurances of "digi" in the next
* three lines, and the driver printk's will all automagically change.
*
* APR((fmt, args, ...)); Always prints message
* DPR((fmt, args, ...)); Only prints if DGNC_TRACER is defined at
* compile time and dgnc_debug!=0
*/
#define PROCSTR "dgnc" /* /proc entries */
#define DEVSTR "/dev/dg/dgnc" /* /dev entries */
#define DRVSTR "dgnc" /* Driver name string
* displayed by APR */
#define APR(args) do { PRINTF_TO_KMEM(args); printk(DRVSTR": "); printk args; \
} while (0)
#define RAPR(args) do { PRINTF_TO_KMEM(args); printk args; } while (0)
#define TRC_TO_CONSOLE 1
/*
* Debugging levels can be set using debug insmod variable
* They can also be compiled out completely.
*/
#define DBG_INIT (dgnc_debug & 0x01)
#define DBG_BASIC (dgnc_debug & 0x02)
#define DBG_CORE (dgnc_debug & 0x04)
#define DBG_OPEN (dgnc_debug & 0x08)
#define DBG_CLOSE (dgnc_debug & 0x10)
#define DBG_READ (dgnc_debug & 0x20)
#define DBG_WRITE (dgnc_debug & 0x40)
#define DBG_IOCTL (dgnc_debug & 0x80)
#define DBG_PROC (dgnc_debug & 0x100)
#define DBG_PARAM (dgnc_debug & 0x200)
#define DBG_PSCAN (dgnc_debug & 0x400)
#define DBG_EVENT (dgnc_debug & 0x800)
#define DBG_DRAIN (dgnc_debug & 0x1000)
#define DBG_MSIGS (dgnc_debug & 0x2000)
#define DBG_MGMT (dgnc_debug & 0x4000)
#define DBG_INTR (dgnc_debug & 0x8000)
#define DBG_CARR (dgnc_debug & 0x10000)
#if defined(DGNC_TRACER)
# if defined(TRC_TO_KMEM)
/* Choose one: */
# define TRC_ON_OVERFLOW_WRAP_AROUND
# undef TRC_ON_OVERFLOW_SHIFT_BUFFER
# endif //TRC_TO_KMEM
# define TRC_MAXMSG 1024
# define TRC_OVERFLOW "(OVERFLOW)"
# define TRC_DTRC "/usr/bin/dtrc"
#if defined TRC_TO_CONSOLE
#define PRINTF_TO_CONSOLE(args) { printk(DRVSTR": "); printk args; }
#else //!defined TRACE_TO_CONSOLE
#define PRINTF_TO_CONSOLE(args)
#endif
#if defined TRC_TO_KMEM
#define PRINTF_TO_KMEM(args) dgnc_tracef args
#else //!defined TRC_TO_KMEM
#define PRINTF_TO_KMEM(args)
#endif
#define TRC(args) { PRINTF_TO_KMEM(args); PRINTF_TO_CONSOLE(args) }
# define DPR_INIT(ARGS) if (DBG_INIT) TRC(ARGS)
# define DPR_BASIC(ARGS) if (DBG_BASIC) TRC(ARGS)
# define DPR_CORE(ARGS) if (DBG_CORE) TRC(ARGS)
# define DPR_OPEN(ARGS) if (DBG_OPEN) TRC(ARGS)
# define DPR_CLOSE(ARGS) if (DBG_CLOSE) TRC(ARGS)
# define DPR_READ(ARGS) if (DBG_READ) TRC(ARGS)
# define DPR_WRITE(ARGS) if (DBG_WRITE) TRC(ARGS)
# define DPR_IOCTL(ARGS) if (DBG_IOCTL) TRC(ARGS)
# define DPR_PROC(ARGS) if (DBG_PROC) TRC(ARGS)
# define DPR_PARAM(ARGS) if (DBG_PARAM) TRC(ARGS)
# define DPR_PSCAN(ARGS) if (DBG_PSCAN) TRC(ARGS)
# define DPR_EVENT(ARGS) if (DBG_EVENT) TRC(ARGS)
# define DPR_DRAIN(ARGS) if (DBG_DRAIN) TRC(ARGS)
# define DPR_CARR(ARGS) if (DBG_CARR) TRC(ARGS)
# define DPR_MGMT(ARGS) if (DBG_MGMT) TRC(ARGS)
# define DPR_INTR(ARGS) if (DBG_INTR) TRC(ARGS)
# define DPR_MSIGS(ARGS) if (DBG_MSIGS) TRC(ARGS)
# define DPR(ARGS) if (dgnc_debug) TRC(ARGS)
# define P(X) dgnc_tracef(#X "=%p\n", X)
# define X(X) dgnc_tracef(#X "=%x\n", X)
#else//!defined DGNC_TRACER
#define PRINTF_TO_KMEM(args)
# define TRC(ARGS)
# define DPR_INIT(ARGS)
# define DPR_BASIC(ARGS)
# define DPR_CORE(ARGS)
# define DPR_OPEN(ARGS)
# define DPR_CLOSE(ARGS)
# define DPR_READ(ARGS)
# define DPR_WRITE(ARGS)
# define DPR_IOCTL(ARGS)
# define DPR_PROC(ARGS)
# define DPR_PARAM(ARGS)
# define DPR_PSCAN(ARGS)
# define DPR_EVENT(ARGS)
# define DPR_DRAIN(ARGS)
# define DPR_CARR(ARGS)
# define DPR_MGMT(ARGS)
# define DPR_INTR(ARGS)
# define DPR_MSIGS(ARGS)
# define DPR(args)
#endif//DGNC_TRACER
/* Number of boards we support at once. */
#define MAXBOARDS 20
#define MAXPORTS 8
#define MAXTTYNAMELEN 200
/* Our 3 magic numbers for our board, channel and unit structs */
#define DGNC_BOARD_MAGIC 0x5c6df104
#define DGNC_CHANNEL_MAGIC 0x6c6df104
#define DGNC_UNIT_MAGIC 0x7c6df104
/* 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 we will send when our read queue is getting full */
#define MAX_STOPS_SENT 5
/* 4 extra for alignment play space */
#define WRITEBUFLEN ((4096) + 4)
#define MYFLIPLEN N_TTY_BUF_SIZE
#define dgnc_jiffies_from_ms(a) (((a) * HZ) / 1000)
/*
* Define a local default termios struct. All ports will be created
* with this termios initially. This is the same structure that is defined
* as the default in tty_io.c with the same settings overriden as in serial.c
*
* In short, this should match the internal serial ports' defaults.
*/
#define DEFAULT_IFLAGS (ICRNL | IXON)
#define DEFAULT_OFLAGS (OPOST | ONLCR)
#define DEFAULT_CFLAGS (B9600 | CS8 | CREAD | HUPCL | CLOCAL)
#define DEFAULT_LFLAGS (ISIG | ICANON | ECHO | ECHOE | ECHOK | \
ECHOCTL | ECHOKE | IEXTEN)
#ifndef _POSIX_VDISABLE
#define _POSIX_VDISABLE '\0'
#endif
#define SNIFF_MAX 65536 /* Sniff buffer size (2^n) */
#define SNIFF_MASK (SNIFF_MAX - 1) /* Sniff wrap mask */
/*
* Lock function/defines.
* Makes spotting lock/unlock locations easier.
*/
# define DGNC_SPINLOCK_INIT(x) spin_lock_init(&(x))
# define DGNC_LOCK(x,y) spin_lock_irqsave(&(x), y)
# define DGNC_UNLOCK(x,y) spin_unlock_irqrestore(&(x), y)
/*
* 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
};
/*************************************************************************
*
* Structures and closely related defines.
*
*************************************************************************/
struct dgnc_board;
struct channel_t;
/************************************************************************
* Per board operations structure *
************************************************************************/
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 */
/*
* Per-board information
*/
struct dgnc_board {
int magic; /* Board Magic number. */
int boardnum; /* Board number: 0-32 */
int type; /* Type of board */
char *name; /* Product Name */
struct pci_dev *pdev; /* Pointer to the pci_dev struct */
unsigned long bd_flags; /* Board flags */
u16 vendor; /* PCI vendor ID */
u16 device; /* PCI device ID */
u16 subvendor; /* PCI subsystem vendor ID */
u16 subdevice; /* PCI subsystem device ID */
uchar rev; /* PCI revision ID */
uint pci_bus; /* PCI bus value */
uint pci_slot; /* PCI slot value */
uint maxports; /* MAX ports this board can handle */
uchar dvid; /* Board specific device id */
uchar vpd[128]; /* VPD of board, if found */
uchar serial_num[20]; /* Serial number of board, if found in VPD */
spinlock_t bd_lock; /* Used to protect board */
spinlock_t bd_intr_lock; /* Used to protect the poller tasklet and
* the interrupt routine from each other.
*/
uint state; /* State of card. */
wait_queue_head_t state_wait; /* Place to sleep on for state change */
struct tasklet_struct helper_tasklet; /* Poll helper tasklet */
uint nasync; /* Number of ports on card */
uint irq; /* Interrupt request number */
ulong intr_count; /* Count of interrupts */
ulong intr_modem; /* Count of interrupts */
ulong intr_tx; /* Count of interrupts */
ulong intr_rx; /* Count of interrupts */
ulong membase; /* Start of base memory of the card */
ulong membase_end; /* End of base memory of the card */
u8 __iomem *re_map_membase;/* Remapped memory of the card */
ulong iobase; /* Start of io base of the card */
ulong iobase_end; /* End of io base of the card */
uint bd_uart_offset; /* Space between each UART */
struct channel_t *channels[MAXPORTS]; /* array of pointers to our channels. */
struct tty_driver SerialDriver;
char SerialName[200];
struct tty_driver PrintDriver;
char PrintName[200];
uint dgnc_Major_Serial_Registered;
uint dgnc_Major_TransparentPrint_Registered;
uint dgnc_Serial_Major;
uint dgnc_TransparentPrint_Major;
uint TtyRefCnt;
char *flipbuf; /* Our flip buffer, alloced if board is found */
u16 dpatype; /* The board "type", as defined by DPA */
u16 dpastatus; /* The board "status", as defined by DPA */
/*
* Mgmt data.
*/
char *msgbuf_head;
char *msgbuf;
uint bd_dividend; /* Board/UARTs specific dividend */
struct board_ops *bd_ops;
/* /proc/<board> entries */
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;
/************************************************************************
* Structure for terminal or printer unit.
************************************************************************/
struct un_t {
int magic; /* Unit Magic Number. */
struct channel_t *un_ch;
ulong un_time;
uint un_type;
uint un_open_count; /* Counter of opens to port */
|