]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/dgap/dgap_fep5.c
staging: dgap: tty.c: fixes termios error
[karo-tx-linux.git] / drivers / staging / dgap / dgap_fep5.c
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.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the 
12  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
13  * PURPOSE.  See the GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  *
20  *      NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
21  *
22  *      This is shared code between Digi's CVS archive and the
23  *      Linux Kernel sources.
24  *      Changing the source just for reformatting needlessly breaks
25  *      our CVS diff history.
26  *
27  *      Send any bug fixes/changes to:  Eng.Linux at digi dot com.
28  *      Thank you.
29  *
30  * $Id: dgap_fep5.c,v 1.2 2011/06/21 10:35:40 markh Exp $
31  */
32
33
34 #include <linux/kernel.h>
35 #include <linux/version.h>
36 #include <linux/module.h>
37 #include <linux/pci.h>
38 #include <linux/delay.h>        /* For udelay */
39 #include <asm/uaccess.h>        /* For copy_from_user/copy_to_user */
40 #include <linux/tty.h>
41 #include <linux/tty_flip.h>     /* For tty_schedule_flip */
42
43 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
44 #include <linux/sched.h>
45 #endif
46
47 #include "dgap_driver.h"
48 #include "dgap_pci.h"
49 #include "dgap_proc.h"
50 #include "dgap_fep5.h"
51 #include "dgap_tty.h"
52 #include "dgap_conf.h"
53 #include "dgap_parse.h"
54 #include "dgap_mgmt.h"
55 #include "dgap_trace.h"
56
57 /*
58  * Our function prototypes
59  */
60 static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds);
61 static int dgap_event(struct board_t *bd);
62
63 /*
64  * internal variables
65  */
66 static uint dgap_count = 500;
67
68
69 /*
70  * Loads the dgap.conf config file from the user.
71  */
72 void dgap_do_config_load(uchar __user *uaddr, int len)
73 {
74         int orig_len = len;
75         char *to_addr;
76         uchar __user *from_addr = uaddr;
77         char buf[U2BSIZE];
78         int n;
79
80         to_addr = dgap_config_buf = dgap_driver_kzmalloc(len + 1, GFP_ATOMIC);
81         if (!dgap_config_buf) {
82                 DPR_INIT(("dgap_do_config_load - unable to allocate memory for file\n"));
83                 dgap_driver_state = DRIVER_NEED_CONFIG_LOAD;
84                 return;
85         }
86
87         n = U2BSIZE;
88         while (len) {
89
90                 if (n > len)
91                         n = len;
92
93                 if (copy_from_user((char *) &buf, from_addr, n) == -1 )
94                         return;
95
96                 /* Copy data from buffer to kernel memory */
97                 memcpy(to_addr, buf, n);
98
99                 /* increment counts */
100                 len -= n;
101                 to_addr += n;
102                 from_addr += n;
103                 n = U2BSIZE;
104         }
105
106         dgap_config_buf[orig_len] = '\0';
107
108         to_addr = dgap_config_buf;
109         dgap_parsefile(&to_addr, TRUE);
110
111         DPR_INIT(("dgap_config_load() finish\n"));
112
113         return;
114 }
115
116
117 int dgap_after_config_loaded(void)
118 {
119         int i = 0;
120         int rc = 0;
121
122         /*
123          * Register our ttys, now that we have the config loaded.
124          */
125         for (i = 0; i < dgap_NumBoards; ++i) {
126
127                 /*
128                  * Initialize KME waitqueues...
129                  */
130                 init_waitqueue_head(&(dgap_Board[i]->kme_wait));
131
132                 /*
133                  * allocate flip buffer for board.
134                  */
135                 dgap_Board[i]->flipbuf = dgap_driver_kzmalloc(MYFLIPLEN, GFP_ATOMIC);
136                 dgap_Board[i]->flipflagbuf = dgap_driver_kzmalloc(MYFLIPLEN, GFP_ATOMIC);
137
138                 //dgap_proc_register_basic_postscan(i);
139         }
140
141         return (rc);
142 }
143
144
145
146 /*=======================================================================
147  *
148  *      usertoboard - copy from user space to board space.
149  *
150  *=======================================================================*/
151 static int dgap_usertoboard(struct board_t *brd, char *to_addr, char __user *from_addr, int len)
152 {
153         char buf[U2BSIZE];
154         int n = U2BSIZE;
155
156         if (!brd || brd->magic != DGAP_BOARD_MAGIC)
157                 return(-EFAULT);
158
159         while (len) {
160                 if (n > len)
161                         n = len;
162
163                 if (copy_from_user((char *) &buf, from_addr, n) == -1 ) {
164                         return(-EFAULT);
165                 }
166
167                 /* Copy data from buffer to card memory */
168                 memcpy_toio(to_addr, buf, n);
169
170                 /* increment counts */
171                 len -= n;
172                 to_addr += n;
173                 from_addr += n;   
174                 n = U2BSIZE;
175         }
176         return(0);
177 }
178
179
180 /*
181  * Copies the BIOS code from the user to the board,
182  * and starts the BIOS running.
183  */
184 void dgap_do_bios_load(struct board_t *brd, uchar __user *ubios, int len)
185 {
186         uchar *addr;
187         uint offset;
188         int i;
189
190         if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
191                 return;
192
193         DPR_INIT(("dgap_do_bios_load() start\n"));
194
195         addr = brd->re_map_membase;
196
197         /*
198          * clear POST area
199          */
200         for (i = 0; i < 16; i++)
201                 writeb(0, addr + POSTAREA + i);
202                                 
203         /*
204          * Download bios
205          */
206         offset = 0x1000;
207         if (dgap_usertoboard(brd, addr + offset, ubios, len) == -1 ) {
208                 brd->state = BOARD_FAILED;
209                 brd->dpastatus = BD_NOFEP;
210                 return;
211         }
212
213         writel(0x0bf00401, addr);
214         writel(0, (addr + 4));
215
216         /* Clear the reset, and change states. */
217         writeb(FEPCLR, brd->re_map_port);
218         brd->state = WAIT_BIOS_LOAD;
219 }
220
221
222 /*
223  * Checks to see if the BIOS completed running on the card.
224  */
225 static void dgap_do_wait_for_bios(struct board_t *brd)
226 {
227         uchar *addr;
228         u16 word;
229
230         if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
231                 return;
232
233         addr = brd->re_map_membase;
234         word = readw(addr + POSTAREA);
235
236         /* Check to see if BIOS thinks board is good. (GD). */
237         if (word == *(u16 *) "GD") {
238                 DPR_INIT(("GOT GD in memory, moving states.\n"));
239                 brd->state = FINISHED_BIOS_LOAD;
240                 return;
241         }
242
243         /* Give up on board after too long of time taken */
244         if (brd->wait_for_bios++ > 5000) {
245                 u16 err1 = readw(addr + SEQUENCE);
246                 u16 err2 = readw(addr + ERROR);
247                 APR(("***WARNING*** %s failed diagnostics.  Error #(%x,%x).\n",
248                         brd->name, err1, err2));
249                 brd->state = BOARD_FAILED;
250                 brd->dpastatus = BD_NOFEP;
251         }
252 }
253
254
255 /*
256  * Copies the FEP code from the user to the board,
257  * and starts the FEP running.
258  */
259 void dgap_do_fep_load(struct board_t *brd, uchar __user *ufep, int len)
260 {
261         uchar *addr;
262         uint offset;
263
264         if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
265                 return;
266
267         addr = brd->re_map_membase;
268
269         DPR_INIT(("dgap_do_fep_load() for board %s : start\n", brd->name));
270
271         /*
272          * Download FEP
273          */
274         offset = 0x1000;
275         if (dgap_usertoboard(brd, addr + offset, ufep, len) == -1 ) {
276                 brd->state = BOARD_FAILED;
277                 brd->dpastatus = BD_NOFEP;
278                 return;
279         }
280
281         /*
282          * If board is a concentrator product, we need to give
283          * it its config string describing how the concentrators look.
284          */
285         if ((brd->type == PCX) || (brd->type == PEPC)) {
286                 uchar string[100];
287                 uchar *config, *xconfig;
288                 int i = 0;
289
290                 xconfig = dgap_create_config_string(brd, string);
291
292                 /* Write string to board memory */
293                 config = addr + CONFIG;
294                 for (; i < CONFIGSIZE; i++, config++, xconfig++) {
295                         writeb(*xconfig, config);
296                         if ((*xconfig & 0xff) == 0xff)
297                                 break;
298                 }
299         }
300
301         writel(0xbfc01004, (addr + 0xc34));
302         writel(0x3, (addr + 0xc30));
303
304         /* change states. */
305         brd->state = WAIT_FEP_LOAD;
306
307         DPR_INIT(("dgap_do_fep_load() for board %s : finish\n", brd->name));
308
309 }
310
311
312 /*
313  * Waits for the FEP to report thats its ready for us to use.
314  */
315 static void dgap_do_wait_for_fep(struct board_t *brd)
316 {
317         uchar *addr;
318         u16 word;
319
320         if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
321                 return;
322
323         addr = brd->re_map_membase;
324
325         DPR_INIT(("dgap_do_wait_for_fep() for board %s : start. addr: %p\n", brd->name, addr));
326
327         word = readw(addr + FEPSTAT);
328
329         /* Check to see if FEP is up and running now. */
330         if (word == *(u16 *) "OS") {
331                 DPR_INIT(("GOT OS in memory for board %s, moving states.\n", brd->name));
332                 brd->state = FINISHED_FEP_LOAD;
333
334                 /*
335                  * Check to see if the board can support FEP5+ commands.
336                  */
337                 word = readw(addr + FEP5_PLUS);
338                 if (word == *(u16 *) "5A") {
339                         DPR_INIT(("GOT 5A in memory for board %s, board supports extended FEP5 commands.\n", brd->name));
340                         brd->bd_flags |= BD_FEP5PLUS;
341                 }
342
343                 return;
344         }
345
346         /* Give up on board after too long of time taken */
347         if (brd->wait_for_fep++ > 5000) {
348                 u16 err1 = readw(addr + SEQUENCE);
349                 u16 err2 = readw(addr + ERROR);
350                 APR(("***WARNING*** FEPOS for %s not functioning.  Error #(%x,%x).\n",
351                         brd->name, err1, err2));
352                 brd->state = BOARD_FAILED;
353                 brd->dpastatus = BD_NOFEP;
354         }
355
356         DPR_INIT(("dgap_do_wait_for_fep() for board %s : finish\n", brd->name));
357 }
358
359
360 /*
361  * Physically forces the FEP5 card to reset itself.
362  */
363 static void dgap_do_reset_board(struct board_t *brd)
364 {
365         uchar check;
366         u32 check1;
367         u32 check2;
368         int i = 0;
369
370         if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase || !brd->re_map_port) {
371                 DPR_INIT(("dgap_do_reset_board() start. bad values. brd: %p mem: %p io: %p\n", 
372                         brd, brd ? brd->re_map_membase : 0, brd ? brd->re_map_port : 0));
373                 return;
374         }
375
376         DPR_INIT(("dgap_do_reset_board() start. io: %p\n", brd->re_map_port));
377
378         /* FEPRST does not vary among supported boards */
379         writeb(FEPRST, brd->re_map_port);
380
381         for (i = 0; i <= 1000; i++) {
382                 check = readb(brd->re_map_port) & 0xe;
383                 if (check == FEPRST)
384                         break;
385                 udelay(10);
386
387         }
388         if (i > 1000) {
389                 APR(("*** WARNING *** Board not resetting...  Failing board.\n"));
390                 brd->state = BOARD_FAILED;
391                 brd->dpastatus = BD_NOFEP;
392                 goto failed;
393         }
394
395         /*
396          * Make sure there really is memory out there.
397          */
398         writel(0xa55a3cc3, (brd->re_map_membase + LOWMEM));
399         writel(0x5aa5c33c, (brd->re_map_membase + HIGHMEM));
400         check1 = readl(brd->re_map_membase + LOWMEM);
401         check2 = readl(brd->re_map_membase + HIGHMEM);
402
403         if ((check1 != 0xa55a3cc3) || (check2 != 0x5aa5c33c)) {
404                 APR(("*** Warning *** No memory at %p for board.\n", brd->re_map_membase));
405                 brd->state = BOARD_FAILED;
406                 brd->dpastatus = BD_NOFEP;
407                 goto failed;
408         }
409
410         if (brd->state != BOARD_FAILED)
411                 brd->state = FINISHED_RESET;
412
413 failed:
414         DPR_INIT(("dgap_do_reset_board() finish\n"));
415 }
416
417
418 /*
419  * Sends a concentrator image into the FEP5 board.
420  */
421 void dgap_do_conc_load(struct board_t *brd, uchar *uaddr, int len)
422 {
423         char *vaddr;
424         u16 offset = 0;
425         struct downld_t *to_dp;
426
427         if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase)
428                 return;
429
430         vaddr = brd->re_map_membase;
431
432         offset = readw((u16 *) (vaddr + DOWNREQ));
433         to_dp = (struct downld_t *) (vaddr + (int) offset);
434
435         /*
436          * The image was already read into kernel space,
437          * we do NOT need a user space read here
438          */
439         memcpy_toio((char *) to_dp, uaddr, sizeof(struct downld_t));
440
441         /* Tell card we have data for it */
442         writew(0, vaddr + (DOWNREQ));
443
444         brd->conc_dl_status = NO_PENDING_CONCENTRATOR_REQUESTS;
445 }
446
447
448 #define EXPANSION_ROM_SIZE      (64 * 1024)
449 #define FEP5_ROM_MAGIC          (0xFEFFFFFF)
450
451 static void dgap_get_vpd(struct board_t *brd)
452 {
453         u32 magic;
454         u32 base_offset;
455         u16 rom_offset;
456         u16 vpd_offset;
457         u16 image_length;
458         u16 i;
459         uchar byte1;
460         uchar byte2;
461
462         /*
463          * Poke the magic number at the PCI Rom Address location.
464          * If VPD is supported, the value read from that address
465          * will be non-zero.
466          */
467         magic = FEP5_ROM_MAGIC;
468         pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic);
469         pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic);
470
471         /* VPD not supported, bail */
472         if (!magic)
473                 return;
474
475         /*
476          * To get to the OTPROM memory, we have to send the boards base
477          * address or'ed with 1 into the PCI Rom Address location.
478          */
479         magic = brd->membase | 0x01;
480         pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic);
481         pci_read_config_dword(brd->pdev, PCI_ROM_ADDRESS, &magic);
482
483         byte1 = readb(brd->re_map_membase);
484         byte2 = readb(brd->re_map_membase + 1);
485
486         /*
487          * If the board correctly swapped to the OTPROM memory,
488          * the first 2 bytes (header) should be 0x55, 0xAA
489          */
490         if (byte1 == 0x55 && byte2 == 0xAA) {
491
492                 base_offset = 0;
493
494                 /*
495                  * We have to run through all the OTPROM memory looking
496                  * for the VPD offset.
497                  */
498                 while (base_offset <= EXPANSION_ROM_SIZE) {
499                 
500                         /*
501                          * Lots of magic numbers here.
502                          *
503                          * The VPD offset is located inside the ROM Data Structure.
504                          * We also have to remember the length of each
505                          * ROM Data Structure, so we can "hop" to the next
506                          * entry if the VPD isn't in the current
507                          * ROM Data Structure.
508                          */
509                         rom_offset = readw(brd->re_map_membase + base_offset + 0x18);
510                         image_length = readw(brd->re_map_membase + rom_offset + 0x10) * 512;
511                         vpd_offset = readw(brd->re_map_membase + rom_offset + 0x08);
512
513                         /* Found the VPD entry */
514                         if (vpd_offset)
515                                 break;
516
517                         /* We didn't find a VPD entry, go to next ROM entry. */
518                         base_offset += image_length;
519
520                         byte1 = readb(brd->re_map_membase + base_offset);
521                         byte2 = readb(brd->re_map_membase + base_offset + 1);
522
523                         /*
524                          * If the new ROM offset doesn't have 0x55, 0xAA
525                          * as its header, we have run out of ROM.
526                          */
527                         if (byte1 != 0x55 || byte2 != 0xAA)
528                                 break;
529                 }
530
531                 /*
532                  * If we have a VPD offset, then mark the board
533                  * as having a valid VPD, and copy VPDSIZE (512) bytes of
534                  * that VPD to the buffer we have in our board structure.
535                  */
536                 if (vpd_offset) {
537                         brd->bd_flags |= BD_HAS_VPD;
538                         for (i = 0; i < VPDSIZE; i++)
539                                 brd->vpd[i] = readb(brd->re_map_membase + vpd_offset + i);
540                 }
541         }
542
543         /*
544          * We MUST poke the magic number at the PCI Rom Address location again.
545          * This makes the card report the regular board memory back to us,
546          * rather than the OTPROM memory.
547          */
548         magic = FEP5_ROM_MAGIC;
549         pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic);
550 }
551
552
553 /*
554  * Our board poller function.
555  */
556 void dgap_poll_tasklet(unsigned long data)
557 {
558         struct board_t *bd = (struct board_t *) data;
559         ulong  lock_flags;
560         ulong  lock_flags2;
561         char *vaddr;
562         u16 head, tail;
563         u16 *chk_addr;
564         u16 check = 0;
565
566         if (!bd || (bd->magic != DGAP_BOARD_MAGIC)) {
567                 APR(("dgap_poll_tasklet() - NULL or bad bd.\n"));
568                 return;
569         }
570
571         if (bd->inhibit_poller)
572                 return;
573
574         DGAP_LOCK(bd->bd_lock, lock_flags);
575
576         vaddr = bd->re_map_membase;
577
578         /*
579          * If board is ready, parse deeper to see if there is anything to do.
580          */
581         if (bd->state == BOARD_READY) {
582
583                 struct ev_t *eaddr = NULL;
584
585                 if (!bd->re_map_membase) {
586                         DGAP_UNLOCK(bd->bd_lock, lock_flags);
587                         return;
588                 }
589                 if (!bd->re_map_port) {
590                         DGAP_UNLOCK(bd->bd_lock, lock_flags);
591                         return;
592                 }
593
594                 if (!bd->nasync) {
595                         goto out;
596                 }
597
598                 /*
599                  * If this is a CX or EPCX, we need to see if the firmware
600                  * is requesting a concentrator image from us.
601                  */
602                 if ((bd->type == PCX) || (bd->type == PEPC)) {
603                         chk_addr = (u16 *) (vaddr + DOWNREQ);
604                         check = readw(chk_addr);
605                         /* Nonzero if FEP is requesting concentrator image. */
606                         if (check) {
607                                 if (bd->conc_dl_status == NO_PENDING_CONCENTRATOR_REQUESTS)
608                                         bd->conc_dl_status = NEED_CONCENTRATOR;
609                                 /*
610                                  * Signal downloader, its got some work to do.
611                                  */
612                                 DGAP_LOCK(dgap_dl_lock, lock_flags2);
613                                 if (dgap_dl_action != 1) {
614                                         dgap_dl_action = 1;
615                                         wake_up_interruptible(&dgap_dl_wait);
616                                 }
617                                 DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
618
619                         }
620                 }
621
622                 eaddr = (struct ev_t *) (vaddr + EVBUF);
623
624                 /* Get our head and tail */
625                 head = readw(&(eaddr->ev_head));
626                 tail = readw(&(eaddr->ev_tail));
627
628                 /*
629                  * If there is an event pending. Go service it.
630                  */
631                 if (head != tail) {
632                         DGAP_UNLOCK(bd->bd_lock, lock_flags);
633                         dgap_event(bd);
634                         DGAP_LOCK(bd->bd_lock, lock_flags);
635                 }
636
637 out:
638                 /*
639                  * If board is doing interrupts, ACK the interrupt.
640                  */
641                 if (bd && bd->intr_running) {
642                         readb(bd->re_map_port + 2);
643                 }
644
645                 DGAP_UNLOCK(bd->bd_lock, lock_flags);
646                 return;
647         }
648
649         /* Our state machine to get the board up and running */
650
651         /* Reset board */
652         if (bd->state == NEED_RESET) {
653
654                 /* Get VPD info */
655                 dgap_get_vpd(bd);
656
657                 dgap_do_reset_board(bd);
658         }
659
660         /* Move to next state */
661         if (bd->state == FINISHED_RESET) {
662                 bd->state = NEED_CONFIG;
663         }
664
665         if (bd->state == NEED_CONFIG) {
666                 /*
667                  * Match this board to a config the user created for us.
668                  */
669                 bd->bd_config = dgap_find_config(bd->type, bd->pci_bus, bd->pci_slot);
670
671                 /*
672                  * Because the 4 port Xr products share the same PCI ID
673                  * as the 8 port Xr products, if we receive a NULL config
674                  * back, and this is a PAPORT8 board, retry with a
675                  * PAPORT4 attempt as well.
676                  */
677                 if (bd->type == PAPORT8 && !bd->bd_config) {
678                         bd->bd_config = dgap_find_config(PAPORT4, bd->pci_bus, bd->pci_slot);
679                 }
680
681                 /*
682                  * Register the ttys (if any) into the kernel.
683                  */
684                 if (bd->bd_config) {
685                         bd->state = FINISHED_CONFIG;
686                 }
687                 else {
688                         bd->state = CONFIG_NOT_FOUND;
689                 }
690         }
691
692         /* Move to next state */
693         if (bd->state == FINISHED_CONFIG) {
694                 bd->state = NEED_DEVICE_CREATION;
695         }
696
697         /* Move to next state */
698         if (bd->state == NEED_DEVICE_CREATION) {
699                 /*
700                  * Signal downloader, its got some work to do.
701                  */
702                 DGAP_LOCK(dgap_dl_lock, lock_flags2);
703                 if (dgap_dl_action != 1) {
704                         dgap_dl_action = 1;
705                         wake_up_interruptible(&dgap_dl_wait);
706                 }
707                 DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
708         }
709
710         /* Move to next state */
711         if (bd->state == FINISHED_DEVICE_CREATION) {
712                 bd->state = NEED_BIOS_LOAD;
713         }
714
715         /* Move to next state */
716         if (bd->state == NEED_BIOS_LOAD) {
717                 /*
718                  * Signal downloader, its got some work to do.
719                  */
720                 DGAP_LOCK(dgap_dl_lock, lock_flags2);
721                 if (dgap_dl_action != 1) {
722                         dgap_dl_action = 1;
723                         wake_up_interruptible(&dgap_dl_wait);
724                 }
725                 DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
726         }
727
728         /* Wait for BIOS to test board... */
729         if (bd->state == WAIT_BIOS_LOAD) {
730                 dgap_do_wait_for_bios(bd);
731         }
732
733         /* Move to next state */
734         if (bd->state == FINISHED_BIOS_LOAD) {
735                 bd->state = NEED_FEP_LOAD;
736
737                 /*
738                  * Signal downloader, its got some work to do.
739                  */
740                 DGAP_LOCK(dgap_dl_lock, lock_flags2);
741                 if (dgap_dl_action != 1) {
742                         dgap_dl_action = 1;
743                         wake_up_interruptible(&dgap_dl_wait);
744                 }
745                 DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
746         }
747
748         /* Wait for FEP to load on board... */
749         if (bd->state == WAIT_FEP_LOAD) {
750                 dgap_do_wait_for_fep(bd);
751         }
752
753
754         /* Move to next state */
755         if (bd->state == FINISHED_FEP_LOAD) {
756
757                 /*
758                  * Do tty device initialization.
759                  */
760                 int rc = dgap_tty_init(bd);
761
762                 if (rc < 0) {
763                         dgap_tty_uninit(bd);
764                         APR(("Can't init tty devices (%d)\n", rc));
765                         bd->state = BOARD_FAILED;
766                         bd->dpastatus = BD_NOFEP;
767                 }
768                 else {
769                         bd->state = NEED_PROC_CREATION;
770
771                         /*
772                          * Signal downloader, its got some work to do.
773                          */
774                         DGAP_LOCK(dgap_dl_lock, lock_flags2);
775                         if (dgap_dl_action != 1) {
776                                 dgap_dl_action = 1;
777                                 wake_up_interruptible(&dgap_dl_wait);
778                         }
779                         DGAP_UNLOCK(dgap_dl_lock, lock_flags2);
780                 }
781         }
782
783         /* Move to next state */
784         if (bd->state == FINISHED_PROC_CREATION) {
785
786                 bd->state = BOARD_READY;
787                 bd->dpastatus = BD_RUNNING;
788
789                 /*
790                  * If user requested the board to run in interrupt mode,
791                  * go and set it up on the board.
792                  */
793                 if (bd->intr_used) {
794                         writew(1, (bd->re_map_membase + ENABLE_INTR));
795                         /*
796                          * Tell the board to poll the UARTS as fast as possible.
797                          */
798                         writew(FEPPOLL_MIN, (bd->re_map_membase + FEPPOLL));
799                         bd->intr_running = 1;
800                 }
801
802                 /* Wake up anyone waiting for board state to change to ready */
803                 wake_up_interruptible(&bd->state_wait);
804         }
805
806         DGAP_UNLOCK(bd->bd_lock, lock_flags);
807 }
808
809
810 /*=======================================================================
811  *
812  *      dgap_cmdb - Sends a 2 byte command to the FEP.
813  *
814  *              ch      - Pointer to channel structure.
815  *              cmd     - Command to be sent.
816  *              byte1   - Integer containing first byte to be sent.
817  *              byte2   - Integer containing second byte to be sent.
818  *              ncmds   - Wait until ncmds or fewer cmds are left
819  *                        in the cmd buffer before returning.
820  *
821  *=======================================================================*/
822 void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1, uchar byte2, uint ncmds)
823 {                       
824         char            *vaddr = NULL;
825         struct cm_t     *cm_addr = NULL;
826         uint            count;
827         uint            n;
828         u16             head;
829         u16             tail;
830
831         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
832                 return;
833
834         /*
835          * Check if board is still alive.
836          */
837         if (ch->ch_bd->state == BOARD_FAILED) {
838                 DPR_CORE(("%s:%d board is in failed state.\n", __FILE__, __LINE__));
839                 return;
840         }               
841
842         /*
843          * Make sure the pointers are in range before
844          * writing to the FEP memory.
845          */
846         vaddr = ch->ch_bd->re_map_membase;
847
848         if (!vaddr)
849                 return;
850
851         cm_addr = (struct cm_t *) (vaddr + CMDBUF);
852         head = readw(&(cm_addr->cm_head));
853
854         /* 
855          * Forget it if pointers out of range.
856          */
857         if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
858                 DPR_CORE(("%s:%d pointers out of range, failing board!\n", __FILE__, __LINE__));
859                 ch->ch_bd->state = BOARD_FAILED;
860                 return; 
861         }
862
863         /*
864          * Put the data in the circular command buffer.
865          */
866         writeb(cmd, (char *) (vaddr + head + CMDSTART + 0));
867         writeb((uchar) ch->ch_portnum, (char *) (vaddr + head + CMDSTART + 1));
868         writeb(byte1, (char *) (vaddr + head + CMDSTART + 2));
869         writeb(byte2, (char *) (vaddr + head + CMDSTART + 3));
870
871         head = (head + 4) & (CMDMAX - CMDSTART - 4);
872
873         writew(head, &(cm_addr->cm_head));
874
875         /*
876          * Wait if necessary before updating the head  
877          * pointer to limit the number of outstanding
878          * commands to the FEP.   If the time spent waiting
879          * is outlandish, declare the FEP dead.
880          */
881         for (count = dgap_count ;;) {
882
883                 head = readw(&(cm_addr->cm_head));
884                 tail = readw(&(cm_addr->cm_tail));
885
886                 n = (head - tail) & (CMDMAX - CMDSTART - 4);
887
888                 if (n <= ncmds * sizeof(struct cm_t))
889                         break;
890
891                 if (--count == 0) {
892                         DPR_CORE(("%s:%d failing board.\n",__FILE__, __LINE__));
893                         ch->ch_bd->state = BOARD_FAILED;
894                         return;
895                 }
896                 udelay(10);
897         }  
898 }
899
900
901 /*=======================================================================
902  *
903  *      dgap_cmdw - Sends a 1 word command to the FEP.
904  *      
905  *              ch      - Pointer to channel structure.
906  *              cmd     - Command to be sent.
907  *              word    - Integer containing word to be sent.
908  *              ncmds   - Wait until ncmds or fewer cmds are left
909  *                        in the cmd buffer before returning.
910  *
911  *=======================================================================*/
912 void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, uint ncmds)
913 {
914         char            *vaddr = NULL;
915         struct cm_t     *cm_addr = NULL;
916         uint            count;
917         uint            n;
918         u16             head;
919         u16             tail;
920
921         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
922                 return;
923
924         /*
925          * Check if board is still alive.
926          */
927         if (ch->ch_bd->state == BOARD_FAILED) {
928                 DPR_CORE(("%s:%d board is failed!\n", __FILE__, __LINE__));
929                 return;
930         }
931
932         /*
933          * Make sure the pointers are in range before
934          * writing to the FEP memory.
935          */
936         vaddr = ch->ch_bd->re_map_membase;
937         if (!vaddr)
938                 return;
939
940         cm_addr = (struct cm_t *) (vaddr + CMDBUF);
941         head = readw(&(cm_addr->cm_head));
942
943         /* 
944          * Forget it if pointers out of range.
945          */
946         if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
947                 DPR_CORE(("%s:%d Pointers out of range.  Failing board.\n",__FILE__, __LINE__));
948                 ch->ch_bd->state = BOARD_FAILED;
949                 return;
950         }
951
952         /*
953          * Put the data in the circular command buffer.
954          */
955         writeb(cmd, (char *) (vaddr + head + CMDSTART + 0));
956         writeb((uchar) ch->ch_portnum, (char *) (vaddr + head + CMDSTART + 1));
957         writew((u16) word, (char *) (vaddr + head + CMDSTART + 2));
958
959         head = (head + 4) & (CMDMAX - CMDSTART - 4);
960
961         writew(head, &(cm_addr->cm_head));
962
963         /*
964          * Wait if necessary before updating the head
965          * pointer to limit the number of outstanding  
966          * commands to the FEP.   If the time spent waiting
967          * is outlandish, declare the FEP dead.
968          */
969         for (count = dgap_count ;;) {
970
971                 head = readw(&(cm_addr->cm_head));
972                 tail = readw(&(cm_addr->cm_tail));
973
974                 n = (head - tail) & (CMDMAX - CMDSTART - 4);
975
976                 if (n <= ncmds * sizeof(struct cm_t))
977                         break;
978
979                 if (--count == 0) {
980                         DPR_CORE(("%s:%d Failing board.\n",__FILE__, __LINE__));
981                         ch->ch_bd->state = BOARD_FAILED;
982                         return;
983                 }
984                 udelay(10);
985         }  
986 }
987
988
989
990 /*=======================================================================
991  *
992  *      dgap_cmdw_ext - Sends a extended word command to the FEP.
993  *      
994  *              ch      - Pointer to channel structure.
995  *              cmd     - Command to be sent.
996  *              word    - Integer containing word to be sent.
997  *              ncmds   - Wait until ncmds or fewer cmds are left
998  *                        in the cmd buffer before returning.
999  *
1000  *=======================================================================*/
1001 static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds)
1002 {
1003         char            *vaddr = NULL;
1004         struct cm_t     *cm_addr = NULL;
1005         uint            count;
1006         uint            n;
1007         u16             head;
1008         u16             tail;
1009
1010         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
1011                 return;
1012
1013         /*
1014          * Check if board is still alive.
1015          */
1016         if (ch->ch_bd->state == BOARD_FAILED) {
1017                 DPR_CORE(("%s:%d board is failed!\n", __FILE__, __LINE__));
1018                 return;
1019         }
1020
1021         /*
1022          * Make sure the pointers are in range before
1023          * writing to the FEP memory.
1024          */
1025         vaddr = ch->ch_bd->re_map_membase;
1026         if (!vaddr)
1027                 return;
1028
1029         cm_addr = (struct cm_t *) (vaddr + CMDBUF);
1030         head = readw(&(cm_addr->cm_head));
1031
1032         /* 
1033          * Forget it if pointers out of range.
1034          */
1035         if (head >= (CMDMAX - CMDSTART) || (head & 03)) {
1036                 DPR_CORE(("%s:%d Pointers out of range.  Failing board.\n",__FILE__, __LINE__));
1037                 ch->ch_bd->state = BOARD_FAILED;
1038                 return;
1039         }
1040
1041         /*
1042          * Put the data in the circular command buffer.
1043          */
1044
1045         /* Write an FF to tell the FEP that we want an extended command */
1046         writeb((uchar) 0xff, (char *) (vaddr + head + CMDSTART + 0));
1047
1048         writeb((uchar) ch->ch_portnum, (uchar *) (vaddr + head + CMDSTART + 1));
1049         writew((u16) cmd, (char *) (vaddr + head + CMDSTART + 2));
1050
1051         /*
1052          * If the second part of the command won't fit,
1053          * put it at the beginning of the circular buffer.
1054          */
1055         if (((head + 4) >= ((CMDMAX - CMDSTART)) || (head & 03))) {
1056                 writew((u16) word, (char *) (vaddr + CMDSTART));
1057         } else {
1058                 writew((u16) word, (char *) (vaddr + head + CMDSTART + 4));
1059         }
1060
1061         head = (head + 8) & (CMDMAX - CMDSTART - 4);
1062
1063         writew(head, &(cm_addr->cm_head));
1064
1065         /*
1066          * Wait if necessary before updating the head
1067          * pointer to limit the number of outstanding  
1068          * commands to the FEP.   If the time spent waiting
1069          * is outlandish, declare the FEP dead.
1070          */
1071         for (count = dgap_count ;;) {
1072
1073                 head = readw(&(cm_addr->cm_head));
1074                 tail = readw(&(cm_addr->cm_tail));
1075
1076                 n = (head - tail) & (CMDMAX - CMDSTART - 4);
1077
1078                 if (n <= ncmds * sizeof(struct cm_t))
1079                         break;
1080
1081                 if (--count == 0) {
1082                         DPR_CORE(("%s:%d Failing board.\n",__FILE__, __LINE__));
1083                         ch->ch_bd->state = BOARD_FAILED;
1084                         return;
1085                 }
1086                 udelay(10);
1087         }  
1088 }
1089
1090
1091 /*=======================================================================
1092  *
1093  *      dgap_wmove - Write data to FEP buffer.
1094  *
1095  *              ch      - Pointer to channel structure.
1096  *              buf     - Poiter to characters to be moved.
1097  *              cnt     - Number of characters to move.
1098  *
1099  *=======================================================================*/
1100 void dgap_wmove(struct channel_t *ch, char *buf, uint cnt)
1101 {
1102         int    n;
1103         char   *taddr;
1104         struct bs_t    *bs;
1105         u16    head;
1106
1107         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
1108                 return;
1109  
1110         /*
1111          * Check parameters.
1112          */
1113         bs   = ch->ch_bs;
1114         head = readw(&(bs->tx_head));
1115
1116         /*
1117          * If pointers are out of range, just return.
1118          */
1119         if ((cnt > ch->ch_tsize) || (unsigned)(head - ch->ch_tstart) >= ch->ch_tsize) {
1120                 DPR_CORE(("%s:%d pointer out of range", __FILE__, __LINE__));
1121                 return;
1122         }
1123
1124         /*
1125          * If the write wraps over the top of the circular buffer,
1126          * move the portion up to the wrap point, and reset the
1127          * pointers to the bottom.
1128          */
1129         n = ch->ch_tstart + ch->ch_tsize - head;
1130
1131         if (cnt >= n) {
1132                 cnt -= n;
1133                 taddr = ch->ch_taddr + head;
1134                 memcpy_toio(taddr, buf, n);
1135                 head = ch->ch_tstart;
1136                 buf += n;
1137         }
1138
1139         /*
1140          * Move rest of data.
1141          */
1142         taddr = ch->ch_taddr + head;
1143         n = cnt;
1144         memcpy_toio(taddr, buf, n);
1145         head += cnt;
1146
1147         writew(head, &(bs->tx_head));
1148 }
1149
1150 /*
1151  * Retrives the current custom baud rate from FEP memory,
1152  * and returns it back to the user.
1153  * Returns 0 on error.
1154  */
1155 uint dgap_get_custom_baud(struct channel_t *ch)
1156 {
1157         uchar *vaddr;
1158         ulong offset = 0;
1159         uint value = 0;
1160
1161         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
1162                 return (0);
1163         }
1164
1165         if (!ch->ch_bd || ch->ch_bd->magic != DGAP_BOARD_MAGIC) {
1166                 return (0);
1167         }
1168
1169         if (!(ch->ch_bd->bd_flags & BD_FEP5PLUS))
1170                 return (0);
1171
1172         vaddr = ch->ch_bd->re_map_membase;
1173
1174         if (!vaddr)
1175                 return (0);
1176
1177         /*
1178          * Go get from fep mem, what the fep
1179          * believes the custom baud rate is. 
1180          */
1181         offset = ((((*(unsigned short *)(vaddr + ECS_SEG)) << 4) +  
1182                 (ch->ch_portnum * 0x28) + LINE_SPEED));
1183
1184         value = readw(vaddr + offset);
1185         return (value);
1186 }
1187
1188
1189 /*
1190  * Calls the firmware to reset this channel.
1191  */
1192 void dgap_firmware_reset_port(struct channel_t *ch)
1193 {
1194         dgap_cmdb(ch, CHRESET, 0, 0, 0);
1195
1196         /*
1197          * Now that the channel is reset, we need to make sure
1198          * all the current settings get reapplied to the port
1199          * in the firmware.
1200          *
1201          * So we will set the driver's cache of firmware
1202          * settings all to 0, and then call param.
1203          */
1204         ch->ch_fepiflag = 0;
1205         ch->ch_fepcflag = 0;
1206         ch->ch_fepoflag = 0;
1207         ch->ch_fepstartc = 0;
1208         ch->ch_fepstopc = 0;
1209         ch->ch_fepastartc = 0;
1210         ch->ch_fepastopc = 0;
1211         ch->ch_mostat = 0;
1212         ch->ch_hflow = 0;
1213 }
1214
1215
1216 /*=======================================================================
1217  *      
1218  *      dgap_param - Set Digi parameters.
1219  *
1220  *              struct tty_struct *     - TTY for port.
1221  *
1222  *=======================================================================*/
1223 int dgap_param(struct tty_struct *tty)
1224 {
1225         struct ktermios *ts;
1226         struct board_t *bd;
1227         struct channel_t *ch;
1228         struct bs_t   *bs;
1229         struct un_t   *un;
1230         u16     head;
1231         u16     cflag;
1232         u16     iflag;
1233         uchar   mval;
1234         uchar   hflow;
1235
1236         if (!tty || tty->magic != TTY_MAGIC) {
1237                 return (-ENXIO);
1238         }
1239
1240         un = (struct un_t *) tty->driver_data;
1241         if (!un || un->magic != DGAP_UNIT_MAGIC) {
1242                 return (-ENXIO);
1243         }
1244
1245         ch = un->un_ch;
1246         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
1247                 return (-ENXIO);
1248         }
1249
1250         bd = ch->ch_bd;
1251         if (!bd || bd->magic != DGAP_BOARD_MAGIC) {
1252                 return (-ENXIO);
1253         }
1254
1255         bs = ch->ch_bs;
1256         if (bs == 0) {
1257                 return (-ENXIO);
1258         }
1259
1260         DPR_PARAM(("param start: tdev: %x cflags: %x oflags: %x iflags: %x\n",
1261                 ch->ch_tun.un_dev, ch->ch_c_cflag, ch->ch_c_oflag, ch->ch_c_iflag));
1262
1263         ts = &tty->termios;
1264
1265         /*
1266          * If baud rate is zero, flush queues, and set mval to drop DTR.
1267          */
1268         if ((ch->ch_c_cflag & (CBAUD)) == 0) {
1269
1270                 /* flush rx */
1271                 head = readw(&(ch->ch_bs->rx_head));
1272                 writew(head, &(ch->ch_bs->rx_tail));
1273
1274                 /* flush tx */
1275                 head = readw(&(ch->ch_bs->tx_head));
1276                 writew(head, &(ch->ch_bs->tx_tail));
1277
1278                 ch->ch_flags |= (CH_BAUD0);
1279
1280                 /* Drop RTS and DTR */
1281                 ch->ch_mval &= ~(D_RTS(ch)|D_DTR(ch));
1282                 mval = D_DTR(ch) | D_RTS(ch);
1283                 ch->ch_baud_info = 0;
1284
1285         } else if (ch->ch_custom_speed && (bd->bd_flags & BD_FEP5PLUS)) {
1286                 /*
1287                  * Tell the fep to do the command
1288                  */
1289
1290                 DPR_PARAM(("param: Want %d speed\n", ch->ch_custom_speed));
1291
1292                 dgap_cmdw_ext(ch, 0xff01, ch->ch_custom_speed, 0);
1293
1294                 /*
1295                  * Now go get from fep mem, what the fep
1296                  * believes the custom baud rate is. 
1297                  */
1298                 ch->ch_baud_info = ch->ch_custom_speed = dgap_get_custom_baud(ch);
1299
1300                 DPR_PARAM(("param: Got %d speed\n", ch->ch_custom_speed));
1301
1302                 /* Handle transition from B0 */   
1303                 if (ch->ch_flags & CH_BAUD0) {
1304                         ch->ch_flags &= ~(CH_BAUD0);
1305                         ch->ch_mval |= (D_RTS(ch)|D_DTR(ch));
1306                 }
1307                 mval = D_DTR(ch) | D_RTS(ch);
1308
1309         } else {
1310                 /*
1311                  * Set baud rate, character size, and parity.
1312                  */
1313
1314
1315                 int iindex = 0;
1316                 int jindex = 0;
1317                 int baud = 0;
1318
1319                 ulong bauds[4][16] = {
1320                         { /* slowbaud */
1321                                 0,      50,     75,     110,
1322                                 134,    150,    200,    300,
1323                                 600,    1200,   1800,   2400,
1324                                 4800,   9600,   19200,  38400 },
1325                         { /* slowbaud & CBAUDEX */
1326                                 0,      57600,  115200, 230400,
1327                                 460800, 150,    200,    921600,
1328                                 600,    1200,   1800,   2400,
1329                                 4800,   9600,   19200,  38400 },
1330                         { /* fastbaud */
1331                                 0,      57600,  76800,  115200,
1332                                 14400,  57600,  230400, 76800,
1333                                 115200, 230400, 28800,  460800,
1334                                 921600, 9600,   19200,  38400 },
1335                         { /* fastbaud & CBAUDEX */
1336                                 0,      57600,  115200, 230400,
1337                                 460800, 150,    200,    921600,
1338                                 600,    1200,   1800,   2400,
1339                                 4800,   9600,   19200,  38400 }
1340                 };
1341
1342                 /* Only use the TXPrint baud rate if the terminal unit is NOT open */
1343                 if (!(ch->ch_tun.un_flags & UN_ISOPEN) && (un->un_type == DGAP_PRINT))
1344                         baud = C_BAUD(ch->ch_pun.un_tty) & 0xff;
1345                 else
1346                         baud = C_BAUD(ch->ch_tun.un_tty) & 0xff;
1347
1348                 if (ch->ch_c_cflag & CBAUDEX)
1349                         iindex = 1;
1350
1351                 if (ch->ch_digi.digi_flags & DIGI_FAST)
1352                         iindex += 2;
1353
1354                 jindex = baud;
1355
1356                 if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && (jindex < 16)) {
1357                         baud = bauds[iindex][jindex];
1358                 } else {
1359                         DPR_IOCTL(("baud indices were out of range (%d)(%d)",
1360                                 iindex, jindex));
1361                         baud = 0;
1362                 }
1363
1364                 if (baud == 0)  
1365                         baud = 9600;
1366
1367                 ch->ch_baud_info = baud;
1368
1369
1370                 /*
1371                  * CBAUD has bit position 0x1000 set these days to indicate Linux
1372                  * baud rate remap.
1373                  * We use a different bit assignment for high speed.  Clear this
1374                  * bit out while grabbing the parts of "cflag" we want.
1375                  */
1376                 cflag = ch->ch_c_cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE);
1377
1378                 /*
1379                  * HUPCL bit is used by FEP to indicate fast baud
1380                  * table is to be used.
1381                  */
1382                 if ((ch->ch_digi.digi_flags & DIGI_FAST) || (ch->ch_c_cflag & CBAUDEX))
1383                         cflag |= HUPCL;
1384
1385
1386                 if ((ch->ch_c_cflag & CBAUDEX) && !(ch->ch_digi.digi_flags & DIGI_FAST)) {
1387                 /*
1388                  * The below code is trying to guarantee that only baud rates
1389                  * 115200, 230400, 460800, 921600 are remapped.  We use exclusive or
1390                  * because the various baud rates share common bit positions
1391                  * and therefore can't be tested for easily.
1392                  */
1393                         tcflag_t tcflag = (ch->ch_c_cflag & CBAUD) | CBAUDEX;
1394                         int baudpart = 0;
1395
1396                         /* Map high speed requests to index into FEP's baud table */
1397                         switch (tcflag) {
1398                         case B57600 :
1399                                 baudpart = 1;
1400                                 break;
1401 #ifdef B76800
1402                         case B76800 :
1403                                 baudpart = 2;
1404                                 break;
1405 #endif
1406                         case B115200 :
1407                                 baudpart = 3;
1408                                 break;
1409                         case B230400 :
1410                                 baudpart = 9;
1411                                 break;
1412                         case B460800 :
1413                                 baudpart = 11;
1414                                 break;
1415 #ifdef B921600
1416                         case B921600 :
1417                                 baudpart = 12;
1418                                 break;
1419 #endif
1420                         default:
1421                                 baudpart = 0;
1422                         }
1423
1424                         if (baudpart)
1425                                 cflag = (cflag & ~(CBAUD | CBAUDEX)) | baudpart;
1426                 }
1427
1428                 cflag &= 0xffff;
1429
1430                 if (cflag != ch->ch_fepcflag) {
1431                         ch->ch_fepcflag = (u16) (cflag & 0xffff);
1432
1433                         /* Okay to have channel and board locks held calling this */
1434                         dgap_cmdw(ch, SCFLAG, (u16) cflag, 0);
1435                 }
1436
1437                 /* Handle transition from B0 */   
1438                 if (ch->ch_flags & CH_BAUD0) {
1439                         ch->ch_flags &= ~(CH_BAUD0);
1440                         ch->ch_mval |= (D_RTS(ch)|D_DTR(ch));
1441                 }
1442                 mval = D_DTR(ch) | D_RTS(ch);
1443         }
1444
1445         /*
1446          * Get input flags.
1447          */
1448         iflag = ch->ch_c_iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | IXON | IXANY | IXOFF);
1449
1450         if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) {
1451                 iflag &= ~(IXON | IXOFF);
1452                 ch->ch_c_iflag &= ~(IXON | IXOFF);
1453         }
1454
1455         /*
1456          * Only the IBM Xr card can switch between
1457          * 232 and 422 modes on the fly
1458          */
1459         if (bd->device == PCI_DEVICE_XR_IBM_DID) {
1460                 if (ch->ch_digi.digi_flags & DIGI_422)
1461                         dgap_cmdb(ch, SCOMMODE, MODE_422, 0, 0);
1462                 else
1463                         dgap_cmdb(ch, SCOMMODE, MODE_232, 0, 0);
1464         }
1465
1466         if (ch->ch_digi.digi_flags & DIGI_ALTPIN)
1467                 iflag |= IALTPIN ;
1468
1469         if (iflag != ch->ch_fepiflag) {
1470                 ch->ch_fepiflag = iflag;
1471
1472                 /* Okay to have channel and board locks held calling this */
1473                 dgap_cmdw(ch, SIFLAG, (u16) ch->ch_fepiflag, 0);
1474         }
1475
1476         /*
1477          * Select hardware handshaking.
1478          */
1479         hflow = 0;
1480
1481         if (ch->ch_c_cflag & CRTSCTS) {
1482                 hflow |= (D_RTS(ch) | D_CTS(ch));
1483         }
1484         if (ch->ch_digi.digi_flags & RTSPACE)
1485                 hflow |= D_RTS(ch);
1486         if (ch->ch_digi.digi_flags & DTRPACE)
1487                 hflow |= D_DTR(ch);  
1488         if (ch->ch_digi.digi_flags & CTSPACE)
1489                 hflow |= D_CTS(ch);
1490         if (ch->ch_digi.digi_flags & DSRPACE)
1491                 hflow |= D_DSR(ch);
1492         if (ch->ch_digi.digi_flags & DCDPACE)
1493                 hflow |= D_CD(ch);
1494
1495         if (hflow != ch->ch_hflow) {
1496                 ch->ch_hflow = hflow;
1497
1498                 /* Okay to have channel and board locks held calling this */
1499                 dgap_cmdb(ch, SHFLOW, (uchar) hflow, 0xff, 0);
1500         }
1501
1502
1503         /*
1504          * Set RTS and/or DTR Toggle if needed, but only if product is FEP5+ based.
1505          */
1506         if (bd->bd_flags & BD_FEP5PLUS) {
1507                 u16 hflow2 = 0;
1508                 if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
1509                         hflow2 |= (D_RTS(ch));
1510                 }
1511                 if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
1512                         hflow2 |= (D_DTR(ch));
1513                 }
1514
1515                 dgap_cmdw_ext(ch, 0xff03, hflow2, 0);
1516         }
1517
1518         /*
1519          * Set modem control lines.  
1520          */
1521
1522         mval ^= ch->ch_mforce & (mval ^ ch->ch_mval);
1523
1524         DPR_PARAM(("dgap_param: mval: %x ch_mforce: %x ch_mval: %x ch_mostat: %x\n",
1525                 mval, ch->ch_mforce, ch->ch_mval, ch->ch_mostat));
1526
1527         if (ch->ch_mostat ^ mval) {
1528                 ch->ch_mostat = mval;
1529
1530                 /* Okay to have channel and board locks held calling this */
1531                 DPR_PARAM(("dgap_param: Sending SMODEM mval: %x\n", mval));
1532                 dgap_cmdb(ch, SMODEM, (uchar) mval, D_RTS(ch)|D_DTR(ch), 0);
1533         }
1534
1535         /*
1536          * Read modem signals, and then call carrier function.             
1537          */
1538         ch->ch_mistat = readb(&(bs->m_stat));
1539         dgap_carrier(ch);
1540
1541         /*      
1542          * Set the start and stop characters.
1543          */
1544         if (ch->ch_startc != ch->ch_fepstartc || ch->ch_stopc != ch->ch_fepstopc) {
1545                 ch->ch_fepstartc = ch->ch_startc;
1546                 ch->ch_fepstopc =  ch->ch_stopc;
1547
1548                 /* Okay to have channel and board locks held calling this */
1549                 dgap_cmdb(ch, SFLOWC, ch->ch_fepstartc, ch->ch_fepstopc, 0);
1550         }
1551
1552         /*
1553          * Set the Auxiliary start and stop characters.
1554          */     
1555         if (ch->ch_astartc != ch->ch_fepastartc || ch->ch_astopc != ch->ch_fepastopc) {
1556                 ch->ch_fepastartc = ch->ch_astartc;
1557                 ch->ch_fepastopc = ch->ch_astopc;
1558
1559                 /* Okay to have channel and board locks held calling this */
1560                 dgap_cmdb(ch, SAFLOWC, ch->ch_fepastartc, ch->ch_fepastopc, 0);
1561         }
1562
1563         DPR_PARAM(("param finish\n"));
1564
1565         return (0);
1566 }
1567
1568
1569 /*
1570  * dgap_parity_scan()
1571  *
1572  * Convert the FEP5 way of reporting parity errors and breaks into
1573  * the Linux line discipline way.
1574  */
1575 void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf, unsigned char *fbuf, int *len)
1576 {
1577         int l = *len;
1578         int count = 0;
1579         unsigned char *in, *cout, *fout;
1580         unsigned char c;
1581
1582         in = cbuf;
1583         cout = cbuf;
1584         fout = fbuf;
1585
1586         DPR_PSCAN(("dgap_parity_scan start\n"));
1587
1588         if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
1589                 return;
1590
1591         while (l--) {
1592                 c = *in++;
1593                 switch (ch->pscan_state) {
1594                 default:
1595                         /* reset to sanity and fall through */
1596                         ch->pscan_state = 0;
1597
1598                 case 0:
1599                         /* No FF seen yet */
1600                         if (c == (unsigned char) '\377') {
1601                                 /* delete this character from stream */
1602                                 ch->pscan_state = 1;
1603                         } else {
1604                                 *cout++ = c;
1605                                 *fout++ = TTY_NORMAL;
1606                                 count += 1;
1607                         }
1608                         break;
1609
1610                 case 1:
1611                         /* first FF seen */
1612                         if (c == (unsigned char) '\377') {
1613                                 /* doubled ff, transform to single ff */
1614                                 *cout++ = c;
1615                                 *fout++ = TTY_NORMAL;
1616                                 count += 1;
1617                                 ch->pscan_state = 0;
1618                         } else {
1619                                 /* save value examination in next state */
1620                                 ch->pscan_savechar = c;
1621                                 ch->pscan_state = 2; 
1622                         }
1623                         break;
1624
1625                 case 2:
1626                         /* third character of ff sequence */
1627
1628                         *cout++ = c;
1629
1630                         if (ch->pscan_savechar == 0x0) {
1631
1632                                 if (c == 0x0) {
1633                                         DPR_PSCAN(("dgap_parity_scan in 3rd char of ff seq. c: %x setting break.\n", c));
1634                                         ch->ch_err_break++;
1635                                         *fout++ = TTY_BREAK;
1636                                 }
1637                                 else {
1638                                         DPR_PSCAN(("dgap_parity_scan in 3rd char of ff seq. c: %x setting parity.\n", c));
1639                                         ch->ch_err_parity++;
1640                                         *fout++ = TTY_PARITY;
1641                                 }
1642                         }
1643                         else {
1644                                 DPR_PSCAN(("%s:%d Logic Error.\n", __FILE__, __LINE__));
1645                         }
1646
1647                         count += 1;
1648                         ch->pscan_state = 0;
1649                 }       
1650         }
1651         *len = count;
1652         DPR_PSCAN(("dgap_parity_scan finish\n"));
1653 }
1654
1655
1656
1657
1658 /*=======================================================================
1659  *
1660  *      dgap_event - FEP to host event processing routine.
1661  *
1662  *              bd     - Board of current event.
1663  *
1664  *=======================================================================*/
1665 static int dgap_event(struct board_t *bd)
1666 {
1667         struct channel_t *ch;
1668         ulong           lock_flags;
1669         ulong           lock_flags2;
1670         struct bs_t     *bs;
1671         uchar           *event;
1672         uchar           *vaddr = NULL;
1673         struct ev_t     *eaddr = NULL;
1674         uint            head;
1675         uint            tail;
1676         int             port;
1677         int             reason;
1678         int             modem;
1679         int             b1;
1680
1681         if (!bd || bd->magic != DGAP_BOARD_MAGIC)
1682                 return (-ENXIO);
1683
1684         DGAP_LOCK(bd->bd_lock, lock_flags);
1685
1686         vaddr = bd->re_map_membase;
1687
1688         if (!vaddr) {
1689                 DGAP_UNLOCK(bd->bd_lock, lock_flags);
1690                 return (-ENXIO);
1691         }
1692
1693         eaddr = (struct ev_t *) (vaddr + EVBUF);
1694
1695         /* Get our head and tail */
1696         head = readw(&(eaddr->ev_head));
1697         tail = readw(&(eaddr->ev_tail));
1698
1699         /*
1700          * Forget it if pointers out of range.
1701          */
1702
1703         if (head >= EVMAX - EVSTART || tail >= EVMAX - EVSTART ||
1704             (head | tail) & 03) {
1705                 DPR_EVENT(("should be calling xxfail %d\n", __LINE__));
1706                 /* Let go of board lock */
1707                 DGAP_UNLOCK(bd->bd_lock, lock_flags);
1708                 return (-ENXIO);
1709         }
1710
1711         /*
1712          * Loop to process all the events in the buffer.
1713          */
1714         while (tail != head) {
1715
1716                 /*
1717                  * Get interrupt information.
1718                  */
1719
1720                 event = bd->re_map_membase + tail + EVSTART;
1721
1722                 port   = event[0];
1723                 reason = event[1];
1724                 modem  = event[2];
1725                 b1     = event[3];
1726
1727                 DPR_EVENT(("event: jiffies: %ld port: %d reason: %x modem: %x\n",
1728                         jiffies, port, reason, modem));
1729
1730                 /*
1731                  * Make sure the interrupt is valid.
1732                  */
1733                 if ( port >= bd->nasync) {
1734                         goto next;
1735                 }
1736
1737                 if (!(reason & (IFMODEM | IFBREAK | IFTLW | IFTEM | IFDATA))) {
1738                         goto next;
1739                 }
1740
1741                 ch = bd->channels[port];
1742
1743                 if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
1744                         goto next;
1745                 }
1746
1747                 /*
1748                  * If we have made it here, the event was valid.
1749                  * Lock down the channel.
1750                  */
1751                 DGAP_LOCK(ch->ch_lock, lock_flags2);
1752
1753                 bs = ch->ch_bs;
1754
1755                 if (!bs) {
1756                         DGAP_UNLOCK(ch->ch_lock, lock_flags2);
1757                         goto next;
1758                 }
1759
1760                 /*
1761                  * Process received data.
1762                  */
1763                 if (reason & IFDATA) {
1764
1765                         /*
1766                          * ALL LOCKS *MUST* BE DROPPED BEFORE CALLING INPUT!
1767                          * input could send some data to ld, which in turn
1768                          * could do a callback to one of our other functions.
1769                          */
1770                         DGAP_UNLOCK(ch->ch_lock, lock_flags2);
1771                         DGAP_UNLOCK(bd->bd_lock, lock_flags);
1772
1773                         dgap_input(ch);
1774
1775                         DGAP_LOCK(bd->bd_lock, lock_flags);
1776                         DGAP_LOCK(ch->ch_lock, lock_flags2);
1777
1778                         if (ch->ch_flags & CH_RACTIVE)
1779                                 ch->ch_flags |= CH_RENABLE;
1780                         else
1781                                 writeb(1, &(bs->idata));
1782
1783                         if (ch->ch_flags & CH_RWAIT) {
1784                                 ch->ch_flags &= ~CH_RWAIT;
1785
1786                                 wake_up_interruptible(&ch->ch_tun.un_flags_wait);
1787                         }
1788                 }
1789
1790                 /*
1791                  * Process Modem change signals. 
1792                  */
1793                 if (reason & IFMODEM) {
1794                         ch->ch_mistat = modem;
1795                         dgap_carrier(ch);
1796                 }
1797
1798                 /*
1799                  * Process break.
1800                  */
1801                 if (reason & IFBREAK) {
1802
1803                         DPR_EVENT(("got IFBREAK\n"));
1804
1805                         if (ch->ch_tun.un_tty) {
1806                                 /* A break has been indicated */
1807                                 ch->ch_err_break++;
1808                                 tty_buffer_request_room(ch->ch_tun.un_tty->port, 1);
1809                                 tty_insert_flip_char(ch->ch_tun.un_tty->port, 0, TTY_BREAK);
1810                                 tty_flip_buffer_push(ch->ch_tun.un_tty->port);
1811                         }
1812                 }
1813
1814                 /*
1815                  * Process Transmit low.
1816                  */
1817                 if (reason & IFTLW) {
1818
1819                         DPR_EVENT(("event: got low event\n"));
1820
1821                         if (ch->ch_tun.un_flags & UN_LOW) {
1822                                 ch->ch_tun.un_flags &= ~UN_LOW;
1823
1824                                 if (ch->ch_tun.un_flags & UN_ISOPEN) {
1825                                         if ((ch->ch_tun.un_tty->flags & 
1826                                            (1 << TTY_DO_WRITE_WAKEUP)) &&
1827 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
1828                                                 ch->ch_tun.un_tty->ldisc->ops->write_wakeup)
1829 #else
1830                                                 ch->ch_tun.un_tty->ldisc.ops->write_wakeup)
1831 #endif
1832                                         {
1833                                                 DGAP_UNLOCK(ch->ch_lock, lock_flags2);
1834                                                 DGAP_UNLOCK(bd->bd_lock, lock_flags);
1835 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
1836                                                 (ch->ch_tun.un_tty->ldisc->ops->write_wakeup)(ch->ch_tun.un_tty);
1837 #else
1838                                                 (ch->ch_tun.un_tty->ldisc.ops->write_wakeup)(ch->ch_tun.un_tty);
1839 #endif
1840                                                 DGAP_LOCK(bd->bd_lock, lock_flags);
1841                                                 DGAP_LOCK(ch->ch_lock, lock_flags2);
1842                                         }
1843                                         wake_up_interruptible(&ch->ch_tun.un_tty->write_wait);
1844                                         wake_up_interruptible(&ch->ch_tun.un_flags_wait);
1845
1846                                         DPR_EVENT(("event: Got low event. jiffies: %lu\n", jiffies));
1847                                 }
1848                         }
1849
1850                         if (ch->ch_pun.un_flags & UN_LOW) {
1851                                 ch->ch_pun.un_flags &= ~UN_LOW;
1852                                 if (ch->ch_pun.un_flags & UN_ISOPEN) {
1853                                         if ((ch->ch_pun.un_tty->flags & 
1854                                            (1 << TTY_DO_WRITE_WAKEUP)) &&
1855 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
1856                                                 ch->ch_pun.un_tty->ldisc->ops->write_wakeup)
1857 #else
1858                                                 ch->ch_pun.un_tty->ldisc.ops->write_wakeup)
1859 #endif
1860                                         {
1861                                                 DGAP_UNLOCK(ch->ch_lock, lock_flags2);
1862                                                 DGAP_UNLOCK(bd->bd_lock, lock_flags);
1863 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
1864                                                 (ch->ch_pun.un_tty->ldisc->ops->write_wakeup)(ch->ch_pun.un_tty);
1865 #else
1866                                                 (ch->ch_pun.un_tty->ldisc.ops->write_wakeup)(ch->ch_pun.un_tty);
1867 #endif
1868                                                 DGAP_LOCK(bd->bd_lock, lock_flags);
1869                                                 DGAP_LOCK(ch->ch_lock, lock_flags2);
1870                                         }
1871                                         wake_up_interruptible(&ch->ch_pun.un_tty->write_wait);
1872                                         wake_up_interruptible(&ch->ch_pun.un_flags_wait);
1873                                 }
1874                         }
1875
1876                         if (ch->ch_flags & CH_WLOW) {
1877                                 ch->ch_flags &= ~CH_WLOW;
1878                                 wake_up_interruptible(&ch->ch_flags_wait);
1879                         }
1880                 }
1881
1882                 /*
1883                  * Process Transmit empty.
1884                  */
1885                 if (reason & IFTEM) {
1886                         DPR_EVENT(("event: got empty event\n"));
1887
1888                         if (ch->ch_tun.un_flags & UN_EMPTY) {
1889                                 ch->ch_tun.un_flags &= ~UN_EMPTY;
1890                                 if (ch->ch_tun.un_flags & UN_ISOPEN) {
1891                                         if ((ch->ch_tun.un_tty->flags & 
1892                                            (1 << TTY_DO_WRITE_WAKEUP)) &&
1893 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
1894                                                 ch->ch_tun.un_tty->ldisc->ops->write_wakeup)
1895 #else
1896                                                 ch->ch_tun.un_tty->ldisc.ops->write_wakeup)
1897 #endif
1898                                         {
1899                                                 DGAP_UNLOCK(ch->ch_lock, lock_flags2);
1900                                                 DGAP_UNLOCK(bd->bd_lock, lock_flags);
1901 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
1902                                                 (ch->ch_tun.un_tty->ldisc->ops->write_wakeup)(ch->ch_tun.un_tty);
1903 #else
1904                                                 (ch->ch_tun.un_tty->ldisc.ops->write_wakeup)(ch->ch_tun.un_tty);
1905 #endif
1906                                                 DGAP_LOCK(bd->bd_lock, lock_flags);
1907                                                 DGAP_LOCK(ch->ch_lock, lock_flags2);
1908                                         }
1909                                         wake_up_interruptible(&ch->ch_tun.un_tty->write_wait);
1910                                         wake_up_interruptible(&ch->ch_tun.un_flags_wait);
1911                                 }
1912                         }
1913
1914                         if (ch->ch_pun.un_flags & UN_EMPTY) {
1915                                 ch->ch_pun.un_flags &= ~UN_EMPTY;
1916                                 if (ch->ch_pun.un_flags & UN_ISOPEN) {
1917                                         if ((ch->ch_pun.un_tty->flags & 
1918                                            (1 << TTY_DO_WRITE_WAKEUP)) &&
1919 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
1920                                                 ch->ch_pun.un_tty->ldisc->ops->write_wakeup)
1921 #else
1922                                                 ch->ch_pun.un_tty->ldisc.ops->write_wakeup)
1923 #endif
1924                                         {
1925                                                 DGAP_UNLOCK(ch->ch_lock, lock_flags2);
1926                                                 DGAP_UNLOCK(bd->bd_lock, lock_flags);
1927 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
1928                                                 (ch->ch_pun.un_tty->ldisc->ops->write_wakeup)(ch->ch_pun.un_tty);
1929 #else
1930                                                 (ch->ch_pun.un_tty->ldisc.ops->write_wakeup)(ch->ch_pun.un_tty);
1931 #endif
1932                                                 DGAP_LOCK(bd->bd_lock, lock_flags);
1933                                                 DGAP_LOCK(ch->ch_lock, lock_flags2);
1934                                         }
1935                                         wake_up_interruptible(&ch->ch_pun.un_tty->write_wait);
1936                                         wake_up_interruptible(&ch->ch_pun.un_flags_wait);
1937                                 }
1938                         }
1939
1940
1941                         if (ch->ch_flags & CH_WEMPTY) {
1942                                 ch->ch_flags &= ~CH_WEMPTY;
1943                                 wake_up_interruptible(&ch->ch_flags_wait);
1944                         }
1945                 }
1946
1947                 DGAP_UNLOCK(ch->ch_lock, lock_flags2);
1948
1949 next:
1950                 tail = (tail + 4) & (EVMAX - EVSTART - 4);
1951         }
1952
1953         writew(tail, &(eaddr->ev_tail));
1954         DGAP_UNLOCK(bd->bd_lock, lock_flags);
1955
1956         return (0);
1957 }