staging: dgap: remove unused variable
[deliverable/linux.git] / drivers / staging / dgap / dgap.c
CommitLineData
c84b8b50
S
1/*
2 * Copyright 2003 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
818cc6fe 9 *
c84b8b50 10 * This program is distributed in the hope that it will be useful,
818cc6fe
MI
11 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
12 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
c84b8b50 13 * PURPOSE. See the GNU General Public License for more details.
818cc6fe 14 *
c84b8b50
S
15 */
16
b28ec88a
MH
17/*
18 * In the original out of kernel Digi dgap driver, firmware
19 * loading was done via user land to driver handshaking.
20 *
21 * For cards that support a concentrator (port expander),
22 * I believe the concentrator its self told the card which
23 * concentrator is actually attached and then that info
24 * was used to tell user land which concentrator firmware
25 * image was to be downloaded. I think even the BIOS or
26 * FEP images required could change with the connection
27 * of a particular concentrator.
28 *
29 * Since I have no access to any of these cards or
30 * concentrators, I cannot put the correct concentrator
31 * firmware file names into the firmware_info structure
32 * as is now done for the BIOS and FEP images.
33 *
34 * I think, but am not certain, that the cards supporting
35 * concentrators will function without them. So support
36 * of these cards has been left in this driver.
37 *
38 * In order to fully support those cards, they would
39 * either have to be acquired for dissection or maybe
40 * Digi International could provide some assistance.
41 */
42#undef DIGI_CONCENTRATORS_SUPPORTED
c84b8b50 43
6c66843d
DY
44#define pr_fmt(fmt) "dgap: " fmt
45
c84b8b50 46#include <linux/kernel.h>
c84b8b50
S
47#include <linux/module.h>
48#include <linux/pci.h>
49#include <linux/delay.h> /* For udelay */
351699d7 50#include <linux/slab.h>
3d9dc5db 51#include <linux/uaccess.h>
c84b8b50 52#include <linux/sched.h>
c84b8b50 53
a6792a3e
MH
54#include <linux/interrupt.h> /* For tasklet and interrupt structs/defines */
55#include <linux/ctype.h>
56#include <linux/tty.h>
57#include <linux/tty_flip.h>
58#include <linux/serial_reg.h>
3d9dc5db 59#include <linux/io.h> /* For read[bwl]/write[bwl] */
a6792a3e 60
7568f7d3
MH
61#include <linux/string.h>
62#include <linux/device.h>
63#include <linux/kdev_t.h>
b28ec88a 64#include <linux/firmware.h>
7568f7d3 65
ffc1c1da 66#include "dgap.h"
a6792a3e 67
c84b8b50
S
68/*
69 * File operations permitted on Control/Management major.
70 */
fea0683e 71static const struct file_operations dgap_board_fops = {
305ec874 72 .owner = THIS_MODULE,
c84b8b50
S
73};
74
fea0683e
MH
75static uint dgap_numboards;
76static struct board_t *dgap_board[MAXBOARDS];
b115b024 77static ulong dgap_poll_counter;
b115b024 78static int dgap_driver_state = DRIVER_INITIALIZED;
b115b024 79static int dgap_poll_tick = 20; /* Poll interval - 20 ms */
c84b8b50 80
b115b024 81static struct class *dgap_class;
c84b8b50 82
b053bb86 83static uint dgap_count = 500;
a6792a3e 84
c84b8b50
S
85/*
86 * Poller stuff
87 */
45c44ddd 88static DEFINE_SPINLOCK(dgap_poll_lock); /* Poll scheduling lock */
b115b024
MH
89static ulong dgap_poll_time; /* Time of next poll */
90static uint dgap_poll_stop; /* Used to tell poller to stop */
c84b8b50
S
91static struct timer_list dgap_poll_timer;
92
b28ec88a
MH
93/*
94 SUPPORTED PRODUCTS
95
96 Card Model Number of Ports Interface
97 ----------------------------------------------------------------
98 Acceleport Xem 4 - 64 (EIA232 & EIA422)
99 Acceleport Xr 4 & 8 (EIA232)
100 Acceleport Xr 920 4 & 8 (EIA232)
101 Acceleport C/X 8 - 128 (EIA232)
102 Acceleport EPC/X 8 - 224 (EIA232)
103 Acceleport Xr/422 4 & 8 (EIA422)
104 Acceleport 2r/920 2 (EIA232)
105 Acceleport 4r/920 4 (EIA232)
106 Acceleport 8r/920 8 (EIA232)
107
108 IBM 8-Port Asynchronous PCI Adapter (EIA232)
109 IBM 128-Port Asynchronous PCI Adapter (EIA232 & EIA422)
110*/
c84b8b50
S
111
112static struct pci_device_id dgap_pci_tbl[] = {
2f60b333
MH
113 { DIGI_VID, PCI_DEV_XEM_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
114 { DIGI_VID, PCI_DEV_CX_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
115 { DIGI_VID, PCI_DEV_CX_IBM_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
116 { DIGI_VID, PCI_DEV_EPCJ_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
117 { DIGI_VID, PCI_DEV_920_2_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
118 { DIGI_VID, PCI_DEV_920_4_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
119 { DIGI_VID, PCI_DEV_920_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
120 { DIGI_VID, PCI_DEV_XR_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
121 { DIGI_VID, PCI_DEV_XRJ_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
122 { DIGI_VID, PCI_DEV_XR_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
123 { DIGI_VID, PCI_DEV_XR_IBM_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
124 { DIGI_VID, PCI_DEV_XR_SAIP_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
125 { DIGI_VID, PCI_DEV_XR_BULL_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
126 { DIGI_VID, PCI_DEV_920_8_HP_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 },
127 { DIGI_VID, PCI_DEV_XEM_HP_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
c84b8b50
S
128 {0,} /* 0 terminated list. */
129};
130MODULE_DEVICE_TABLE(pci, dgap_pci_tbl);
131
c84b8b50
S
132/*
133 * A generic list of Product names, PCI Vendor ID, and PCI Device ID.
134 */
135struct board_id {
136 uint config_type;
2023d18e 137 u8 *name;
c84b8b50
S
138 uint maxports;
139 uint dpatype;
140};
141
fea0683e 142static struct board_id dgap_ids[] = {
2f60b333
MH
143 { PPCM, PCI_DEV_XEM_NAME, 64, (T_PCXM|T_PCLITE|T_PCIBUS) },
144 { PCX, PCI_DEV_CX_NAME, 128, (T_CX|T_PCIBUS) },
145 { PCX, PCI_DEV_CX_IBM_NAME, 128, (T_CX|T_PCIBUS) },
146 { PEPC, PCI_DEV_EPCJ_NAME, 224, (T_EPC|T_PCIBUS) },
147 { APORT2_920P, PCI_DEV_920_2_NAME, 2, (T_PCXR|T_PCLITE|T_PCIBUS) },
148 { APORT4_920P, PCI_DEV_920_4_NAME, 4, (T_PCXR|T_PCLITE|T_PCIBUS) },
149 { APORT8_920P, PCI_DEV_920_8_NAME, 8, (T_PCXR|T_PCLITE|T_PCIBUS) },
150 { PAPORT8, PCI_DEV_XR_NAME, 8, (T_PCXR|T_PCLITE|T_PCIBUS) },
151 { PAPORT8, PCI_DEV_XRJ_NAME, 8, (T_PCXR|T_PCLITE|T_PCIBUS) },
152 { PAPORT8, PCI_DEV_XR_422_NAME, 8, (T_PCXR|T_PCLITE|T_PCIBUS) },
153 { PAPORT8, PCI_DEV_XR_IBM_NAME, 8, (T_PCXR|T_PCLITE|T_PCIBUS) },
154 { PAPORT8, PCI_DEV_XR_SAIP_NAME, 8, (T_PCXR|T_PCLITE|T_PCIBUS) },
155 { PAPORT8, PCI_DEV_XR_BULL_NAME, 8, (T_PCXR|T_PCLITE|T_PCIBUS) },
156 { APORT8_920P, PCI_DEV_920_8_HP_NAME, 8, (T_PCXR|T_PCLITE|T_PCIBUS) },
157 { PPCM, PCI_DEV_XEM_HP_NAME, 64, (T_PCXM|T_PCLITE|T_PCIBUS) },
c84b8b50
S
158 {0,} /* 0 terminated list. */
159};
160
b28ec88a 161struct firmware_info {
174efc1f 162 u8 *conf_name; /* dgap.conf */
2023d18e
MH
163 u8 *bios_name; /* BIOS filename */
164 u8 *fep_name; /* FEP filename */
165 u8 *con_name; /* Concentrator filename FIXME*/
174efc1f 166 int num; /* sequence number */
b28ec88a
MH
167};
168
169/*
170 * Firmware - BIOS, FEP, and CONC filenames
171 */
172static struct firmware_info fw_info[] = {
8f5879c4
MH
173 { "dgap/dgap.conf", "dgap/sxbios.bin", "dgap/sxfep.bin", NULL, 0 },
174 { "dgap/dgap.conf", "dgap/cxpbios.bin", "dgap/cxpfep.bin", NULL, 1 },
175 { "dgap/dgap.conf", "dgap/cxpbios.bin", "dgap/cxpfep.bin", NULL, 2 },
176 { "dgap/dgap.conf", "dgap/pcibios.bin", "dgap/pcifep.bin", NULL, 3 },
177 { "dgap/dgap.conf", "dgap/xrbios.bin", "dgap/xrfep.bin", NULL, 4 },
178 { "dgap/dgap.conf", "dgap/xrbios.bin", "dgap/xrfep.bin", NULL, 5 },
179 { "dgap/dgap.conf", "dgap/xrbios.bin", "dgap/xrfep.bin", NULL, 6 },
180 { "dgap/dgap.conf", "dgap/xrbios.bin", "dgap/xrfep.bin", NULL, 7 },
181 { "dgap/dgap.conf", "dgap/xrbios.bin", "dgap/xrfep.bin", NULL, 8 },
182 { "dgap/dgap.conf", "dgap/xrbios.bin", "dgap/xrfep.bin", NULL, 9 },
183 { "dgap/dgap.conf", "dgap/xrbios.bin", "dgap/xrfep.bin", NULL, 10 },
184 { "dgap/dgap.conf", "dgap/xrbios.bin", "dgap/xrfep.bin", NULL, 11 },
185 { "dgap/dgap.conf", "dgap/xrbios.bin", "dgap/xrfep.bin", NULL, 12 },
186 { "dgap/dgap.conf", "dgap/xrbios.bin", "dgap/xrfep.bin", NULL, 13 },
187 { "dgap/dgap.conf", "dgap/sxbios.bin", "dgap/sxfep.bin", NULL, 14 },
188 {NULL,}
b28ec88a 189};
c84b8b50 190
a6792a3e
MH
191/*
192 * Default transparent print information.
193 */
194static struct digi_t dgap_digi_init = {
195 .digi_flags = DIGI_COOK, /* Flags */
196 .digi_maxcps = 100, /* Max CPS */
197 .digi_maxchar = 50, /* Max chars in print queue */
198 .digi_bufsize = 100, /* Printer buffer size */
199 .digi_onlen = 4, /* size of printer on string */
200 .digi_offlen = 4, /* size of printer off string */
201 .digi_onstr = "\033[5i", /* ANSI printer on string ] */
202 .digi_offstr = "\033[4i", /* ANSI printer off string ] */
203 .digi_term = "ansi" /* default terminal type */
204};
205
a6792a3e
MH
206/*
207 * Define a local default termios struct. All ports will be created
208 * with this termios initially.
209 *
210 * This defines a raw port at 9600 baud, 8 data bits, no parity,
211 * 1 stop bit.
212 */
213
fea0683e 214static struct ktermios dgap_default_termios = {
a6792a3e
MH
215 .c_iflag = (DEFAULT_IFLAGS), /* iflags */
216 .c_oflag = (DEFAULT_OFLAGS), /* oflags */
217 .c_cflag = (DEFAULT_CFLAGS), /* cflags */
218 .c_lflag = (DEFAULT_LFLAGS), /* lflags */
219 .c_cc = INIT_C_CC,
7d6069d7 220 .c_line = 0,
a6792a3e
MH
221};
222
69edaa21
MH
223/*
224 * Our needed internal static variables from dgap_parse.c
225 */
226static struct cnode dgap_head;
227#define MAXCWORD 200
228static char dgap_cword[MAXCWORD];
229
230struct toklist {
174efc1f
MH
231 int token;
232 char *string;
69edaa21
MH
233};
234
77a4492f 235static struct toklist dgap_brdtype[] = {
2f60b333
MH
236 { PCX, "Digi_AccelePort_C/X_PCI" },
237 { PEPC, "Digi_AccelePort_EPC/X_PCI" },
238 { PPCM, "Digi_AccelePort_Xem_PCI" },
239 { APORT2_920P, "Digi_AccelePort_2r_920_PCI" },
240 { APORT4_920P, "Digi_AccelePort_4r_920_PCI" },
241 { APORT8_920P, "Digi_AccelePort_8r_920_PCI" },
242 { PAPORT4, "Digi_AccelePort_4r_PCI(EIA-232/RS-422)" },
243 { PAPORT8, "Digi_AccelePort_8r_PCI(EIA-232/RS-422)" },
77a4492f
DY
244 { 0, NULL }
245};
246
247static struct toklist dgap_tlist[] = {
248 { BEGIN, "config_begin" },
249 { END, "config_end" },
250 { BOARD, "board" },
2f60b333
MH
251 { IO, "io" },
252 { PCIINFO, "pciinfo" },
253 { LINE, "line" },
254 { CONC, "conc" },
255 { CONC, "concentrator" },
256 { CX, "cx" },
257 { CX, "ccon" },
258 { EPC, "epccon" },
259 { EPC, "epc" },
260 { MOD, "module" },
261 { ID, "id" },
262 { STARTO, "start" },
263 { SPEED, "speed" },
264 { CABLE, "cable" },
265 { CONNECT, "connect" },
266 { METHOD, "method" },
267 { STATUS, "status" },
268 { CUSTOM, "Custom" },
269 { BASIC, "Basic" },
270 { MEM, "mem" },
271 { MEM, "memory" },
272 { PORTS, "ports" },
273 { MODEM, "modem" },
274 { NPORTS, "nports" },
275 { TTYN, "ttyname" },
276 { CU, "cuname" },
277 { PRINT, "prname" },
278 { CMAJOR, "major" },
279 { ALTPIN, "altpin" },
280 { USEINTR, "useintr" },
281 { TTSIZ, "ttysize" },
282 { CHSIZ, "chsize" },
283 { BSSIZ, "boardsize" },
284 { UNTSIZ, "schedsize" },
285 { F2SIZ, "f2200size" },
286 { VPSIZ, "vpixsize" },
287 { 0, NULL }
69edaa21 288};
c84b8b50 289
c84b8b50
S
290
291/*
0b2cf5c8
DY
292 * dgap_sindex: much like index(), but it looks for a match of any character in
293 * the group, and returns that position. If the first character is a ^, then
294 * this will match the first occurrence not in that group.
c84b8b50 295 */
0b2cf5c8 296static char *dgap_sindex(char *string, char *group)
c84b8b50 297{
0b2cf5c8 298 char *ptr;
002de0ba 299
0b2cf5c8
DY
300 if (!string || !group)
301 return NULL;
002de0ba 302
0b2cf5c8
DY
303 if (*group == '^') {
304 group++;
305 for (; *string; string++) {
306 for (ptr = group; *ptr; ptr++) {
307 if (*ptr == *string)
308 break;
309 }
310 if (*ptr == '\0')
311 return string;
312 }
313 } else {
314 for (; *string; string++) {
315 for (ptr = group; *ptr; ptr++) {
316 if (*ptr == *string)
317 return string;
318 }
319 }
320 }
818cc6fe 321
0b2cf5c8 322 return NULL;
c84b8b50
S
323}
324
c84b8b50 325/*
0b2cf5c8
DY
326 * get a word from the input stream, also keep track of current line number.
327 * words are separated by whitespace.
c84b8b50 328 */
0b2cf5c8 329static char *dgap_getword(char **in)
c84b8b50 330{
0b2cf5c8 331 char *ret_ptr = *in;
c84b8b50 332
0b2cf5c8 333 char *ptr = dgap_sindex(*in, " \t\n");
af07daa0 334
0b2cf5c8
DY
335 /* If no word found, return null */
336 if (!ptr)
337 return NULL;
af07daa0 338
0b2cf5c8
DY
339 /* Mark new location for our buffer */
340 *ptr = '\0';
341 *in = ptr + 1;
0669e5fa 342
0b2cf5c8
DY
343 /* Eat any extra spaces/tabs/newlines that might be present */
344 while (*in && **in && ((**in == ' ') ||
345 (**in == '\t') ||
346 (**in == '\n'))) {
347 **in = '\0';
348 *in = *in + 1;
0669e5fa 349 }
af07daa0 350
0b2cf5c8 351 return ret_ptr;
c84b8b50
S
352}
353
ebf72ccf 354
0b2cf5c8
DY
355/*
356 * Get a token from the input file; return 0 if end of file is reached
357 */
358static int dgap_gettok(char **in)
359{
360 char *w;
361 struct toklist *t;
ebf72ccf 362
0b2cf5c8
DY
363 if (strstr(dgap_cword, "board")) {
364 w = dgap_getword(in);
365 snprintf(dgap_cword, MAXCWORD, "%s", w);
366 for (t = dgap_brdtype; t->token != 0; t++) {
367 if (!strcmp(w, t->string))
368 return t->token;
369 }
370 } else {
371 while ((w = dgap_getword(in))) {
372 snprintf(dgap_cword, MAXCWORD, "%s", w);
373 for (t = dgap_tlist; t->token != 0; t++) {
374 if (!strcmp(w, t->string))
375 return t->token;
376 }
377 }
378 }
ebf72ccf 379
0b2cf5c8 380 return 0;
ebf72ccf
DY
381}
382
0b2cf5c8
DY
383/*
384 * dgap_checknode: see if all the necessary info has been supplied for a node
385 * before creating the next node.
386 */
387static int dgap_checknode(struct cnode *p)
c84b8b50 388{
0b2cf5c8
DY
389 switch (p->type) {
390 case LNODE:
391 if (p->u.line.v_speed == 0) {
392 pr_err("line speed not specified");
393 return 1;
394 }
395 return 0;
acfd4aae 396
0b2cf5c8
DY
397 case CNODE:
398 if (p->u.conc.v_speed == 0) {
399 pr_err("concentrator line speed not specified");
400 return 1;
401 }
402 if (p->u.conc.v_nport == 0) {
403 pr_err("number of ports on concentrator not specified");
404 return 1;
405 }
406 if (p->u.conc.v_id == 0) {
407 pr_err("concentrator id letter not specified");
408 return 1;
409 }
410 return 0;
3c3befef 411
0b2cf5c8
DY
412 case MNODE:
413 if (p->u.module.v_nport == 0) {
414 pr_err("number of ports on EBI module not specified");
415 return 1;
416 }
417 if (p->u.module.v_id == 0) {
418 pr_err("EBI module id letter not specified");
419 return 1;
420 }
421 return 0;
422 }
423 return 0;
424}
3c3befef 425
0b2cf5c8
DY
426/*
427 * Given a board pointer, returns whether we should use interrupts or not.
428 */
429static uint dgap_config_get_useintr(struct board_t *bd)
430{
431 struct cnode *p;
3c3befef 432
0b2cf5c8
DY
433 if (!bd)
434 return 0;
3c3befef 435
0b2cf5c8
DY
436 for (p = bd->bd_config; p; p = p->next) {
437 if (p->type == INTRNODE) {
438 /*
439 * check for pcxr types.
440 */
441 return p->u.useintr;
442 }
443 }
7bc26a68 444
0b2cf5c8 445 /* If not found, then don't turn on interrupts. */
3c3befef 446 return 0;
c84b8b50
S
447}
448
c84b8b50 449/*
0b2cf5c8 450 * Given a board pointer, returns whether we turn on altpin or not.
c84b8b50 451 */
0b2cf5c8 452static uint dgap_config_get_altpin(struct board_t *bd)
c84b8b50 453{
0b2cf5c8 454 struct cnode *p;
c84b8b50 455
0b2cf5c8
DY
456 if (!bd)
457 return 0;
c84b8b50 458
0b2cf5c8
DY
459 for (p = bd->bd_config; p; p = p->next) {
460 if (p->type == ANODE) {
461 /*
462 * check for pcxr types.
463 */
464 return p->u.altpin;
465 }
c84b8b50
S
466 }
467
0b2cf5c8
DY
468 /* If not found, then don't turn on interrupts. */
469 return 0;
c84b8b50
S
470}
471
c84b8b50 472/*
0b2cf5c8
DY
473 * Given a specific type of board, if found, detached link and
474 * returns the first occurrence in the list.
c84b8b50 475 */
0b2cf5c8 476static struct cnode *dgap_find_config(int type, int bus, int slot)
c84b8b50 477{
0b2cf5c8 478 struct cnode *p, *prev, *prev2, *found;
c84b8b50 479
0b2cf5c8 480 p = &dgap_head;
c84b8b50 481
0b2cf5c8
DY
482 while (p->next) {
483 prev = p;
484 p = p->next;
c84b8b50 485
0b2cf5c8
DY
486 if (p->type != BNODE)
487 continue;
c84b8b50 488
0b2cf5c8
DY
489 if (p->u.board.type != type)
490 continue;
c84b8b50 491
0b2cf5c8
DY
492 if (p->u.board.v_pcibus &&
493 p->u.board.pcibus != bus)
494 continue;
c84b8b50 495
0b2cf5c8
DY
496 if (p->u.board.v_pcislot &&
497 p->u.board.pcislot != slot)
498 continue;
c84b8b50 499
0b2cf5c8
DY
500 found = p;
501 /*
502 * Keep walking thru the list till we
503 * find the next board.
504 */
505 while (p->next) {
506 prev2 = p;
507 p = p->next;
c84b8b50 508
0b2cf5c8
DY
509 if (p->type != BNODE)
510 continue;
511
512 /*
513 * Mark the end of our 1 board
514 * chain of configs.
515 */
516 prev2->next = NULL;
517
518 /*
519 * Link the "next" board to the
520 * previous board, effectively
521 * "unlinking" our board from
522 * the main config.
523 */
524 prev->next = p;
525
526 return found;
527 }
528 /*
529 * It must be the last board in the list.
530 */
531 prev->next = NULL;
532 return found;
533 }
534 return NULL;
c84b8b50
S
535}
536
c84b8b50 537/*
0b2cf5c8
DY
538 * Given a board pointer, walks the config link, counting up
539 * all ports user specified should be on the board.
540 * (This does NOT mean they are all actually present right now tho)
c84b8b50 541 */
0b2cf5c8 542static uint dgap_config_get_num_prts(struct board_t *bd)
c84b8b50 543{
0b2cf5c8
DY
544 int count = 0;
545 struct cnode *p;
c84b8b50 546
0b2cf5c8
DY
547 if (!bd)
548 return 0;
c84b8b50 549
0b2cf5c8 550 for (p = bd->bd_config; p; p = p->next) {
c84b8b50 551
0b2cf5c8
DY
552 switch (p->type) {
553 case BNODE:
554 /*
555 * check for pcxr types.
556 */
557 if (p->u.board.type > EPCFE)
558 count += p->u.board.nport;
559 break;
560 case CNODE:
561 count += p->u.conc.nport;
562 break;
563 case MNODE:
564 count += p->u.module.nport;
565 break;
566 }
f86c55c9 567 }
0b2cf5c8
DY
568 return count;
569}
c84b8b50 570
0b2cf5c8
DY
571static char *dgap_create_config_string(struct board_t *bd, char *string)
572{
573 char *ptr = string;
574 struct cnode *p;
575 struct cnode *q;
576 int speed;
c84b8b50 577
0b2cf5c8
DY
578 if (!bd) {
579 *ptr = 0xff;
580 return string;
c84b8b50
S
581 }
582
0b2cf5c8 583 for (p = bd->bd_config; p; p = p->next) {
c0c31b9b 584
0b2cf5c8
DY
585 switch (p->type) {
586 case LNODE:
587 *ptr = '\0';
588 ptr++;
589 *ptr = p->u.line.speed;
590 ptr++;
591 break;
592 case CNODE:
593 /*
594 * Because the EPC/con concentrators can have EM modules
595 * hanging off of them, we have to walk ahead in the
596 * list and keep adding the number of ports on each EM
597 * to the config. UGH!
598 */
599 speed = p->u.conc.speed;
600 q = p->next;
601 if (q && (q->type == MNODE)) {
602 *ptr = (p->u.conc.nport + 0x80);
603 ptr++;
604 p = q;
605 while (q->next && (q->next->type) == MNODE) {
606 *ptr = (q->u.module.nport + 0x80);
607 ptr++;
608 p = q;
609 q = q->next;
610 }
611 *ptr = q->u.module.nport;
612 ptr++;
613 } else {
614 *ptr = p->u.conc.nport;
615 ptr++;
616 }
f86c55c9 617
0b2cf5c8
DY
618 *ptr = speed;
619 ptr++;
620 break;
621 }
622 }
f86c55c9 623
0b2cf5c8
DY
624 *ptr = 0xff;
625 return string;
c84b8b50
S
626}
627
0b2cf5c8
DY
628/*
629 * Parse a configuration file read into memory as a string.
630 */
631static int dgap_parsefile(char **in)
305ec874 632{
0b2cf5c8 633 struct cnode *p, *brd, *line, *conc;
7d6069d7 634 int rc;
0b2cf5c8
DY
635 char *s;
636 int linecnt = 0;
c84b8b50 637
0b2cf5c8
DY
638 p = &dgap_head;
639 brd = line = conc = NULL;
c84b8b50 640
0b2cf5c8
DY
641 /* perhaps we are adding to an existing list? */
642 while (p->next)
643 p = p->next;
c84b8b50 644
0b2cf5c8
DY
645 /* file must start with a BEGIN */
646 while ((rc = dgap_gettok(in)) != BEGIN) {
647 if (rc == 0) {
648 pr_err("unexpected EOF");
649 return -1;
650 }
c84b8b50 651 }
c84b8b50 652
0b2cf5c8
DY
653 for (; ;) {
654 int board_type = 0;
655 int conc_type = 0;
656 int module_type = 0;
78a7966e 657
0b2cf5c8
DY
658 rc = dgap_gettok(in);
659 if (rc == 0) {
660 pr_err("unexpected EOF");
661 return -1;
662 }
b28ec88a 663
0b2cf5c8
DY
664 switch (rc) {
665 case BEGIN: /* should only be 1 begin */
666 pr_err("unexpected config_begin\n");
667 return -1;
b28ec88a 668
0b2cf5c8
DY
669 case END:
670 return 0;
9e844016 671
0b2cf5c8
DY
672 case BOARD: /* board info */
673 if (dgap_checknode(p))
674 return -1;
b28ec88a 675
0b2cf5c8
DY
676 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
677 if (!p->next)
678 return -1;
b28ec88a 679
0b2cf5c8 680 p = p->next;
23aa2ad4 681
0b2cf5c8
DY
682 p->type = BNODE;
683 p->u.board.status = kstrdup("No", GFP_KERNEL);
684 line = conc = NULL;
685 brd = p;
686 linecnt = -1;
b28ec88a 687
0b2cf5c8
DY
688 board_type = dgap_gettok(in);
689 if (board_type == 0) {
690 pr_err("board !!type not specified");
691 return -1;
692 }
b28ec88a 693
0b2cf5c8 694 p->u.board.type = board_type;
b28ec88a 695
0b2cf5c8 696 break;
b28ec88a 697
0b2cf5c8
DY
698 case IO: /* i/o port */
699 if (p->type != BNODE) {
700 pr_err("IO port only valid for boards");
701 return -1;
702 }
703 s = dgap_getword(in);
704 if (!s) {
705 pr_err("unexpected end of file");
706 return -1;
707 }
708 p->u.board.portstr = kstrdup(s, GFP_KERNEL);
709 if (kstrtol(s, 0, &p->u.board.port)) {
710 pr_err("bad number for IO port");
711 return -1;
712 }
713 p->u.board.v_port = 1;
714 break;
c84b8b50 715
0b2cf5c8
DY
716 case MEM: /* memory address */
717 if (p->type != BNODE) {
718 pr_err("memory address only valid for boards");
719 return -1;
720 }
721 s = dgap_getword(in);
722 if (!s) {
723 pr_err("unexpected end of file");
724 return -1;
725 }
726 p->u.board.addrstr = kstrdup(s, GFP_KERNEL);
727 if (kstrtoul(s, 0, &p->u.board.addr)) {
728 pr_err("bad number for memory address");
729 return -1;
c84b8b50 730 }
0b2cf5c8
DY
731 p->u.board.v_addr = 1;
732 break;
c84b8b50 733
0b2cf5c8
DY
734 case PCIINFO: /* pci information */
735 if (p->type != BNODE) {
736 pr_err("memory address only valid for boards");
737 return -1;
738 }
739 s = dgap_getword(in);
740 if (!s) {
741 pr_err("unexpected end of file");
742 return -1;
743 }
744 p->u.board.pcibusstr = kstrdup(s, GFP_KERNEL);
745 if (kstrtoul(s, 0, &p->u.board.pcibus)) {
746 pr_err("bad number for pci bus");
747 return -1;
748 }
749 p->u.board.v_pcibus = 1;
750 s = dgap_getword(in);
751 if (!s) {
752 pr_err("unexpected end of file");
753 return -1;
754 }
755 p->u.board.pcislotstr = kstrdup(s, GFP_KERNEL);
756 if (kstrtoul(s, 0, &p->u.board.pcislot)) {
757 pr_err("bad number for pci slot");
758 return -1;
759 }
760 p->u.board.v_pcislot = 1;
761 break;
c84b8b50 762
0b2cf5c8
DY
763 case METHOD:
764 if (p->type != BNODE) {
765 pr_err("install method only valid for boards");
766 return -1;
767 }
768 s = dgap_getword(in);
769 if (!s) {
770 pr_err("unexpected end of file");
771 return -1;
772 }
773 p->u.board.method = kstrdup(s, GFP_KERNEL);
774 p->u.board.v_method = 1;
775 break;
a6792a3e 776
0b2cf5c8
DY
777 case STATUS:
778 if (p->type != BNODE) {
779 pr_err("config status only valid for boards");
780 return -1;
781 }
782 s = dgap_getword(in);
783 if (!s) {
784 pr_err("unexpected end of file");
785 return -1;
786 }
787 p->u.board.status = kstrdup(s, GFP_KERNEL);
788 break;
a6792a3e 789
0b2cf5c8
DY
790 case NPORTS: /* number of ports */
791 if (p->type == BNODE) {
792 s = dgap_getword(in);
793 if (!s) {
794 pr_err("unexpected end of file");
795 return -1;
796 }
797 if (kstrtol(s, 0, &p->u.board.nport)) {
798 pr_err("bad number for number of ports");
799 return -1;
800 }
801 p->u.board.v_nport = 1;
802 } else if (p->type == CNODE) {
803 s = dgap_getword(in);
804 if (!s) {
805 pr_err("unexpected end of file");
806 return -1;
807 }
808 if (kstrtol(s, 0, &p->u.conc.nport)) {
809 pr_err("bad number for number of ports");
810 return -1;
811 }
812 p->u.conc.v_nport = 1;
813 } else if (p->type == MNODE) {
814 s = dgap_getword(in);
815 if (!s) {
816 pr_err("unexpected end of file");
817 return -1;
818 }
819 if (kstrtol(s, 0, &p->u.module.nport)) {
820 pr_err("bad number for number of ports");
821 return -1;
822 }
823 p->u.module.v_nport = 1;
824 } else {
825 pr_err("nports only valid for concentrators or modules");
826 return -1;
827 }
828 break;
a6792a3e 829
0b2cf5c8
DY
830 case ID: /* letter ID used in tty name */
831 s = dgap_getword(in);
832 if (!s) {
833 pr_err("unexpected end of file");
834 return -1;
835 }
a6792a3e 836
0b2cf5c8 837 p->u.board.status = kstrdup(s, GFP_KERNEL);
a6792a3e 838
0b2cf5c8
DY
839 if (p->type == CNODE) {
840 p->u.conc.id = kstrdup(s, GFP_KERNEL);
841 p->u.conc.v_id = 1;
842 } else if (p->type == MNODE) {
843 p->u.module.id = kstrdup(s, GFP_KERNEL);
844 p->u.module.v_id = 1;
845 } else {
846 pr_err("id only valid for concentrators or modules");
847 return -1;
848 }
849 break;
a6792a3e 850
0b2cf5c8
DY
851 case STARTO: /* start offset of ID */
852 if (p->type == BNODE) {
853 s = dgap_getword(in);
854 if (!s) {
855 pr_err("unexpected end of file");
856 return -1;
857 }
858 if (kstrtol(s, 0, &p->u.board.start)) {
859 pr_err("bad number for start of tty count");
860 return -1;
861 }
862 p->u.board.v_start = 1;
863 } else if (p->type == CNODE) {
864 s = dgap_getword(in);
865 if (!s) {
866 pr_err("unexpected end of file");
867 return -1;
868 }
869 if (kstrtol(s, 0, &p->u.conc.start)) {
870 pr_err("bad number for start of tty count");
871 return -1;
872 }
873 p->u.conc.v_start = 1;
874 } else if (p->type == MNODE) {
875 s = dgap_getword(in);
876 if (!s) {
877 pr_err("unexpected end of file");
878 return -1;
879 }
880 if (kstrtol(s, 0, &p->u.module.start)) {
881 pr_err("bad number for start of tty count");
882 return -1;
883 }
884 p->u.module.v_start = 1;
885 } else {
886 pr_err("start only valid for concentrators or modules");
887 return -1;
888 }
889 break;
a6792a3e 890
0b2cf5c8
DY
891 case TTYN: /* tty name prefix */
892 if (dgap_checknode(p))
893 return -1;
a6792a3e 894
0b2cf5c8
DY
895 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
896 if (!p->next)
897 return -1;
a6792a3e 898
0b2cf5c8
DY
899 p = p->next;
900 p->type = TNODE;
a6792a3e 901
0b2cf5c8
DY
902 s = dgap_getword(in);
903 if (!s) {
904 pr_err("unexpeced end of file");
905 return -1;
906 }
907 p->u.ttyname = kstrdup(s, GFP_KERNEL);
908 if (!p->u.ttyname)
909 return -1;
a6792a3e 910
0b2cf5c8 911 break;
a6792a3e 912
0b2cf5c8
DY
913 case CU: /* cu name prefix */
914 if (dgap_checknode(p))
915 return -1;
a6792a3e 916
0b2cf5c8
DY
917 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
918 if (!p->next)
919 return -1;
a6792a3e 920
0b2cf5c8
DY
921 p = p->next;
922 p->type = CUNODE;
a6792a3e 923
0b2cf5c8
DY
924 s = dgap_getword(in);
925 if (!s) {
926 pr_err("unexpeced end of file");
927 return -1;
928 }
929 p->u.cuname = kstrdup(s, GFP_KERNEL);
930 if (!p->u.cuname)
931 return -1;
a6792a3e 932
0b2cf5c8 933 break;
a6792a3e 934
0b2cf5c8
DY
935 case LINE: /* line information */
936 if (dgap_checknode(p))
937 return -1;
938 if (!brd) {
939 pr_err("must specify board before line info");
940 return -1;
941 }
942 switch (brd->u.board.type) {
943 case PPCM:
944 pr_err("line not valid for PC/em");
945 return -1;
946 }
a6792a3e 947
0b2cf5c8
DY
948 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
949 if (!p->next)
950 return -1;
a6792a3e 951
0b2cf5c8
DY
952 p = p->next;
953 p->type = LNODE;
954 conc = NULL;
955 line = p;
956 linecnt++;
a6792a3e
MH
957 break;
958
0b2cf5c8
DY
959 case CONC: /* concentrator information */
960 if (dgap_checknode(p))
961 return -1;
962 if (!line) {
963 pr_err("must specify line info before concentrator");
964 return -1;
965 }
a6792a3e 966
0b2cf5c8
DY
967 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
968 if (!p->next)
969 return -1;
a6792a3e 970
0b2cf5c8
DY
971 p = p->next;
972 p->type = CNODE;
973 conc = p;
a6792a3e 974
0b2cf5c8
DY
975 if (linecnt)
976 brd->u.board.conc2++;
977 else
978 brd->u.board.conc1++;
a6792a3e 979
0b2cf5c8 980 conc_type = dgap_gettok(in);
ce5b615b
DY
981 if (conc_type == 0 || (conc_type != CX &&
982 conc_type != EPC)) {
0b2cf5c8
DY
983 pr_err("failed to set a type of concentratros");
984 return -1;
985 }
a6792a3e 986
0b2cf5c8 987 p->u.conc.type = conc_type;
a6792a3e 988
0b2cf5c8 989 break;
a6792a3e 990
0b2cf5c8
DY
991 case MOD: /* EBI module */
992 if (dgap_checknode(p))
993 return -1;
994 if (!brd) {
995 pr_err("must specify board info before EBI modules");
996 return -1;
997 }
998 switch (brd->u.board.type) {
999 case PPCM:
1000 linecnt = 0;
1001 break;
1002 default:
1003 if (!conc) {
1004 pr_err("must specify concentrator info before EBI module");
1005 return -1;
1006 }
1007 }
a6792a3e 1008
0b2cf5c8
DY
1009 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1010 if (!p->next)
1011 return -1;
a6792a3e 1012
0b2cf5c8
DY
1013 p = p->next;
1014 p->type = MNODE;
a6792a3e 1015
0b2cf5c8
DY
1016 if (linecnt)
1017 brd->u.board.module2++;
1018 else
1019 brd->u.board.module1++;
a6792a3e 1020
0b2cf5c8 1021 module_type = dgap_gettok(in);
ce5b615b
DY
1022 if (module_type == 0 || (module_type != PORTS &&
1023 module_type != MODEM)) {
0b2cf5c8
DY
1024 pr_err("failed to set a type of module");
1025 return -1;
1026 }
a6792a3e 1027
0b2cf5c8 1028 p->u.module.type = module_type;
a6792a3e 1029
0b2cf5c8 1030 break;
a6792a3e 1031
0b2cf5c8
DY
1032 case CABLE:
1033 if (p->type == LNODE) {
1034 s = dgap_getword(in);
1035 if (!s) {
1036 pr_err("unexpected end of file");
1037 return -1;
1038 }
1039 p->u.line.cable = kstrdup(s, GFP_KERNEL);
1040 p->u.line.v_cable = 1;
1041 }
1042 break;
a6792a3e 1043
0b2cf5c8
DY
1044 case SPEED: /* sync line speed indication */
1045 if (p->type == LNODE) {
1046 s = dgap_getword(in);
1047 if (!s) {
1048 pr_err("unexpected end of file");
1049 return -1;
1050 }
1051 if (kstrtol(s, 0, &p->u.line.speed)) {
1052 pr_err("bad number for line speed");
1053 return -1;
1054 }
1055 p->u.line.v_speed = 1;
1056 } else if (p->type == CNODE) {
1057 s = dgap_getword(in);
1058 if (!s) {
1059 pr_err("unexpected end of file");
1060 return -1;
1061 }
1062 if (kstrtol(s, 0, &p->u.conc.speed)) {
1063 pr_err("bad number for line speed");
1064 return -1;
1065 }
1066 p->u.conc.v_speed = 1;
1067 } else {
1068 pr_err("speed valid only for lines or concentrators.");
1069 return -1;
1070 }
1071 break;
a6792a3e 1072
0b2cf5c8
DY
1073 case CONNECT:
1074 if (p->type == CNODE) {
1075 s = dgap_getword(in);
1076 if (!s) {
1077 pr_err("unexpected end of file");
1078 return -1;
1079 }
1080 p->u.conc.connect = kstrdup(s, GFP_KERNEL);
1081 p->u.conc.v_connect = 1;
1082 }
1083 break;
1084 case PRINT: /* transparent print name prefix */
1085 if (dgap_checknode(p))
1086 return -1;
a6792a3e 1087
0b2cf5c8
DY
1088 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1089 if (!p->next)
1090 return -1;
a6792a3e 1091
0b2cf5c8
DY
1092 p = p->next;
1093 p->type = PNODE;
a6792a3e 1094
0b2cf5c8
DY
1095 s = dgap_getword(in);
1096 if (!s) {
1097 pr_err("unexpeced end of file");
1098 return -1;
1099 }
1100 p->u.printname = kstrdup(s, GFP_KERNEL);
1101 if (!p->u.printname)
1102 return -1;
a6792a3e 1103
0b2cf5c8 1104 break;
a6792a3e 1105
0b2cf5c8
DY
1106 case CMAJOR: /* major number */
1107 if (dgap_checknode(p))
1108 return -1;
a6792a3e 1109
0b2cf5c8
DY
1110 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1111 if (!p->next)
1112 return -1;
a6792a3e 1113
0b2cf5c8
DY
1114 p = p->next;
1115 p->type = JNODE;
a6792a3e 1116
0b2cf5c8
DY
1117 s = dgap_getword(in);
1118 if (!s) {
1119 pr_err("unexpected end of file");
1120 return -1;
1121 }
1122 if (kstrtol(s, 0, &p->u.majornumber)) {
1123 pr_err("bad number for major number");
1124 return -1;
1125 }
1126 break;
a6792a3e 1127
0b2cf5c8
DY
1128 case ALTPIN: /* altpin setting */
1129 if (dgap_checknode(p))
1130 return -1;
a6792a3e 1131
0b2cf5c8
DY
1132 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1133 if (!p->next)
1134 return -1;
a6792a3e 1135
0b2cf5c8
DY
1136 p = p->next;
1137 p->type = ANODE;
a6792a3e 1138
0b2cf5c8
DY
1139 s = dgap_getword(in);
1140 if (!s) {
1141 pr_err("unexpected end of file");
1142 return -1;
1143 }
1144 if (kstrtol(s, 0, &p->u.altpin)) {
1145 pr_err("bad number for altpin");
1146 return -1;
1147 }
1148 break;
a6792a3e 1149
0b2cf5c8
DY
1150 case USEINTR: /* enable interrupt setting */
1151 if (dgap_checknode(p))
1152 return -1;
a6792a3e 1153
0b2cf5c8
DY
1154 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1155 if (!p->next)
1156 return -1;
a6792a3e 1157
0b2cf5c8
DY
1158 p = p->next;
1159 p->type = INTRNODE;
1160 s = dgap_getword(in);
1161 if (!s) {
1162 pr_err("unexpected end of file");
1163 return -1;
1164 }
1165 if (kstrtol(s, 0, &p->u.useintr)) {
1166 pr_err("bad number for useintr");
1167 return -1;
1168 }
1169 break;
a6792a3e 1170
0b2cf5c8
DY
1171 case TTSIZ: /* size of tty structure */
1172 if (dgap_checknode(p))
1173 return -1;
a6792a3e 1174
0b2cf5c8
DY
1175 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1176 if (!p->next)
1177 return -1;
a6792a3e 1178
0b2cf5c8
DY
1179 p = p->next;
1180 p->type = TSNODE;
a6792a3e 1181
0b2cf5c8
DY
1182 s = dgap_getword(in);
1183 if (!s) {
1184 pr_err("unexpected end of file");
1185 return -1;
1186 }
1187 if (kstrtol(s, 0, &p->u.ttysize)) {
1188 pr_err("bad number for ttysize");
1189 return -1;
1190 }
1191 break;
a6792a3e 1192
0b2cf5c8
DY
1193 case CHSIZ: /* channel structure size */
1194 if (dgap_checknode(p))
1195 return -1;
a6792a3e 1196
0b2cf5c8
DY
1197 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1198 if (!p->next)
1199 return -1;
a6792a3e 1200
0b2cf5c8
DY
1201 p = p->next;
1202 p->type = CSNODE;
a6792a3e 1203
0b2cf5c8
DY
1204 s = dgap_getword(in);
1205 if (!s) {
1206 pr_err("unexpected end of file");
1207 return -1;
1208 }
1209 if (kstrtol(s, 0, &p->u.chsize)) {
1210 pr_err("bad number for chsize");
1211 return -1;
1212 }
1213 break;
a6792a3e 1214
0b2cf5c8
DY
1215 case BSSIZ: /* board structure size */
1216 if (dgap_checknode(p))
1217 return -1;
a6792a3e 1218
0b2cf5c8
DY
1219 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1220 if (!p->next)
1221 return -1;
a6792a3e 1222
0b2cf5c8
DY
1223 p = p->next;
1224 p->type = BSNODE;
a6792a3e 1225
0b2cf5c8
DY
1226 s = dgap_getword(in);
1227 if (!s) {
1228 pr_err("unexpected end of file");
1229 return -1;
1230 }
1231 if (kstrtol(s, 0, &p->u.bssize)) {
1232 pr_err("bad number for bssize");
1233 return -1;
1234 }
1235 break;
a6792a3e 1236
0b2cf5c8
DY
1237 case UNTSIZ: /* sched structure size */
1238 if (dgap_checknode(p))
1239 return -1;
a6792a3e 1240
0b2cf5c8
DY
1241 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1242 if (!p->next)
1243 return -1;
a6792a3e 1244
0b2cf5c8
DY
1245 p = p->next;
1246 p->type = USNODE;
a6792a3e 1247
0b2cf5c8
DY
1248 s = dgap_getword(in);
1249 if (!s) {
1250 pr_err("unexpected end of file");
1251 return -1;
1252 }
1253 if (kstrtol(s, 0, &p->u.unsize)) {
1254 pr_err("bad number for schedsize");
1255 return -1;
1256 }
1257 break;
a6792a3e 1258
0b2cf5c8
DY
1259 case F2SIZ: /* f2200 structure size */
1260 if (dgap_checknode(p))
1261 return -1;
a6792a3e 1262
0b2cf5c8
DY
1263 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1264 if (!p->next)
1265 return -1;
1266
1267 p = p->next;
1268 p->type = FSNODE;
1269
1270 s = dgap_getword(in);
1271 if (!s) {
1272 pr_err("unexpected end of file");
1273 return -1;
1274 }
1275 if (kstrtol(s, 0, &p->u.f2size)) {
1276 pr_err("bad number for f2200size");
1277 return -1;
1278 }
1279 break;
a6792a3e 1280
0b2cf5c8
DY
1281 case VPSIZ: /* vpix structure size */
1282 if (dgap_checknode(p))
1283 return -1;
a6792a3e 1284
0b2cf5c8
DY
1285 p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
1286 if (!p->next)
1287 return -1;
a6792a3e 1288
0b2cf5c8
DY
1289 p = p->next;
1290 p->type = VSNODE;
a6792a3e 1291
0b2cf5c8
DY
1292 s = dgap_getword(in);
1293 if (!s) {
1294 pr_err("unexpected end of file");
1295 return -1;
1296 }
1297 if (kstrtol(s, 0, &p->u.vpixsize)) {
1298 pr_err("bad number for vpixsize");
1299 return -1;
1300 }
1301 break;
1302 }
1303 }
1304}
a6792a3e 1305
0b2cf5c8
DY
1306static void dgap_cleanup_nodes(void)
1307{
1308 struct cnode *p;
a6792a3e 1309
0b2cf5c8 1310 p = &dgap_head;
a6792a3e 1311
0b2cf5c8
DY
1312 while (p) {
1313 struct cnode *tmp = p->next;
a6792a3e 1314
0b2cf5c8
DY
1315 if (p->type == NULLNODE) {
1316 p = tmp;
1317 continue;
1318 }
a6792a3e 1319
0b2cf5c8
DY
1320 switch (p->type) {
1321 case BNODE:
1322 kfree(p->u.board.portstr);
1323 kfree(p->u.board.addrstr);
1324 kfree(p->u.board.pcibusstr);
1325 kfree(p->u.board.pcislotstr);
1326 kfree(p->u.board.method);
1327 break;
1328 case CNODE:
1329 kfree(p->u.conc.id);
1330 kfree(p->u.conc.connect);
1331 break;
1332 case MNODE:
1333 kfree(p->u.module.id);
1334 break;
1335 case TNODE:
1336 kfree(p->u.ttyname);
1337 break;
1338 case CUNODE:
1339 kfree(p->u.cuname);
1340 break;
1341 case LNODE:
1342 kfree(p->u.line.cable);
1343 break;
1344 case PNODE:
1345 kfree(p->u.printname);
1346 break;
1347 }
a6792a3e 1348
0b2cf5c8
DY
1349 kfree(p->u.board.status);
1350 kfree(p);
1351 p = tmp;
1352 }
a6792a3e
MH
1353}
1354
a6792a3e 1355/*
0b2cf5c8
DY
1356 * Retrives the current custom baud rate from FEP memory,
1357 * and returns it back to the user.
1358 * Returns 0 on error.
a6792a3e 1359 */
0b2cf5c8 1360static uint dgap_get_custom_baud(struct channel_t *ch)
a6792a3e 1361{
0b2cf5c8
DY
1362 u8 __iomem *vaddr;
1363 ulong offset;
1364 uint value;
a6792a3e 1365
0b2cf5c8
DY
1366 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
1367 return 0;
a6792a3e 1368
0b2cf5c8
DY
1369 if (!ch->ch_bd || ch->ch_bd->magic != DGAP_BOARD_MAGIC)
1370 return 0;
a6792a3e 1371
0b2cf5c8
DY
1372 if (!(ch->ch_bd->bd_flags & BD_FEP5PLUS))
1373 return 0;
a6792a3e 1374
0b2cf5c8 1375 vaddr = ch->ch_bd->re_map_membase;
a6792a3e 1376
0b2cf5c8
DY
1377 if (!vaddr)
1378 return 0;
a6792a3e 1379
0b2cf5c8
DY
1380 /*
1381 * Go get from fep mem, what the fep
1382 * believes the custom baud rate is.
1383 */
1384 offset = (ioread16(vaddr + ECS_SEG) << 4) + (ch->ch_portnum * 0x28)
1385 + LINE_SPEED;
a6792a3e 1386
0b2cf5c8
DY
1387 value = readw(vaddr + offset);
1388 return value;
1389}
a6792a3e 1390
0b2cf5c8
DY
1391/*
1392 * Remap PCI memory.
1393 */
1394static int dgap_remap(struct board_t *brd)
1395{
1396 if (!brd || brd->magic != DGAP_BOARD_MAGIC)
1397 return -EIO;
a6792a3e 1398
0b2cf5c8
DY
1399 if (!request_mem_region(brd->membase, 0x200000, "dgap"))
1400 return -ENOMEM;
a6792a3e 1401
0b2cf5c8 1402 if (!request_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000,
aa9895da
DY
1403 "dgap"))
1404 goto err_req_mem;
a6792a3e 1405
0b2cf5c8 1406 brd->re_map_membase = ioremap(brd->membase, 0x200000);
aa9895da
DY
1407 if (!brd->re_map_membase)
1408 goto err_remap_mem;
a6792a3e 1409
0b2cf5c8 1410 brd->re_map_port = ioremap((brd->membase + PCI_IO_OFFSET), 0x200000);
aa9895da
DY
1411 if (!brd->re_map_port)
1412 goto err_remap_port;
a6792a3e 1413
0b2cf5c8 1414 return 0;
aa9895da
DY
1415
1416err_remap_port:
1417 iounmap(brd->re_map_membase);
1418err_remap_mem:
1419 release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
1420err_req_mem:
1421 release_mem_region(brd->membase, 0x200000);
1422
1423 return -ENOMEM;
0b2cf5c8 1424}
a6792a3e 1425
0b2cf5c8
DY
1426static void dgap_unmap(struct board_t *brd)
1427{
1428 iounmap(brd->re_map_port);
1429 iounmap(brd->re_map_membase);
1430 release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
1431 release_mem_region(brd->membase, 0x200000);
1432}
a6792a3e 1433
0b2cf5c8
DY
1434/*
1435 * dgap_parity_scan()
1436 *
1437 * Convert the FEP5 way of reporting parity errors and breaks into
1438 * the Linux line discipline way.
1439 */
1440static void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf,
1441 unsigned char *fbuf, int *len)
1442{
1443 int l = *len;
1444 int count = 0;
1445 unsigned char *in, *cout, *fout;
1446 unsigned char c;
a6792a3e 1447
0b2cf5c8
DY
1448 in = cbuf;
1449 cout = cbuf;
1450 fout = fbuf;
1451
1452 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
1453 return;
1454
1455 while (l--) {
1456 c = *in++;
1457 switch (ch->pscan_state) {
1458 default:
1459 /* reset to sanity and fall through */
1460 ch->pscan_state = 0;
a6792a3e 1461
0b2cf5c8
DY
1462 case 0:
1463 /* No FF seen yet */
1464 if (c == (unsigned char) '\377')
1465 /* delete this character from stream */
1466 ch->pscan_state = 1;
1467 else {
1468 *cout++ = c;
1469 *fout++ = TTY_NORMAL;
1470 count += 1;
1471 }
1472 break;
a6792a3e 1473
0b2cf5c8
DY
1474 case 1:
1475 /* first FF seen */
1476 if (c == (unsigned char) '\377') {
1477 /* doubled ff, transform to single ff */
1478 *cout++ = c;
1479 *fout++ = TTY_NORMAL;
1480 count += 1;
1481 ch->pscan_state = 0;
1482 } else {
1483 /* save value examination in next state */
1484 ch->pscan_savechar = c;
1485 ch->pscan_state = 2;
1486 }
1487 break;
a6792a3e 1488
0b2cf5c8
DY
1489 case 2:
1490 /* third character of ff sequence */
a6792a3e 1491
0b2cf5c8 1492 *cout++ = c;
a6792a3e 1493
0b2cf5c8 1494 if (ch->pscan_savechar == 0x0) {
a6792a3e 1495
0b2cf5c8
DY
1496 if (c == 0x0) {
1497 ch->ch_err_break++;
1498 *fout++ = TTY_BREAK;
1499 } else {
1500 ch->ch_err_parity++;
1501 *fout++ = TTY_PARITY;
1502 }
1503 }
a6792a3e 1504
0b2cf5c8
DY
1505 count += 1;
1506 ch->pscan_state = 0;
1507 }
1508 }
1509 *len = count;
a6792a3e
MH
1510}
1511
0b2cf5c8 1512/*=======================================================================
a6792a3e 1513 *
0b2cf5c8
DY
1514 * dgap_input - Process received data.
1515 *
1516 * ch - Pointer to channel structure.
1517 *
1518 *=======================================================================*/
1519
1520static void dgap_input(struct channel_t *ch)
a6792a3e 1521{
174efc1f 1522 struct board_t *bd;
0b2cf5c8
DY
1523 struct bs_t __iomem *bs;
1524 struct tty_struct *tp;
1525 struct tty_ldisc *ld;
1526 uint rmask;
1527 uint head;
1528 uint tail;
1529 int data_len;
1530 ulong lock_flags;
1531 ulong lock_flags2;
1532 int flip_len;
1533 int len;
1534 int n;
1535 u8 *buf;
1536 u8 tmpchar;
1537 int s;
a6792a3e 1538
0b2cf5c8 1539 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
a6792a3e
MH
1540 return;
1541
0b2cf5c8 1542 tp = ch->ch_tun.un_tty;
a6792a3e 1543
0b2cf5c8
DY
1544 bs = ch->ch_bs;
1545 if (!bs)
a6792a3e
MH
1546 return;
1547
1548 bd = ch->ch_bd;
1549 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
1550 return;
1551
0b2cf5c8
DY
1552 spin_lock_irqsave(&bd->bd_lock, lock_flags);
1553 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
a6792a3e 1554
0b2cf5c8
DY
1555 /*
1556 * Figure the number of characters in the buffer.
1557 * Exit immediately if none.
1558 */
a6792a3e 1559
0b2cf5c8 1560 rmask = ch->ch_rsize - 1;
a6792a3e 1561
0b2cf5c8
DY
1562 head = readw(&(bs->rx_head));
1563 head &= rmask;
1564 tail = readw(&(bs->rx_tail));
1565 tail &= rmask;
1566
1567 data_len = (head - tail) & rmask;
1568
1569 if (data_len == 0) {
1570 writeb(1, &(bs->idata));
1571 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
1572 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
a6792a3e 1573 return;
0b2cf5c8 1574 }
a6792a3e 1575
0b2cf5c8
DY
1576 /*
1577 * If the device is not open, or CREAD is off, flush
1578 * input data and return immediately.
1579 */
1580 if ((bd->state != BOARD_READY) || !tp ||
1581 (tp->magic != TTY_MAGIC) ||
1582 !(ch->ch_tun.un_flags & UN_ISOPEN) ||
1583 !(tp->termios.c_cflag & CREAD) ||
1584 (ch->ch_tun.un_flags & UN_CLOSING)) {
1585
1586 writew(head, &(bs->rx_tail));
1587 writeb(1, &(bs->idata));
1588 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
1589 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
a6792a3e 1590 return;
0b2cf5c8 1591 }
a6792a3e 1592
0b2cf5c8
DY
1593 /*
1594 * If we are throttled, simply don't read any data.
1595 */
1596 if (ch->ch_flags & CH_RXBLOCK) {
1597 writeb(1, &(bs->idata));
1598 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
1599 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
a6792a3e 1600 return;
0b2cf5c8 1601 }
a6792a3e 1602
0b2cf5c8
DY
1603 /*
1604 * Ignore oruns.
1605 */
1606 tmpchar = readb(&(bs->orun));
1607 if (tmpchar) {
1608 ch->ch_err_overrun++;
1609 writeb(0, &(bs->orun));
1610 }
a6792a3e 1611
0b2cf5c8
DY
1612 /* Decide how much data we can send into the tty layer */
1613 flip_len = TTY_FLIPBUF_SIZE;
1614
1615 /* Chop down the length, if needed */
1616 len = min(data_len, flip_len);
1617 len = min(len, (N_TTY_BUF_SIZE - 1));
1618
1619 ld = tty_ldisc_ref(tp);
a6792a3e 1620
0b2cf5c8 1621#ifdef TTY_DONT_FLIP
a6792a3e 1622 /*
0b2cf5c8
DY
1623 * If the DONT_FLIP flag is on, don't flush our buffer, and act
1624 * like the ld doesn't have any space to put the data right now.
a6792a3e 1625 */
0b2cf5c8
DY
1626 if (test_bit(TTY_DONT_FLIP, &tp->flags))
1627 len = 0;
1628#endif
1629
1630 /*
1631 * If we were unable to get a reference to the ld,
1632 * don't flush our buffer, and act like the ld doesn't
1633 * have any space to put the data right now.
1634 */
1635 if (!ld) {
1636 len = 0;
1637 } else {
a6792a3e 1638 /*
0b2cf5c8
DY
1639 * If ld doesn't have a pointer to a receive_buf function,
1640 * flush the data, then act like the ld doesn't have any
1641 * space to put the data right now.
a6792a3e 1642 */
0b2cf5c8
DY
1643 if (!ld->ops->receive_buf) {
1644 writew(head, &(bs->rx_tail));
1645 len = 0;
1646 }
82ed9774 1647 }
a6792a3e 1648
0b2cf5c8
DY
1649 if (len <= 0) {
1650 writeb(1, &(bs->idata));
1651 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
1652 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
1653 if (ld)
1654 tty_ldisc_deref(ld);
7d6069d7
MH
1655 return;
1656 }
a6792a3e 1657
0b2cf5c8
DY
1658 buf = ch->ch_bd->flipbuf;
1659 n = len;
1660
1661 /*
1662 * n now contains the most amount of data we can copy,
1663 * bounded either by our buffer size or the amount
1664 * of data the card actually has pending...
1665 */
1666 while (n) {
1667
1668 s = ((head >= tail) ? head : ch->ch_rsize) - tail;
1669 s = min(s, n);
1670
1671 if (s <= 0)
1672 break;
1673
1674 memcpy_fromio(buf, ch->ch_raddr + tail, s);
1675
1676 tail += s;
1677 buf += s;
a6792a3e 1678
0b2cf5c8
DY
1679 n -= s;
1680 /* Flip queue if needed */
1681 tail &= rmask;
1682 }
a6792a3e 1683
0b2cf5c8
DY
1684 writew(tail, &(bs->rx_tail));
1685 writeb(1, &(bs->idata));
1686 ch->ch_rxcount += len;
a6792a3e
MH
1687
1688 /*
0b2cf5c8
DY
1689 * If we are completely raw, we don't need to go through a lot
1690 * of the tty layers that exist.
1691 * In this case, we take the shortest and fastest route we
1692 * can to relay the data to the user.
1693 *
1694 * On the other hand, if we are not raw, we need to go through
1695 * the tty layer, which has its API more well defined.
a6792a3e 1696 */
0b2cf5c8
DY
1697 if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
1698 dgap_parity_scan(ch, ch->ch_bd->flipbuf,
1699 ch->ch_bd->flipflagbuf, &len);
a6792a3e 1700
0b2cf5c8
DY
1701 len = tty_buffer_request_room(tp->port, len);
1702 tty_insert_flip_string_flags(tp->port, ch->ch_bd->flipbuf,
1703 ch->ch_bd->flipflagbuf, len);
1704 } else {
1705 len = tty_buffer_request_room(tp->port, len);
1706 tty_insert_flip_string(tp->port, ch->ch_bd->flipbuf, len);
1707 }
a6792a3e 1708
0b2cf5c8
DY
1709 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
1710 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
a6792a3e 1711
0b2cf5c8
DY
1712 /* Tell the tty layer its okay to "eat" the data now */
1713 tty_flip_buffer_push(tp->port);
a6792a3e 1714
0b2cf5c8
DY
1715 if (ld)
1716 tty_ldisc_deref(ld);
a6792a3e 1717
0b2cf5c8 1718}
a6792a3e 1719
0b2cf5c8
DY
1720static void dgap_write_wakeup(struct board_t *bd, struct channel_t *ch,
1721 struct un_t *un, u32 mask,
1722 unsigned long *irq_flags1,
1723 unsigned long *irq_flags2)
1724{
1725 if (!(un->un_flags & mask))
1726 return;
492a1e7b 1727
0b2cf5c8 1728 un->un_flags &= ~mask;
492a1e7b 1729
0b2cf5c8
DY
1730 if (!(un->un_flags & UN_ISOPEN))
1731 return;
a6792a3e 1732
0b2cf5c8
DY
1733 if ((un->un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
1734 un->un_tty->ldisc->ops->write_wakeup) {
1735 spin_unlock_irqrestore(&ch->ch_lock, *irq_flags2);
1736 spin_unlock_irqrestore(&bd->bd_lock, *irq_flags1);
a6792a3e 1737
0b2cf5c8 1738 (un->un_tty->ldisc->ops->write_wakeup)(un->un_tty);
a6792a3e 1739
0b2cf5c8
DY
1740 spin_lock_irqsave(&bd->bd_lock, *irq_flags1);
1741 spin_lock_irqsave(&ch->ch_lock, *irq_flags2);
a6792a3e 1742 }
0b2cf5c8 1743 wake_up_interruptible(&un->un_tty->write_wait);
a6792a3e 1744 wake_up_interruptible(&un->un_flags_wait);
a6792a3e
MH
1745}
1746
0b2cf5c8
DY
1747/************************************************************************
1748 * Determines when CARRIER changes state and takes appropriate
1749 * action.
1750 ************************************************************************/
1751static void dgap_carrier(struct channel_t *ch)
a6792a3e 1752{
7dfa3831 1753 struct board_t *bd;
a6792a3e 1754
0b2cf5c8
DY
1755 int virt_carrier = 0;
1756 int phys_carrier = 0;
a6792a3e 1757
a6792a3e 1758 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
0b2cf5c8 1759 return;
a6792a3e
MH
1760
1761 bd = ch->ch_bd;
0b2cf5c8 1762
a6792a3e 1763 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
0b2cf5c8 1764 return;
a6792a3e 1765
0b2cf5c8
DY
1766 /* Make sure altpin is always set correctly */
1767 if (ch->ch_digi.digi_flags & DIGI_ALTPIN) {
1768 ch->ch_dsr = DM_CD;
1769 ch->ch_cd = DM_DSR;
1770 } else {
1771 ch->ch_dsr = DM_DSR;
1772 ch->ch_cd = DM_CD;
1773 }
a6792a3e 1774
0b2cf5c8
DY
1775 if (ch->ch_mistat & D_CD(ch))
1776 phys_carrier = 1;
a6792a3e 1777
0b2cf5c8
DY
1778 if (ch->ch_digi.digi_flags & DIGI_FORCEDCD)
1779 virt_carrier = 1;
a6792a3e 1780
0b2cf5c8
DY
1781 if (ch->ch_c_cflag & CLOCAL)
1782 virt_carrier = 1;
a6792a3e 1783
0b2cf5c8
DY
1784 /*
1785 * Test for a VIRTUAL carrier transition to HIGH.
1786 */
1787 if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) {
a6792a3e 1788
0b2cf5c8
DY
1789 /*
1790 * When carrier rises, wake any threads waiting
1791 * for carrier in the open routine.
1792 */
a6792a3e 1793
0b2cf5c8
DY
1794 if (waitqueue_active(&(ch->ch_flags_wait)))
1795 wake_up_interruptible(&ch->ch_flags_wait);
1796 }
a6792a3e
MH
1797
1798 /*
0b2cf5c8 1799 * Test for a PHYSICAL carrier transition to HIGH.
7d6069d7 1800 */
0b2cf5c8 1801 if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) {
a6792a3e 1802
a6792a3e 1803 /*
0b2cf5c8
DY
1804 * When carrier rises, wake any threads waiting
1805 * for carrier in the open routine.
a6792a3e 1806 */
0b2cf5c8
DY
1807
1808 if (waitqueue_active(&(ch->ch_flags_wait)))
1809 wake_up_interruptible(&ch->ch_flags_wait);
1810 }
1811
1812 /*
1813 * Test for a PHYSICAL transition to low, so long as we aren't
1814 * currently ignoring physical transitions (which is what "virtual
1815 * carrier" indicates).
1816 *
1817 * The transition of the virtual carrier to low really doesn't
1818 * matter... it really only means "ignore carrier state", not
1819 * "make pretend that carrier is there".
1820 */
1821 if ((virt_carrier == 0) &&
1822 ((ch->ch_flags & CH_CD) != 0) &&
1823 (phys_carrier == 0)) {
1824
1825 /*
1826 * When carrier drops:
1827 *
1828 * Drop carrier on all open units.
1829 *
1830 * Flush queues, waking up any task waiting in the
1831 * line discipline.
1832 *
1833 * Send a hangup to the control terminal.
1834 *
1835 * Enable all select calls.
1836 */
1837 if (waitqueue_active(&(ch->ch_flags_wait)))
1838 wake_up_interruptible(&ch->ch_flags_wait);
1839
1840 if (ch->ch_tun.un_open_count > 0)
1841 tty_hangup(ch->ch_tun.un_tty);
1842
1843 if (ch->ch_pun.un_open_count > 0)
1844 tty_hangup(ch->ch_pun.un_tty);
a6792a3e
MH
1845 }
1846
0b2cf5c8
DY
1847 /*
1848 * Make sure that our cached values reflect the current reality.
1849 */
1850 if (virt_carrier == 1)
1851 ch->ch_flags |= CH_FCAR;
1852 else
1853 ch->ch_flags &= ~CH_FCAR;
1854
1855 if (phys_carrier == 1)
1856 ch->ch_flags |= CH_CD;
1857 else
1858 ch->ch_flags &= ~CH_CD;
a6792a3e
MH
1859}
1860
0b2cf5c8
DY
1861/*=======================================================================
1862 *
1863 * dgap_event - FEP to host event processing routine.
1864 *
1865 * bd - Board of current event.
1866 *
1867 *=======================================================================*/
1868static int dgap_event(struct board_t *bd)
a6792a3e
MH
1869{
1870 struct channel_t *ch;
0b2cf5c8
DY
1871 ulong lock_flags;
1872 ulong lock_flags2;
405b26d9 1873 struct bs_t __iomem *bs;
0b2cf5c8
DY
1874 u8 __iomem *event;
1875 u8 __iomem *vaddr;
1876 struct ev_t __iomem *eaddr;
1877 uint head;
1878 uint tail;
1879 int port;
1880 int reason;
1881 int modem;
1882 int b1;
a6792a3e 1883
0b2cf5c8 1884 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
7dfa3831 1885 return -EIO;
a6792a3e 1886
0b2cf5c8 1887 spin_lock_irqsave(&bd->bd_lock, lock_flags);
a6792a3e 1888
0b2cf5c8 1889 vaddr = bd->re_map_membase;
a6792a3e 1890
0b2cf5c8
DY
1891 if (!vaddr) {
1892 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
7dfa3831 1893 return -EIO;
0b2cf5c8 1894 }
a6792a3e 1895
0b2cf5c8 1896 eaddr = (struct ev_t __iomem *) (vaddr + EVBUF);
a6792a3e 1897
0b2cf5c8
DY
1898 /* Get our head and tail */
1899 head = readw(&(eaddr->ev_head));
1900 tail = readw(&(eaddr->ev_tail));
a6792a3e 1901
0b2cf5c8
DY
1902 /*
1903 * Forget it if pointers out of range.
1904 */
a6792a3e 1905
0b2cf5c8
DY
1906 if (head >= EVMAX - EVSTART || tail >= EVMAX - EVSTART ||
1907 (head | tail) & 03) {
1908 /* Let go of board lock */
1909 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
1910 return -EIO;
a6792a3e
MH
1911 }
1912
a6792a3e 1913 /*
0b2cf5c8 1914 * Loop to process all the events in the buffer.
a6792a3e 1915 */
0b2cf5c8 1916 while (tail != head) {
a6792a3e 1917
0b2cf5c8
DY
1918 /*
1919 * Get interrupt information.
1920 */
a6792a3e 1921
0b2cf5c8 1922 event = bd->re_map_membase + tail + EVSTART;
a6792a3e 1923
0b2cf5c8
DY
1924 port = ioread8(event);
1925 reason = ioread8(event + 1);
1926 modem = ioread8(event + 2);
1927 b1 = ioread8(event + 3);
a6792a3e 1928
0b2cf5c8
DY
1929 /*
1930 * Make sure the interrupt is valid.
1931 */
1932 if (port >= bd->nasync)
1933 goto next;
a6792a3e 1934
0b2cf5c8
DY
1935 if (!(reason & (IFMODEM | IFBREAK | IFTLW | IFTEM | IFDATA)))
1936 goto next;
a6792a3e 1937
0b2cf5c8 1938 ch = bd->channels[port];
a6792a3e 1939
0b2cf5c8
DY
1940 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
1941 goto next;
1942
1943 /*
1944 * If we have made it here, the event was valid.
1945 * Lock down the channel.
1946 */
1947 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
1948
1949 bs = ch->ch_bs;
1950
1951 if (!bs) {
1952 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
1953 goto next;
a6792a3e 1954 }
a6792a3e 1955
0b2cf5c8
DY
1956 /*
1957 * Process received data.
1958 */
1959 if (reason & IFDATA) {
a6792a3e 1960
0b2cf5c8
DY
1961 /*
1962 * ALL LOCKS *MUST* BE DROPPED BEFORE CALLING INPUT!
1963 * input could send some data to ld, which in turn
1964 * could do a callback to one of our other functions.
1965 */
1966 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
1967 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
a6792a3e 1968
0b2cf5c8 1969 dgap_input(ch);
a6792a3e 1970
0b2cf5c8
DY
1971 spin_lock_irqsave(&bd->bd_lock, lock_flags);
1972 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
a6792a3e 1973
0b2cf5c8
DY
1974 if (ch->ch_flags & CH_RACTIVE)
1975 ch->ch_flags |= CH_RENABLE;
1976 else
1977 writeb(1, &(bs->idata));
a6792a3e 1978
0b2cf5c8
DY
1979 if (ch->ch_flags & CH_RWAIT) {
1980 ch->ch_flags &= ~CH_RWAIT;
a6792a3e 1981
0b2cf5c8
DY
1982 wake_up_interruptible
1983 (&ch->ch_tun.un_flags_wait);
1984 }
1985 }
a6792a3e 1986
0b2cf5c8
DY
1987 /*
1988 * Process Modem change signals.
1989 */
1990 if (reason & IFMODEM) {
1991 ch->ch_mistat = modem;
1992 dgap_carrier(ch);
1993 }
1994
1995 /*
1996 * Process break.
1997 */
1998 if (reason & IFBREAK) {
1999
2000 if (ch->ch_tun.un_tty) {
2001 /* A break has been indicated */
2002 ch->ch_err_break++;
2003 tty_buffer_request_room
2004 (ch->ch_tun.un_tty->port, 1);
2005 tty_insert_flip_char(ch->ch_tun.un_tty->port,
2006 0, TTY_BREAK);
2007 tty_flip_buffer_push(ch->ch_tun.un_tty->port);
2008 }
2009 }
a6792a3e 2010
0b2cf5c8
DY
2011 /*
2012 * Process Transmit low.
2013 */
2014 if (reason & IFTLW) {
2015 dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_LOW,
2016 &lock_flags, &lock_flags2);
2017 dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_LOW,
2018 &lock_flags, &lock_flags2);
2019 if (ch->ch_flags & CH_WLOW) {
2020 ch->ch_flags &= ~CH_WLOW;
2021 wake_up_interruptible(&ch->ch_flags_wait);
2022 }
2023 }
a6792a3e 2024
0b2cf5c8
DY
2025 /*
2026 * Process Transmit empty.
2027 */
2028 if (reason & IFTEM) {
2029 dgap_write_wakeup(bd, ch, &ch->ch_tun, UN_EMPTY,
2030 &lock_flags, &lock_flags2);
2031 dgap_write_wakeup(bd, ch, &ch->ch_pun, UN_EMPTY,
2032 &lock_flags, &lock_flags2);
2033 if (ch->ch_flags & CH_WEMPTY) {
2034 ch->ch_flags &= ~CH_WEMPTY;
2035 wake_up_interruptible(&ch->ch_flags_wait);
2036 }
2037 }
a6792a3e 2038
0b2cf5c8 2039 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
a6792a3e 2040
0b2cf5c8
DY
2041next:
2042 tail = (tail + 4) & (EVMAX - EVSTART - 4);
2043 }
a6792a3e 2044
0b2cf5c8
DY
2045 writew(tail, &(eaddr->ev_tail));
2046 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
a6792a3e 2047
0b2cf5c8 2048 return 0;
a6792a3e
MH
2049}
2050
a6792a3e 2051/*
0b2cf5c8 2052 * Our board poller function.
a6792a3e 2053 */
0b2cf5c8 2054static void dgap_poll_tasklet(unsigned long data)
a6792a3e 2055{
0b2cf5c8 2056 struct board_t *bd = (struct board_t *) data;
a6792a3e 2057 ulong lock_flags;
0b2cf5c8
DY
2058 char __iomem *vaddr;
2059 u16 head, tail;
a6792a3e 2060
0b2cf5c8
DY
2061 if (!bd || (bd->magic != DGAP_BOARD_MAGIC))
2062 return;
a6792a3e 2063
0b2cf5c8
DY
2064 if (bd->inhibit_poller)
2065 return;
a6792a3e 2066
0b2cf5c8 2067 spin_lock_irqsave(&bd->bd_lock, lock_flags);
a6792a3e 2068
0b2cf5c8 2069 vaddr = bd->re_map_membase;
a6792a3e 2070
0b2cf5c8
DY
2071 /*
2072 * If board is ready, parse deeper to see if there is anything to do.
2073 */
2074 if (bd->state == BOARD_READY) {
a6792a3e 2075
0b2cf5c8 2076 struct ev_t __iomem *eaddr;
a6792a3e 2077
0b2cf5c8
DY
2078 if (!bd->re_map_membase) {
2079 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
2080 return;
2081 }
2082 if (!bd->re_map_port) {
2083 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
2084 return;
2085 }
a6792a3e 2086
0b2cf5c8
DY
2087 if (!bd->nasync)
2088 goto out;
a6792a3e 2089
0b2cf5c8 2090 eaddr = (struct ev_t __iomem *) (vaddr + EVBUF);
a6792a3e 2091
0b2cf5c8
DY
2092 /* Get our head and tail */
2093 head = readw(&(eaddr->ev_head));
2094 tail = readw(&(eaddr->ev_tail));
a6792a3e 2095
0b2cf5c8
DY
2096 /*
2097 * If there is an event pending. Go service it.
2098 */
2099 if (head != tail) {
2100 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
2101 dgap_event(bd);
2102 spin_lock_irqsave(&bd->bd_lock, lock_flags);
2103 }
a6792a3e 2104
0b2cf5c8
DY
2105out:
2106 /*
2107 * If board is doing interrupts, ACK the interrupt.
2108 */
2109 if (bd && bd->intr_running)
2110 readb(bd->re_map_port + 2);
a6792a3e 2111
0b2cf5c8
DY
2112 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
2113 return;
a6792a3e
MH
2114 }
2115
0b2cf5c8
DY
2116 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
2117}
a6792a3e 2118
0b2cf5c8
DY
2119/*
2120 * dgap_found_board()
2121 *
2122 * A board has been found, init it.
2123 */
2124static struct board_t *dgap_found_board(struct pci_dev *pdev, int id,
2125 int boardnum)
2126{
2127 struct board_t *brd;
2128 unsigned int pci_irq;
2129 int i;
2130 int ret;
a6792a3e 2131
0b2cf5c8
DY
2132 /* get the board structure and prep it */
2133 brd = kzalloc(sizeof(struct board_t), GFP_KERNEL);
2134 if (!brd)
2135 return ERR_PTR(-ENOMEM);
a6792a3e 2136
0b2cf5c8
DY
2137 /* store the info for the board we've found */
2138 brd->magic = DGAP_BOARD_MAGIC;
2139 brd->boardnum = boardnum;
2140 brd->vendor = dgap_pci_tbl[id].vendor;
2141 brd->device = dgap_pci_tbl[id].device;
2142 brd->pdev = pdev;
2143 brd->pci_bus = pdev->bus->number;
2144 brd->pci_slot = PCI_SLOT(pdev->devfn);
2145 brd->name = dgap_ids[id].name;
2146 brd->maxports = dgap_ids[id].maxports;
2147 brd->type = dgap_ids[id].config_type;
2148 brd->dpatype = dgap_ids[id].dpatype;
2149 brd->dpastatus = BD_NOFEP;
2150 init_waitqueue_head(&brd->state_wait);
a6792a3e 2151
0b2cf5c8 2152 spin_lock_init(&brd->bd_lock);
a6792a3e 2153
0b2cf5c8
DY
2154 brd->inhibit_poller = FALSE;
2155 brd->wait_for_bios = 0;
2156 brd->wait_for_fep = 0;
a6792a3e 2157
0b2cf5c8
DY
2158 for (i = 0; i < MAXPORTS; i++)
2159 brd->channels[i] = NULL;
2160
2161 /* store which card & revision we have */
2162 pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &brd->subvendor);
2163 pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &brd->subdevice);
2164 pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev);
2165
2166 pci_irq = pdev->irq;
2167 brd->irq = pci_irq;
a6792a3e 2168
0b2cf5c8 2169 /* get the PCI Base Address Registers */
a6792a3e 2170
0b2cf5c8
DY
2171 /* Xr Jupiter and EPC use BAR 2 */
2172 if (brd->device == PCI_DEV_XRJ_DID || brd->device == PCI_DEV_EPCJ_DID) {
2173 brd->membase = pci_resource_start(pdev, 2);
2174 brd->membase_end = pci_resource_end(pdev, 2);
2175 }
2176 /* Everyone else uses BAR 0 */
2177 else {
2178 brd->membase = pci_resource_start(pdev, 0);
2179 brd->membase_end = pci_resource_end(pdev, 0);
a6792a3e
MH
2180 }
2181
0b2cf5c8
DY
2182 if (!brd->membase) {
2183 ret = -ENODEV;
2184 goto free_brd;
a6792a3e
MH
2185 }
2186
0b2cf5c8
DY
2187 if (brd->membase & 1)
2188 brd->membase &= ~3;
2189 else
2190 brd->membase &= ~15;
a6792a3e
MH
2191
2192 /*
0b2cf5c8
DY
2193 * On the PCI boards, there is no IO space allocated
2194 * The I/O registers will be in the first 3 bytes of the
2195 * upper 2MB of the 4MB memory space. The board memory
2196 * will be mapped into the low 2MB of the 4MB memory space
a6792a3e 2197 */
0b2cf5c8
DY
2198 brd->port = brd->membase + PCI_IO_OFFSET;
2199 brd->port_end = brd->port + PCI_IO_SIZE;
a6792a3e 2200
0b2cf5c8
DY
2201 /*
2202 * Special initialization for non-PLX boards
2203 */
2204 if (brd->device != PCI_DEV_XRJ_DID && brd->device != PCI_DEV_EPCJ_DID) {
2205 unsigned short cmd;
a6792a3e 2206
0b2cf5c8
DY
2207 pci_write_config_byte(pdev, 0x40, 0);
2208 pci_write_config_byte(pdev, 0x46, 0);
a6792a3e 2209
0b2cf5c8
DY
2210 /* Limit burst length to 2 doubleword transactions */
2211 pci_write_config_byte(pdev, 0x42, 1);
a6792a3e 2212
0b2cf5c8
DY
2213 /*
2214 * Enable IO and mem if not already done.
2215 * This was needed for support on Itanium.
2216 */
2217 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
2218 cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
2219 pci_write_config_word(pdev, PCI_COMMAND, cmd);
2220 }
a6792a3e 2221
0b2cf5c8
DY
2222 /* init our poll helper tasklet */
2223 tasklet_init(&brd->helper_tasklet, dgap_poll_tasklet,
2224 (unsigned long) brd);
a6792a3e 2225
0b2cf5c8
DY
2226 ret = dgap_remap(brd);
2227 if (ret)
2228 goto free_brd;
a6792a3e 2229
0b2cf5c8
DY
2230 pr_info("dgap: board %d: %s (rev %d), irq %ld\n",
2231 boardnum, brd->name, brd->rev, brd->irq);
a6792a3e 2232
0b2cf5c8 2233 return brd;
a6792a3e 2234
0b2cf5c8
DY
2235free_brd:
2236 kfree(brd);
a6792a3e 2237
0b2cf5c8 2238 return ERR_PTR(ret);
a6792a3e
MH
2239}
2240
a6792a3e 2241/*
0b2cf5c8 2242 * dgap_intr()
a6792a3e 2243 *
0b2cf5c8 2244 * Driver interrupt handler.
a6792a3e 2245 */
0b2cf5c8 2246static irqreturn_t dgap_intr(int irq, void *voidbrd)
a6792a3e 2247{
0b2cf5c8 2248 struct board_t *brd = voidbrd;
a6792a3e 2249
0b2cf5c8
DY
2250 if (!brd)
2251 return IRQ_NONE;
a6792a3e 2252
0b2cf5c8
DY
2253 /*
2254 * Check to make sure its for us.
2255 */
2256 if (brd->magic != DGAP_BOARD_MAGIC)
2257 return IRQ_NONE;
a6792a3e 2258
0b2cf5c8 2259 brd->intr_count++;
a6792a3e 2260
0b2cf5c8
DY
2261 /*
2262 * Schedule tasklet to run at a better time.
2263 */
2264 tasklet_schedule(&brd->helper_tasklet);
2265 return IRQ_HANDLED;
2266}
a6792a3e 2267
0b2cf5c8
DY
2268/*****************************************************************************
2269*
2270* Function:
2271*
2272* dgap_poll_handler
2273*
2274* Author:
2275*
2276* Scott H Kilau
2277*
2278* Parameters:
2279*
2280* dummy -- ignored
2281*
2282* Return Values:
2283*
2284* none
2285*
2286* Description:
2287*
2288* As each timer expires, it determines (a) whether the "transmit"
2289* waiter needs to be woken up, and (b) whether the poller needs to
2290* be rescheduled.
2291*
2292******************************************************************************/
a6792a3e 2293
0b2cf5c8
DY
2294static void dgap_poll_handler(ulong dummy)
2295{
2296 unsigned int i;
2297 struct board_t *brd;
2298 unsigned long lock_flags;
2299 ulong new_time;
a6792a3e 2300
0b2cf5c8 2301 dgap_poll_counter++;
a6792a3e 2302
0b2cf5c8
DY
2303 /*
2304 * Do not start the board state machine until
2305 * driver tells us its up and running, and has
2306 * everything it needs.
2307 */
2308 if (dgap_driver_state != DRIVER_READY)
2309 goto schedule_poller;
a6792a3e 2310
0b2cf5c8
DY
2311 /*
2312 * If we have just 1 board, or the system is not SMP,
2313 * then use the typical old style poller.
2314 * Otherwise, use our new tasklet based poller, which should
2315 * speed things up for multiple boards.
2316 */
2317 if ((dgap_numboards == 1) || (num_online_cpus() <= 1)) {
2318 for (i = 0; i < dgap_numboards; i++) {
a6792a3e 2319
0b2cf5c8 2320 brd = dgap_board[i];
a6792a3e 2321
0b2cf5c8
DY
2322 if (brd->state == BOARD_FAILED)
2323 continue;
2324 if (!brd->intr_running)
2325 /* Call the real board poller directly */
2326 dgap_poll_tasklet((unsigned long) brd);
2327 }
2328 } else {
2329 /*
2330 * Go thru each board, kicking off a
2331 * tasklet for each if needed
2332 */
2333 for (i = 0; i < dgap_numboards; i++) {
2334 brd = dgap_board[i];
2335
2336 /*
2337 * Attempt to grab the board lock.
2338 *
2339 * If we can't get it, no big deal, the next poll
2340 * will get it. Basically, I just really don't want
2341 * to spin in here, because I want to kick off my
2342 * tasklets as fast as I can, and then get out the
2343 * poller.
2344 */
2345 if (!spin_trylock(&brd->bd_lock))
2346 continue;
a6792a3e 2347
0b2cf5c8
DY
2348 /*
2349 * If board is in a failed state, don't bother
2350 * scheduling a tasklet
2351 */
2352 if (brd->state == BOARD_FAILED) {
2353 spin_unlock(&brd->bd_lock);
2354 continue;
2355 }
a6792a3e 2356
0b2cf5c8
DY
2357 /* Schedule a poll helper task */
2358 if (!brd->intr_running)
2359 tasklet_schedule(&brd->helper_tasklet);
a6792a3e 2360
0b2cf5c8
DY
2361 /*
2362 * Can't do DGAP_UNLOCK here, as we don't have
2363 * lock_flags because we did a trylock above.
2364 */
2365 spin_unlock(&brd->bd_lock);
2366 }
2367 }
a6792a3e 2368
0b2cf5c8 2369schedule_poller:
a6792a3e 2370
0b2cf5c8
DY
2371 /*
2372 * Schedule ourself back at the nominal wakeup interval.
2373 */
2374 spin_lock_irqsave(&dgap_poll_lock, lock_flags);
2375 dgap_poll_time += dgap_jiffies_from_ms(dgap_poll_tick);
a6792a3e 2376
0b2cf5c8 2377 new_time = dgap_poll_time - jiffies;
a6792a3e 2378
0b2cf5c8
DY
2379 if ((ulong) new_time >= 2 * dgap_poll_tick) {
2380 dgap_poll_time =
2381 jiffies + dgap_jiffies_from_ms(dgap_poll_tick);
a6792a3e
MH
2382 }
2383
0b2cf5c8
DY
2384 dgap_poll_timer.function = dgap_poll_handler;
2385 dgap_poll_timer.data = 0;
2386 dgap_poll_timer.expires = dgap_poll_time;
2387 spin_unlock_irqrestore(&dgap_poll_lock, lock_flags);
a6792a3e 2388
0b2cf5c8
DY
2389 if (!dgap_poll_stop)
2390 add_timer(&dgap_poll_timer);
a6792a3e
MH
2391}
2392
0b2cf5c8 2393/*=======================================================================
a6792a3e 2394 *
0b2cf5c8 2395 * dgap_cmdb - Sends a 2 byte command to the FEP.
a6792a3e 2396 *
0b2cf5c8
DY
2397 * ch - Pointer to channel structure.
2398 * cmd - Command to be sent.
2399 * byte1 - Integer containing first byte to be sent.
2400 * byte2 - Integer containing second byte to be sent.
2401 * ncmds - Wait until ncmds or fewer cmds are left
2402 * in the cmd buffer before returning.
2403 *
2404 *=======================================================================*/
2405static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1,
2406 u8 byte2, uint ncmds)
a6792a3e 2407{
0b2cf5c8
DY
2408 char __iomem *vaddr;
2409 struct __iomem cm_t *cm_addr;
2410 uint count;
2411 uint n;
2412 u16 head;
2413 u16 tail;
a6792a3e 2414
0b2cf5c8 2415 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
a6792a3e
MH
2416 return;
2417
0b2cf5c8
DY
2418 /*
2419 * Check if board is still alive.
2420 */
2421 if (ch->ch_bd->state == BOARD_FAILED)
a6792a3e
MH
2422 return;
2423
0b2cf5c8
DY
2424 /*
2425 * Make sure the pointers are in range before
2426 * writing to the FEP memory.
2427 */
2428 vaddr = ch->ch_bd->re_map_membase;
2429
2430 if (!vaddr)
a6792a3e
MH
2431 return;
2432
0b2cf5c8
DY
2433 cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF);
2434 head = readw(&(cm_addr->cm_head));
2435
2436 /*
2437 * Forget it if pointers out of range.
2438 */
2439 if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
2440 ch->ch_bd->state = BOARD_FAILED;
a6792a3e 2441 return;
0b2cf5c8 2442 }
a6792a3e 2443
0b2cf5c8
DY
2444 /*
2445 * Put the data in the circular command buffer.
2446 */
2447 writeb(cmd, (vaddr + head + CMDSTART + 0));
2448 writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1));
2449 writeb(byte1, (vaddr + head + CMDSTART + 2));
2450 writeb(byte2, (vaddr + head + CMDSTART + 3));
2451
2452 head = (head + 4) & (CMDMAX - CMDSTART - 4);
2453
2454 writew(head, &(cm_addr->cm_head));
a6792a3e
MH
2455
2456 /*
0b2cf5c8
DY
2457 * Wait if necessary before updating the head
2458 * pointer to limit the number of outstanding
2459 * commands to the FEP. If the time spent waiting
2460 * is outlandish, declare the FEP dead.
a6792a3e 2461 */
0b2cf5c8 2462 for (count = dgap_count ;;) {
a6792a3e 2463
0b2cf5c8
DY
2464 head = readw(&(cm_addr->cm_head));
2465 tail = readw(&(cm_addr->cm_tail));
a6792a3e 2466
0b2cf5c8 2467 n = (head - tail) & (CMDMAX - CMDSTART - 4);
a6792a3e 2468
0b2cf5c8
DY
2469 if (n <= ncmds * sizeof(struct cm_t))
2470 break;
a6792a3e 2471
0b2cf5c8
DY
2472 if (--count == 0) {
2473 ch->ch_bd->state = BOARD_FAILED;
2474 return;
2475 }
2476 udelay(10);
2477 }
2478}
a6792a3e 2479
0b2cf5c8
DY
2480/*=======================================================================
2481 *
2482 * dgap_cmdw - Sends a 1 word command to the FEP.
2483 *
2484 * ch - Pointer to channel structure.
2485 * cmd - Command to be sent.
2486 * word - Integer containing word to be sent.
2487 * ncmds - Wait until ncmds or fewer cmds are left
2488 * in the cmd buffer before returning.
2489 *
2490 *=======================================================================*/
2491static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds)
2492{
2493 char __iomem *vaddr;
2494 struct __iomem cm_t *cm_addr;
2495 uint count;
2496 uint n;
2497 u16 head;
2498 u16 tail;
a6792a3e 2499
0b2cf5c8
DY
2500 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
2501 return;
a6792a3e 2502
0b2cf5c8
DY
2503 /*
2504 * Check if board is still alive.
2505 */
2506 if (ch->ch_bd->state == BOARD_FAILED)
2507 return;
2508
2509 /*
2510 * Make sure the pointers are in range before
2511 * writing to the FEP memory.
2512 */
2513 vaddr = ch->ch_bd->re_map_membase;
2514 if (!vaddr)
2515 return;
a6792a3e 2516
0b2cf5c8
DY
2517 cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF);
2518 head = readw(&(cm_addr->cm_head));
a6792a3e 2519
0b2cf5c8
DY
2520 /*
2521 * Forget it if pointers out of range.
2522 */
2523 if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
2524 ch->ch_bd->state = BOARD_FAILED;
2525 return;
2526 }
a6792a3e 2527
0b2cf5c8
DY
2528 /*
2529 * Put the data in the circular command buffer.
2530 */
2531 writeb(cmd, (vaddr + head + CMDSTART + 0));
2532 writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1));
2533 writew((u16) word, (vaddr + head + CMDSTART + 2));
a6792a3e 2534
0b2cf5c8 2535 head = (head + 4) & (CMDMAX - CMDSTART - 4);
a6792a3e 2536
0b2cf5c8 2537 writew(head, &(cm_addr->cm_head));
a6792a3e 2538
0b2cf5c8
DY
2539 /*
2540 * Wait if necessary before updating the head
2541 * pointer to limit the number of outstanding
2542 * commands to the FEP. If the time spent waiting
2543 * is outlandish, declare the FEP dead.
2544 */
2545 for (count = dgap_count ;;) {
a6792a3e 2546
0b2cf5c8
DY
2547 head = readw(&(cm_addr->cm_head));
2548 tail = readw(&(cm_addr->cm_tail));
a6792a3e 2549
0b2cf5c8 2550 n = (head - tail) & (CMDMAX - CMDSTART - 4);
a6792a3e 2551
0b2cf5c8
DY
2552 if (n <= ncmds * sizeof(struct cm_t))
2553 break;
2554
2555 if (--count == 0) {
2556 ch->ch_bd->state = BOARD_FAILED;
2557 return;
7d6069d7 2558 }
0b2cf5c8
DY
2559 udelay(10);
2560 }
2561}
a6792a3e 2562
0b2cf5c8
DY
2563/*=======================================================================
2564 *
2565 * dgap_cmdw_ext - Sends a extended word command to the FEP.
2566 *
2567 * ch - Pointer to channel structure.
2568 * cmd - Command to be sent.
2569 * word - Integer containing word to be sent.
2570 * ncmds - Wait until ncmds or fewer cmds are left
2571 * in the cmd buffer before returning.
2572 *
2573 *=======================================================================*/
2574static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds)
2575{
2576 char __iomem *vaddr;
2577 struct __iomem cm_t *cm_addr;
2578 uint count;
2579 uint n;
2580 u16 head;
2581 u16 tail;
a6792a3e 2582
0b2cf5c8
DY
2583 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
2584 return;
a6792a3e 2585
0b2cf5c8
DY
2586 /*
2587 * Check if board is still alive.
2588 */
2589 if (ch->ch_bd->state == BOARD_FAILED)
2590 return;
a6792a3e 2591
0b2cf5c8
DY
2592 /*
2593 * Make sure the pointers are in range before
2594 * writing to the FEP memory.
2595 */
2596 vaddr = ch->ch_bd->re_map_membase;
2597 if (!vaddr)
2598 return;
a6792a3e 2599
0b2cf5c8
DY
2600 cm_addr = (struct cm_t __iomem *) (vaddr + CMDBUF);
2601 head = readw(&(cm_addr->cm_head));
a6792a3e 2602
0b2cf5c8
DY
2603 /*
2604 * Forget it if pointers out of range.
2605 */
2606 if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
2607 ch->ch_bd->state = BOARD_FAILED;
2608 return;
a6792a3e
MH
2609 }
2610
0b2cf5c8
DY
2611 /*
2612 * Put the data in the circular command buffer.
2613 */
a6792a3e 2614
0b2cf5c8
DY
2615 /* Write an FF to tell the FEP that we want an extended command */
2616 writeb((u8) 0xff, (vaddr + head + CMDSTART + 0));
a6792a3e 2617
0b2cf5c8
DY
2618 writeb((u8) ch->ch_portnum, (vaddr + head + CMDSTART + 1));
2619 writew((u16) cmd, (vaddr + head + CMDSTART + 2));
a6792a3e 2620
0b2cf5c8
DY
2621 /*
2622 * If the second part of the command won't fit,
2623 * put it at the beginning of the circular buffer.
2624 */
2625 if (((head + 4) >= ((CMDMAX - CMDSTART)) || (head & 03)))
2626 writew((u16) word, (vaddr + CMDSTART));
2627 else
2628 writew((u16) word, (vaddr + head + CMDSTART + 4));
a6792a3e 2629
0b2cf5c8 2630 head = (head + 8) & (CMDMAX - CMDSTART - 4);
a6792a3e 2631
0b2cf5c8 2632 writew(head, &(cm_addr->cm_head));
a6792a3e 2633
0b2cf5c8
DY
2634 /*
2635 * Wait if necessary before updating the head
2636 * pointer to limit the number of outstanding
2637 * commands to the FEP. If the time spent waiting
2638 * is outlandish, declare the FEP dead.
2639 */
2640 for (count = dgap_count ;;) {
a6792a3e 2641
0b2cf5c8
DY
2642 head = readw(&(cm_addr->cm_head));
2643 tail = readw(&(cm_addr->cm_tail));
a6792a3e 2644
0b2cf5c8 2645 n = (head - tail) & (CMDMAX - CMDSTART - 4);
a6792a3e 2646
0b2cf5c8
DY
2647 if (n <= ncmds * sizeof(struct cm_t))
2648 break;
2649
2650 if (--count == 0) {
2651 ch->ch_bd->state = BOARD_FAILED;
2652 return;
2653 }
2654 udelay(10);
2655 }
a6792a3e
MH
2656}
2657
0b2cf5c8 2658/*=======================================================================
a6792a3e 2659 *
0b2cf5c8 2660 * dgap_wmove - Write data to FEP buffer.
a6792a3e 2661 *
0b2cf5c8
DY
2662 * ch - Pointer to channel structure.
2663 * buf - Poiter to characters to be moved.
2664 * cnt - Number of characters to move.
a6792a3e 2665 *
0b2cf5c8
DY
2666 *=======================================================================*/
2667static void dgap_wmove(struct channel_t *ch, char *buf, uint cnt)
a6792a3e 2668{
0b2cf5c8
DY
2669 int n;
2670 char __iomem *taddr;
2671 struct bs_t __iomem *bs;
2672 u16 head;
a6792a3e 2673
0b2cf5c8
DY
2674 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
2675 return;
a6792a3e 2676
0b2cf5c8
DY
2677 /*
2678 * Check parameters.
2679 */
2680 bs = ch->ch_bs;
2681 head = readw(&(bs->tx_head));
a6792a3e 2682
0b2cf5c8
DY
2683 /*
2684 * If pointers are out of range, just return.
2685 */
2686 if ((cnt > ch->ch_tsize) ||
2687 (unsigned)(head - ch->ch_tstart) >= ch->ch_tsize)
2688 return;
a6792a3e 2689
0b2cf5c8
DY
2690 /*
2691 * If the write wraps over the top of the circular buffer,
2692 * move the portion up to the wrap point, and reset the
2693 * pointers to the bottom.
2694 */
2695 n = ch->ch_tstart + ch->ch_tsize - head;
a6792a3e 2696
0b2cf5c8
DY
2697 if (cnt >= n) {
2698 cnt -= n;
2699 taddr = ch->ch_taddr + head;
2700 memcpy_toio(taddr, buf, n);
2701 head = ch->ch_tstart;
2702 buf += n;
2703 }
a6792a3e 2704
0b2cf5c8
DY
2705 /*
2706 * Move rest of data.
2707 */
2708 taddr = ch->ch_taddr + head;
2709 n = cnt;
2710 memcpy_toio(taddr, buf, n);
2711 head += cnt;
a6792a3e 2712
0b2cf5c8 2713 writew(head, &(bs->tx_head));
a6792a3e
MH
2714}
2715
a6792a3e 2716/*
0b2cf5c8 2717 * Calls the firmware to reset this channel.
a6792a3e 2718 */
0b2cf5c8 2719static void dgap_firmware_reset_port(struct channel_t *ch)
a6792a3e 2720{
0b2cf5c8 2721 dgap_cmdb(ch, CHRESET, 0, 0, 0);
a6792a3e 2722
0b2cf5c8
DY
2723 /*
2724 * Now that the channel is reset, we need to make sure
2725 * all the current settings get reapplied to the port
2726 * in the firmware.
2727 *
2728 * So we will set the driver's cache of firmware
2729 * settings all to 0, and then call param.
2730 */
2731 ch->ch_fepiflag = 0;
2732 ch->ch_fepcflag = 0;
2733 ch->ch_fepoflag = 0;
2734 ch->ch_fepstartc = 0;
2735 ch->ch_fepstopc = 0;
2736 ch->ch_fepastartc = 0;
2737 ch->ch_fepastopc = 0;
2738 ch->ch_mostat = 0;
2739 ch->ch_hflow = 0;
2740}
a6792a3e 2741
0b2cf5c8
DY
2742/*=======================================================================
2743 *
2744 * dgap_param - Set Digi parameters.
2745 *
2746 * struct tty_struct * - TTY for port.
2747 *
2748 *=======================================================================*/
2749static int dgap_param(struct channel_t *ch, struct board_t *bd, u32 un_type)
2750{
2751 u16 head;
2752 u16 cflag;
2753 u16 iflag;
2754 u8 mval;
2755 u8 hflow;
a6792a3e 2756
0b2cf5c8
DY
2757 /*
2758 * If baud rate is zero, flush queues, and set mval to drop DTR.
2759 */
2760 if ((ch->ch_c_cflag & (CBAUD)) == 0) {
a6792a3e 2761
0b2cf5c8
DY
2762 /* flush rx */
2763 head = readw(&(ch->ch_bs->rx_head));
2764 writew(head, &(ch->ch_bs->rx_tail));
a6792a3e 2765
0b2cf5c8
DY
2766 /* flush tx */
2767 head = readw(&(ch->ch_bs->tx_head));
2768 writew(head, &(ch->ch_bs->tx_tail));
a6792a3e 2769
0b2cf5c8 2770 ch->ch_flags |= (CH_BAUD0);
a6792a3e 2771
0b2cf5c8
DY
2772 /* Drop RTS and DTR */
2773 ch->ch_mval &= ~(D_RTS(ch)|D_DTR(ch));
2774 mval = D_DTR(ch) | D_RTS(ch);
2775 ch->ch_baud_info = 0;
a6792a3e 2776
0b2cf5c8
DY
2777 } else if (ch->ch_custom_speed && (bd->bd_flags & BD_FEP5PLUS)) {
2778 /*
2779 * Tell the fep to do the command
2780 */
a6792a3e 2781
0b2cf5c8 2782 dgap_cmdw_ext(ch, 0xff01, ch->ch_custom_speed, 0);
a6792a3e 2783
0b2cf5c8
DY
2784 /*
2785 * Now go get from fep mem, what the fep
2786 * believes the custom baud rate is.
2787 */
2788 ch->ch_custom_speed = dgap_get_custom_baud(ch);
2789 ch->ch_baud_info = ch->ch_custom_speed;
a6792a3e 2790
0b2cf5c8
DY
2791 /* Handle transition from B0 */
2792 if (ch->ch_flags & CH_BAUD0) {
2793 ch->ch_flags &= ~(CH_BAUD0);
2794 ch->ch_mval |= (D_RTS(ch)|D_DTR(ch));
2795 }
2796 mval = D_DTR(ch) | D_RTS(ch);
a6792a3e 2797
0b2cf5c8
DY
2798 } else {
2799 /*
2800 * Set baud rate, character size, and parity.
2801 */
a6792a3e 2802
a6792a3e 2803
0b2cf5c8
DY
2804 int iindex = 0;
2805 int jindex = 0;
2806 int baud = 0;
a6792a3e 2807
0b2cf5c8
DY
2808 ulong bauds[4][16] = {
2809 { /* slowbaud */
2810 0, 50, 75, 110,
2811 134, 150, 200, 300,
2812 600, 1200, 1800, 2400,
2813 4800, 9600, 19200, 38400 },
2814 { /* slowbaud & CBAUDEX */
2815 0, 57600, 115200, 230400,
2816 460800, 150, 200, 921600,
2817 600, 1200, 1800, 2400,
2818 4800, 9600, 19200, 38400 },
2819 { /* fastbaud */
2820 0, 57600, 76800, 115200,
2821 14400, 57600, 230400, 76800,
2822 115200, 230400, 28800, 460800,
2823 921600, 9600, 19200, 38400 },
2824 { /* fastbaud & CBAUDEX */
2825 0, 57600, 115200, 230400,
2826 460800, 150, 200, 921600,
2827 600, 1200, 1800, 2400,
2828 4800, 9600, 19200, 38400 }
2829 };
a6792a3e 2830
0b2cf5c8
DY
2831 /*
2832 * Only use the TXPrint baud rate if the
2833 * terminal unit is NOT open
2834 */
2835 if (!(ch->ch_tun.un_flags & UN_ISOPEN) &&
2836 un_type == DGAP_PRINT)
2837 baud = C_BAUD(ch->ch_pun.un_tty) & 0xff;
2838 else
2839 baud = C_BAUD(ch->ch_tun.un_tty) & 0xff;
a6792a3e 2840
0b2cf5c8
DY
2841 if (ch->ch_c_cflag & CBAUDEX)
2842 iindex = 1;
a6792a3e 2843
0b2cf5c8
DY
2844 if (ch->ch_digi.digi_flags & DIGI_FAST)
2845 iindex += 2;
a6792a3e 2846
0b2cf5c8 2847 jindex = baud;
a6792a3e 2848
0b2cf5c8
DY
2849 if ((iindex >= 0) && (iindex < 4) &&
2850 (jindex >= 0) && (jindex < 16))
2851 baud = bauds[iindex][jindex];
2852 else
2853 baud = 0;
a6792a3e 2854
0b2cf5c8
DY
2855 if (baud == 0)
2856 baud = 9600;
a6792a3e 2857
0b2cf5c8 2858 ch->ch_baud_info = baud;
a6792a3e 2859
0b2cf5c8
DY
2860 /*
2861 * CBAUD has bit position 0x1000 set these days to
2862 * indicate Linux baud rate remap.
2863 * We use a different bit assignment for high speed.
2864 * Clear this bit out while grabbing the parts of
2865 * "cflag" we want.
2866 */
2867 cflag = ch->ch_c_cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB |
2868 CSTOPB | CSIZE);
a6792a3e 2869
0b2cf5c8
DY
2870 /*
2871 * HUPCL bit is used by FEP to indicate fast baud
2872 * table is to be used.
2873 */
2874 if ((ch->ch_digi.digi_flags & DIGI_FAST) ||
2875 (ch->ch_c_cflag & CBAUDEX))
2876 cflag |= HUPCL;
a6792a3e 2877
0b2cf5c8
DY
2878 if ((ch->ch_c_cflag & CBAUDEX) &&
2879 !(ch->ch_digi.digi_flags & DIGI_FAST)) {
2880 /*
2881 * The below code is trying to guarantee that only
2882 * baud rates 115200, 230400, 460800, 921600 are
2883 * remapped. We use exclusive or because the various
2884 * baud rates share common bit positions and therefore
2885 * can't be tested for easily.
2886 */
2887 tcflag_t tcflag = (ch->ch_c_cflag & CBAUD) | CBAUDEX;
2888 int baudpart = 0;
a6792a3e 2889
0b2cf5c8
DY
2890 /*
2891 * Map high speed requests to index
2892 * into FEP's baud table
2893 */
2894 switch (tcflag) {
2895 case B57600:
2896 baudpart = 1;
2897 break;
2898#ifdef B76800
2899 case B76800:
2900 baudpart = 2;
2901 break;
2902#endif
2903 case B115200:
2904 baudpart = 3;
2905 break;
2906 case B230400:
2907 baudpart = 9;
2908 break;
2909 case B460800:
2910 baudpart = 11;
2911 break;
2912#ifdef B921600
2913 case B921600:
2914 baudpart = 12;
2915 break;
2916#endif
2917 default:
2918 baudpart = 0;
2919 }
a6792a3e 2920
0b2cf5c8
DY
2921 if (baudpart)
2922 cflag = (cflag & ~(CBAUD | CBAUDEX)) | baudpart;
2923 }
a6792a3e 2924
0b2cf5c8 2925 cflag &= 0xffff;
a6792a3e 2926
0b2cf5c8
DY
2927 if (cflag != ch->ch_fepcflag) {
2928 ch->ch_fepcflag = (u16) (cflag & 0xffff);
a6792a3e 2929
0b2cf5c8
DY
2930 /*
2931 * Okay to have channel and board
2932 * locks held calling this
2933 */
2934 dgap_cmdw(ch, SCFLAG, (u16) cflag, 0);
2935 }
a6792a3e 2936
0b2cf5c8
DY
2937 /* Handle transition from B0 */
2938 if (ch->ch_flags & CH_BAUD0) {
2939 ch->ch_flags &= ~(CH_BAUD0);
2940 ch->ch_mval |= (D_RTS(ch)|D_DTR(ch));
2941 }
2942 mval = D_DTR(ch) | D_RTS(ch);
2943 }
a6792a3e 2944
0b2cf5c8
DY
2945 /*
2946 * Get input flags.
2947 */
2948 iflag = ch->ch_c_iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK |
2949 INPCK | ISTRIP | IXON | IXANY | IXOFF);
a6792a3e 2950
0b2cf5c8
DY
2951 if ((ch->ch_startc == _POSIX_VDISABLE) ||
2952 (ch->ch_stopc == _POSIX_VDISABLE)) {
2953 iflag &= ~(IXON | IXOFF);
2954 ch->ch_c_iflag &= ~(IXON | IXOFF);
2955 }
a6792a3e 2956
0b2cf5c8
DY
2957 /*
2958 * Only the IBM Xr card can switch between
2959 * 232 and 422 modes on the fly
2960 */
2961 if (bd->device == PCI_DEV_XR_IBM_DID) {
2962 if (ch->ch_digi.digi_flags & DIGI_422)
2963 dgap_cmdb(ch, SCOMMODE, MODE_422, 0, 0);
2964 else
2965 dgap_cmdb(ch, SCOMMODE, MODE_232, 0, 0);
2966 }
a6792a3e 2967
0b2cf5c8
DY
2968 if (ch->ch_digi.digi_flags & DIGI_ALTPIN)
2969 iflag |= IALTPIN;
a6792a3e 2970
0b2cf5c8
DY
2971 if (iflag != ch->ch_fepiflag) {
2972 ch->ch_fepiflag = iflag;
a6792a3e 2973
0b2cf5c8
DY
2974 /* Okay to have channel and board locks held calling this */
2975 dgap_cmdw(ch, SIFLAG, (u16) ch->ch_fepiflag, 0);
2976 }
a6792a3e 2977
0b2cf5c8
DY
2978 /*
2979 * Select hardware handshaking.
2980 */
2981 hflow = 0;
a6792a3e 2982
0b2cf5c8
DY
2983 if (ch->ch_c_cflag & CRTSCTS)
2984 hflow |= (D_RTS(ch) | D_CTS(ch));
2985 if (ch->ch_digi.digi_flags & RTSPACE)
2986 hflow |= D_RTS(ch);
2987 if (ch->ch_digi.digi_flags & DTRPACE)
2988 hflow |= D_DTR(ch);
2989 if (ch->ch_digi.digi_flags & CTSPACE)
2990 hflow |= D_CTS(ch);
2991 if (ch->ch_digi.digi_flags & DSRPACE)
2992 hflow |= D_DSR(ch);
2993 if (ch->ch_digi.digi_flags & DCDPACE)
2994 hflow |= D_CD(ch);
a6792a3e 2995
0b2cf5c8
DY
2996 if (hflow != ch->ch_hflow) {
2997 ch->ch_hflow = hflow;
a6792a3e 2998
0b2cf5c8
DY
2999 /* Okay to have channel and board locks held calling this */
3000 dgap_cmdb(ch, SHFLOW, (u8) hflow, 0xff, 0);
3001 }
a6792a3e 3002
0b2cf5c8
DY
3003 /*
3004 * Set RTS and/or DTR Toggle if needed,
3005 * but only if product is FEP5+ based.
3006 */
3007 if (bd->bd_flags & BD_FEP5PLUS) {
3008 u16 hflow2 = 0;
a6792a3e 3009
0b2cf5c8
DY
3010 if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
3011 hflow2 |= (D_RTS(ch));
3012 if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)
3013 hflow2 |= (D_DTR(ch));
a6792a3e 3014
0b2cf5c8
DY
3015 dgap_cmdw_ext(ch, 0xff03, hflow2, 0);
3016 }
a6792a3e 3017
0b2cf5c8
DY
3018 /*
3019 * Set modem control lines.
3020 */
a6792a3e 3021
0b2cf5c8 3022 mval ^= ch->ch_mforce & (mval ^ ch->ch_mval);
a6792a3e 3023
0b2cf5c8
DY
3024 if (ch->ch_mostat ^ mval) {
3025 ch->ch_mostat = mval;
a6792a3e 3026
0b2cf5c8
DY
3027 /* Okay to have channel and board locks held calling this */
3028 dgap_cmdb(ch, SMODEM, (u8) mval, D_RTS(ch)|D_DTR(ch), 0);
3029 }
a6792a3e 3030
0b2cf5c8
DY
3031 /*
3032 * Read modem signals, and then call carrier function.
3033 */
3034 ch->ch_mistat = readb(&(ch->ch_bs->m_stat));
3035 dgap_carrier(ch);
a6792a3e 3036
0b2cf5c8
DY
3037 /*
3038 * Set the start and stop characters.
3039 */
3040 if (ch->ch_startc != ch->ch_fepstartc ||
3041 ch->ch_stopc != ch->ch_fepstopc) {
3042 ch->ch_fepstartc = ch->ch_startc;
3043 ch->ch_fepstopc = ch->ch_stopc;
a6792a3e 3044
0b2cf5c8
DY
3045 /* Okay to have channel and board locks held calling this */
3046 dgap_cmdb(ch, SFLOWC, ch->ch_fepstartc, ch->ch_fepstopc, 0);
3047 }
a6792a3e 3048
0b2cf5c8
DY
3049 /*
3050 * Set the Auxiliary start and stop characters.
3051 */
3052 if (ch->ch_astartc != ch->ch_fepastartc ||
3053 ch->ch_astopc != ch->ch_fepastopc) {
3054 ch->ch_fepastartc = ch->ch_astartc;
3055 ch->ch_fepastopc = ch->ch_astopc;
a6792a3e 3056
0b2cf5c8
DY
3057 /* Okay to have channel and board locks held calling this */
3058 dgap_cmdb(ch, SAFLOWC, ch->ch_fepastartc, ch->ch_fepastopc, 0);
3059 }
a6792a3e 3060
0b2cf5c8 3061 return 0;
a6792a3e
MH
3062}
3063
0b2cf5c8
DY
3064/*
3065 * dgap_block_til_ready()
3066 *
3067 * Wait for DCD, if needed.
3068 */
3069static int dgap_block_til_ready(struct tty_struct *tty, struct file *file,
3070 struct channel_t *ch)
a6792a3e 3071{
0b2cf5c8 3072 int retval = 0;
a6792a3e 3073 struct un_t *un;
174efc1f 3074 ulong lock_flags;
0b2cf5c8
DY
3075 uint old_flags;
3076 int sleep_on_un_flags;
a6792a3e 3077
0b2cf5c8
DY
3078 if (!tty || tty->magic != TTY_MAGIC || !file || !ch ||
3079 ch->magic != DGAP_CHANNEL_MAGIC)
3080 return -EIO;
a6792a3e
MH
3081
3082 un = tty->driver_data;
3083 if (!un || un->magic != DGAP_UNIT_MAGIC)
0b2cf5c8 3084 return -EIO;
a6792a3e 3085
0b2cf5c8 3086 spin_lock_irqsave(&ch->ch_lock, lock_flags);
a6792a3e 3087
0b2cf5c8 3088 ch->ch_wopen++;
a6792a3e 3089
0b2cf5c8
DY
3090 /* Loop forever */
3091 while (1) {
a6792a3e 3092
0b2cf5c8 3093 sleep_on_un_flags = 0;
a6792a3e 3094
0b2cf5c8
DY
3095 /*
3096 * If board has failed somehow during our sleep,
3097 * bail with error.
3098 */
3099 if (ch->ch_bd->state == BOARD_FAILED) {
3100 retval = -EIO;
3101 break;
3102 }
a6792a3e 3103
0b2cf5c8
DY
3104 /* If tty was hung up, break out of loop and set error. */
3105 if (tty_hung_up_p(file)) {
3106 retval = -EAGAIN;
3107 break;
3108 }
a6792a3e 3109
0b2cf5c8
DY
3110 /*
3111 * If either unit is in the middle of the fragile part of close,
3112 * we just cannot touch the channel safely.
3113 * Go back to sleep, knowing that when the channel can be
3114 * touched safely, the close routine will signal the
3115 * ch_wait_flags to wake us back up.
3116 */
3117 if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) &
3118 UN_CLOSING)) {
a6792a3e 3119
0b2cf5c8
DY
3120 /*
3121 * Our conditions to leave cleanly and happily:
3122 * 1) NONBLOCKING on the tty is set.
3123 * 2) CLOCAL is set.
3124 * 3) DCD (fake or real) is active.
3125 */
a6792a3e 3126
0b2cf5c8
DY
3127 if (file->f_flags & O_NONBLOCK)
3128 break;
a6792a3e 3129
0b2cf5c8
DY
3130 if (tty->flags & (1 << TTY_IO_ERROR))
3131 break;
a6792a3e 3132
0b2cf5c8
DY
3133 if (ch->ch_flags & CH_CD)
3134 break;
a6792a3e 3135
0b2cf5c8
DY
3136 if (ch->ch_flags & CH_FCAR)
3137 break;
3138 } else {
3139 sleep_on_un_flags = 1;
3140 }
a6792a3e 3141
0b2cf5c8
DY
3142 /*
3143 * If there is a signal pending, the user probably
3144 * interrupted (ctrl-c) us.
3145 * Leave loop with error set.
3146 */
3147 if (signal_pending(current)) {
3148 retval = -ERESTARTSYS;
3149 break;
3150 }
a6792a3e 3151
0b2cf5c8
DY
3152 /*
3153 * Store the flags before we let go of channel lock
3154 */
3155 if (sleep_on_un_flags)
3156 old_flags = ch->ch_tun.un_flags | ch->ch_pun.un_flags;
3157 else
3158 old_flags = ch->ch_flags;
a6792a3e 3159
0b2cf5c8
DY
3160 /*
3161 * Let go of channel lock before calling schedule.
3162 * Our poller will get any FEP events and wake us up when DCD
3163 * eventually goes active.
3164 */
a6792a3e 3165
0b2cf5c8 3166 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
a6792a3e 3167
0b2cf5c8
DY
3168 /*
3169 * Wait for something in the flags to change
3170 * from the current value.
3171 */
3172 if (sleep_on_un_flags) {
3173 retval = wait_event_interruptible(un->un_flags_wait,
3174 (old_flags != (ch->ch_tun.un_flags |
3175 ch->ch_pun.un_flags)));
3176 } else {
3177 retval = wait_event_interruptible(ch->ch_flags_wait,
3178 (old_flags != ch->ch_flags));
3179 }
a6792a3e 3180
0b2cf5c8
DY
3181 /*
3182 * We got woken up for some reason.
3183 * Before looping around, grab our channel lock.
3184 */
3185 spin_lock_irqsave(&ch->ch_lock, lock_flags);
3186 }
a6792a3e 3187
0b2cf5c8 3188 ch->ch_wopen--;
a6792a3e 3189
0b2cf5c8 3190 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
a6792a3e 3191
0b2cf5c8 3192 return retval;
a6792a3e
MH
3193}
3194
a6792a3e
MH
3195/*
3196 * dgap_tty_flush_buffer()
3197 *
3198 * Flush Tx buffer (make in == out)
3199 */
3200static void dgap_tty_flush_buffer(struct tty_struct *tty)
3201{
3202 struct board_t *bd;
3203 struct channel_t *ch;
3204 struct un_t *un;
174efc1f
MH
3205 ulong lock_flags;
3206 ulong lock_flags2;
3207 u16 head;
a6792a3e
MH
3208
3209 if (!tty || tty->magic != TTY_MAGIC)
3210 return;
3211
3212 un = tty->driver_data;
3213 if (!un || un->magic != DGAP_UNIT_MAGIC)
3214 return;
3215
7d6069d7
MH
3216 ch = un->un_ch;
3217 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
cf42c34d 3218 return;
a6792a3e
MH
3219
3220 bd = ch->ch_bd;
3221 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
3222 return;
3223
c43846a9
MH
3224 spin_lock_irqsave(&bd->bd_lock, lock_flags);
3225 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
a6792a3e
MH
3226
3227 ch->ch_flags &= ~CH_STOP;
3228 head = readw(&(ch->ch_bs->tx_head));
3229 dgap_cmdw(ch, FLUSHTX, (u16) head, 0);
3230 dgap_cmdw(ch, RESUMETX, 0, 0);
3231 if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) {
3232 ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY);
3233 wake_up_interruptible(&ch->ch_tun.un_flags_wait);
3234 }
3235 if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) {
3236 ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY);
3237 wake_up_interruptible(&ch->ch_pun.un_flags_wait);
3238 }
3239
c43846a9
MH
3240 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
3241 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
a6792a3e
MH
3242 if (waitqueue_active(&tty->write_wait))
3243 wake_up_interruptible(&tty->write_wait);
3244 tty_wakeup(tty);
a6792a3e
MH
3245}
3246
a6792a3e 3247/*
0b2cf5c8 3248 * dgap_tty_hangup()
a6792a3e 3249 *
0b2cf5c8 3250 * Hangup the port. Like a close, but don't wait for output to drain.
a6792a3e 3251 */
0b2cf5c8 3252static void dgap_tty_hangup(struct tty_struct *tty)
a6792a3e
MH
3253{
3254 struct board_t *bd;
3255 struct channel_t *ch;
3256 struct un_t *un;
a6792a3e
MH
3257
3258 if (!tty || tty->magic != TTY_MAGIC)
0b2cf5c8 3259 return;
a6792a3e
MH
3260
3261 un = tty->driver_data;
3262 if (!un || un->magic != DGAP_UNIT_MAGIC)
0b2cf5c8 3263 return;
a6792a3e
MH
3264
3265 ch = un->un_ch;
3266 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
0b2cf5c8 3267 return;
a6792a3e
MH
3268
3269 bd = ch->ch_bd;
3270 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
0b2cf5c8 3271 return;
a6792a3e 3272
0b2cf5c8
DY
3273 /* flush the transmit queues */
3274 dgap_tty_flush_buffer(tty);
3275}
a6792a3e 3276
0b2cf5c8
DY
3277/*
3278 * dgap_tty_chars_in_buffer()
3279 *
3280 * Return number of characters that have not been transmitted yet.
3281 *
3282 * This routine is used by the line discipline to determine if there
3283 * is data waiting to be transmitted/drained/flushed or not.
3284 */
3285static int dgap_tty_chars_in_buffer(struct tty_struct *tty)
3286{
3287 struct board_t *bd;
3288 struct channel_t *ch;
3289 struct un_t *un;
3290 struct bs_t __iomem *bs;
3291 u8 tbusy;
3292 uint chars;
3293 u16 thead, ttail, tmask, chead, ctail;
3294 ulong lock_flags = 0;
3295 ulong lock_flags2 = 0;
a6792a3e 3296
0b2cf5c8
DY
3297 if (!tty)
3298 return 0;
a6792a3e 3299
0b2cf5c8
DY
3300 un = tty->driver_data;
3301 if (!un || un->magic != DGAP_UNIT_MAGIC)
3302 return 0;
a6792a3e 3303
0b2cf5c8
DY
3304 ch = un->un_ch;
3305 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
3306 return 0;
a6792a3e 3307
0b2cf5c8
DY
3308 bd = ch->ch_bd;
3309 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
3310 return 0;
a6792a3e 3311
0b2cf5c8
DY
3312 bs = ch->ch_bs;
3313 if (!bs)
cf42c34d 3314 return 0;
a6792a3e 3315
0b2cf5c8
DY
3316 spin_lock_irqsave(&bd->bd_lock, lock_flags);
3317 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
a6792a3e 3318
0b2cf5c8 3319 tmask = (ch->ch_tsize - 1);
a6792a3e 3320
0b2cf5c8
DY
3321 /* Get Transmit queue pointers */
3322 thead = readw(&(bs->tx_head)) & tmask;
3323 ttail = readw(&(bs->tx_tail)) & tmask;
a6792a3e 3324
0b2cf5c8
DY
3325 /* Get tbusy flag */
3326 tbusy = readb(&(bs->tbusy));
a6792a3e 3327
0b2cf5c8
DY
3328 /* Get Command queue pointers */
3329 chead = readw(&(ch->ch_cm->cm_head));
3330 ctail = readw(&(ch->ch_cm->cm_tail));
a6792a3e 3331
0b2cf5c8
DY
3332 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
3333 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
a6792a3e 3334
0b2cf5c8
DY
3335 /*
3336 * The only way we know for sure if there is no pending
3337 * data left to be transferred, is if:
3338 * 1) Transmit head and tail are equal (empty).
3339 * 2) Command queue head and tail are equal (empty).
3340 * 3) The "TBUSY" flag is 0. (Transmitter not busy).
3341 */
a6792a3e 3342
0b2cf5c8
DY
3343 if ((ttail == thead) && (tbusy == 0) && (chead == ctail)) {
3344 chars = 0;
3345 } else {
3346 if (thead >= ttail)
3347 chars = thead - ttail;
3348 else
3349 chars = thead - ttail + ch->ch_tsize;
a6792a3e 3350 /*
0b2cf5c8
DY
3351 * Fudge factor here.
3352 * If chars is zero, we know that the command queue had
3353 * something in it or tbusy was set. Because we cannot
3354 * be sure if there is still some data to be transmitted,
3355 * lets lie, and tell ld we have 1 byte left.
a6792a3e 3356 */
0b2cf5c8
DY
3357 if (chars == 0) {
3358 /*
3359 * If TBUSY is still set, and our tx buffers are empty,
3360 * force the firmware to send me another wakeup after
3361 * TBUSY has been cleared.
3362 */
3363 if (tbusy != 0) {
3364 spin_lock_irqsave(&ch->ch_lock, lock_flags);
3365 un->un_flags |= UN_EMPTY;
3366 writeb(1, &(bs->iempty));
3367 spin_unlock_irqrestore(&ch->ch_lock,
3368 lock_flags);
3369 }
3370 chars = 1;
3371 }
3372 }
a6792a3e 3373
0b2cf5c8
DY
3374 return chars;
3375}
a6792a3e 3376
0b2cf5c8
DY
3377static int dgap_wait_for_drain(struct tty_struct *tty)
3378{
3379 struct channel_t *ch;
3380 struct un_t *un;
3381 struct bs_t __iomem *bs;
3382 int ret = 0;
3383 uint count = 1;
3384 ulong lock_flags = 0;
a6792a3e 3385
0b2cf5c8
DY
3386 if (!tty || tty->magic != TTY_MAGIC)
3387 return -EIO;
a6792a3e 3388
0b2cf5c8
DY
3389 un = tty->driver_data;
3390 if (!un || un->magic != DGAP_UNIT_MAGIC)
3391 return -EIO;
a6792a3e 3392
0b2cf5c8
DY
3393 ch = un->un_ch;
3394 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
3395 return -EIO;
a6792a3e 3396
0b2cf5c8
DY
3397 bs = ch->ch_bs;
3398 if (!bs)
3399 return -EIO;
a6792a3e 3400
0b2cf5c8
DY
3401 /* Loop until data is drained */
3402 while (count != 0) {
a6792a3e 3403
0b2cf5c8 3404 count = dgap_tty_chars_in_buffer(tty);
a6792a3e 3405
0b2cf5c8
DY
3406 if (count == 0)
3407 break;
a6792a3e 3408
0b2cf5c8
DY
3409 /* Set flag waiting for drain */
3410 spin_lock_irqsave(&ch->ch_lock, lock_flags);
3411 un->un_flags |= UN_EMPTY;
3412 writeb(1, &(bs->iempty));
3413 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
a6792a3e 3414
0b2cf5c8
DY
3415 /* Go to sleep till we get woken up */
3416 ret = wait_event_interruptible(un->un_flags_wait,
3417 ((un->un_flags & UN_EMPTY) == 0));
3418 /* If ret is non-zero, user ctrl-c'ed us */
3419 if (ret)
3420 break;
3421 }
a6792a3e 3422
0b2cf5c8
DY
3423 spin_lock_irqsave(&ch->ch_lock, lock_flags);
3424 un->un_flags &= ~(UN_EMPTY);
3425 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
a6792a3e 3426
0b2cf5c8
DY
3427 return ret;
3428}
a6792a3e 3429
0b2cf5c8
DY
3430/*
3431 * dgap_maxcps_room
3432 *
3433 * Reduces bytes_available to the max number of characters
3434 * that can be sent currently given the maxcps value, and
3435 * returns the new bytes_available. This only affects printer
3436 * output.
3437 */
3438static int dgap_maxcps_room(struct channel_t *ch, struct un_t *un,
3439 int bytes_available)
3440{
3441 /*
3442 * If its not the Transparent print device, return
3443 * the full data amount.
3444 */
3445 if (un->un_type != DGAP_PRINT)
3446 return bytes_available;
a6792a3e 3447
0b2cf5c8
DY
3448 if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) {
3449 int cps_limit = 0;
3450 unsigned long current_time = jiffies;
3451 unsigned long buffer_time = current_time +
3452 (HZ * ch->ch_digi.digi_bufsize) /
3453 ch->ch_digi.digi_maxcps;
a6792a3e 3454
0b2cf5c8
DY
3455 if (ch->ch_cpstime < current_time) {
3456 /* buffer is empty */
3457 ch->ch_cpstime = current_time; /* reset ch_cpstime */
3458 cps_limit = ch->ch_digi.digi_bufsize;
3459 } else if (ch->ch_cpstime < buffer_time) {
3460 /* still room in the buffer */
3461 cps_limit = ((buffer_time - ch->ch_cpstime) *
3462 ch->ch_digi.digi_maxcps) / HZ;
3463 } else {
3464 /* no room in the buffer */
3465 cps_limit = 0;
a6792a3e
MH
3466 }
3467
0b2cf5c8
DY
3468 bytes_available = min(cps_limit, bytes_available);
3469 }
a6792a3e 3470
0b2cf5c8
DY
3471 return bytes_available;
3472}
70d97a61 3473
0b2cf5c8
DY
3474static inline void dgap_set_firmware_event(struct un_t *un, unsigned int event)
3475{
3476 struct channel_t *ch;
3477 struct bs_t __iomem *bs;
3478
3479 if (!un || un->magic != DGAP_UNIT_MAGIC)
3480 return;
3481 ch = un->un_ch;
3482 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
3483 return;
3484 bs = ch->ch_bs;
3485 if (!bs)
3486 return;
a6792a3e 3487
0b2cf5c8
DY
3488 if ((event & UN_LOW) != 0) {
3489 if ((un->un_flags & UN_LOW) == 0) {
3490 un->un_flags |= UN_LOW;
3491 writeb(1, &(bs->ilow));
70d97a61 3492 }
0b2cf5c8
DY
3493 }
3494 if ((event & UN_LOW) != 0) {
3495 if ((un->un_flags & UN_EMPTY) == 0) {
3496 un->un_flags |= UN_EMPTY;
3497 writeb(1, &(bs->iempty));
70d97a61 3498 }
0b2cf5c8
DY
3499 }
3500}
70d97a61 3501
0b2cf5c8
DY
3502/*
3503 * dgap_tty_write_room()
3504 *
3505 * Return space available in Tx buffer
3506 */
3507static int dgap_tty_write_room(struct tty_struct *tty)
3508{
3509 struct channel_t *ch;
3510 struct un_t *un;
3511 struct bs_t __iomem *bs;
3512 u16 head, tail, tmask;
3513 int ret;
3514 ulong lock_flags = 0;
a6792a3e 3515
0b2cf5c8
DY
3516 if (!tty)
3517 return 0;
a6792a3e 3518
0b2cf5c8
DY
3519 un = tty->driver_data;
3520 if (!un || un->magic != DGAP_UNIT_MAGIC)
3521 return 0;
a6792a3e 3522
0b2cf5c8
DY
3523 ch = un->un_ch;
3524 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
3525 return 0;
a6792a3e 3526
0b2cf5c8
DY
3527 bs = ch->ch_bs;
3528 if (!bs)
3529 return 0;
a6792a3e 3530
0b2cf5c8 3531 spin_lock_irqsave(&ch->ch_lock, lock_flags);
a6792a3e 3532
0b2cf5c8
DY
3533 tmask = ch->ch_tsize - 1;
3534 head = readw(&(bs->tx_head)) & tmask;
3535 tail = readw(&(bs->tx_tail)) & tmask;
a6792a3e 3536
0b2cf5c8
DY
3537 ret = tail - head - 1;
3538 if (ret < 0)
3539 ret += ch->ch_tsize;
a6792a3e 3540
0b2cf5c8
DY
3541 /* Limit printer to maxcps */
3542 ret = dgap_maxcps_room(ch, un, ret);
a6792a3e 3543
0b2cf5c8
DY
3544 /*
3545 * If we are printer device, leave space for
3546 * possibly both the on and off strings.
3547 */
3548 if (un->un_type == DGAP_PRINT) {
3549 if (!(ch->ch_flags & CH_PRON))
3550 ret -= ch->ch_digi.digi_onlen;
3551 ret -= ch->ch_digi.digi_offlen;
3552 } else {
3553 if (ch->ch_flags & CH_PRON)
3554 ret -= ch->ch_digi.digi_offlen;
3555 }
a6792a3e 3556
0b2cf5c8
DY
3557 if (ret < 0)
3558 ret = 0;
a6792a3e 3559
0b2cf5c8
DY
3560 /*
3561 * Schedule FEP to wake us up if needed.
3562 *
3563 * TODO: This might be overkill...
3564 * Do we really need to schedule callbacks from the FEP
3565 * in every case? Can we get smarter based on ret?
3566 */
3567 dgap_set_firmware_event(un, UN_LOW | UN_EMPTY);
3568 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
a6792a3e 3569
0b2cf5c8
DY
3570 return ret;
3571}
a6792a3e 3572
0b2cf5c8
DY
3573/*
3574 * dgap_tty_write()
3575 *
3576 * Take data from the user or kernel and send it out to the FEP.
3577 * In here exists all the Transparent Print magic as well.
3578 */
3579static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf,
3580 int count)
3581{
3582 struct channel_t *ch;
3583 struct un_t *un;
3584 struct bs_t __iomem *bs;
3585 char __iomem *vaddr;
3586 u16 head, tail, tmask, remain;
3587 int bufcount, n;
3588 ulong lock_flags;
a6792a3e 3589
0b2cf5c8
DY
3590 if (!tty)
3591 return 0;
a6792a3e 3592
0b2cf5c8
DY
3593 un = tty->driver_data;
3594 if (!un || un->magic != DGAP_UNIT_MAGIC)
3595 return 0;
a6792a3e 3596
0b2cf5c8
DY
3597 ch = un->un_ch;
3598 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
3599 return 0;
a6792a3e 3600
0b2cf5c8
DY
3601 bs = ch->ch_bs;
3602 if (!bs)
3603 return 0;
a6792a3e 3604
0b2cf5c8
DY
3605 if (!count)
3606 return 0;
a6792a3e 3607
0b2cf5c8 3608 spin_lock_irqsave(&ch->ch_lock, lock_flags);
a6792a3e 3609
0b2cf5c8
DY
3610 /* Get our space available for the channel from the board */
3611 tmask = ch->ch_tsize - 1;
3612 head = readw(&(bs->tx_head)) & tmask;
3613 tail = readw(&(bs->tx_tail)) & tmask;
a6792a3e 3614
0b2cf5c8
DY
3615 bufcount = tail - head - 1;
3616 if (bufcount < 0)
3617 bufcount += ch->ch_tsize;
3618
3619 /*
3620 * Limit printer output to maxcps overall, with bursts allowed
3621 * up to bufsize characters.
3622 */
3623 bufcount = dgap_maxcps_room(ch, un, bufcount);
3624
3625 /*
3626 * Take minimum of what the user wants to send, and the
3627 * space available in the FEP buffer.
3628 */
3629 count = min(count, bufcount);
a6792a3e 3630
0b2cf5c8
DY
3631 /*
3632 * Bail if no space left.
3633 */
3634 if (count <= 0) {
3635 dgap_set_firmware_event(un, UN_LOW | UN_EMPTY);
3636 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
3637 return 0;
a6792a3e 3638 }
b053bb86 3639
b28ec88a 3640 /*
0b2cf5c8
DY
3641 * Output the printer ON string, if we are in terminal mode, but
3642 * need to be in printer mode.
b28ec88a 3643 */
0b2cf5c8
DY
3644 if ((un->un_type == DGAP_PRINT) && !(ch->ch_flags & CH_PRON)) {
3645 dgap_wmove(ch, ch->ch_digi.digi_onstr,
3646 (int) ch->ch_digi.digi_onlen);
3647 head = readw(&(bs->tx_head)) & tmask;
3648 ch->ch_flags |= CH_PRON;
b053bb86
MH
3649 }
3650
0b2cf5c8
DY
3651 /*
3652 * On the other hand, output the printer OFF string, if we are
3653 * currently in printer mode, but need to output to the terminal.
3654 */
3655 if ((un->un_type != DGAP_PRINT) && (ch->ch_flags & CH_PRON)) {
3656 dgap_wmove(ch, ch->ch_digi.digi_offstr,
3657 (int) ch->ch_digi.digi_offlen);
3658 head = readw(&(bs->tx_head)) & tmask;
3659 ch->ch_flags &= ~CH_PRON;
3660 }
b053bb86 3661
0b2cf5c8 3662 n = count;
91177d53 3663
0b2cf5c8
DY
3664 /*
3665 * If the write wraps over the top of the circular buffer,
3666 * move the portion up to the wrap point, and reset the
3667 * pointers to the bottom.
3668 */
3669 remain = ch->ch_tstart + ch->ch_tsize - head;
6c8b84ef 3670
0b2cf5c8
DY
3671 if (n >= remain) {
3672 n -= remain;
3673 vaddr = ch->ch_taddr + head;
6c8b84ef 3674
0b2cf5c8 3675 memcpy_toio(vaddr, (u8 *) buf, remain);
0ade4a34 3676
0b2cf5c8
DY
3677 head = ch->ch_tstart;
3678 buf += remain;
a66369a5 3679 }
b053bb86 3680
0b2cf5c8 3681 if (n > 0) {
72d0f6fc 3682
0b2cf5c8
DY
3683 /*
3684 * Move rest of data.
3685 */
3686 vaddr = ch->ch_taddr + head;
3687 remain = n;
6c8b84ef 3688
0b2cf5c8
DY
3689 memcpy_toio(vaddr, (u8 *) buf, remain);
3690 head += remain;
b28ec88a 3691
0b2cf5c8 3692 }
72d0f6fc 3693
0b2cf5c8
DY
3694 if (count) {
3695 ch->ch_txcount += count;
3696 head &= tmask;
3697 writew(head, &(bs->tx_head));
b28ec88a 3698 }
6c8b84ef 3699
0b2cf5c8 3700 dgap_set_firmware_event(un, UN_LOW | UN_EMPTY);
72d0f6fc 3701
0b2cf5c8
DY
3702 /*
3703 * If this is the print device, and the
3704 * printer is still on, we need to turn it
3705 * off before going idle. If the buffer is
3706 * non-empty, wait until it goes empty.
3707 * Otherwise turn it off right now.
3708 */
3709 if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) {
3710 tail = readw(&(bs->tx_tail)) & tmask;
72d0f6fc 3711
0b2cf5c8
DY
3712 if (tail != head) {
3713 un->un_flags |= UN_EMPTY;
3714 writeb(1, &(bs->iempty));
3715 } else {
3716 dgap_wmove(ch, ch->ch_digi.digi_offstr,
3717 (int) ch->ch_digi.digi_offlen);
3718 head = readw(&(bs->tx_head)) & tmask;
3719 ch->ch_flags &= ~CH_PRON;
72d0f6fc 3720 }
72d0f6fc
DY
3721 }
3722
0b2cf5c8
DY
3723 /* Update printer buffer empty time. */
3724 if ((un->un_type == DGAP_PRINT) && (ch->ch_digi.digi_maxcps > 0)
3725 && (ch->ch_digi.digi_bufsize > 0)) {
3726 ch->ch_cpstime += (HZ * count) / ch->ch_digi.digi_maxcps;
72d0f6fc
DY
3727 }
3728
0b2cf5c8 3729 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
72d0f6fc 3730
0b2cf5c8 3731 return count;
b053bb86
MH
3732}
3733
b053bb86 3734/*
0b2cf5c8
DY
3735 * dgap_tty_put_char()
3736 *
3737 * Put a character into ch->ch_buf
3738 *
3739 * - used by the line discipline for OPOST processing
b053bb86 3740 */
0b2cf5c8 3741static int dgap_tty_put_char(struct tty_struct *tty, unsigned char c)
b053bb86 3742{
b053bb86 3743 /*
0b2cf5c8 3744 * Simply call tty_write.
b053bb86 3745 */
0b2cf5c8
DY
3746 dgap_tty_write(tty, &c, 1);
3747 return 1;
b053bb86
MH
3748}
3749
b053bb86 3750/*
0b2cf5c8 3751 * Return modem signals to ld.
b053bb86 3752 */
0b2cf5c8 3753static int dgap_tty_tiocmget(struct tty_struct *tty)
b053bb86 3754{
0b2cf5c8
DY
3755 struct channel_t *ch;
3756 struct un_t *un;
3757 int result;
3758 u8 mstat;
3759 ulong lock_flags;
b053bb86 3760
0b2cf5c8
DY
3761 if (!tty || tty->magic != TTY_MAGIC)
3762 return -EIO;
b053bb86 3763
0b2cf5c8
DY
3764 un = tty->driver_data;
3765 if (!un || un->magic != DGAP_UNIT_MAGIC)
3766 return -EIO;
b053bb86 3767
0b2cf5c8
DY
3768 ch = un->un_ch;
3769 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
3770 return -EIO;
b28ec88a 3771
0b2cf5c8
DY
3772 spin_lock_irqsave(&ch->ch_lock, lock_flags);
3773
3774 mstat = readb(&(ch->ch_bs->m_stat));
3775 /* Append any outbound signals that might be pending... */
3776 mstat |= ch->ch_mostat;
3777
3778 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
3779
3780 result = 0;
3781
3782 if (mstat & D_DTR(ch))
3783 result |= TIOCM_DTR;
3784 if (mstat & D_RTS(ch))
3785 result |= TIOCM_RTS;
3786 if (mstat & D_CTS(ch))
3787 result |= TIOCM_CTS;
3788 if (mstat & D_DSR(ch))
3789 result |= TIOCM_DSR;
3790 if (mstat & D_RI(ch))
3791 result |= TIOCM_RI;
3792 if (mstat & D_CD(ch))
3793 result |= TIOCM_CD;
bd3e43e5 3794
0b2cf5c8 3795 return result;
b053bb86
MH
3796}
3797
b053bb86 3798/*
0b2cf5c8
DY
3799 * dgap_tty_tiocmset()
3800 *
3801 * Set modem signals, called by ld.
b053bb86 3802 */
0b2cf5c8
DY
3803static int dgap_tty_tiocmset(struct tty_struct *tty,
3804 unsigned int set, unsigned int clear)
b053bb86 3805{
0b2cf5c8
DY
3806 struct board_t *bd;
3807 struct channel_t *ch;
3808 struct un_t *un;
3809 ulong lock_flags;
3810 ulong lock_flags2;
b053bb86 3811
0b2cf5c8
DY
3812 if (!tty || tty->magic != TTY_MAGIC)
3813 return -EIO;
b053bb86 3814
0b2cf5c8
DY
3815 un = tty->driver_data;
3816 if (!un || un->magic != DGAP_UNIT_MAGIC)
3817 return -EIO;
b053bb86 3818
0b2cf5c8
DY
3819 ch = un->un_ch;
3820 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
3821 return -EIO;
b053bb86 3822
0b2cf5c8
DY
3823 bd = ch->ch_bd;
3824 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
3825 return -EIO;
b053bb86 3826
0b2cf5c8
DY
3827 spin_lock_irqsave(&bd->bd_lock, lock_flags);
3828 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86 3829
0b2cf5c8
DY
3830 if (set & TIOCM_RTS) {
3831 ch->ch_mforce |= D_RTS(ch);
3832 ch->ch_mval |= D_RTS(ch);
b053bb86
MH
3833 }
3834
0b2cf5c8
DY
3835 if (set & TIOCM_DTR) {
3836 ch->ch_mforce |= D_DTR(ch);
3837 ch->ch_mval |= D_DTR(ch);
3838 }
3839
3840 if (clear & TIOCM_RTS) {
3841 ch->ch_mforce |= D_RTS(ch);
3842 ch->ch_mval &= ~(D_RTS(ch));
3843 }
3844
3845 if (clear & TIOCM_DTR) {
3846 ch->ch_mforce |= D_DTR(ch);
3847 ch->ch_mval &= ~(D_DTR(ch));
3848 }
3849
3850 dgap_param(ch, bd, un->un_type);
b053bb86 3851
0b2cf5c8
DY
3852 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
3853 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
3854
3855 return 0;
b053bb86
MH
3856}
3857
b053bb86 3858/*
0b2cf5c8
DY
3859 * dgap_tty_send_break()
3860 *
3861 * Send a Break, called by ld.
b053bb86 3862 */
0b2cf5c8 3863static int dgap_tty_send_break(struct tty_struct *tty, int msec)
b053bb86 3864{
0b2cf5c8
DY
3865 struct board_t *bd;
3866 struct channel_t *ch;
3867 struct un_t *un;
3868 ulong lock_flags;
3869 ulong lock_flags2;
b053bb86 3870
0b2cf5c8
DY
3871 if (!tty || tty->magic != TTY_MAGIC)
3872 return -EIO;
b053bb86 3873
0b2cf5c8
DY
3874 un = tty->driver_data;
3875 if (!un || un->magic != DGAP_UNIT_MAGIC)
3876 return -EIO;
b053bb86 3877
0b2cf5c8
DY
3878 ch = un->un_ch;
3879 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
3880 return -EIO;
b053bb86 3881
0b2cf5c8
DY
3882 bd = ch->ch_bd;
3883 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
3884 return -EIO;
3885
3886 switch (msec) {
3887 case -1:
3888 msec = 0xFFFF;
3889 break;
3890 case 0:
3891 msec = 1;
3892 break;
3893 default:
3894 msec /= 10;
3895 break;
b053bb86
MH
3896 }
3897
0b2cf5c8
DY
3898 spin_lock_irqsave(&bd->bd_lock, lock_flags);
3899 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
3900#if 0
3901 dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0);
3902#endif
3903 dgap_cmdw(ch, SBREAK, (u16) msec, 0);
bd3e43e5 3904
0b2cf5c8
DY
3905 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
3906 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
3907
3908 return 0;
b053bb86
MH
3909}
3910
b053bb86 3911/*
0b2cf5c8
DY
3912 * dgap_tty_wait_until_sent()
3913 *
3914 * wait until data has been transmitted, called by ld.
b053bb86 3915 */
0b2cf5c8 3916static void dgap_tty_wait_until_sent(struct tty_struct *tty, int timeout)
b053bb86 3917{
0b2cf5c8
DY
3918 dgap_wait_for_drain(tty);
3919}
b053bb86 3920
0b2cf5c8
DY
3921/*
3922 * dgap_send_xchar()
3923 *
3924 * send a high priority character, called by ld.
3925 */
3926static void dgap_tty_send_xchar(struct tty_struct *tty, char c)
3927{
3928 struct board_t *bd;
3929 struct channel_t *ch;
3930 struct un_t *un;
3931 ulong lock_flags;
3932 ulong lock_flags2;
3933
3934 if (!tty || tty->magic != TTY_MAGIC)
b053bb86 3935 return;
b053bb86 3936
0b2cf5c8
DY
3937 un = tty->driver_data;
3938 if (!un || un->magic != DGAP_UNIT_MAGIC)
3939 return;
b053bb86 3940
0b2cf5c8
DY
3941 ch = un->un_ch;
3942 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
3943 return;
b053bb86 3944
0b2cf5c8
DY
3945 bd = ch->ch_bd;
3946 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
31960c16 3947 return;
0b2cf5c8
DY
3948
3949 spin_lock_irqsave(&bd->bd_lock, lock_flags);
3950 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86
MH
3951
3952 /*
0b2cf5c8
DY
3953 * This is technically what we should do.
3954 * However, the NIST tests specifically want
3955 * to see each XON or XOFF character that it
3956 * sends, so lets just send each character
3957 * by hand...
b053bb86 3958 */
0b2cf5c8
DY
3959#if 0
3960 if (c == STOP_CHAR(tty))
3961 dgap_cmdw(ch, RPAUSE, 0, 0);
3962 else if (c == START_CHAR(tty))
3963 dgap_cmdw(ch, RRESUME, 0, 0);
3964 else
3965 dgap_wmove(ch, &c, 1);
3966#else
3967 dgap_wmove(ch, &c, 1);
3968#endif
b053bb86 3969
0b2cf5c8
DY
3970 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
3971 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
b053bb86
MH
3972}
3973
b053bb86 3974/*
0b2cf5c8 3975 * Return modem signals to ld.
b053bb86 3976 */
0b2cf5c8 3977static int dgap_get_modem_info(struct channel_t *ch, unsigned int __user *value)
b053bb86 3978{
0b2cf5c8
DY
3979 int result;
3980 u8 mstat;
3981 ulong lock_flags;
b053bb86 3982
0b2cf5c8 3983 spin_lock_irqsave(&ch->ch_lock, lock_flags);
b053bb86 3984
0b2cf5c8
DY
3985 mstat = readb(&(ch->ch_bs->m_stat));
3986 /* Append any outbound signals that might be pending... */
3987 mstat |= ch->ch_mostat;
b053bb86 3988
0b2cf5c8 3989 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
b053bb86 3990
0b2cf5c8 3991 result = 0;
b053bb86 3992
0b2cf5c8
DY
3993 if (mstat & D_DTR(ch))
3994 result |= TIOCM_DTR;
3995 if (mstat & D_RTS(ch))
3996 result |= TIOCM_RTS;
3997 if (mstat & D_CTS(ch))
3998 result |= TIOCM_CTS;
3999 if (mstat & D_DSR(ch))
4000 result |= TIOCM_DSR;
4001 if (mstat & D_RI(ch))
4002 result |= TIOCM_RI;
4003 if (mstat & D_CD(ch))
4004 result |= TIOCM_CD;
b053bb86 4005
e20af8ac 4006 return put_user(result, value);
0b2cf5c8 4007}
b053bb86 4008
0b2cf5c8
DY
4009/*
4010 * dgap_set_modem_info()
4011 *
4012 * Set modem signals, called by ld.
4013 */
4014static int dgap_set_modem_info(struct channel_t *ch, struct board_t *bd,
4015 struct un_t *un, unsigned int command,
4016 unsigned int __user *value)
4017{
4018 int ret;
4019 unsigned int arg;
4020 ulong lock_flags;
4021 ulong lock_flags2;
b053bb86 4022
0b2cf5c8
DY
4023 ret = get_user(arg, value);
4024 if (ret)
4025 return ret;
b053bb86 4026
0b2cf5c8
DY
4027 switch (command) {
4028 case TIOCMBIS:
4029 if (arg & TIOCM_RTS) {
4030 ch->ch_mforce |= D_RTS(ch);
4031 ch->ch_mval |= D_RTS(ch);
4032 }
b053bb86 4033
0b2cf5c8
DY
4034 if (arg & TIOCM_DTR) {
4035 ch->ch_mforce |= D_DTR(ch);
4036 ch->ch_mval |= D_DTR(ch);
4037 }
b053bb86 4038
0b2cf5c8 4039 break;
b053bb86 4040
0b2cf5c8
DY
4041 case TIOCMBIC:
4042 if (arg & TIOCM_RTS) {
4043 ch->ch_mforce |= D_RTS(ch);
4044 ch->ch_mval &= ~(D_RTS(ch));
4045 }
b053bb86 4046
0b2cf5c8
DY
4047 if (arg & TIOCM_DTR) {
4048 ch->ch_mforce |= D_DTR(ch);
4049 ch->ch_mval &= ~(D_DTR(ch));
4050 }
b053bb86 4051
0b2cf5c8 4052 break;
b053bb86 4053
0b2cf5c8
DY
4054 case TIOCMSET:
4055 ch->ch_mforce = D_DTR(ch)|D_RTS(ch);
b053bb86 4056
0b2cf5c8
DY
4057 if (arg & TIOCM_RTS)
4058 ch->ch_mval |= D_RTS(ch);
4059 else
4060 ch->ch_mval &= ~(D_RTS(ch));
b053bb86 4061
0b2cf5c8
DY
4062 if (arg & TIOCM_DTR)
4063 ch->ch_mval |= (D_DTR(ch));
4064 else
4065 ch->ch_mval &= ~(D_DTR(ch));
b053bb86 4066
0b2cf5c8 4067 break;
b053bb86 4068
0b2cf5c8
DY
4069 default:
4070 return -EINVAL;
b053bb86
MH
4071 }
4072
0b2cf5c8
DY
4073 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4074 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
4075
4076 dgap_param(ch, bd, un->un_type);
4077
4078 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4079 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4080
4081 return 0;
b053bb86
MH
4082}
4083
b053bb86 4084/*
0b2cf5c8
DY
4085 * dgap_tty_digigeta()
4086 *
4087 * Ioctl to get the information for ditty.
4088 *
4089 *
4090 *
b053bb86 4091 */
0b2cf5c8
DY
4092static int dgap_tty_digigeta(struct channel_t *ch,
4093 struct digi_t __user *retinfo)
b053bb86 4094{
0b2cf5c8 4095 struct digi_t tmp;
174efc1f 4096 ulong lock_flags;
b053bb86 4097
0b2cf5c8
DY
4098 if (!retinfo)
4099 return -EFAULT;
b053bb86 4100
0b2cf5c8 4101 memset(&tmp, 0, sizeof(tmp));
b053bb86 4102
0b2cf5c8
DY
4103 spin_lock_irqsave(&ch->ch_lock, lock_flags);
4104 memcpy(&tmp, &ch->ch_digi, sizeof(tmp));
4105 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
b053bb86 4106
0b2cf5c8
DY
4107 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
4108 return -EFAULT;
b053bb86 4109
0b2cf5c8
DY
4110 return 0;
4111}
b053bb86 4112
0b2cf5c8
DY
4113/*
4114 * dgap_tty_digiseta()
4115 *
4116 * Ioctl to set the information for ditty.
4117 *
4118 *
4119 *
4120 */
4121static int dgap_tty_digiseta(struct channel_t *ch, struct board_t *bd,
4122 struct un_t *un, struct digi_t __user *new_info)
4123{
4124 struct digi_t new_digi;
4125 ulong lock_flags = 0;
4126 unsigned long lock_flags2;
b053bb86 4127
0b2cf5c8
DY
4128 if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t)))
4129 return -EFAULT;
4130
4131 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4132 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86 4133
0b2cf5c8 4134 memcpy(&ch->ch_digi, &new_digi, sizeof(struct digi_t));
b053bb86 4135
0b2cf5c8
DY
4136 if (ch->ch_digi.digi_maxcps < 1)
4137 ch->ch_digi.digi_maxcps = 1;
b053bb86 4138
0b2cf5c8
DY
4139 if (ch->ch_digi.digi_maxcps > 10000)
4140 ch->ch_digi.digi_maxcps = 10000;
b053bb86 4141
0b2cf5c8
DY
4142 if (ch->ch_digi.digi_bufsize < 10)
4143 ch->ch_digi.digi_bufsize = 10;
b053bb86 4144
0b2cf5c8
DY
4145 if (ch->ch_digi.digi_maxchar < 1)
4146 ch->ch_digi.digi_maxchar = 1;
b053bb86 4147
0b2cf5c8
DY
4148 if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
4149 ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;
4150
4151 if (ch->ch_digi.digi_onlen > DIGI_PLEN)
4152 ch->ch_digi.digi_onlen = DIGI_PLEN;
4153
4154 if (ch->ch_digi.digi_offlen > DIGI_PLEN)
4155 ch->ch_digi.digi_offlen = DIGI_PLEN;
b053bb86 4156
0b2cf5c8
DY
4157 dgap_param(ch, bd, un->un_type);
4158
4159 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
c43846a9 4160 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
0b2cf5c8
DY
4161
4162 return 0;
b053bb86
MH
4163}
4164
0b2cf5c8
DY
4165/*
4166 * dgap_tty_digigetedelay()
b053bb86 4167 *
0b2cf5c8 4168 * Ioctl to get the current edelay setting.
b053bb86 4169 *
b053bb86 4170 *
0b2cf5c8
DY
4171 *
4172 */
4173static int dgap_tty_digigetedelay(struct tty_struct *tty, int __user *retinfo)
b053bb86 4174{
0b2cf5c8
DY
4175 struct channel_t *ch;
4176 struct un_t *un;
4177 int tmp;
4178 ulong lock_flags;
b053bb86 4179
0b2cf5c8
DY
4180 if (!retinfo)
4181 return -EFAULT;
b053bb86 4182
0b2cf5c8
DY
4183 if (!tty || tty->magic != TTY_MAGIC)
4184 return -EFAULT;
b053bb86 4185
0b2cf5c8
DY
4186 un = tty->driver_data;
4187 if (!un || un->magic != DGAP_UNIT_MAGIC)
4188 return -EFAULT;
b053bb86 4189
0b2cf5c8
DY
4190 ch = un->un_ch;
4191 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
4192 return -EFAULT;
b053bb86 4193
0b2cf5c8 4194 memset(&tmp, 0, sizeof(tmp));
b053bb86 4195
0b2cf5c8
DY
4196 spin_lock_irqsave(&ch->ch_lock, lock_flags);
4197 tmp = readw(&(ch->ch_bs->edelay));
4198 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
b053bb86 4199
0b2cf5c8
DY
4200 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
4201 return -EFAULT;
b053bb86 4202
0b2cf5c8
DY
4203 return 0;
4204}
b053bb86 4205
0b2cf5c8
DY
4206/*
4207 * dgap_tty_digisetedelay()
4208 *
4209 * Ioctl to set the EDELAY setting
4210 *
4211 */
4212static int dgap_tty_digisetedelay(struct channel_t *ch, struct board_t *bd,
4213 struct un_t *un, int __user *new_info)
4214{
4215 int new_digi;
4216 ulong lock_flags;
4217 ulong lock_flags2;
b053bb86 4218
0b2cf5c8
DY
4219 if (copy_from_user(&new_digi, new_info, sizeof(int)))
4220 return -EFAULT;
b053bb86 4221
0b2cf5c8
DY
4222 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4223 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86 4224
0b2cf5c8 4225 writew((u16) new_digi, &(ch->ch_bs->edelay));
b053bb86 4226
0b2cf5c8 4227 dgap_param(ch, bd, un->un_type);
b053bb86 4228
0b2cf5c8
DY
4229 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4230 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4231
4232 return 0;
b053bb86
MH
4233}
4234
0b2cf5c8
DY
4235/*
4236 * dgap_tty_digigetcustombaud()
b053bb86 4237 *
0b2cf5c8
DY
4238 * Ioctl to get the current custom baud rate setting.
4239 */
4240static int dgap_tty_digigetcustombaud(struct channel_t *ch, struct un_t *un,
4241 int __user *retinfo)
4242{
4243 int tmp;
4244 ulong lock_flags;
4245
4246 if (!retinfo)
4247 return -EFAULT;
4248
4249 memset(&tmp, 0, sizeof(tmp));
4250
4251 spin_lock_irqsave(&ch->ch_lock, lock_flags);
4252 tmp = dgap_get_custom_baud(ch);
4253 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
4254
4255 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
4256 return -EFAULT;
4257
4258 return 0;
4259}
4260
4261/*
4262 * dgap_tty_digisetcustombaud()
b053bb86 4263 *
0b2cf5c8
DY
4264 * Ioctl to set the custom baud rate setting
4265 */
4266static int dgap_tty_digisetcustombaud(struct channel_t *ch, struct board_t *bd,
4267 struct un_t *un, int __user *new_info)
b053bb86 4268{
0b2cf5c8
DY
4269 uint new_rate;
4270 ulong lock_flags;
4271 ulong lock_flags2;
b053bb86 4272
0b2cf5c8
DY
4273 if (copy_from_user(&new_rate, new_info, sizeof(unsigned int)))
4274 return -EFAULT;
b053bb86 4275
0b2cf5c8 4276 if (bd->bd_flags & BD_FEP5PLUS) {
b053bb86 4277
0b2cf5c8
DY
4278 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4279 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86 4280
0b2cf5c8 4281 ch->ch_custom_speed = new_rate;
b053bb86 4282
0b2cf5c8
DY
4283 dgap_param(ch, bd, un->un_type);
4284
4285 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4286 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
b053bb86
MH
4287 }
4288
0b2cf5c8
DY
4289 return 0;
4290}
4291
4292/*
4293 * dgap_set_termios()
4294 */
4295static void dgap_tty_set_termios(struct tty_struct *tty,
4296 struct ktermios *old_termios)
4297{
4298 struct board_t *bd;
4299 struct channel_t *ch;
4300 struct un_t *un;
4301 unsigned long lock_flags;
4302 unsigned long lock_flags2;
4303
4304 if (!tty || tty->magic != TTY_MAGIC)
4305 return;
b053bb86 4306
0b2cf5c8
DY
4307 un = tty->driver_data;
4308 if (!un || un->magic != DGAP_UNIT_MAGIC)
4309 return;
b053bb86 4310
0b2cf5c8
DY
4311 ch = un->un_ch;
4312 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
4313 return;
b053bb86 4314
0b2cf5c8
DY
4315 bd = ch->ch_bd;
4316 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
4317 return;
b053bb86 4318
0b2cf5c8
DY
4319 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4320 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86 4321
0b2cf5c8
DY
4322 ch->ch_c_cflag = tty->termios.c_cflag;
4323 ch->ch_c_iflag = tty->termios.c_iflag;
4324 ch->ch_c_oflag = tty->termios.c_oflag;
4325 ch->ch_c_lflag = tty->termios.c_lflag;
4326 ch->ch_startc = tty->termios.c_cc[VSTART];
4327 ch->ch_stopc = tty->termios.c_cc[VSTOP];
b053bb86 4328
0b2cf5c8
DY
4329 dgap_carrier(ch);
4330 dgap_param(ch, bd, un->un_type);
b053bb86 4331
0b2cf5c8
DY
4332 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4333 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
b053bb86
MH
4334}
4335
0b2cf5c8 4336static void dgap_tty_throttle(struct tty_struct *tty)
b053bb86 4337{
0b2cf5c8
DY
4338 struct board_t *bd;
4339 struct channel_t *ch;
4340 struct un_t *un;
4341 ulong lock_flags;
4342 ulong lock_flags2;
b053bb86 4343
0b2cf5c8 4344 if (!tty || tty->magic != TTY_MAGIC)
b053bb86
MH
4345 return;
4346
0b2cf5c8
DY
4347 un = tty->driver_data;
4348 if (!un || un->magic != DGAP_UNIT_MAGIC)
b053bb86 4349 return;
b053bb86 4350
0b2cf5c8
DY
4351 ch = un->un_ch;
4352 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
b053bb86
MH
4353 return;
4354
0b2cf5c8
DY
4355 bd = ch->ch_bd;
4356 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
b053bb86 4357 return;
b053bb86 4358
0b2cf5c8
DY
4359 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4360 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86 4361
0b2cf5c8
DY
4362 ch->ch_flags |= (CH_RXBLOCK);
4363#if 1
4364 dgap_cmdw(ch, RPAUSE, 0, 0);
4365#endif
b053bb86 4366
0b2cf5c8
DY
4367 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4368 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
b053bb86 4369
0b2cf5c8 4370}
b053bb86 4371
0b2cf5c8
DY
4372static void dgap_tty_unthrottle(struct tty_struct *tty)
4373{
4374 struct board_t *bd;
4375 struct channel_t *ch;
4376 struct un_t *un;
4377 ulong lock_flags;
4378 ulong lock_flags2;
b053bb86 4379
0b2cf5c8
DY
4380 if (!tty || tty->magic != TTY_MAGIC)
4381 return;
b053bb86 4382
0b2cf5c8
DY
4383 un = tty->driver_data;
4384 if (!un || un->magic != DGAP_UNIT_MAGIC)
4385 return;
b053bb86 4386
0b2cf5c8
DY
4387 ch = un->un_ch;
4388 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
4389 return;
b053bb86 4390
0b2cf5c8
DY
4391 bd = ch->ch_bd;
4392 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
4393 return;
b053bb86 4394
0b2cf5c8
DY
4395 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4396 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86 4397
0b2cf5c8
DY
4398 ch->ch_flags &= ~(CH_RXBLOCK);
4399
4400#if 1
4401 dgap_cmdw(ch, RRESUME, 0, 0);
4402#endif
4403
4404 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4405 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
b053bb86
MH
4406}
4407
48d43be4
DY
4408static struct board_t *find_board_by_major(unsigned int major)
4409{
4410 unsigned int i;
4411
4412 for (i = 0; i < MAXBOARDS; i++) {
4413 struct board_t *brd = dgap_board[i];
d268b50e 4414
48d43be4
DY
4415 if (!brd)
4416 return NULL;
4417 if (major == brd->serial_driver->major ||
4418 major == brd->print_driver->major)
4419 return brd;
4420 }
4421
4422 return NULL;
4423}
4424
0b2cf5c8 4425/************************************************************************
b053bb86 4426 *
0b2cf5c8 4427 * TTY Entry points and helper functions
b053bb86 4428 *
0b2cf5c8
DY
4429 ************************************************************************/
4430
4431/*
4432 * dgap_tty_open()
b053bb86 4433 *
0b2cf5c8
DY
4434 */
4435static int dgap_tty_open(struct tty_struct *tty, struct file *file)
b053bb86 4436{
0b2cf5c8
DY
4437 struct board_t *brd;
4438 struct channel_t *ch;
4439 struct un_t *un;
405b26d9 4440 struct bs_t __iomem *bs;
0b2cf5c8
DY
4441 uint major;
4442 uint minor;
4443 int rc;
4444 ulong lock_flags;
4445 ulong lock_flags2;
174efc1f 4446 u16 head;
b053bb86 4447
0b2cf5c8
DY
4448 major = MAJOR(tty_devnum(tty));
4449 minor = MINOR(tty_devnum(tty));
4450
48d43be4 4451 brd = find_board_by_major(major);
0b2cf5c8
DY
4452 if (!brd)
4453 return -EIO;
b053bb86
MH
4454
4455 /*
0b2cf5c8
DY
4456 * If board is not yet up to a state of READY, go to
4457 * sleep waiting for it to happen or they cancel the open.
b053bb86 4458 */
0b2cf5c8
DY
4459 rc = wait_event_interruptible(brd->state_wait,
4460 (brd->state & BOARD_READY));
4461
4462 if (rc)
4463 return rc;
4464
4465 spin_lock_irqsave(&brd->bd_lock, lock_flags);
4466
4467 /* The wait above should guarantee this cannot happen */
4468 if (brd->state != BOARD_READY) {
4469 spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
4470 return -EIO;
4471 }
4472
4473 /* If opened device is greater than our number of ports, bail. */
4474 if (MINOR(tty_devnum(tty)) > brd->nasync) {
4475 spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
4476 return -EIO;
4477 }
4478
4479 ch = brd->channels[minor];
4480 if (!ch) {
4481 spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
4482 return -EIO;
4483 }
4484
4485 /* Grab channel lock */
4486 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
4487
4488 /* Figure out our type */
4c5dbca6 4489 if (major == brd->serial_driver->major) {
0b2cf5c8
DY
4490 un = &brd->channels[minor]->ch_tun;
4491 un->un_type = DGAP_SERIAL;
4c5dbca6 4492 } else if (major == brd->print_driver->major) {
0b2cf5c8
DY
4493 un = &brd->channels[minor]->ch_pun;
4494 un->un_type = DGAP_PRINT;
4495 } else {
4496 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4497 spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
4498 return -EIO;
4499 }
4500
4501 /* Store our unit into driver_data, so we always have it available. */
4502 tty->driver_data = un;
b053bb86
MH
4503
4504 /*
0b2cf5c8 4505 * Error if channel info pointer is NULL.
b053bb86 4506 */
0b2cf5c8
DY
4507 bs = ch->ch_bs;
4508 if (!bs) {
4509 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4510 spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
4511 return -EIO;
4512 }
b053bb86
MH
4513
4514 /*
0b2cf5c8 4515 * Initialize tty's
b053bb86 4516 */
0b2cf5c8
DY
4517 if (!(un->un_flags & UN_ISOPEN)) {
4518 /* Store important variables. */
4519 un->un_tty = tty;
b053bb86 4520
0b2cf5c8 4521 /* Maybe do something here to the TTY struct as well? */
b053bb86
MH
4522 }
4523
4524 /*
0b2cf5c8 4525 * Initialize if neither terminal or printer is open.
b053bb86 4526 */
0b2cf5c8 4527 if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) {
b053bb86 4528
0b2cf5c8
DY
4529 ch->ch_mforce = 0;
4530 ch->ch_mval = 0;
b053bb86 4531
0b2cf5c8
DY
4532 /*
4533 * Flush input queue.
4534 */
4535 head = readw(&(bs->rx_head));
4536 writew(head, &(bs->rx_tail));
b053bb86 4537
0b2cf5c8
DY
4538 ch->ch_flags = 0;
4539 ch->pscan_state = 0;
4540 ch->pscan_savechar = 0;
b053bb86 4541
0b2cf5c8
DY
4542 ch->ch_c_cflag = tty->termios.c_cflag;
4543 ch->ch_c_iflag = tty->termios.c_iflag;
4544 ch->ch_c_oflag = tty->termios.c_oflag;
4545 ch->ch_c_lflag = tty->termios.c_lflag;
4546 ch->ch_startc = tty->termios.c_cc[VSTART];
4547 ch->ch_stopc = tty->termios.c_cc[VSTOP];
b053bb86 4548
0b2cf5c8
DY
4549 /* TODO: flush our TTY struct here? */
4550 }
b053bb86 4551
0b2cf5c8
DY
4552 dgap_carrier(ch);
4553 /*
4554 * Run param in case we changed anything
4555 */
4556 dgap_param(ch, brd, un->un_type);
b053bb86
MH
4557
4558 /*
0b2cf5c8 4559 * follow protocol for opening port
b053bb86 4560 */
b053bb86 4561
0b2cf5c8
DY
4562 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4563 spin_unlock_irqrestore(&brd->bd_lock, lock_flags);
b053bb86 4564
0b2cf5c8 4565 rc = dgap_block_til_ready(tty, file, ch);
b053bb86 4566
0b2cf5c8
DY
4567 if (!un->un_tty)
4568 return -ENODEV;
4569
4570 /* No going back now, increment our unit and channel counters */
4571 spin_lock_irqsave(&ch->ch_lock, lock_flags);
4572 ch->ch_open_count++;
4573 un->un_open_count++;
4574 un->un_flags |= (UN_ISOPEN);
4575 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
4576
4577 return rc;
b053bb86
MH
4578}
4579
0b2cf5c8
DY
4580/*
4581 * dgap_tty_close()
b053bb86 4582 *
0b2cf5c8
DY
4583 */
4584static void dgap_tty_close(struct tty_struct *tty, struct file *file)
b053bb86 4585{
0b2cf5c8
DY
4586 struct ktermios *ts;
4587 struct board_t *bd;
4588 struct channel_t *ch;
4589 struct un_t *un;
4590 ulong lock_flags;
b053bb86 4591
0b2cf5c8
DY
4592 if (!tty || tty->magic != TTY_MAGIC)
4593 return;
b053bb86 4594
0b2cf5c8
DY
4595 un = tty->driver_data;
4596 if (!un || un->magic != DGAP_UNIT_MAGIC)
4597 return;
b053bb86 4598
0b2cf5c8
DY
4599 ch = un->un_ch;
4600 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
4601 return;
b053bb86 4602
0b2cf5c8
DY
4603 bd = ch->ch_bd;
4604 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
4605 return;
b053bb86 4606
0b2cf5c8 4607 ts = &tty->termios;
b053bb86 4608
0b2cf5c8 4609 spin_lock_irqsave(&ch->ch_lock, lock_flags);
b053bb86 4610
0b2cf5c8
DY
4611 /*
4612 * Determine if this is the last close or not - and if we agree about
4613 * which type of close it is with the Line Discipline
4614 */
4615 if ((tty->count == 1) && (un->un_open_count != 1)) {
b053bb86 4616 /*
0b2cf5c8
DY
4617 * Uh, oh. tty->count is 1, which means that the tty
4618 * structure will be freed. un_open_count should always
4619 * be one in these conditions. If it's greater than
4620 * one, we've got real problems, since it means the
4621 * serial port won't be shutdown.
b053bb86 4622 */
0b2cf5c8
DY
4623 un->un_open_count = 1;
4624 }
b053bb86 4625
0b2cf5c8
DY
4626 if (--un->un_open_count < 0)
4627 un->un_open_count = 0;
b053bb86 4628
0b2cf5c8 4629 ch->ch_open_count--;
b053bb86 4630
0b2cf5c8
DY
4631 if (ch->ch_open_count && un->un_open_count) {
4632 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
4633 return;
4634 }
b053bb86 4635
0b2cf5c8 4636 /* OK, its the last close on the unit */
b053bb86 4637
0b2cf5c8 4638 un->un_flags |= UN_CLOSING;
b053bb86 4639
0b2cf5c8
DY
4640 tty->closing = 1;
4641
4642 /*
4643 * Only officially close channel if count is 0 and
4644 * DIGI_PRINTER bit is not set.
4645 */
4646 if ((ch->ch_open_count == 0) &&
4647 !(ch->ch_digi.digi_flags & DIGI_PRINTER)) {
b053bb86 4648
0b2cf5c8 4649 ch->ch_flags &= ~(CH_RXBLOCK);
b053bb86 4650
0b2cf5c8 4651 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
b053bb86 4652
0b2cf5c8
DY
4653 /* wait for output to drain */
4654 /* This will also return if we take an interrupt */
b053bb86 4655
0b2cf5c8 4656 dgap_wait_for_drain(tty);
b053bb86 4657
0b2cf5c8
DY
4658 dgap_tty_flush_buffer(tty);
4659 tty_ldisc_flush(tty);
b053bb86 4660
0b2cf5c8 4661 spin_lock_irqsave(&ch->ch_lock, lock_flags);
b053bb86 4662
0b2cf5c8 4663 tty->closing = 0;
b053bb86
MH
4664
4665 /*
0b2cf5c8 4666 * If we have HUPCL set, lower DTR and RTS
b053bb86 4667 */
0b2cf5c8
DY
4668 if (ch->ch_c_cflag & HUPCL) {
4669 ch->ch_mostat &= ~(D_RTS(ch)|D_DTR(ch));
4670 dgap_cmdb(ch, SMODEM, 0, D_DTR(ch)|D_RTS(ch), 0);
b053bb86 4671
af5b80be 4672 /*
0b2cf5c8
DY
4673 * Go to sleep to ensure RTS/DTR
4674 * have been dropped for modems to see it.
af5b80be 4675 */
0b2cf5c8
DY
4676 spin_unlock_irqrestore(&ch->ch_lock,
4677 lock_flags);
b053bb86 4678
0b2cf5c8
DY
4679 /* .25 second delay for dropping RTS/DTR */
4680 schedule_timeout_interruptible(msecs_to_jiffies(250));
b053bb86 4681
0b2cf5c8 4682 spin_lock_irqsave(&ch->ch_lock, lock_flags);
b053bb86
MH
4683 }
4684
0b2cf5c8
DY
4685 ch->pscan_state = 0;
4686 ch->pscan_savechar = 0;
4687 ch->ch_baud_info = 0;
b053bb86 4688
b053bb86
MH
4689 }
4690
4691 /*
0b2cf5c8 4692 * turn off print device when closing print device.
b053bb86 4693 */
0b2cf5c8
DY
4694 if ((un->un_type == DGAP_PRINT) && (ch->ch_flags & CH_PRON)) {
4695 dgap_wmove(ch, ch->ch_digi.digi_offstr,
4696 (int) ch->ch_digi.digi_offlen);
4697 ch->ch_flags &= ~CH_PRON;
b053bb86
MH
4698 }
4699
0b2cf5c8
DY
4700 un->un_tty = NULL;
4701 un->un_flags &= ~(UN_ISOPEN | UN_CLOSING);
4702 tty->driver_data = NULL;
b053bb86 4703
0b2cf5c8
DY
4704 wake_up_interruptible(&ch->ch_flags_wait);
4705 wake_up_interruptible(&un->un_flags_wait);
b053bb86 4706
0b2cf5c8
DY
4707 spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
4708}
b053bb86 4709
0b2cf5c8
DY
4710static void dgap_tty_start(struct tty_struct *tty)
4711{
4712 struct board_t *bd;
4713 struct channel_t *ch;
4714 struct un_t *un;
4715 ulong lock_flags;
4716 ulong lock_flags2;
b053bb86 4717
0b2cf5c8
DY
4718 if (!tty || tty->magic != TTY_MAGIC)
4719 return;
b053bb86 4720
0b2cf5c8
DY
4721 un = tty->driver_data;
4722 if (!un || un->magic != DGAP_UNIT_MAGIC)
4723 return;
b053bb86 4724
0b2cf5c8
DY
4725 ch = un->un_ch;
4726 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
4727 return;
b053bb86 4728
0b2cf5c8
DY
4729 bd = ch->ch_bd;
4730 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
4731 return;
b053bb86 4732
0b2cf5c8
DY
4733 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4734 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
96045db8 4735
0b2cf5c8 4736 dgap_cmdw(ch, RESUMETX, 0, 0);
b053bb86 4737
0b2cf5c8
DY
4738 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4739 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4740}
b053bb86 4741
0b2cf5c8
DY
4742static void dgap_tty_stop(struct tty_struct *tty)
4743{
4744 struct board_t *bd;
4745 struct channel_t *ch;
4746 struct un_t *un;
4747 ulong lock_flags;
4748 ulong lock_flags2;
b053bb86 4749
0b2cf5c8
DY
4750 if (!tty || tty->magic != TTY_MAGIC)
4751 return;
b053bb86 4752
0b2cf5c8
DY
4753 un = tty->driver_data;
4754 if (!un || un->magic != DGAP_UNIT_MAGIC)
4755 return;
4756
4757 ch = un->un_ch;
4758 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
4759 return;
4760
4761 bd = ch->ch_bd;
4762 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
4763 return;
4764
4765 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4766 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
4767
4768 dgap_cmdw(ch, PAUSETX, 0, 0);
4769
4770 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4771 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4772}
4773
4774/*
4775 * dgap_tty_flush_chars()
4776 *
4777 * Flush the cook buffer
4778 *
4779 * Note to self, and any other poor souls who venture here:
4780 *
4781 * flush in this case DOES NOT mean dispose of the data.
4782 * instead, it means "stop buffering and send it if you
4783 * haven't already." Just guess how I figured that out... SRW 2-Jun-98
4784 *
4785 * It is also always called in interrupt context - JAR 8-Sept-99
4786 */
4787static void dgap_tty_flush_chars(struct tty_struct *tty)
4788{
4789 struct board_t *bd;
4790 struct channel_t *ch;
4791 struct un_t *un;
4792 ulong lock_flags;
4793 ulong lock_flags2;
b053bb86 4794
0b2cf5c8
DY
4795 if (!tty || tty->magic != TTY_MAGIC)
4796 return;
b053bb86 4797
0b2cf5c8
DY
4798 un = tty->driver_data;
4799 if (!un || un->magic != DGAP_UNIT_MAGIC)
4800 return;
b053bb86 4801
0b2cf5c8
DY
4802 ch = un->un_ch;
4803 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
4804 return;
b053bb86 4805
0b2cf5c8
DY
4806 bd = ch->ch_bd;
4807 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
4808 return;
b053bb86 4809
0b2cf5c8
DY
4810 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4811 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86 4812
0b2cf5c8 4813 /* TODO: Do something here */
b053bb86 4814
0b2cf5c8
DY
4815 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4816 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
b053bb86
MH
4817}
4818
0b2cf5c8
DY
4819/*****************************************************************************
4820 *
4821 * The IOCTL function and all of its helpers
4822 *
4823 *****************************************************************************/
4824
b053bb86 4825/*
0b2cf5c8 4826 * dgap_tty_ioctl()
b053bb86 4827 *
0b2cf5c8 4828 * The usual assortment of ioctl's
b053bb86 4829 */
0b2cf5c8
DY
4830static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
4831 unsigned long arg)
b053bb86 4832{
0b2cf5c8
DY
4833 struct board_t *bd;
4834 struct channel_t *ch;
4835 struct un_t *un;
4836 int rc;
4837 u16 head;
4838 ulong lock_flags = 0;
4839 ulong lock_flags2 = 0;
4840 void __user *uarg = (void __user *) arg;
b053bb86 4841
0b2cf5c8
DY
4842 if (!tty || tty->magic != TTY_MAGIC)
4843 return -ENODEV;
4844
4845 un = tty->driver_data;
4846 if (!un || un->magic != DGAP_UNIT_MAGIC)
4847 return -ENODEV;
b053bb86 4848
0b2cf5c8 4849 ch = un->un_ch;
b053bb86 4850 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
0b2cf5c8 4851 return -ENODEV;
b053bb86 4852
0b2cf5c8
DY
4853 bd = ch->ch_bd;
4854 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
4855 return -ENODEV;
b053bb86 4856
0b2cf5c8
DY
4857 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4858 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86 4859
0b2cf5c8
DY
4860 if (un->un_open_count <= 0) {
4861 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4862 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4863 return -EIO;
4864 }
b053bb86 4865
0b2cf5c8 4866 switch (cmd) {
b053bb86 4867
0b2cf5c8 4868 /* Here are all the standard ioctl's that we MUST implement */
b053bb86 4869
0b2cf5c8
DY
4870 case TCSBRK:
4871 /*
4872 * TCSBRK is SVID version: non-zero arg --> no break
4873 * this behaviour is exploited by tcdrain().
4874 *
4875 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
4876 * between 0.25 and 0.5 seconds so we'll ask for something
4877 * in the middle: 0.375 seconds.
4878 */
4879 rc = tty_check_change(tty);
4880 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4881 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4882 if (rc)
4883 return rc;
b053bb86 4884
0b2cf5c8 4885 rc = dgap_wait_for_drain(tty);
b053bb86 4886
0b2cf5c8
DY
4887 if (rc)
4888 return -EINTR;
b053bb86 4889
0b2cf5c8
DY
4890 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4891 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
8cdd7639 4892
0b2cf5c8
DY
4893 if (((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP))
4894 dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0);
8cdd7639 4895
0b2cf5c8
DY
4896 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4897 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
8cdd7639 4898
0b2cf5c8 4899 return 0;
8cdd7639 4900
0b2cf5c8
DY
4901 case TCSBRKP:
4902 /* support for POSIX tcsendbreak()
8cdd7639 4903
0b2cf5c8
DY
4904 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
4905 * between 0.25 and 0.5 seconds so we'll ask for something
4906 * in the middle: 0.375 seconds.
4907 */
4908 rc = tty_check_change(tty);
4909 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4910 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4911 if (rc)
4912 return rc;
8cdd7639 4913
0b2cf5c8
DY
4914 rc = dgap_wait_for_drain(tty);
4915 if (rc)
4916 return -EINTR;
4917
4918 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4919 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
4920
4921 dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0);
4922
4923 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4924 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4925
4926 return 0;
4927
4928 case TIOCSBRK:
4929 /*
4930 * FEP5 doesn't support turning on a break unconditionally.
4931 * The FEP5 device will stop sending a break automatically
4932 * after the specified time value that was sent when turning on
4933 * the break.
4934 */
4935 rc = tty_check_change(tty);
4936 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4937 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4938 if (rc)
4939 return rc;
4940
4941 rc = dgap_wait_for_drain(tty);
4942 if (rc)
4943 return -EINTR;
b053bb86 4944
0b2cf5c8
DY
4945 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4946 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
b053bb86 4947
0b2cf5c8 4948 dgap_cmdw(ch, SBREAK, (u16) SBREAK_TIME, 0);
b053bb86 4949
0b2cf5c8
DY
4950 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4951 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
b053bb86 4952
0b2cf5c8
DY
4953 return 0;
4954
4955 case TIOCCBRK:
4956 /*
4957 * FEP5 doesn't support turning off a break unconditionally.
4958 * The FEP5 device will stop sending a break automatically
4959 * after the specified time value that was sent when turning on
4960 * the break.
4961 */
4962 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
c43846a9 4963 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
0b2cf5c8 4964 return 0;
b053bb86 4965
0b2cf5c8 4966 case TIOCGSOFTCAR:
b053bb86 4967
0b2cf5c8
DY
4968 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4969 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
b053bb86 4970
0b2cf5c8
DY
4971 rc = put_user(C_CLOCAL(tty) ? 1 : 0,
4972 (unsigned long __user *) arg);
4973 return rc;
b053bb86 4974
0b2cf5c8
DY
4975 case TIOCSSOFTCAR:
4976 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
c43846a9 4977 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
b053bb86 4978
0b2cf5c8
DY
4979 rc = get_user(arg, (unsigned long __user *) arg);
4980 if (rc)
4981 return rc;
4982
4983 spin_lock_irqsave(&bd->bd_lock, lock_flags);
4984 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
4985 tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) |
4986 (arg ? CLOCAL : 0));
4987 dgap_param(ch, bd, un->un_type);
4988 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4989 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4990
4991 return 0;
4992
4993 case TIOCMGET:
4994 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
4995 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
4996 return dgap_get_modem_info(ch, uarg);
4997
4998 case TIOCMBIS:
4999 case TIOCMBIC:
5000 case TIOCMSET:
5001 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5002 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5003 return dgap_set_modem_info(ch, bd, un, cmd, uarg);
b053bb86
MH
5004
5005 /*
0b2cf5c8 5006 * Here are any additional ioctl's that we want to implement
b053bb86
MH
5007 */
5008
0b2cf5c8
DY
5009 case TCFLSH:
5010 /*
5011 * The linux tty driver doesn't have a flush
5012 * input routine for the driver, assuming all backed
5013 * up data is in the line disc. buffers. However,
5014 * we all know that's not the case. Here, we
5015 * act on the ioctl, but then lie and say we didn't
5016 * so the line discipline will process the flush
5017 * also.
5018 */
5019 rc = tty_check_change(tty);
5020 if (rc) {
5021 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5022 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5023 return rc;
5024 }
b053bb86 5025
0b2cf5c8
DY
5026 if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) {
5027 if (!(un->un_type == DGAP_PRINT)) {
5028 head = readw(&(ch->ch_bs->rx_head));
5029 writew(head, &(ch->ch_bs->rx_tail));
5030 writeb(0, &(ch->ch_bs->orun));
5031 }
5032 }
5033
5034 if ((arg != TCOFLUSH) && (arg != TCIOFLUSH)) {
5035 /* pretend we didn't recognize this IOCTL */
5036 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5037 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5038
5039 return -ENOIOCTLCMD;
5040 }
5041
5042 ch->ch_flags &= ~CH_STOP;
5043 head = readw(&(ch->ch_bs->tx_head));
5044 dgap_cmdw(ch, FLUSHTX, (u16) head, 0);
5045 dgap_cmdw(ch, RESUMETX, 0, 0);
5046 if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) {
5047 ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY);
5048 wake_up_interruptible(&ch->ch_tun.un_flags_wait);
5049 }
5050 if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) {
5051 ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY);
5052 wake_up_interruptible(&ch->ch_pun.un_flags_wait);
5053 }
5054 if (waitqueue_active(&tty->write_wait))
5055 wake_up_interruptible(&tty->write_wait);
b053bb86 5056
0b2cf5c8
DY
5057 /* Can't hold any locks when calling tty_wakeup! */
5058 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5059 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5060 tty_wakeup(tty);
5061
5062 /* pretend we didn't recognize this IOCTL */
5063 return -ENOIOCTLCMD;
5064
5065 case TCSETSF:
5066 case TCSETSW:
b053bb86 5067 /*
0b2cf5c8
DY
5068 * The linux tty driver doesn't have a flush
5069 * input routine for the driver, assuming all backed
5070 * up data is in the line disc. buffers. However,
5071 * we all know that's not the case. Here, we
5072 * act on the ioctl, but then lie and say we didn't
5073 * so the line discipline will process the flush
5074 * also.
b053bb86 5075 */
0b2cf5c8
DY
5076 if (cmd == TCSETSF) {
5077 /* flush rx */
5078 ch->ch_flags &= ~CH_STOP;
5079 head = readw(&(ch->ch_bs->rx_head));
5080 writew(head, &(ch->ch_bs->rx_tail));
5081 }
b053bb86 5082
0b2cf5c8
DY
5083 /* now wait for all the output to drain */
5084 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5085 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5086 rc = dgap_wait_for_drain(tty);
5087 if (rc)
5088 return -EINTR;
b053bb86 5089
0b2cf5c8
DY
5090 /* pretend we didn't recognize this */
5091 return -ENOIOCTLCMD;
b053bb86 5092
0b2cf5c8
DY
5093 case TCSETAW:
5094
5095 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5096 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5097 rc = dgap_wait_for_drain(tty);
5098 if (rc)
5099 return -EINTR;
5100
5101 /* pretend we didn't recognize this */
5102 return -ENOIOCTLCMD;
b053bb86 5103
0b2cf5c8 5104 case TCXONC:
b053bb86 5105 /*
0b2cf5c8
DY
5106 * The Linux Line Discipline (LD) would do this for us if we
5107 * let it, but we have the special firmware options to do this
5108 * the "right way" regardless of hardware or software flow
5109 * control so we'll do it outselves instead of letting the LD
5110 * do it.
b053bb86 5111 */
0b2cf5c8
DY
5112 rc = tty_check_change(tty);
5113 if (rc) {
5114 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5115 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5116 return rc;
5117 }
b053bb86 5118
0b2cf5c8 5119 switch (arg) {
b053bb86 5120
0b2cf5c8 5121 case TCOON:
c43846a9 5122 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
0b2cf5c8
DY
5123 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5124 dgap_tty_start(tty);
5125 return 0;
5126 case TCOOFF:
5127 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5128 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5129 dgap_tty_stop(tty);
5130 return 0;
5131 case TCION:
5132 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5133 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5134 /* Make the ld do it */
5135 return -ENOIOCTLCMD;
5136 case TCIOFF:
5137 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5138 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5139 /* Make the ld do it */
5140 return -ENOIOCTLCMD;
5141 default:
5142 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5143 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5144 return -EINVAL;
b053bb86
MH
5145 }
5146
0b2cf5c8
DY
5147 case DIGI_GETA:
5148 /* get information for ditty */
5149 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5150 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5151 return dgap_tty_digigeta(ch, uarg);
5152
5153 case DIGI_SETAW:
5154 case DIGI_SETAF:
5155
5156 /* set information for ditty */
5157 if (cmd == (DIGI_SETAW)) {
5158
5159 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5160 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5161 rc = dgap_wait_for_drain(tty);
5162 if (rc)
5163 return -EINTR;
5164 spin_lock_irqsave(&bd->bd_lock, lock_flags);
5165 spin_lock_irqsave(&ch->ch_lock, lock_flags2);
5166 } else
5167 tty_ldisc_flush(tty);
5168 /* fall thru */
5169
5170 case DIGI_SETA:
5171 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5172 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5173 return dgap_tty_digiseta(ch, bd, un, uarg);
5174
5175 case DIGI_GEDELAY:
5176 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5177 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5178 return dgap_tty_digigetedelay(tty, uarg);
5179
5180 case DIGI_SEDELAY:
5181 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5182 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5183 return dgap_tty_digisetedelay(ch, bd, un, uarg);
b053bb86 5184
0b2cf5c8
DY
5185 case DIGI_GETCUSTOMBAUD:
5186 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5187 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5188 return dgap_tty_digigetcustombaud(ch, un, uarg);
b053bb86 5189
0b2cf5c8
DY
5190 case DIGI_SETCUSTOMBAUD:
5191 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5192 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5193 return dgap_tty_digisetcustombaud(ch, bd, un, uarg);
b053bb86 5194
0b2cf5c8
DY
5195 case DIGI_RESET_PORT:
5196 dgap_firmware_reset_port(ch);
5197 dgap_param(ch, bd, un->un_type);
5198 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5199 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
5200 return 0;
b053bb86 5201
0b2cf5c8
DY
5202 default:
5203 spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
5204 spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
b053bb86 5205
0b2cf5c8
DY
5206 return -ENOIOCTLCMD;
5207 }
5208}
b053bb86 5209
0b2cf5c8
DY
5210static const struct tty_operations dgap_tty_ops = {
5211 .open = dgap_tty_open,
5212 .close = dgap_tty_close,
5213 .write = dgap_tty_write,
5214 .write_room = dgap_tty_write_room,
5215 .flush_buffer = dgap_tty_flush_buffer,
5216 .chars_in_buffer = dgap_tty_chars_in_buffer,
5217 .flush_chars = dgap_tty_flush_chars,
5218 .ioctl = dgap_tty_ioctl,
5219 .set_termios = dgap_tty_set_termios,
5220 .stop = dgap_tty_stop,
5221 .start = dgap_tty_start,
5222 .throttle = dgap_tty_throttle,
5223 .unthrottle = dgap_tty_unthrottle,
5224 .hangup = dgap_tty_hangup,
5225 .put_char = dgap_tty_put_char,
5226 .tiocmget = dgap_tty_tiocmget,
5227 .tiocmset = dgap_tty_tiocmset,
5228 .break_ctl = dgap_tty_send_break,
5229 .wait_until_sent = dgap_tty_wait_until_sent,
5230 .send_xchar = dgap_tty_send_xchar
5231};
b053bb86 5232
0b2cf5c8
DY
5233/************************************************************************
5234 *
5235 * TTY Initialization/Cleanup Functions
5236 *
5237 ************************************************************************/
b053bb86 5238
0b2cf5c8
DY
5239/*
5240 * dgap_tty_register()
5241 *
5242 * Init the tty subsystem for this board.
5243 */
5244static int dgap_tty_register(struct board_t *brd)
5245{
5246 int rc;
b053bb86 5247
dc3cfcd3
DY
5248 brd->serial_driver = tty_alloc_driver(MAXPORTS,
5249 TTY_DRIVER_REAL_RAW |
5250 TTY_DRIVER_DYNAMIC_DEV |
5251 TTY_DRIVER_HARDWARE_BREAK);
0b2cf5c8
DY
5252 if (IS_ERR(brd->serial_driver))
5253 return PTR_ERR(brd->serial_driver);
b053bb86 5254
0b2cf5c8
DY
5255 snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgap_%d_",
5256 brd->boardnum);
5257 brd->serial_driver->name = brd->serial_name;
5258 brd->serial_driver->name_base = 0;
5259 brd->serial_driver->major = 0;
5260 brd->serial_driver->minor_start = 0;
5261 brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
5262 brd->serial_driver->subtype = SERIAL_TYPE_NORMAL;
5263 brd->serial_driver->init_termios = dgap_default_termios;
5264 brd->serial_driver->driver_name = DRVSTR;
b053bb86 5265
0b2cf5c8
DY
5266 /*
5267 * Entry points for driver. Called by the kernel from
5268 * tty_io.c and n_tty.c.
5269 */
5270 tty_set_operations(brd->serial_driver, &dgap_tty_ops);
b053bb86 5271
0b2cf5c8
DY
5272 /*
5273 * If we're doing transparent print, we have to do all of the above
5274 * again, separately so we don't get the LD confused about what major
5275 * we are when we get into the dgap_tty_open() routine.
5276 */
dc3cfcd3
DY
5277 brd->print_driver = tty_alloc_driver(MAXPORTS,
5278 TTY_DRIVER_REAL_RAW |
5279 TTY_DRIVER_DYNAMIC_DEV |
5280 TTY_DRIVER_HARDWARE_BREAK);
0b2cf5c8
DY
5281 if (IS_ERR(brd->print_driver)) {
5282 rc = PTR_ERR(brd->print_driver);
5283 goto free_serial_drv;
b053bb86
MH
5284 }
5285
0b2cf5c8
DY
5286 snprintf(brd->print_name, MAXTTYNAMELEN, "pr_dgap_%d_",
5287 brd->boardnum);
5288 brd->print_driver->name = brd->print_name;
5289 brd->print_driver->name_base = 0;
5290 brd->print_driver->major = 0;
5291 brd->print_driver->minor_start = 0;
5292 brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL;
5293 brd->print_driver->subtype = SERIAL_TYPE_NORMAL;
5294 brd->print_driver->init_termios = dgap_default_termios;
5295 brd->print_driver->driver_name = DRVSTR;
b053bb86 5296
0b2cf5c8
DY
5297 /*
5298 * Entry points for driver. Called by the kernel from
5299 * tty_io.c and n_tty.c.
5300 */
5301 tty_set_operations(brd->print_driver, &dgap_tty_ops);
7568f7d3 5302
0b2cf5c8
DY
5303 /* Register tty devices */
5304 rc = tty_register_driver(brd->serial_driver);
5305 if (rc < 0)
5306 goto free_print_drv;
7568f7d3 5307
0b2cf5c8
DY
5308 /* Register Transparent Print devices */
5309 rc = tty_register_driver(brd->print_driver);
5310 if (rc < 0)
5311 goto unregister_serial_drv;
7568f7d3 5312
0b2cf5c8 5313 return 0;
7568f7d3 5314
0b2cf5c8
DY
5315unregister_serial_drv:
5316 tty_unregister_driver(brd->serial_driver);
5317free_print_drv:
5318 put_tty_driver(brd->print_driver);
5319free_serial_drv:
5320 put_tty_driver(brd->serial_driver);
7568f7d3 5321
0b2cf5c8 5322 return rc;
7568f7d3
MH
5323}
5324
0b2cf5c8 5325static void dgap_tty_unregister(struct board_t *brd)
7568f7d3 5326{
0b2cf5c8
DY
5327 tty_unregister_driver(brd->print_driver);
5328 tty_unregister_driver(brd->serial_driver);
5329 put_tty_driver(brd->print_driver);
5330 put_tty_driver(brd->serial_driver);
7568f7d3 5331}
7568f7d3 5332
0b2cf5c8
DY
5333static int dgap_alloc_flipbuf(struct board_t *brd)
5334{
5335 /*
5336 * allocate flip buffer for board.
5337 */
5338 brd->flipbuf = kmalloc(MYFLIPLEN, GFP_KERNEL);
5339 if (!brd->flipbuf)
5340 return -ENOMEM;
7568f7d3 5341
0b2cf5c8
DY
5342 brd->flipflagbuf = kmalloc(MYFLIPLEN, GFP_KERNEL);
5343 if (!brd->flipflagbuf) {
5344 kfree(brd->flipbuf);
5345 return -ENOMEM;
5346 }
434b679b 5347
0b2cf5c8 5348 return 0;
7568f7d3
MH
5349}
5350
0b2cf5c8 5351static void dgap_free_flipbuf(struct board_t *brd)
7568f7d3 5352{
0b2cf5c8
DY
5353 kfree(brd->flipbuf);
5354 kfree(brd->flipflagbuf);
7568f7d3
MH
5355}
5356
3eb14151
MH
5357static struct board_t *dgap_verify_board(struct device *p)
5358{
5359 struct board_t *bd;
5360
5361 if (!p)
5362 return NULL;
5363
5364 bd = dev_get_drvdata(p);
5365 if (!bd || bd->magic != DGAP_BOARD_MAGIC || bd->state != BOARD_READY)
5366 return NULL;
5367
5368 return bd;
5369}
7568f7d3 5370
84e88287
MH
5371static ssize_t dgap_ports_state_show(struct device *p,
5372 struct device_attribute *attr,
5373 char *buf)
7568f7d3
MH
5374{
5375 struct board_t *bd;
5376 int count = 0;
ac2f46c3 5377 unsigned int i;
7568f7d3 5378
3eb14151
MH
5379 bd = dgap_verify_board(p);
5380 if (!bd)
5381 return 0;
7568f7d3
MH
5382
5383 for (i = 0; i < bd->nasync; i++) {
5384 count += snprintf(buf + count, PAGE_SIZE - count,
5385 "%d %s\n", bd->channels[i]->ch_portnum,
5386 bd->channels[i]->ch_open_count ? "Open" : "Closed");
5387 }
5388 return count;
5389}
5390static DEVICE_ATTR(ports_state, S_IRUSR, dgap_ports_state_show, NULL);
5391
84e88287
MH
5392static ssize_t dgap_ports_baud_show(struct device *p,
5393 struct device_attribute *attr,
5394 char *buf)
7568f7d3
MH
5395{
5396 struct board_t *bd;
5397 int count = 0;
ac2f46c3 5398 unsigned int i;
7568f7d3 5399
3eb14151
MH
5400 bd = dgap_verify_board(p);
5401 if (!bd)
5402 return 0;
7568f7d3
MH
5403
5404 for (i = 0; i < bd->nasync; i++) {
84e88287
MH
5405 count += snprintf(buf + count, PAGE_SIZE - count, "%d %d\n",
5406 bd->channels[i]->ch_portnum,
5407 bd->channels[i]->ch_baud_info);
7568f7d3
MH
5408 }
5409 return count;
5410}
5411static DEVICE_ATTR(ports_baud, S_IRUSR, dgap_ports_baud_show, NULL);
5412
84e88287
MH
5413static ssize_t dgap_ports_msignals_show(struct device *p,
5414 struct device_attribute *attr,
5415 char *buf)
7568f7d3
MH
5416{
5417 struct board_t *bd;
5418 int count = 0;
ac2f46c3 5419 unsigned int i;
7568f7d3 5420
3eb14151
MH
5421 bd = dgap_verify_board(p);
5422 if (!bd)
5423 return 0;
7568f7d3
MH
5424
5425 for (i = 0; i < bd->nasync; i++) {
305ec874 5426 if (bd->channels[i]->ch_open_count)
7568f7d3 5427 count += snprintf(buf + count, PAGE_SIZE - count,
84e88287
MH
5428 "%d %s %s %s %s %s %s\n",
5429 bd->channels[i]->ch_portnum,
5430 (bd->channels[i]->ch_mostat &
5431 UART_MCR_RTS) ? "RTS" : "",
5432 (bd->channels[i]->ch_mistat &
5433 UART_MSR_CTS) ? "CTS" : "",
5434 (bd->channels[i]->ch_mostat &
5435 UART_MCR_DTR) ? "DTR" : "",
5436 (bd->channels[i]->ch_mistat &
5437 UART_MSR_DSR) ? "DSR" : "",
5438 (bd->channels[i]->ch_mistat &
5439 UART_MSR_DCD) ? "DCD" : "",
5440 (bd->channels[i]->ch_mistat &
5441 UART_MSR_RI) ? "RI" : "");
305ec874 5442 else
7568f7d3
MH
5443 count += snprintf(buf + count, PAGE_SIZE - count,
5444 "%d\n", bd->channels[i]->ch_portnum);
7568f7d3
MH
5445 }
5446 return count;
5447}
5448static DEVICE_ATTR(ports_msignals, S_IRUSR, dgap_ports_msignals_show, NULL);
5449
84e88287
MH
5450static ssize_t dgap_ports_iflag_show(struct device *p,
5451 struct device_attribute *attr,
5452 char *buf)
7568f7d3
MH
5453{
5454 struct board_t *bd;
5455 int count = 0;
ac2f46c3 5456 unsigned int i;
7568f7d3 5457
3eb14151
MH
5458 bd = dgap_verify_board(p);
5459 if (!bd)
5460 return 0;
7568f7d3 5461
305ec874 5462 for (i = 0; i < bd->nasync; i++)
7568f7d3 5463 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
84e88287
MH
5464 bd->channels[i]->ch_portnum,
5465 bd->channels[i]->ch_c_iflag);
7568f7d3
MH
5466 return count;
5467}
5468static DEVICE_ATTR(ports_iflag, S_IRUSR, dgap_ports_iflag_show, NULL);
5469
84e88287
MH
5470static ssize_t dgap_ports_cflag_show(struct device *p,
5471 struct device_attribute *attr,
5472 char *buf)
7568f7d3
MH
5473{
5474 struct board_t *bd;
5475 int count = 0;
ac2f46c3 5476 unsigned int i;
7568f7d3 5477
3eb14151
MH
5478 bd = dgap_verify_board(p);
5479 if (!bd)
5480 return 0;
7568f7d3 5481
305ec874 5482 for (i = 0; i < bd->nasync; i++)
7568f7d3 5483 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
84e88287
MH
5484 bd->channels[i]->ch_portnum,
5485 bd->channels[i]->ch_c_cflag);
7568f7d3
MH
5486 return count;
5487}
5488static DEVICE_ATTR(ports_cflag, S_IRUSR, dgap_ports_cflag_show, NULL);
5489
84e88287
MH
5490static ssize_t dgap_ports_oflag_show(struct device *p,
5491 struct device_attribute *attr,
5492 char *buf)
7568f7d3
MH
5493{
5494 struct board_t *bd;
5495 int count = 0;
ac2f46c3 5496 unsigned int i;
7568f7d3 5497
3eb14151
MH
5498 bd = dgap_verify_board(p);
5499 if (!bd)
5500 return 0;
7568f7d3 5501
305ec874 5502 for (i = 0; i < bd->nasync; i++)
7568f7d3 5503 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
84e88287
MH
5504 bd->channels[i]->ch_portnum,
5505 bd->channels[i]->ch_c_oflag);
7568f7d3
MH
5506 return count;
5507}
5508static DEVICE_ATTR(ports_oflag, S_IRUSR, dgap_ports_oflag_show, NULL);
5509
84e88287
MH
5510static ssize_t dgap_ports_lflag_show(struct device *p,
5511 struct device_attribute *attr,
5512 char *buf)
7568f7d3
MH
5513{
5514 struct board_t *bd;
5515 int count = 0;
ac2f46c3 5516 unsigned int i;
7568f7d3 5517
3eb14151
MH
5518 bd = dgap_verify_board(p);
5519 if (!bd)
5520 return 0;
7568f7d3 5521
305ec874 5522 for (i = 0; i < bd->nasync; i++)
7568f7d3 5523 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
84e88287
MH
5524 bd->channels[i]->ch_portnum,
5525 bd->channels[i]->ch_c_lflag);
7568f7d3
MH
5526 return count;
5527}
5528static DEVICE_ATTR(ports_lflag, S_IRUSR, dgap_ports_lflag_show, NULL);
5529
84e88287
MH
5530static ssize_t dgap_ports_digi_flag_show(struct device *p,
5531 struct device_attribute *attr,
5532 char *buf)
7568f7d3
MH
5533{
5534 struct board_t *bd;
5535 int count = 0;
ac2f46c3 5536 unsigned int i;
7568f7d3 5537
3eb14151
MH
5538 bd = dgap_verify_board(p);
5539 if (!bd)
5540 return 0;
7568f7d3 5541
305ec874 5542 for (i = 0; i < bd->nasync; i++)
7568f7d3 5543 count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n",
84e88287
MH
5544 bd->channels[i]->ch_portnum,
5545 bd->channels[i]->ch_digi.digi_flags);
7568f7d3
MH
5546 return count;
5547}
5548static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgap_ports_digi_flag_show, NULL);
5549
84e88287
MH
5550static ssize_t dgap_ports_rxcount_show(struct device *p,
5551 struct device_attribute *attr,
5552 char *buf)
7568f7d3
MH
5553{
5554 struct board_t *bd;
5555 int count = 0;
ac2f46c3 5556 unsigned int i;
7568f7d3 5557
3eb14151
MH
5558 bd = dgap_verify_board(p);
5559 if (!bd)
5560 return 0;
7568f7d3 5561
305ec874 5562 for (i = 0; i < bd->nasync; i++)
7568f7d3 5563 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
84e88287
MH
5564 bd->channels[i]->ch_portnum,
5565 bd->channels[i]->ch_rxcount);
7568f7d3
MH
5566 return count;
5567}
5568static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgap_ports_rxcount_show, NULL);
5569
84e88287
MH
5570static ssize_t dgap_ports_txcount_show(struct device *p,
5571 struct device_attribute *attr,
5572 char *buf)
7568f7d3
MH
5573{
5574 struct board_t *bd;
5575 int count = 0;
ac2f46c3 5576 unsigned int i;
7568f7d3 5577
3eb14151
MH
5578 bd = dgap_verify_board(p);
5579 if (!bd)
5580 return 0;
7568f7d3 5581
305ec874 5582 for (i = 0; i < bd->nasync; i++)
7568f7d3 5583 count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n",
84e88287
MH
5584 bd->channels[i]->ch_portnum,
5585 bd->channels[i]->ch_txcount);
7568f7d3
MH
5586 return count;
5587}
5588static DEVICE_ATTR(ports_txcount, S_IRUSR, dgap_ports_txcount_show, NULL);
5589
0b2cf5c8
DY
5590static ssize_t dgap_tty_state_show(struct device *d,
5591 struct device_attribute *attr,
5592 char *buf)
7568f7d3 5593{
0b2cf5c8
DY
5594 struct board_t *bd;
5595 struct channel_t *ch;
5596 struct un_t *un;
5597
5598 if (!d)
5599 return 0;
5600 un = dev_get_drvdata(d);
5601 if (!un || un->magic != DGAP_UNIT_MAGIC)
5602 return 0;
5603 ch = un->un_ch;
5604 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
5605 return 0;
5606 bd = ch->ch_bd;
5607 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
5608 return 0;
5609 if (bd->state != BOARD_READY)
5610 return 0;
5611
5612 return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ?
5613 "Open" : "Closed");
5614}
5615static DEVICE_ATTR(state, S_IRUSR, dgap_tty_state_show, NULL);
5616
5617static ssize_t dgap_tty_baud_show(struct device *d,
5618 struct device_attribute *attr,
5619 char *buf)
5620{
5621 struct board_t *bd;
5622 struct channel_t *ch;
5623 struct un_t *un;
5624
5625 if (!d)
5626 return 0;
5627 un = dev_get_drvdata(d);
5628 if (!un || un->magic != DGAP_UNIT_MAGIC)
5629 return 0;
5630 ch = un->un_ch;
5631 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
5632 return 0;
5633 bd = ch->ch_bd;
5634 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
5635 return 0;
5636 if (bd->state != BOARD_READY)
5637 return 0;
5638
5639 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_baud_info);
5640}
5641static DEVICE_ATTR(baud, S_IRUSR, dgap_tty_baud_show, NULL);
5642
5643static ssize_t dgap_tty_msignals_show(struct device *d,
5644 struct device_attribute *attr,
5645 char *buf)
5646{
5647 struct board_t *bd;
5648 struct channel_t *ch;
5649 struct un_t *un;
5650
5651 if (!d)
5652 return 0;
5653 un = dev_get_drvdata(d);
5654 if (!un || un->magic != DGAP_UNIT_MAGIC)
5655 return 0;
5656 ch = un->un_ch;
5657 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
5658 return 0;
5659 bd = ch->ch_bd;
5660 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
5661 return 0;
5662 if (bd->state != BOARD_READY)
5663 return 0;
5664
5665 if (ch->ch_open_count) {
5666 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
5667 (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "",
5668 (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "",
5669 (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "",
5670 (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "",
5671 (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "",
5672 (ch->ch_mistat & UART_MSR_RI) ? "RI" : "");
5673 }
5674 return 0;
5675}
5676static DEVICE_ATTR(msignals, S_IRUSR, dgap_tty_msignals_show, NULL);
5677
5678static ssize_t dgap_tty_iflag_show(struct device *d,
5679 struct device_attribute *attr,
5680 char *buf)
5681{
5682 struct board_t *bd;
5683 struct channel_t *ch;
5684 struct un_t *un;
5685
5686 if (!d)
5687 return 0;
5688 un = dev_get_drvdata(d);
5689 if (!un || un->magic != DGAP_UNIT_MAGIC)
5690 return 0;
5691 ch = un->un_ch;
5692 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
5693 return 0;
5694 bd = ch->ch_bd;
5695 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
5696 return 0;
5697 if (bd->state != BOARD_READY)
5698 return 0;
5699
5700 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
5701}
5702static DEVICE_ATTR(iflag, S_IRUSR, dgap_tty_iflag_show, NULL);
5703
5704static ssize_t dgap_tty_cflag_show(struct device *d,
5705 struct device_attribute *attr,
5706 char *buf)
5707{
5708 struct board_t *bd;
5709 struct channel_t *ch;
5710 struct un_t *un;
5711
5712 if (!d)
5713 return 0;
5714 un = dev_get_drvdata(d);
5715 if (!un || un->magic != DGAP_UNIT_MAGIC)
5716 return 0;
5717 ch = un->un_ch;
5718 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
5719 return 0;
5720 bd = ch->ch_bd;
5721 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
5722 return 0;
5723 if (bd->state != BOARD_READY)
5724 return 0;
5725
5726 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
5727}
5728static DEVICE_ATTR(cflag, S_IRUSR, dgap_tty_cflag_show, NULL);
5729
5730static ssize_t dgap_tty_oflag_show(struct device *d,
5731 struct device_attribute *attr,
5732 char *buf)
5733{
5734 struct board_t *bd;
5735 struct channel_t *ch;
5736 struct un_t *un;
5737
5738 if (!d)
5739 return 0;
5740 un = dev_get_drvdata(d);
5741 if (!un || un->magic != DGAP_UNIT_MAGIC)
5742 return 0;
5743 ch = un->un_ch;
5744 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
5745 return 0;
5746 bd = ch->ch_bd;
5747 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
5748 return 0;
5749 if (bd->state != BOARD_READY)
5750 return 0;
5751
5752 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
5753}
5754static DEVICE_ATTR(oflag, S_IRUSR, dgap_tty_oflag_show, NULL);
5755
5756static ssize_t dgap_tty_lflag_show(struct device *d,
5757 struct device_attribute *attr,
5758 char *buf)
5759{
5760 struct board_t *bd;
5761 struct channel_t *ch;
5762 struct un_t *un;
5763
5764 if (!d)
5765 return 0;
5766 un = dev_get_drvdata(d);
5767 if (!un || un->magic != DGAP_UNIT_MAGIC)
5768 return 0;
5769 ch = un->un_ch;
5770 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
5771 return 0;
5772 bd = ch->ch_bd;
5773 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
5774 return 0;
5775 if (bd->state != BOARD_READY)
5776 return 0;
5777
5778 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
7568f7d3 5779}
0b2cf5c8
DY
5780static DEVICE_ATTR(lflag, S_IRUSR, dgap_tty_lflag_show, NULL);
5781
5782static ssize_t dgap_tty_digi_flag_show(struct device *d,
5783 struct device_attribute *attr,
5784 char *buf)
5785{
5786 struct board_t *bd;
5787 struct channel_t *ch;
5788 struct un_t *un;
5789
5790 if (!d)
5791 return 0;
5792 un = dev_get_drvdata(d);
5793 if (!un || un->magic != DGAP_UNIT_MAGIC)
5794 return 0;
5795 ch = un->un_ch;
5796 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
5797 return 0;
5798 bd = ch->ch_bd;
5799 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
5800 return 0;
5801 if (bd->state != BOARD_READY)
5802 return 0;
7568f7d3 5803
0b2cf5c8 5804 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
7568f7d3 5805}
0b2cf5c8 5806static DEVICE_ATTR(digi_flag, S_IRUSR, dgap_tty_digi_flag_show, NULL);
7568f7d3 5807
0b2cf5c8
DY
5808static ssize_t dgap_tty_rxcount_show(struct device *d,
5809 struct device_attribute *attr,
5810 char *buf)
7568f7d3
MH
5811{
5812 struct board_t *bd;
5813 struct channel_t *ch;
5814 struct un_t *un;
5815
5816 if (!d)
cf42c34d 5817 return 0;
7568f7d3
MH
5818 un = dev_get_drvdata(d);
5819 if (!un || un->magic != DGAP_UNIT_MAGIC)
cf42c34d 5820 return 0;
7568f7d3
MH
5821 ch = un->un_ch;
5822 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
cf42c34d 5823 return 0;
7568f7d3
MH
5824 bd = ch->ch_bd;
5825 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
cf42c34d 5826 return 0;
7568f7d3 5827 if (bd->state != BOARD_READY)
cf42c34d 5828 return 0;
7568f7d3 5829
0b2cf5c8 5830 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
7568f7d3 5831}
0b2cf5c8 5832static DEVICE_ATTR(rxcount, S_IRUSR, dgap_tty_rxcount_show, NULL);
7568f7d3 5833
0b2cf5c8
DY
5834static ssize_t dgap_tty_txcount_show(struct device *d,
5835 struct device_attribute *attr,
5836 char *buf)
7568f7d3
MH
5837{
5838 struct board_t *bd;
5839 struct channel_t *ch;
5840 struct un_t *un;
5841
5842 if (!d)
cf42c34d 5843 return 0;
7568f7d3
MH
5844 un = dev_get_drvdata(d);
5845 if (!un || un->magic != DGAP_UNIT_MAGIC)
cf42c34d 5846 return 0;
7568f7d3
MH
5847 ch = un->un_ch;
5848 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
cf42c34d 5849 return 0;
7568f7d3
MH
5850 bd = ch->ch_bd;
5851 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
cf42c34d 5852 return 0;
7568f7d3 5853 if (bd->state != BOARD_READY)
cf42c34d 5854 return 0;
7568f7d3 5855
0b2cf5c8 5856 return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
7568f7d3 5857}
0b2cf5c8 5858static DEVICE_ATTR(txcount, S_IRUSR, dgap_tty_txcount_show, NULL);
7568f7d3 5859
0b2cf5c8
DY
5860static ssize_t dgap_tty_name_show(struct device *d,
5861 struct device_attribute *attr,
5862 char *buf)
7568f7d3
MH
5863{
5864 struct board_t *bd;
5865 struct channel_t *ch;
5866 struct un_t *un;
0b2cf5c8
DY
5867 int cn;
5868 int bn;
5869 struct cnode *cptr;
5870 int found = FALSE;
5871 int ncount = 0;
5872 int starto = 0;
5873 int i;
7568f7d3
MH
5874
5875 if (!d)
cf42c34d 5876 return 0;
7568f7d3
MH
5877 un = dev_get_drvdata(d);
5878 if (!un || un->magic != DGAP_UNIT_MAGIC)
cf42c34d 5879 return 0;
7568f7d3
MH
5880 ch = un->un_ch;
5881 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
cf42c34d 5882 return 0;
7568f7d3
MH
5883 bd = ch->ch_bd;
5884 if (!bd || bd->magic != DGAP_BOARD_MAGIC)
cf42c34d 5885 return 0;
7568f7d3 5886 if (bd->state != BOARD_READY)
cf42c34d 5887 return 0;
7568f7d3 5888
0b2cf5c8
DY
5889 bn = bd->boardnum;
5890 cn = ch->ch_portnum;
5891
5892 for (cptr = bd->bd_config; cptr; cptr = cptr->next) {
5893
5894 if ((cptr->type == BNODE) &&
5895 ((cptr->u.board.type == APORT2_920P) ||
5896 (cptr->u.board.type == APORT4_920P) ||
5897 (cptr->u.board.type == APORT8_920P) ||
5898 (cptr->u.board.type == PAPORT4) ||
5899 (cptr->u.board.type == PAPORT8))) {
5900
5901 found = TRUE;
5902 if (cptr->u.board.v_start)
5903 starto = cptr->u.board.start;
5904 else
5905 starto = 1;
5906 }
5907
5908 if (cptr->type == TNODE && found == TRUE) {
5909 char *ptr1;
5910
5911 if (strstr(cptr->u.ttyname, "tty")) {
5912 ptr1 = cptr->u.ttyname;
5913 ptr1 += 3;
5914 } else
5915 ptr1 = cptr->u.ttyname;
5916
5917 for (i = 0; i < dgap_config_get_num_prts(bd); i++) {
5918 if (cn != i)
5919 continue;
5920
5921 return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
5922 (un->un_type == DGAP_PRINT) ?
5923 "pr" : "tty",
5924 ptr1, i + starto);
5925 }
5926 }
5927
5928 if (cptr->type == CNODE) {
5929
5930 for (i = 0; i < cptr->u.conc.nport; i++) {
5931 if (cn != (i + ncount))
5932 continue;
5933
5934 return snprintf(buf, PAGE_SIZE, "%s%s%02ld\n",
5935 (un->un_type == DGAP_PRINT) ?
5936 "pr" : "tty",
5937 cptr->u.conc.id,
5938 i + (cptr->u.conc.v_start ?
5939 cptr->u.conc.start : 1));
5940 }
5941
5942 ncount += cptr->u.conc.nport;
5943 }
5944
5945 if (cptr->type == MNODE) {
5946
5947 for (i = 0; i < cptr->u.module.nport; i++) {
5948 if (cn != (i + ncount))
5949 continue;
5950
5951 return snprintf(buf, PAGE_SIZE, "%s%s%02ld\n",
5952 (un->un_type == DGAP_PRINT) ?
5953 "pr" : "tty",
5954 cptr->u.module.id,
5955 i + (cptr->u.module.v_start ?
5956 cptr->u.module.start : 1));
5957 }
5958
5959 ncount += cptr->u.module.nport;
5960 }
7568f7d3 5961 }
0b2cf5c8
DY
5962
5963 return snprintf(buf, PAGE_SIZE, "%s_dgap_%d_%d\n",
5964 (un->un_type == DGAP_PRINT) ? "pr" : "tty", bn, cn);
5965}
5966static DEVICE_ATTR(custom_name, S_IRUSR, dgap_tty_name_show, NULL);
5967
5968static struct attribute *dgap_sysfs_tty_entries[] = {
5969 &dev_attr_state.attr,
5970 &dev_attr_baud.attr,
5971 &dev_attr_msignals.attr,
5972 &dev_attr_iflag.attr,
5973 &dev_attr_cflag.attr,
5974 &dev_attr_oflag.attr,
5975 &dev_attr_lflag.attr,
5976 &dev_attr_digi_flag.attr,
5977 &dev_attr_rxcount.attr,
5978 &dev_attr_txcount.attr,
5979 &dev_attr_custom_name.attr,
5980 NULL
5981};
5982
5983
5984/* this function creates the sys files that will export each signal status
5985 * to sysfs each value will be put in a separate filename
5986 */
5987static void dgap_create_ports_sysfiles(struct board_t *bd)
5988{
5989 dev_set_drvdata(&bd->pdev->dev, bd);
5990 device_create_file(&(bd->pdev->dev), &dev_attr_ports_state);
5991 device_create_file(&(bd->pdev->dev), &dev_attr_ports_baud);
5992 device_create_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
5993 device_create_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
5994 device_create_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
5995 device_create_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
5996 device_create_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
5997 device_create_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
5998 device_create_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
5999 device_create_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
6000}
6001
6002/* removes all the sys files created for that port */
6003static void dgap_remove_ports_sysfiles(struct board_t *bd)
6004{
6005 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state);
6006 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud);
6007 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_msignals);
6008 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_iflag);
6009 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_cflag);
6010 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_oflag);
6011 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_lflag);
6012 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_digi_flag);
6013 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_rxcount);
6014 device_remove_file(&(bd->pdev->dev), &dev_attr_ports_txcount);
6015}
6016
6017/*
6018 * Copies the BIOS code from the user to the board,
6019 * and starts the BIOS running.
6020 */
6021static void dgap_do_bios_load(struct board_t *brd, const u8 *ubios, int len)
6022{
6023 u8 __iomem *addr;
6024 uint offset;
6025 unsigned int i;
6026
6027 if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
6028 return;
6029
6030 addr = brd->re_map_membase;
6031
6032 /*
6033 * clear POST area
6034 */
6035 for (i = 0; i < 16; i++)
6036 writeb(0, addr + POSTAREA + i);
6037
6038 /*
6039 * Download bios
6040 */
6041 offset = 0x1000;
6042 memcpy_toio(addr + offset, ubios, len);
6043
6044 writel(0x0bf00401, addr);
6045 writel(0, (addr + 4));
6046
6047 /* Clear the reset, and change states. */
6048 writeb(FEPCLR, brd->re_map_port);
6049}
6050
6051/*
6052 * Checks to see if the BIOS completed running on the card.
6053 */
6054static int dgap_test_bios(struct board_t *brd)
6055{
6056 u8 __iomem *addr;
6057 u16 word;
6058 u16 err1;
6059 u16 err2;
6060
6061 if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
6062 return -EINVAL;
6063
6064 addr = brd->re_map_membase;
6065 word = readw(addr + POSTAREA);
6066
6067 /*
6068 * It can take 5-6 seconds for a board to
6069 * pass the bios self test and post results.
6070 * Give it 10 seconds.
6071 */
6072 brd->wait_for_bios = 0;
6073 while (brd->wait_for_bios < 1000) {
6074 /* Check to see if BIOS thinks board is good. (GD). */
6075 if (word == *(u16 *) "GD")
6076 return 0;
6077 msleep_interruptible(10);
6078 brd->wait_for_bios++;
6079 word = readw(addr + POSTAREA);
6080 }
6081
6082 /* Gave up on board after too long of time taken */
6083 err1 = readw(addr + SEQUENCE);
6084 err2 = readw(addr + ERROR);
6085 dev_warn(&brd->pdev->dev, "%s failed diagnostics. Error #(%x,%x).\n",
6086 brd->name, err1, err2);
6087 brd->state = BOARD_FAILED;
6088 brd->dpastatus = BD_NOBIOS;
6089
6090 return -EIO;
7568f7d3 6091}
7568f7d3 6092
0b2cf5c8
DY
6093/*
6094 * Copies the FEP code from the user to the board,
6095 * and starts the FEP running.
6096 */
6097static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len)
7568f7d3 6098{
0b2cf5c8
DY
6099 u8 __iomem *addr;
6100 uint offset;
7568f7d3 6101
0b2cf5c8
DY
6102 if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
6103 return;
7568f7d3 6104
0b2cf5c8 6105 addr = brd->re_map_membase;
7568f7d3 6106
0b2cf5c8
DY
6107 /*
6108 * Download FEP
6109 */
6110 offset = 0x1000;
6111 memcpy_toio(addr + offset, ufep, len);
7568f7d3 6112
0b2cf5c8
DY
6113 /*
6114 * If board is a concentrator product, we need to give
6115 * it its config string describing how the concentrators look.
6116 */
6117 if ((brd->type == PCX) || (brd->type == PEPC)) {
6118 u8 string[100];
6119 u8 __iomem *config;
6120 u8 *xconfig;
6121 unsigned int i = 0;
7568f7d3 6122
0b2cf5c8 6123 xconfig = dgap_create_config_string(brd, string);
7568f7d3 6124
0b2cf5c8
DY
6125 /* Write string to board memory */
6126 config = addr + CONFIG;
6127 for (; i < CONFIGSIZE; i++, config++, xconfig++) {
6128 writeb(*xconfig, config);
6129 if ((*xconfig & 0xff) == 0xff)
6130 break;
6131 }
6132 }
7568f7d3 6133
0b2cf5c8
DY
6134 writel(0xbfc01004, (addr + 0xc34));
6135 writel(0x3, (addr + 0xc30));
7568f7d3 6136
7568f7d3 6137}
7568f7d3 6138
0b2cf5c8
DY
6139/*
6140 * Waits for the FEP to report thats its ready for us to use.
6141 */
6142static int dgap_test_fep(struct board_t *brd)
7568f7d3 6143{
0b2cf5c8
DY
6144 u8 __iomem *addr;
6145 u16 word;
6146 u16 err1;
6147 u16 err2;
7568f7d3 6148
0b2cf5c8
DY
6149 if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
6150 return -EINVAL;
7568f7d3 6151
0b2cf5c8
DY
6152 addr = brd->re_map_membase;
6153 word = readw(addr + FEPSTAT);
7568f7d3 6154
0b2cf5c8
DY
6155 /*
6156 * It can take 2-3 seconds for the FEP to
6157 * be up and running. Give it 5 secs.
6158 */
6159 brd->wait_for_fep = 0;
6160 while (brd->wait_for_fep < 500) {
6161 /* Check to see if FEP is up and running now. */
6162 if (word == *(u16 *) "OS") {
6163 /*
6164 * Check to see if the board can support FEP5+ commands.
6165 */
6166 word = readw(addr + FEP5_PLUS);
6167 if (word == *(u16 *) "5A")
6168 brd->bd_flags |= BD_FEP5PLUS;
7568f7d3 6169
0b2cf5c8
DY
6170 return 0;
6171 }
6172 msleep_interruptible(10);
6173 brd->wait_for_fep++;
6174 word = readw(addr + FEPSTAT);
6175 }
7568f7d3 6176
0b2cf5c8
DY
6177 /* Gave up on board after too long of time taken */
6178 err1 = readw(addr + SEQUENCE);
6179 err2 = readw(addr + ERROR);
6180 dev_warn(&brd->pdev->dev,
6181 "FEPOS for %s not functioning. Error #(%x,%x).\n",
6182 brd->name, err1, err2);
6183 brd->state = BOARD_FAILED;
6184 brd->dpastatus = BD_NOFEP;
6185
6186 return -EIO;
7568f7d3 6187}
7568f7d3 6188
0b2cf5c8
DY
6189/*
6190 * Physically forces the FEP5 card to reset itself.
6191 */
6192static void dgap_do_reset_board(struct board_t *brd)
7568f7d3 6193{
0b2cf5c8
DY
6194 u8 check;
6195 u32 check1;
6196 u32 check2;
6197 unsigned int i;
7568f7d3 6198
0b2cf5c8
DY
6199 if (!brd || (brd->magic != DGAP_BOARD_MAGIC) ||
6200 !brd->re_map_membase || !brd->re_map_port)
6201 return;
7568f7d3 6202
0b2cf5c8
DY
6203 /* FEPRST does not vary among supported boards */
6204 writeb(FEPRST, brd->re_map_port);
6205
6206 for (i = 0; i <= 1000; i++) {
6207 check = readb(brd->re_map_port) & 0xe;
6208 if (check == FEPRST)
6209 break;
6210 udelay(10);
6211
6212 }
6213 if (i > 1000) {
6214 dev_warn(&brd->pdev->dev,
6215 "dgap: Board not resetting... Failing board.\n");
6216 brd->state = BOARD_FAILED;
6217 brd->dpastatus = BD_NOFEP;
6218 return;
6219 }
6220
6221 /*
6222 * Make sure there really is memory out there.
6223 */
6224 writel(0xa55a3cc3, (brd->re_map_membase + LOWMEM));
6225 writel(0x5aa5c33c, (brd->re_map_membase + HIGHMEM));
6226 check1 = readl(brd->re_map_membase + LOWMEM);
6227 check2 = readl(brd->re_map_membase + HIGHMEM);
6228
6229 if ((check1 != 0xa55a3cc3) || (check2 != 0x5aa5c33c)) {
6230 dev_warn(&brd->pdev->dev,
6231 "No memory at %p for board.\n",
6232 brd->re_map_membase);
6233 brd->state = BOARD_FAILED;
6234 brd->dpastatus = BD_NOFEP;
6235 return;
6236 }
7568f7d3 6237}
7568f7d3 6238
0b2cf5c8
DY
6239#ifdef DIGI_CONCENTRATORS_SUPPORTED
6240/*
6241 * Sends a concentrator image into the FEP5 board.
6242 */
6243static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len)
7568f7d3 6244{
0b2cf5c8
DY
6245 char __iomem *vaddr;
6246 u16 offset;
6247 struct downld_t *to_dp;
7568f7d3 6248
0b2cf5c8
DY
6249 if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
6250 return;
7568f7d3 6251
0b2cf5c8
DY
6252 vaddr = brd->re_map_membase;
6253
6254 offset = readw((u16 *) (vaddr + DOWNREQ));
6255 to_dp = (struct downld_t *) (vaddr + (int) offset);
6256 memcpy_toio(to_dp, uaddr, len);
6257
6258 /* Tell card we have data for it */
6259 writew(0, vaddr + (DOWNREQ));
6260
6261 brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS;
7568f7d3 6262}
0b2cf5c8 6263#endif
7568f7d3 6264
0b2cf5c8
DY
6265#define EXPANSION_ROM_SIZE (64 * 1024)
6266#define FEP5_ROM_MAGIC (0xFEFFFFFF)
6267
6268static void dgap_get_vpd(struct board_t *brd)
7568f7d3 6269{
0b2cf5c8
DY
6270 u32 magic;
6271 u32 base_offset;
6272 u16 rom_offset;
6273 u16 vpd_offset;
6274 u16 image_length;
6275 u16 i;
6276 u8 byte1;
6277 u8 byte2;
7568f7d3 6278
0b2cf5c8
DY
6279 /*
6280 * Poke the magic number at the PCI Rom Address location.
6281 * If VPD is supported, the value read from that address
6282 * will be non-zero.
6283 */
6284 magic = FEP5_ROM_MAGIC;
6285 pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic);
6286 pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic);
7568f7d3 6287
0b2cf5c8
DY
6288 /* VPD not supported, bail */
6289 if (!magic)
6290 return;
7568f7d3 6291
0b2cf5c8
DY
6292 /*
6293 * To get to the OTPROM memory, we have to send the boards base
6294 * address or'ed with 1 into the PCI Rom Address location.
6295 */
6296 magic = brd->membase | 0x01;
6297 pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic);
6298 pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic);
7568f7d3 6299
0b2cf5c8
DY
6300 byte1 = readb(brd->re_map_membase);
6301 byte2 = readb(brd->re_map_membase + 1);
7568f7d3 6302
0b2cf5c8
DY
6303 /*
6304 * If the board correctly swapped to the OTPROM memory,
6305 * the first 2 bytes (header) should be 0x55, 0xAA
6306 */
6307 if (byte1 == 0x55 && byte2 == 0xAA) {
7568f7d3 6308
0b2cf5c8 6309 base_offset = 0;
96045db8 6310
0b2cf5c8
DY
6311 /*
6312 * We have to run through all the OTPROM memory looking
6313 * for the VPD offset.
6314 */
6315 while (base_offset <= EXPANSION_ROM_SIZE) {
7568f7d3 6316
0b2cf5c8
DY
6317 /*
6318 * Lots of magic numbers here.
6319 *
6320 * The VPD offset is located inside the ROM Data
6321 * Structure.
6322 *
6323 * We also have to remember the length of each
6324 * ROM Data Structure, so we can "hop" to the next
6325 * entry if the VPD isn't in the current
6326 * ROM Data Structure.
6327 */
6328 rom_offset = readw(brd->re_map_membase +
6329 base_offset + 0x18);
6330 image_length = readw(brd->re_map_membase +
6331 rom_offset + 0x10) * 512;
6332 vpd_offset = readw(brd->re_map_membase +
6333 rom_offset + 0x08);
bbfbe832 6334
0b2cf5c8
DY
6335 /* Found the VPD entry */
6336 if (vpd_offset)
6337 break;
6338
6339 /* We didn't find a VPD entry, go to next ROM entry. */
6340 base_offset += image_length;
6341
6342 byte1 = readb(brd->re_map_membase + base_offset);
6343 byte2 = readb(brd->re_map_membase + base_offset + 1);
6344
6345 /*
6346 * If the new ROM offset doesn't have 0x55, 0xAA
6347 * as its header, we have run out of ROM.
6348 */
6349 if (byte1 != 0x55 || byte2 != 0xAA)
6350 break;
6351 }
6352
6353 /*
6354 * If we have a VPD offset, then mark the board
6355 * as having a valid VPD, and copy VPDSIZE (512) bytes of
6356 * that VPD to the buffer we have in our board structure.
6357 */
6358 if (vpd_offset) {
6359 brd->bd_flags |= BD_HAS_VPD;
6360 for (i = 0; i < VPDSIZE; i++) {
6361 brd->vpd[i] = readb(brd->re_map_membase +
6362 vpd_offset + i);
7568f7d3
MH
6363 }
6364 }
0b2cf5c8 6365 }
7568f7d3 6366
0b2cf5c8
DY
6367 /*
6368 * We MUST poke the magic number at the PCI Rom Address location again.
6369 * This makes the card report the regular board memory back to us,
6370 * rather than the OTPROM memory.
6371 */
6372 magic = FEP5_ROM_MAGIC;
6373 pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic);
6374}
7568f7d3 6375
7568f7d3 6376
0b2cf5c8
DY
6377static ssize_t dgap_driver_version_show(struct device_driver *ddp, char *buf)
6378{
6379 return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
6380}
6381static DRIVER_ATTR(version, S_IRUSR, dgap_driver_version_show, NULL);
7568f7d3 6382
7568f7d3 6383
0b2cf5c8
DY
6384static ssize_t dgap_driver_boards_show(struct device_driver *ddp, char *buf)
6385{
6386 return snprintf(buf, PAGE_SIZE, "%d\n", dgap_numboards);
6387}
6388static DRIVER_ATTR(boards, S_IRUSR, dgap_driver_boards_show, NULL);
7568f7d3 6389
bbfbe832 6390
0b2cf5c8
DY
6391static ssize_t dgap_driver_maxboards_show(struct device_driver *ddp, char *buf)
6392{
6393 return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
6394}
6395static DRIVER_ATTR(maxboards, S_IRUSR, dgap_driver_maxboards_show, NULL);
6396
6397
6398static ssize_t dgap_driver_pollcounter_show(struct device_driver *ddp,
6399 char *buf)
6400{
6401 return snprintf(buf, PAGE_SIZE, "%ld\n", dgap_poll_counter);
6402}
6403static DRIVER_ATTR(pollcounter, S_IRUSR, dgap_driver_pollcounter_show, NULL);
6404
6405static ssize_t dgap_driver_pollrate_show(struct device_driver *ddp, char *buf)
6406{
6407 return snprintf(buf, PAGE_SIZE, "%dms\n", dgap_poll_tick);
6408}
6409
6410static ssize_t dgap_driver_pollrate_store(struct device_driver *ddp,
6411 const char *buf, size_t count)
6412{
6413 if (sscanf(buf, "%d\n", &dgap_poll_tick) != 1)
6414 return -EINVAL;
6415 return count;
6416}
6417static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgap_driver_pollrate_show,
6418 dgap_driver_pollrate_store);
7568f7d3 6419
7568f7d3 6420
0b2cf5c8
DY
6421static int dgap_create_driver_sysfiles(struct pci_driver *dgap_driver)
6422{
6423 int rc = 0;
6424 struct device_driver *driverfs = &dgap_driver->driver;
7568f7d3 6425
0b2cf5c8
DY
6426 rc |= driver_create_file(driverfs, &driver_attr_version);
6427 rc |= driver_create_file(driverfs, &driver_attr_boards);
6428 rc |= driver_create_file(driverfs, &driver_attr_maxboards);
6429 rc |= driver_create_file(driverfs, &driver_attr_pollrate);
6430 rc |= driver_create_file(driverfs, &driver_attr_pollcounter);
6431
6432 return rc;
7568f7d3 6433}
7568f7d3 6434
0b2cf5c8
DY
6435static void dgap_remove_driver_sysfiles(struct pci_driver *dgap_driver)
6436{
6437 struct device_driver *driverfs = &dgap_driver->driver;
6438
6439 driver_remove_file(driverfs, &driver_attr_version);
6440 driver_remove_file(driverfs, &driver_attr_boards);
6441 driver_remove_file(driverfs, &driver_attr_maxboards);
6442 driver_remove_file(driverfs, &driver_attr_pollrate);
6443 driver_remove_file(driverfs, &driver_attr_pollcounter);
6444}
7568f7d3 6445
7568f7d3
MH
6446static struct attribute_group dgap_tty_attribute_group = {
6447 .name = NULL,
6448 .attrs = dgap_sysfs_tty_entries,
6449};
6450
fe0ef8e6 6451static void dgap_create_tty_sysfs(struct un_t *un, struct device *c)
7568f7d3
MH
6452{
6453 int ret;
6454
6455 ret = sysfs_create_group(&c->kobj, &dgap_tty_attribute_group);
54794d19 6456 if (ret)
7568f7d3 6457 return;
7568f7d3
MH
6458
6459 dev_set_drvdata(c, un);
6460
6461}
6462
fe0ef8e6 6463static void dgap_remove_tty_sysfs(struct device *c)
7568f7d3
MH
6464{
6465 sysfs_remove_group(&c->kobj, &dgap_tty_attribute_group);
6466}
69edaa21
MH
6467
6468/*
0b2cf5c8 6469 * Create pr and tty device entries
69edaa21 6470 */
0b2cf5c8 6471static int dgap_tty_register_ports(struct board_t *brd)
69edaa21 6472{
0b2cf5c8
DY
6473 struct channel_t *ch;
6474 int i;
6475 int ret;
69edaa21 6476
0b2cf5c8
DY
6477 brd->serial_ports = kcalloc(brd->nasync, sizeof(*brd->serial_ports),
6478 GFP_KERNEL);
6479 if (!brd->serial_ports)
6480 return -ENOMEM;
69edaa21 6481
0b2cf5c8
DY
6482 brd->printer_ports = kcalloc(brd->nasync, sizeof(*brd->printer_ports),
6483 GFP_KERNEL);
6484 if (!brd->printer_ports) {
6485 ret = -ENOMEM;
6486 goto free_serial_ports;
69edaa21
MH
6487 }
6488
0b2cf5c8
DY
6489 for (i = 0; i < brd->nasync; i++) {
6490 tty_port_init(&brd->serial_ports[i]);
6491 tty_port_init(&brd->printer_ports[i]);
6492 }
69edaa21 6493
0b2cf5c8
DY
6494 ch = brd->channels[0];
6495 for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) {
69edaa21 6496
0b2cf5c8 6497 struct device *classp;
69edaa21 6498
0b2cf5c8
DY
6499 classp = tty_port_register_device(&brd->serial_ports[i],
6500 brd->serial_driver,
6501 i, NULL);
69edaa21 6502
0b2cf5c8
DY
6503 if (IS_ERR(classp)) {
6504 ret = PTR_ERR(classp);
6505 goto unregister_ttys;
6506 }
69edaa21 6507
0b2cf5c8
DY
6508 dgap_create_tty_sysfs(&ch->ch_tun, classp);
6509 ch->ch_tun.un_sysfs = classp;
69edaa21 6510
0b2cf5c8
DY
6511 classp = tty_port_register_device(&brd->printer_ports[i],
6512 brd->print_driver,
6513 i, NULL);
69edaa21 6514
0b2cf5c8
DY
6515 if (IS_ERR(classp)) {
6516 ret = PTR_ERR(classp);
6517 goto unregister_ttys;
6518 }
69edaa21 6519
0b2cf5c8
DY
6520 dgap_create_tty_sysfs(&ch->ch_pun, classp);
6521 ch->ch_pun.un_sysfs = classp;
6522 }
6523 dgap_create_ports_sysfiles(brd);
69edaa21 6524
0b2cf5c8 6525 return 0;
69edaa21 6526
0b2cf5c8
DY
6527unregister_ttys:
6528 while (i >= 0) {
6529 ch = brd->channels[i];
6530 if (ch->ch_tun.un_sysfs) {
6531 dgap_remove_tty_sysfs(ch->ch_tun.un_sysfs);
6532 tty_unregister_device(brd->serial_driver, i);
6533 }
69edaa21 6534
0b2cf5c8
DY
6535 if (ch->ch_pun.un_sysfs) {
6536 dgap_remove_tty_sysfs(ch->ch_pun.un_sysfs);
6537 tty_unregister_device(brd->print_driver, i);
6538 }
6539 i--;
6540 }
69edaa21 6541
0b2cf5c8
DY
6542 for (i = 0; i < brd->nasync; i++) {
6543 tty_port_destroy(&brd->serial_ports[i]);
6544 tty_port_destroy(&brd->printer_ports[i]);
6545 }
69edaa21 6546
0b2cf5c8
DY
6547 kfree(brd->printer_ports);
6548 brd->printer_ports = NULL;
69edaa21 6549
0b2cf5c8
DY
6550free_serial_ports:
6551 kfree(brd->serial_ports);
6552 brd->serial_ports = NULL;
82512235 6553
0b2cf5c8
DY
6554 return ret;
6555}
82512235 6556
0b2cf5c8
DY
6557/*
6558 * dgap_cleanup_tty()
6559 *
6560 * Uninitialize the TTY portion of this driver. Free all memory and
6561 * resources.
6562 */
6563static void dgap_cleanup_tty(struct board_t *brd)
6564{
6565 struct device *dev;
6566 unsigned int i;
82512235 6567
0b2cf5c8
DY
6568 for (i = 0; i < brd->nasync; i++) {
6569 tty_port_destroy(&brd->serial_ports[i]);
6570 dev = brd->channels[i]->ch_tun.un_sysfs;
6571 dgap_remove_tty_sysfs(dev);
6572 tty_unregister_device(brd->serial_driver, i);
6573 }
6574 tty_unregister_driver(brd->serial_driver);
6575 put_tty_driver(brd->serial_driver);
6576 kfree(brd->serial_ports);
6c66843d 6577
0b2cf5c8
DY
6578 for (i = 0; i < brd->nasync; i++) {
6579 tty_port_destroy(&brd->printer_ports[i]);
6580 dev = brd->channels[i]->ch_pun.un_sysfs;
6581 dgap_remove_tty_sysfs(dev);
6582 tty_unregister_device(brd->print_driver, i);
6583 }
6584 tty_unregister_driver(brd->print_driver);
6585 put_tty_driver(brd->print_driver);
6586 kfree(brd->printer_ports);
6587}
69edaa21 6588
0b2cf5c8
DY
6589static int dgap_request_irq(struct board_t *brd)
6590{
6591 int rc;
82512235 6592
0b2cf5c8
DY
6593 if (!brd || brd->magic != DGAP_BOARD_MAGIC)
6594 return -ENODEV;
82512235 6595
0b2cf5c8
DY
6596 /*
6597 * Set up our interrupt handler if we are set to do interrupts.
6598 */
6599 if (dgap_config_get_useintr(brd) && brd->irq) {
82512235 6600
0b2cf5c8 6601 rc = request_irq(brd->irq, dgap_intr, IRQF_SHARED, "DGAP", brd);
6c66843d 6602
0b2cf5c8
DY
6603 if (!rc)
6604 brd->intr_used = 1;
6605 }
6606 return 0;
6607}
69edaa21 6608
0b2cf5c8
DY
6609static void dgap_free_irq(struct board_t *brd)
6610{
6611 if (brd->intr_used && brd->irq)
6612 free_irq(brd->irq, brd);
6613}
6614
6615static int dgap_firmware_load(struct pci_dev *pdev, int card_type,
6616 struct board_t *brd)
6617{
6618 const struct firmware *fw;
6619 char *tmp_ptr;
6620 int ret;
6621 char *dgap_config_buf;
6622
6623 dgap_get_vpd(brd);
6624 dgap_do_reset_board(brd);
6625
6626 if (fw_info[card_type].conf_name) {
6627 ret = request_firmware(&fw, fw_info[card_type].conf_name,
6628 &pdev->dev);
6629 if (ret) {
6630 dev_err(&pdev->dev, "config file %s not found\n",
6631 fw_info[card_type].conf_name);
6632 return ret;
6633 }
82512235 6634
0b2cf5c8
DY
6635 dgap_config_buf = kzalloc(fw->size + 1, GFP_KERNEL);
6636 if (!dgap_config_buf) {
6637 release_firmware(fw);
6638 return -ENOMEM;
6639 }
82512235 6640
0b2cf5c8
DY
6641 memcpy(dgap_config_buf, fw->data, fw->size);
6642 release_firmware(fw);
69edaa21 6643
0b2cf5c8
DY
6644 /*
6645 * preserve dgap_config_buf
6646 * as dgap_parsefile would
6647 * otherwise alter it.
6648 */
6649 tmp_ptr = dgap_config_buf;
82512235 6650
0b2cf5c8
DY
6651 if (dgap_parsefile(&tmp_ptr) != 0) {
6652 kfree(dgap_config_buf);
6653 return -EINVAL;
6654 }
6655 kfree(dgap_config_buf);
6656 }
82512235 6657
0b2cf5c8
DY
6658 /*
6659 * Match this board to a config the user created for us.
6660 */
6661 brd->bd_config =
6662 dgap_find_config(brd->type, brd->pci_bus, brd->pci_slot);
82512235 6663
0b2cf5c8
DY
6664 /*
6665 * Because the 4 port Xr products share the same PCI ID
6666 * as the 8 port Xr products, if we receive a NULL config
6667 * back, and this is a PAPORT8 board, retry with a
6668 * PAPORT4 attempt as well.
6669 */
6670 if (brd->type == PAPORT8 && !brd->bd_config)
6671 brd->bd_config =
6672 dgap_find_config(PAPORT4, brd->pci_bus, brd->pci_slot);
69edaa21 6673
0b2cf5c8
DY
6674 if (!brd->bd_config) {
6675 dev_err(&pdev->dev, "No valid configuration found\n");
6676 return -EINVAL;
6677 }
69edaa21 6678
0b2cf5c8
DY
6679 if (fw_info[card_type].bios_name) {
6680 ret = request_firmware(&fw, fw_info[card_type].bios_name,
6681 &pdev->dev);
6682 if (ret) {
6683 dev_err(&pdev->dev, "bios file %s not found\n",
6684 fw_info[card_type].bios_name);
6685 return ret;
6686 }
6687 dgap_do_bios_load(brd, fw->data, fw->size);
6688 release_firmware(fw);
f6aa0164 6689
0b2cf5c8
DY
6690 /* Wait for BIOS to test board... */
6691 ret = dgap_test_bios(brd);
6692 if (ret)
6693 return ret;
6694 }
69edaa21 6695
0b2cf5c8
DY
6696 if (fw_info[card_type].fep_name) {
6697 ret = request_firmware(&fw, fw_info[card_type].fep_name,
6698 &pdev->dev);
6699 if (ret) {
6700 dev_err(&pdev->dev, "dgap: fep file %s not found\n",
6701 fw_info[card_type].fep_name);
6702 return ret;
6703 }
6704 dgap_do_fep_load(brd, fw->data, fw->size);
6705 release_firmware(fw);
82512235 6706
0b2cf5c8
DY
6707 /* Wait for FEP to load on board... */
6708 ret = dgap_test_fep(brd);
6709 if (ret)
6710 return ret;
6711 }
6c66843d 6712
0b2cf5c8
DY
6713#ifdef DIGI_CONCENTRATORS_SUPPORTED
6714 /*
6715 * If this is a CX or EPCX, we need to see if the firmware
6716 * is requesting a concentrator image from us.
6717 */
6718 if ((bd->type == PCX) || (bd->type == PEPC)) {
6719 chk_addr = (u16 *) (vaddr + DOWNREQ);
6720 /* Nonzero if FEP is requesting concentrator image. */
6721 check = readw(chk_addr);
6722 vaddr = brd->re_map_membase;
6723 }
82512235 6724
0b2cf5c8
DY
6725 if (fw_info[card_type].con_name && check && vaddr) {
6726 ret = request_firmware(&fw, fw_info[card_type].con_name,
6727 &pdev->dev);
6728 if (ret) {
6729 dev_err(&pdev->dev, "conc file %s not found\n",
6730 fw_info[card_type].con_name);
6731 return ret;
6732 }
6733 /* Put concentrator firmware loading code here */
6734 offset = readw((u16 *) (vaddr + DOWNREQ));
6735 memcpy_toio(offset, fw->data, fw->size);
69edaa21 6736
0b2cf5c8
DY
6737 dgap_do_conc_load(brd, (char *)fw->data, fw->size)
6738 release_firmware(fw);
6739 }
6740#endif
69edaa21 6741
0b2cf5c8
DY
6742 return 0;
6743}
3cfa648b 6744
0b2cf5c8
DY
6745/*
6746 * dgap_tty_init()
6747 *
6748 * Init the tty subsystem. Called once per board after board has been
6749 * downloaded and init'ed.
6750 */
6751static int dgap_tty_init(struct board_t *brd)
6752{
6753 int i;
6754 int tlw;
6755 uint true_count;
6756 u8 __iomem *vaddr;
6757 u8 modem;
6758 struct channel_t *ch;
6759 struct bs_t __iomem *bs;
6760 struct cm_t __iomem *cm;
6761 int ret;
69edaa21 6762
0b2cf5c8
DY
6763 /*
6764 * Initialize board structure elements.
6765 */
69edaa21 6766
0b2cf5c8
DY
6767 vaddr = brd->re_map_membase;
6768 true_count = readw((vaddr + NCHAN));
69edaa21 6769
0b2cf5c8 6770 brd->nasync = dgap_config_get_num_prts(brd);
82512235 6771
0b2cf5c8
DY
6772 if (!brd->nasync)
6773 brd->nasync = brd->maxports;
82512235 6774
0b2cf5c8
DY
6775 if (brd->nasync > brd->maxports)
6776 brd->nasync = brd->maxports;
6777
6778 if (true_count != brd->nasync) {
6779 dev_warn(&brd->pdev->dev,
6780 "%s configured for %d ports, has %d ports.\n",
6781 brd->name, brd->nasync, true_count);
6782
6783 if ((brd->type == PPCM) &&
6784 (true_count == 64 || true_count == 0)) {
6785 dev_warn(&brd->pdev->dev,
6786 "Please make SURE the EBI cable running from the card\n");
6787 dev_warn(&brd->pdev->dev,
6788 "to each EM module is plugged into EBI IN!\n");
6789 }
82512235 6790
0b2cf5c8 6791 brd->nasync = true_count;
6c66843d 6792
0b2cf5c8
DY
6793 /* If no ports, don't bother going any further */
6794 if (!brd->nasync) {
6795 brd->state = BOARD_FAILED;
6796 brd->dpastatus = BD_NOFEP;
6797 return -EIO;
6798 }
6799 }
69edaa21 6800
0b2cf5c8
DY
6801 /*
6802 * Allocate channel memory that might not have been allocated
6803 * when the driver was first loaded.
6804 */
6805 for (i = 0; i < brd->nasync; i++) {
6806 brd->channels[i] =
6807 kzalloc(sizeof(struct channel_t), GFP_KERNEL);
6808 if (!brd->channels[i]) {
6809 ret = -ENOMEM;
6810 goto free_chan;
6811 }
6812 }
82512235 6813
0b2cf5c8
DY
6814 ch = brd->channels[0];
6815 vaddr = brd->re_map_membase;
82512235 6816
0b2cf5c8
DY
6817 bs = (struct bs_t __iomem *) ((ulong) vaddr + CHANBUF);
6818 cm = (struct cm_t __iomem *) ((ulong) vaddr + CMDBUF);
82512235 6819
0b2cf5c8 6820 brd->bd_bs = bs;
69edaa21 6821
0b2cf5c8
DY
6822 /* Set up channel variables */
6823 for (i = 0; i < brd->nasync; i++, ch = brd->channels[i], bs++) {
82512235 6824
0b2cf5c8 6825 spin_lock_init(&ch->ch_lock);
82512235 6826
0b2cf5c8
DY
6827 /* Store all our magic numbers */
6828 ch->magic = DGAP_CHANNEL_MAGIC;
6829 ch->ch_tun.magic = DGAP_UNIT_MAGIC;
6830 ch->ch_tun.un_type = DGAP_SERIAL;
6831 ch->ch_tun.un_ch = ch;
6832 ch->ch_tun.un_dev = i;
82512235 6833
0b2cf5c8
DY
6834 ch->ch_pun.magic = DGAP_UNIT_MAGIC;
6835 ch->ch_pun.un_type = DGAP_PRINT;
6836 ch->ch_pun.un_ch = ch;
6837 ch->ch_pun.un_dev = i;
69edaa21 6838
0b2cf5c8
DY
6839 ch->ch_vaddr = vaddr;
6840 ch->ch_bs = bs;
6841 ch->ch_cm = cm;
6842 ch->ch_bd = brd;
6843 ch->ch_portnum = i;
6844 ch->ch_digi = dgap_digi_init;
82512235 6845
0b2cf5c8
DY
6846 /*
6847 * Set up digi dsr and dcd bits based on altpin flag.
6848 */
6849 if (dgap_config_get_altpin(brd)) {
6850 ch->ch_dsr = DM_CD;
6851 ch->ch_cd = DM_DSR;
6852 ch->ch_digi.digi_flags |= DIGI_ALTPIN;
6853 } else {
6854 ch->ch_cd = DM_CD;
6855 ch->ch_dsr = DM_DSR;
6856 }
6c66843d 6857
0b2cf5c8
DY
6858 ch->ch_taddr = vaddr + (ioread16(&(ch->ch_bs->tx_seg)) << 4);
6859 ch->ch_raddr = vaddr + (ioread16(&(ch->ch_bs->rx_seg)) << 4);
6860 ch->ch_tx_win = 0;
6861 ch->ch_rx_win = 0;
6862 ch->ch_tsize = readw(&(ch->ch_bs->tx_max)) + 1;
6863 ch->ch_rsize = readw(&(ch->ch_bs->rx_max)) + 1;
6864 ch->ch_tstart = 0;
6865 ch->ch_rstart = 0;
69edaa21 6866
0b2cf5c8
DY
6867 /*
6868 * Set queue water marks, interrupt mask,
6869 * and general tty parameters.
6870 */
6871 tlw = ch->ch_tsize >= 2000 ? ((ch->ch_tsize * 5) / 8) :
6872 ch->ch_tsize / 2;
6873 ch->ch_tlw = tlw;
82512235 6874
0b2cf5c8 6875 dgap_cmdw(ch, STLOW, tlw, 0);
82512235 6876
0b2cf5c8 6877 dgap_cmdw(ch, SRLOW, ch->ch_rsize / 2, 0);
82512235 6878
0b2cf5c8 6879 dgap_cmdw(ch, SRHIGH, 7 * ch->ch_rsize / 8, 0);
69edaa21 6880
0b2cf5c8 6881 ch->ch_mistat = readb(&(ch->ch_bs->m_stat));
82512235 6882
0b2cf5c8
DY
6883 init_waitqueue_head(&ch->ch_flags_wait);
6884 init_waitqueue_head(&ch->ch_tun.un_flags_wait);
6885 init_waitqueue_head(&ch->ch_pun.un_flags_wait);
82512235 6886
0b2cf5c8
DY
6887 /* Turn on all modem interrupts for now */
6888 modem = (DM_CD | DM_DSR | DM_CTS | DM_RI);
6889 writeb(modem, &(ch->ch_bs->m_int));
82512235 6890
0b2cf5c8
DY
6891 /*
6892 * Set edelay to 0 if interrupts are turned on,
6893 * otherwise set edelay to the usual 100.
6894 */
6895 if (brd->intr_used)
6896 writew(0, &(ch->ch_bs->edelay));
6897 else
6898 writew(100, &(ch->ch_bs->edelay));
69edaa21 6899
0b2cf5c8
DY
6900 writeb(1, &(ch->ch_bs->idata));
6901 }
82512235 6902
0b2cf5c8 6903 return 0;
82512235 6904
0b2cf5c8
DY
6905free_chan:
6906 while (--i >= 0) {
6907 kfree(brd->channels[i]);
6908 brd->channels[i] = NULL;
6909 }
6910 return ret;
6911}
82512235 6912
0b2cf5c8
DY
6913/*
6914 * dgap_tty_free()
6915 *
6916 * Free the channles which are allocated in dgap_tty_init().
6917 */
6918static void dgap_tty_free(struct board_t *brd)
6919{
6920 int i;
69edaa21 6921
0b2cf5c8
DY
6922 for (i = 0; i < brd->nasync; i++)
6923 kfree(brd->channels[i]);
6924}
82512235 6925
0b2cf5c8
DY
6926static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
6927{
6928 int rc;
6929 struct board_t *brd;
82512235 6930
0b2cf5c8
DY
6931 if (dgap_numboards >= MAXBOARDS)
6932 return -EPERM;
82512235 6933
0b2cf5c8
DY
6934 rc = pci_enable_device(pdev);
6935 if (rc)
6936 return -EIO;
69edaa21 6937
0b2cf5c8
DY
6938 brd = dgap_found_board(pdev, ent->driver_data, dgap_numboards);
6939 if (IS_ERR(brd))
6940 return PTR_ERR(brd);
82512235 6941
0b2cf5c8
DY
6942 rc = dgap_firmware_load(pdev, ent->driver_data, brd);
6943 if (rc)
6944 goto cleanup_brd;
82512235 6945
0b2cf5c8
DY
6946 rc = dgap_alloc_flipbuf(brd);
6947 if (rc)
6948 goto cleanup_brd;
82512235 6949
0b2cf5c8
DY
6950 rc = dgap_tty_register(brd);
6951 if (rc)
6952 goto free_flipbuf;
69edaa21 6953
0b2cf5c8
DY
6954 rc = dgap_request_irq(brd);
6955 if (rc)
6956 goto unregister_tty;
82512235 6957
0b2cf5c8
DY
6958 /*
6959 * Do tty device initialization.
6960 */
6961 rc = dgap_tty_init(brd);
6962 if (rc < 0)
6963 goto free_irq;
82512235 6964
0b2cf5c8
DY
6965 rc = dgap_tty_register_ports(brd);
6966 if (rc)
6967 goto tty_free;
82512235 6968
0b2cf5c8
DY
6969 brd->state = BOARD_READY;
6970 brd->dpastatus = BD_RUNNING;
69edaa21 6971
0b2cf5c8 6972 dgap_board[dgap_numboards++] = brd;
69edaa21 6973
0b2cf5c8 6974 return 0;
69edaa21 6975
0b2cf5c8
DY
6976tty_free:
6977 dgap_tty_free(brd);
6978free_irq:
6979 dgap_free_irq(brd);
6980unregister_tty:
6981 dgap_tty_unregister(brd);
6982free_flipbuf:
6983 dgap_free_flipbuf(brd);
6984cleanup_brd:
6985 dgap_cleanup_nodes();
6986 dgap_unmap(brd);
6987 kfree(brd);
69edaa21 6988
0b2cf5c8
DY
6989 return rc;
6990}
6991
6992static void dgap_remove_one(struct pci_dev *dev)
6993{
6994 /* Do Nothing */
69edaa21
MH
6995}
6996
0b2cf5c8
DY
6997static struct pci_driver dgap_driver = {
6998 .name = "dgap",
6999 .probe = dgap_init_one,
7000 .id_table = dgap_pci_tbl,
7001 .remove = dgap_remove_one,
7002};
7003
69edaa21 7004/*
0b2cf5c8 7005 * Start of driver.
69edaa21 7006 */
0b2cf5c8 7007static int dgap_start(void)
69edaa21 7008{
0b2cf5c8
DY
7009 int rc;
7010 unsigned long flags;
7011 struct device *device;
69edaa21 7012
0b2cf5c8 7013 dgap_numboards = 0;
69edaa21 7014
0b2cf5c8 7015 pr_info("For the tools package please visit http://www.digi.com\n");
69edaa21 7016
0b2cf5c8
DY
7017 /*
7018 * Register our base character device into the kernel.
7019 */
7020
7021 /*
7022 * Register management/dpa devices
7023 */
7024 rc = register_chrdev(DIGI_DGAP_MAJOR, "dgap", &dgap_board_fops);
7025 if (rc < 0)
7026 return rc;
7027
7028 dgap_class = class_create(THIS_MODULE, "dgap_mgmt");
7029 if (IS_ERR(dgap_class)) {
7030 rc = PTR_ERR(dgap_class);
7031 goto failed_class;
69edaa21
MH
7032 }
7033
0b2cf5c8
DY
7034 device = device_create(dgap_class, NULL,
7035 MKDEV(DIGI_DGAP_MAJOR, 0),
7036 NULL, "dgap_mgmt");
7037 if (IS_ERR(device)) {
7038 rc = PTR_ERR(device);
7039 goto failed_device;
7040 }
69edaa21 7041
0b2cf5c8
DY
7042 /* Start the poller */
7043 spin_lock_irqsave(&dgap_poll_lock, flags);
7044 init_timer(&dgap_poll_timer);
7045 dgap_poll_timer.function = dgap_poll_handler;
7046 dgap_poll_timer.data = 0;
7047 dgap_poll_time = jiffies + dgap_jiffies_from_ms(dgap_poll_tick);
7048 dgap_poll_timer.expires = dgap_poll_time;
7049 spin_unlock_irqrestore(&dgap_poll_lock, flags);
69edaa21 7050
0b2cf5c8 7051 add_timer(&dgap_poll_timer);
69edaa21 7052
0b2cf5c8
DY
7053 return rc;
7054
7055failed_device:
7056 class_destroy(dgap_class);
7057failed_class:
7058 unregister_chrdev(DIGI_DGAP_MAJOR, "dgap");
7059 return rc;
69edaa21
MH
7060}
7061
0b2cf5c8 7062static void dgap_stop(void)
69edaa21 7063{
0b2cf5c8 7064 unsigned long lock_flags;
69edaa21 7065
0b2cf5c8
DY
7066 spin_lock_irqsave(&dgap_poll_lock, lock_flags);
7067 dgap_poll_stop = 1;
7068 spin_unlock_irqrestore(&dgap_poll_lock, lock_flags);
69edaa21 7069
0b2cf5c8 7070 del_timer_sync(&dgap_poll_timer);
69edaa21 7071
0b2cf5c8
DY
7072 device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0));
7073 class_destroy(dgap_class);
7074 unregister_chrdev(DIGI_DGAP_MAJOR, "dgap");
69edaa21
MH
7075}
7076
69edaa21 7077/*
0b2cf5c8
DY
7078 * dgap_cleanup_board()
7079 *
7080 * Free all the memory associated with a board
69edaa21 7081 */
0b2cf5c8 7082static void dgap_cleanup_board(struct board_t *brd)
69edaa21 7083{
0b2cf5c8 7084 unsigned int i;
69edaa21 7085
0b2cf5c8
DY
7086 if (!brd || brd->magic != DGAP_BOARD_MAGIC)
7087 return;
69edaa21 7088
0b2cf5c8 7089 dgap_free_irq(brd);
69edaa21 7090
0b2cf5c8
DY
7091 tasklet_kill(&brd->helper_tasklet);
7092
7093 dgap_unmap(brd);
7094
7095 /* Free all allocated channels structs */
7096 for (i = 0; i < MAXPORTS ; i++)
7097 kfree(brd->channels[i]);
7098
7099 kfree(brd->flipbuf);
7100 kfree(brd->flipflagbuf);
7101
7102 dgap_board[brd->boardnum] = NULL;
7103
7104 kfree(brd);
69edaa21
MH
7105}
7106
0b2cf5c8
DY
7107
7108/************************************************************************
7109 *
7110 * Driver load/unload functions
7111 *
7112 ************************************************************************/
7113
69edaa21 7114/*
0b2cf5c8
DY
7115 * init_module()
7116 *
7117 * Module load. This is where it all starts.
69edaa21 7118 */
0b2cf5c8 7119static int dgap_init_module(void)
69edaa21 7120{
0b2cf5c8 7121 int rc;
69edaa21 7122
0b2cf5c8 7123 pr_info("%s, Digi International Part Number %s\n", DG_NAME, DG_PART);
69edaa21 7124
0b2cf5c8
DY
7125 rc = dgap_start();
7126 if (rc)
7127 return rc;
69edaa21 7128
0b2cf5c8
DY
7129 rc = pci_register_driver(&dgap_driver);
7130 if (rc)
7131 goto err_stop;
0be048cb 7132
0b2cf5c8
DY
7133 rc = dgap_create_driver_sysfiles(&dgap_driver);
7134 if (rc)
7135 goto err_unregister;
0be048cb 7136
0b2cf5c8 7137 dgap_driver_state = DRIVER_READY;
0be048cb 7138
0b2cf5c8 7139 return 0;
0be048cb 7140
0b2cf5c8
DY
7141err_unregister:
7142 pci_unregister_driver(&dgap_driver);
7143err_stop:
7144 dgap_stop();
0be048cb 7145
0b2cf5c8 7146 return rc;
69edaa21
MH
7147}
7148
7149/*
0b2cf5c8
DY
7150 * dgap_cleanup_module()
7151 *
7152 * Module unload. This is where it all ends.
69edaa21 7153 */
0b2cf5c8 7154static void dgap_cleanup_module(void)
69edaa21 7155{
0b2cf5c8
DY
7156 unsigned int i;
7157 ulong lock_flags;
69edaa21 7158
0b2cf5c8
DY
7159 spin_lock_irqsave(&dgap_poll_lock, lock_flags);
7160 dgap_poll_stop = 1;
7161 spin_unlock_irqrestore(&dgap_poll_lock, lock_flags);
69edaa21 7162
0b2cf5c8
DY
7163 /* Turn off poller right away. */
7164 del_timer_sync(&dgap_poll_timer);
69edaa21 7165
0b2cf5c8 7166 dgap_remove_driver_sysfiles(&dgap_driver);
69edaa21 7167
0b2cf5c8
DY
7168 device_destroy(dgap_class, MKDEV(DIGI_DGAP_MAJOR, 0));
7169 class_destroy(dgap_class);
7170 unregister_chrdev(DIGI_DGAP_MAJOR, "dgap");
69edaa21 7171
0b2cf5c8
DY
7172 for (i = 0; i < dgap_numboards; ++i) {
7173 dgap_remove_ports_sysfiles(dgap_board[i]);
7174 dgap_cleanup_tty(dgap_board[i]);
7175 dgap_cleanup_board(dgap_board[i]);
69edaa21
MH
7176 }
7177
0b2cf5c8 7178 dgap_cleanup_nodes();
69edaa21 7179
0b2cf5c8
DY
7180 if (dgap_numboards)
7181 pci_unregister_driver(&dgap_driver);
7182}
69edaa21 7183
0b2cf5c8
DY
7184module_init(dgap_init_module);
7185module_exit(dgap_cleanup_module);
69edaa21 7186
0b2cf5c8
DY
7187MODULE_LICENSE("GPL");
7188MODULE_AUTHOR("Digi International, http://www.digi.com");
7189MODULE_DESCRIPTION("Driver for the Digi International EPCA PCI based product line");
7190MODULE_SUPPORTED_DEVICE("dgap");
This page took 0.728063 seconds and 5 git commands to generate.