1#undef BLOCKMOVE
2#define Z_WAKE
3#undef Z_EXT_CHARS_IN_BUFFER
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#define CY_VERSION "2.6"
25
26
27
28
29
30#define NR_CARDS 4
31
32
33
34
35
36
37#define NR_PORTS 256
38
39#define ZO_V1 0
40#define ZO_V2 1
41#define ZE_V1 2
42
43#define SERIAL_PARANOIA_CHECK
44#undef CY_DEBUG_OPEN
45#undef CY_DEBUG_THROTTLE
46#undef CY_DEBUG_OTHER
47#undef CY_DEBUG_IO
48#undef CY_DEBUG_COUNT
49#undef CY_DEBUG_DTR
50#undef CY_DEBUG_WAIT_UNTIL_SENT
51#undef CY_DEBUG_INTERRUPTS
52#undef CY_16Y_HACK
53#undef CY_ENABLE_MONITORING
54#undef CY_PCI_DEBUG
55
56
57
58
59#include <linux/module.h>
60#include <linux/errno.h>
61#include <linux/signal.h>
62#include <linux/sched.h>
63#include <linux/timer.h>
64#include <linux/interrupt.h>
65#include <linux/tty.h>
66#include <linux/tty_flip.h>
67#include <linux/serial.h>
68#include <linux/major.h>
69#include <linux/string.h>
70#include <linux/fcntl.h>
71#include <linux/ptrace.h>
72#include <linux/cyclades.h>
73#include <linux/mm.h>
74#include <linux/ioport.h>
75#include <linux/init.h>
76#include <linux/delay.h>
77#include <linux/spinlock.h>
78#include <linux/bitops.h>
79#include <linux/firmware.h>
80#include <linux/device.h>
81#include <linux/slab.h>
82
83#include <linux/io.h>
84#include <linux/uaccess.h>
85
86#include <linux/kernel.h>
87#include <linux/pci.h>
88
89#include <linux/stat.h>
90#include <linux/proc_fs.h>
91#include <linux/seq_file.h>
92
93static void cy_send_xchar(struct tty_struct *tty, char ch);
94
95#ifndef SERIAL_XMIT_SIZE
96#define SERIAL_XMIT_SIZE (min(PAGE_SIZE, 4096))
97#endif
98
99#define STD_COM_FLAGS (0)
100
101
102#define ZL_MAX_BLOCKS 16
103#define DRIVER_VERSION 0x02010203
104#define RAM_SIZE 0x80000
105
106enum zblock_type {
107 ZBLOCK_PRG = 0,
108 ZBLOCK_FPGA = 1
109};
110
111struct zfile_header {
112 char name[64];
113 char date[32];
114 char aux[32];
115 u32 n_config;
116 u32 config_offset;
117 u32 n_blocks;
118 u32 block_offset;
119 u32 reserved[9];
120} __attribute__ ((packed));
121
122struct zfile_config {
123 char name[64];
124 u32 mailbox;
125 u32 function;
126 u32 n_blocks;
127 u32 block_list[ZL_MAX_BLOCKS];
128} __attribute__ ((packed));
129
130struct zfile_block {
131 u32 type;
132 u32 file_offset;
133 u32 ram_offset;
134 u32 size;
135} __attribute__ ((packed));
136
137static struct tty_driver *cy_serial_driver;
138
139#ifdef CONFIG_ISA
140
141
142
143
144
145
146
147static unsigned int cy_isa_addresses[] = {
148 0xD0000,
149 0xD2000,
150 0xD4000,
151 0xD6000,
152 0xD8000,
153 0xDA000,
154 0xDC000,
155 0xDE000,
156 0, 0, 0, 0, 0, 0, 0, 0
157};
158
159#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
160
161static long maddr[NR_CARDS];
162static int irq[NR_CARDS];
163
164module_param_array(maddr, long, NULL, 0);
165module_param_array(irq, int, NULL, 0);
166
167#endif
168
169
170
171
172static struct cyclades_card cy_card[NR_CARDS];
173
174static int cy_next_channel;
175
176
177
178
179
180
181
182
183
184
185static const int baud_table[] = {
186 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
187 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000,
188 230400, 0
189};
190
191static const char baud_co_25[] = {
192
193
194 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
195 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
196};
197
198static const char baud_bpr_25[] = {
199 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
200 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15
201};
202
203static const char baud_co_60[] = {
204
205
206 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
207 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00
209};
210
211static const char baud_bpr_60[] = {
212 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62,
213 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32,
214 0x21
215};
216
217static const char baud_cor3[] = {
218 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
219 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07,
220 0x07
221};
222
223
224
225
226
227
228
229
230
231
232
233
234static const char rflow_thr[] = {
235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
237 0x0a
238};
239
240
241
242
243static const unsigned int cy_chip_offset[] = { 0x0000,
244 0x0400,
245 0x0800,
246 0x0C00,
247 0x0200,
248 0x0600,
249 0x0A00,
250 0x0E00
251};
252
253
254
255#ifdef CONFIG_PCI
256static const struct pci_device_id cy_pci_dev_id[] = {
257
258 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) },
259
260 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Hi) },
261
262 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Lo) },
263
264 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Hi) },
265
266 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Lo) },
267
268 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Hi) },
269
270 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Lo) },
271
272 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Hi) },
273 { }
274};
275MODULE_DEVICE_TABLE(pci, cy_pci_dev_id);
276#endif
277
278static void cy_start(struct tty_struct *);
279static void cy_set_line_char(struct cyclades_port *, struct tty_struct *);
280static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
281#ifdef CONFIG_ISA
282static unsigned detect_isa_irq(void __iomem *);
283#endif
284
285#ifndef CONFIG_CYZ_INTR
286static void cyz_poll(unsigned long);
287
288
289static long cyz_polling_cycle = CZ_DEF_POLL;
290
291static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0);
292
293#else
294static void cyz_rx_restart(unsigned long);
295static struct timer_list cyz_rx_full_timer[NR_PORTS];
296#endif
297
298static inline void cyy_writeb(struct cyclades_port *port, u32 reg, u8 val)
299{
300 struct cyclades_card *card = port->card;
301
302 cy_writeb(port->u.cyy.base_addr + (reg << card->bus_index), val);
303}
304
305static inline u8 cyy_readb(struct cyclades_port *port, u32 reg)
306{
307 struct cyclades_card *card = port->card;
308
309 return readb(port->u.cyy.base_addr + (reg << card->bus_index));
310}
311
312static inline bool cy_is_Z(struct cyclades_card *card)
313{
314 return card->num_chips == (unsigned int)-1;
315}
316
317static inline bool __cyz_fpga_loaded(struct RUNTIME_9060 __iomem *ctl_addr)
318{
319 return readl(&ctl_addr->init_ctrl) & (1 << 17);
320}
321
322static inline bool cyz_fpga_loaded(struct cyclades_card *card)
323{
324 return __cyz_fpga_loaded(card->ctl_addr.p9060);
325}
326
327static inline bool cyz_is_loaded(struct cyclades_card *card)
328{
329 struct FIRM_ID __iomem *fw_id = card->base_addr + ID_ADDRESS;
330
331 return (card->hw_ver == ZO_V1 || cyz_fpga_loaded(card)) &&
332 readl(&fw_id->signature) == ZFIRM_ID;
333}
334
335static inline int serial_paranoia_check(struct cyclades_port *info,
336 const char *name, const char *routine)
337{
338#ifdef SERIAL_PARANOIA_CHECK
339 if (!info) {
340 printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) "
341 "in %s\n", name, routine);
342 return 1;
343 }
344
345 if (info->magic != CYCLADES_MAGIC) {
346 printk(KERN_WARNING "cyc Warning: bad magic number for serial "
347 "struct (%s) in %s\n", name, routine);
348 return 1;
349 }
350#endif
351 return 0;
352}
353
354
355
356
357
358
359
360
361
362
363
364static int __cyy_issue_cmd(void __iomem *base_addr, u8 cmd, int index)
365{
366 void __iomem *ccr = base_addr + (CyCCR << index);
367 unsigned int i;
368
369
370 for (i = 0; i < 100; i++) {
371 if (readb(ccr) == 0)
372 break;
373 udelay(10L);
374 }
375
376
377 if (i == 100)
378 return -1;
379
380
381 cy_writeb(ccr, cmd);
382
383 return 0;
384}
385
386static inline int cyy_issue_cmd(struct cyclades_port *port, u8 cmd)
387{
388 return __cyy_issue_cmd(port->u.cyy.base_addr, cmd,
389 port->card->bus_index);
390}
391
392#ifdef CONFIG_ISA
393
394static unsigned detect_isa_irq(void __iomem *address)
395{
396 int irq;
397 unsigned long irqs, flags;
398 int save_xir, save_car;
399 int index = 0;
400
401
402 irq = probe_irq_off(probe_irq_on());
403
404
405 cy_writeb(address + (Cy_ClrIntr << index), 0);
406
407
408 irqs = probe_irq_on();
409
410 msleep(5);
411
412
413 local_irq_save(flags);
414 cy_writeb(address + (CyCAR << index), 0);
415 __cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index);
416
417 cy_writeb(address + (CyCAR << index), 0);
418 cy_writeb(address + (CySRER << index),
419 readb(address + (CySRER << index)) | CyTxRdy);
420 local_irq_restore(flags);
421
422
423 msleep(5);
424
425
426 irq = probe_irq_off(irqs);
427
428
429 save_xir = (u_char) readb(address + (CyTIR << index));
430 save_car = readb(address + (CyCAR << index));
431 cy_writeb(address + (CyCAR << index), (save_xir & 0x3));
432 cy_writeb(address + (CySRER << index),
433 readb(address + (CySRER << index)) & ~CyTxRdy);
434 cy_writeb(address + (CyTIR << index), (save_xir & 0x3f));
435 cy_writeb(address + (CyCAR << index), (save_car));
436 cy_writeb(address + (Cy_ClrIntr << index), 0);
437
438
439 return (irq > 0) ? irq : 0;
440}
441#endif
442
443static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
444 void __iomem *base_addr)
445{
446 struct cyclades_port *info;
447 struct tty_struct *tty;
448 int len, index = cinfo->bus_index;
449 u8 ivr, save_xir, channel, save_car, data, char_count;
450
451#ifdef CY_DEBUG_INTERRUPTS
452 printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
453#endif
454
455 save_xir = readb(base_addr + (CyRIR << index));
456 channel = save_xir & CyIRChannel;
457 info = &cinfo->ports[channel + chip * 4];
458 save_car = cyy_readb(info, CyCAR);
459 cyy_writeb(info, CyCAR, save_xir);
460 ivr = cyy_readb(info, CyRIVR) & CyIVRMask;
461
462 tty = tty_port_tty_get(&info->port);
463
464 if (tty == NULL) {
465 if (ivr == CyIVRRxEx) {
466 data = cyy_readb(info, CyRDSR);
467 } else {
468 char_count = cyy_readb(info, CyRDCR);
469 while (char_count--)
470 data = cyy_readb(info, CyRDSR);
471 }
472 goto end;
473 }
474
475 if (ivr == CyIVRRxEx) {
476 data = cyy_readb(info, CyRDSR);
477
478
479 if (data & CyBREAK)
480 info->icount.brk++;
481 else if (data & CyFRAME)
482 info->icount.frame++;
483 else if (data & CyPARITY)
484 info->icount.parity++;
485 else if (data & CyOVERRUN)
486 info->icount.overrun++;
487
488 if (data & info->ignore_status_mask) {
489 info->icount.rx++;
490 tty_kref_put(tty);
491 return;
492 }
493 if (tty_buffer_request_room(tty, 1)) {
494 if (data & info->read_status_mask) {
495 if (data & CyBREAK) {
496 tty_insert_flip_char(tty,
497 cyy_readb(info, CyRDSR),
498 TTY_BREAK);
499 info->icount.rx++;
500 if (info->port.flags & ASYNC_SAK)
501 do_SAK(tty);
502 } else if (data & CyFRAME) {
503 tty_insert_flip_char(tty,
504 cyy_readb(info, CyRDSR),
505 TTY_FRAME);
506 info->icount.rx++;
507 info->idle_stats.frame_errs++;
508 } else if (data & CyPARITY) {
509
510 tty_insert_flip_char(tty,
511 cyy_readb(info, CyRDSR),
512 TTY_PARITY);
513 info->icount.rx++;
514 info->idle_stats.parity_errs++;
515 } else if (data & CyOVERRUN) {
516 tty_insert_flip_char(tty, 0,
517 TTY_OVERRUN);
518 info->icount.rx++;
519
520
521
522
523 tty_insert_flip_char(tty,
524 cyy_readb(info, CyRDSR),
525 TTY_FRAME);
526 info->icount.rx++;
527 info->idle_stats.overruns++;
528
529
530
531
532 } else {
533 tty_insert_flip_char(tty, 0,
534 TTY_NORMAL);
535 info->icount.rx++;
536 }
537 } else {
538 tty_insert_flip_char(tty, 0, TTY_NORMAL);
539 info->icount.rx++;
540 }
541 } else {
542
543
544 info->icount.buf_overrun++;
545 info->idle_stats.overruns++;
546 }
547 } else {
548
549 char_count = cyy_readb(info, CyRDCR);
550
551#ifdef CY_ENABLE_MONITORING
552 ++info->mon.int_count;
553 info->mon.char_count += char_count;
554 if (char_count > info->mon.char_max)
555 info->mon.char_max = char_count;
556 info->mon.char_last = char_count;
557#endif
558 len = tty_buffer_request_room(tty, char_count);
559 while (len--) {
560 data = cyy_readb(info, CyRDSR);
561 tty_insert_flip_char(tty, data, TTY_NORMAL);
562 info->idle_stats.recv_bytes++;
563 info->icount.rx++;
564#ifdef CY_16Y_HACK
565 udelay(10L);
566#endif
567 }
568 info->idle_stats.recv_idle = jiffies;
569 }
570 tty_schedule_flip(tty);
571 tty_kref_put(tty);
572end:
573
574 cyy_writeb(info, CyRIR, save_xir & 0x3f);
575 cyy_writeb(info, CyCAR, save_car);
576}
577
578static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
579 void __iomem *base_addr)
580{
581 struct cyclades_port *info;
582 struct tty_struct *tty;
583 int char_count, index = cinfo->bus_index;
584 u8 save_xir, channel, save_car, outch;
585
586
587
588
589#ifdef CY_DEBUG_INTERRUPTS
590 printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
591#endif
592
593
594 save_xir = readb(base_addr + (CyTIR << index));
595 channel = save_xir & CyIRChannel;
596 save_car = readb(base_addr + (CyCAR << index));
597 cy_writeb(base_addr + (CyCAR << index), save_xir);
598
599 info = &cinfo->ports[channel + chip * 4];
600 tty = tty_port_tty_get(&info->port);
601 if (tty == NULL) {
602 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy);
603 goto end;
604 }
605
606
607 char_count = info->xmit_fifo_size;
608
609 if (info->x_char) {
610 outch = info->x_char;
611 cyy_writeb(info, CyTDR, outch);
612 char_count--;
613 info->icount.tx++;
614 info->x_char = 0;
615 }
616
617 if (info->breakon || info->breakoff) {
618 if (info->breakon) {
619 cyy_writeb(info, CyTDR, 0);
620 cyy_writeb(info, CyTDR, 0x81);
621 info->breakon = 0;
622 char_count -= 2;
623 }
624 if (info->breakoff) {
625 cyy_writeb(info, CyTDR, 0);
626 cyy_writeb(info, CyTDR, 0x83);
627 info->breakoff = 0;
628 char_count -= 2;
629 }
630 }
631
632 while (char_count-- > 0) {
633 if (!info->xmit_cnt) {
634 if (cyy_readb(info, CySRER) & CyTxMpty) {
635 cyy_writeb(info, CySRER,
636 cyy_readb(info, CySRER) & ~CyTxMpty);
637 } else {
638 cyy_writeb(info, CySRER, CyTxMpty |
639 (cyy_readb(info, CySRER) & ~CyTxRdy));
640 }
641 goto done;
642 }
643 if (info->port.xmit_buf == NULL) {
644 cyy_writeb(info, CySRER,
645 cyy_readb(info, CySRER) & ~CyTxRdy);
646 goto done;
647 }
648 if (tty->stopped || tty->hw_stopped) {
649 cyy_writeb(info, CySRER,
650 cyy_readb(info, CySRER) & ~CyTxRdy);
651 goto done;
652 }
653
654
655
656
657
658
659
660
661
662 outch = info->port.xmit_buf[info->xmit_tail];
663 if (outch) {
664 info->xmit_cnt--;
665 info->xmit_tail = (info->xmit_tail + 1) &
666 (SERIAL_XMIT_SIZE - 1);
667 cyy_writeb(info, CyTDR, outch);
668 info->icount.tx++;
669 } else {
670 if (char_count > 1) {
671 info->xmit_cnt--;
672 info->xmit_tail = (info->xmit_tail + 1) &
673 (SERIAL_XMIT_SIZE - 1);
674 cyy_writeb(info, CyTDR, outch);
675 cyy_writeb(info, CyTDR, 0);
676 info->icount.tx++;
677 char_count--;
678 }
679 }
680 }
681
682done:
683 tty_wakeup(tty);
684 tty_kref_put(tty);
685end:
686
687 cyy_writeb(info, CyTIR, save_xir & 0x3f);
688 cyy_writeb(info, CyCAR, save_car);
689}
690
691static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
692 void __iomem *base_addr)
693{
694 struct cyclades_port *info;
695 struct tty_struct *tty;
696 int index = cinfo->bus_index;
697 u8 save_xir, channel, save_car, mdm_change, mdm_status;
698
699
700 save_xir = readb(base_addr + (CyMIR << index));
701 channel = save_xir & CyIRChannel;
702 info = &cinfo->ports[channel + chip * 4];
703 save_car = cyy_readb(info, CyCAR);
704 cyy_writeb(info, CyCAR, save_xir);
705
706 mdm_change = cyy_readb(info, CyMISR);
707 mdm_status = cyy_readb(info, CyMSVR1);
708
709 tty = tty_port_tty_get(&info->port);
710 if (!tty)
711 goto end;
712
713 if (mdm_change & CyANY_DELTA) {
714
715 if (mdm_change & CyDCD)
716 info->icount.dcd++;
717 if (mdm_change & CyCTS)
718 info->icount.cts++;
719 if (mdm_change & CyDSR)
720 info->icount.dsr++;
721 if (mdm_change & CyRI)
722 info->icount.rng++;
723
724 wake_up_interruptible(&info->port.delta_msr_wait);
725 }
726
727 if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) {
728 if (mdm_status & CyDCD)
729 wake_up_interruptible(&info->port.open_wait);
730 else
731 tty_hangup(tty);
732 }
733 if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) {
734 if (tty->hw_stopped) {
735 if (mdm_status & CyCTS) {
736
737
738 tty->hw_stopped = 0;
739 cyy_writeb(info, CySRER,
740 cyy_readb(info, CySRER) | CyTxRdy);
741 tty_wakeup(tty);
742 }
743 } else {
744 if (!(mdm_status & CyCTS)) {
745
746
747 tty->hw_stopped = 1;
748 cyy_writeb(info, CySRER,
749 cyy_readb(info, CySRER) & ~CyTxRdy);
750 }
751 }
752 }
753
754
755
756
757 tty_kref_put(tty);
758end:
759
760 cyy_writeb(info, CyMIR, save_xir & 0x3f);
761 cyy_writeb(info, CyCAR, save_car);
762}
763
764
765
766
767
768static irqreturn_t cyy_interrupt(int irq, void *dev_id)
769{
770 int status;
771 struct cyclades_card *cinfo = dev_id;
772 void __iomem *base_addr, *card_base_addr;
773 unsigned int chip, too_many, had_work;
774 int index;
775
776 if (unlikely(cinfo == NULL)) {
777#ifdef CY_DEBUG_INTERRUPTS
778 printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",
779 irq);
780#endif
781 return IRQ_NONE;
782 }
783
784 card_base_addr = cinfo->base_addr;
785 index = cinfo->bus_index;
786
787
788 if (unlikely(card_base_addr == NULL))
789 return IRQ_HANDLED;
790
791
792
793
794
795
796 do {
797 had_work = 0;
798 for (chip = 0; chip < cinfo->num_chips; chip++) {
799 base_addr = cinfo->base_addr +
800 (cy_chip_offset[chip] << index);
801 too_many = 0;
802 while ((status = readb(base_addr +
803 (CySVRR << index))) != 0x00) {
804 had_work++;
805
806
807
808
809
810 if (1000 < too_many++)
811 break;
812 spin_lock(&cinfo->card_lock);
813 if (status & CySRReceive)
814 cyy_chip_rx(cinfo, chip, base_addr);
815 if (status & CySRTransmit)
816 cyy_chip_tx(cinfo, chip, base_addr);
817 if (status & CySRModem)
818 cyy_chip_modem(cinfo, chip, base_addr);
819 spin_unlock(&cinfo->card_lock);
820 }
821 }
822 } while (had_work);
823
824
825 spin_lock(&cinfo->card_lock);
826 cy_writeb(card_base_addr + (Cy_ClrIntr << index), 0);
827
828 spin_unlock(&cinfo->card_lock);
829 return IRQ_HANDLED;
830}
831
832static void cyy_change_rts_dtr(struct cyclades_port *info, unsigned int set,
833 unsigned int clear)
834{
835 struct cyclades_card *card = info->card;
836 int channel = info->line - card->first_line;
837 u32 rts, dtr, msvrr, msvrd;
838
839 channel &= 0x03;
840
841 if (info->rtsdtr_inv) {
842 msvrr = CyMSVR2;
843 msvrd = CyMSVR1;
844 rts = CyDTR;
845 dtr = CyRTS;
846 } else {
847 msvrr = CyMSVR1;
848 msvrd = CyMSVR2;
849 rts = CyRTS;
850 dtr = CyDTR;
851 }
852 if (set & TIOCM_RTS) {
853 cyy_writeb(info, CyCAR, channel);
854 cyy_writeb(info, msvrr, rts);
855 }
856 if (clear & TIOCM_RTS) {
857 cyy_writeb(info, CyCAR, channel);
858 cyy_writeb(info, msvrr, ~rts);
859 }
860 if (set & TIOCM_DTR) {
861 cyy_writeb(info, CyCAR, channel);
862 cyy_writeb(info, msvrd, dtr);
863#ifdef CY_DEBUG_DTR
864 printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n");
865 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
866 cyy_readb(info, CyMSVR1),
867 cyy_readb(info, CyMSVR2));
868#endif
869 }
870 if (clear & TIOCM_DTR) {
871 cyy_writeb(info, CyCAR, channel);
872 cyy_writeb(info, msvrd, ~dtr);
873#ifdef CY_DEBUG_DTR
874 printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n");
875 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
876 cyy_readb(info, CyMSVR1),
877 cyy_readb(info, CyMSVR2));
878#endif
879 }
880}
881
882
883
884
885
886
887static int
888cyz_fetch_msg(struct cyclades_card *cinfo,
889 __u32 *channel, __u8 *cmd, __u32 *param)
890{
891 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
892 unsigned long loc_doorbell;
893
894 loc_doorbell = readl(&cinfo->ctl_addr.p9060->loc_doorbell);
895 if (loc_doorbell) {
896 *cmd = (char)(0xff & loc_doorbell);
897 *channel = readl(&board_ctrl->fwcmd_channel);
898 *param = (__u32) readl(&board_ctrl->fwcmd_param);
899 cy_writel(&cinfo->ctl_addr.p9060->loc_doorbell, 0xffffffff);
900 return 1;
901 }
902 return 0;
903}
904
905static int
906cyz_issue_cmd(struct cyclades_card *cinfo,
907 __u32 channel, __u8 cmd, __u32 param)
908{
909 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
910 __u32 __iomem *pci_doorbell;
911 unsigned int index;
912
913 if (!cyz_is_loaded(cinfo))
914 return -1;
915
916 index = 0;
917 pci_doorbell = &cinfo->ctl_addr.p9060->pci_doorbell;
918 while ((readl(pci_doorbell) & 0xff) != 0) {
919 if (index++ == 1000)
920 return (int)(readl(pci_doorbell) & 0xff);
921 udelay(50L);
922 }
923 cy_writel(&board_ctrl->hcmd_channel, channel);
924 cy_writel(&board_ctrl->hcmd_param, param);
925 cy_writel(pci_doorbell, (long)cmd);
926
927 return 0;
928}
929
930static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty)
931{
932 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
933 struct cyclades_card *cinfo = info->card;
934 unsigned int char_count;
935 int len;
936#ifdef BLOCKMOVE
937 unsigned char *buf;
938#else
939 char data;
940#endif
941 __u32 rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
942
943 rx_get = new_rx_get = readl(&buf_ctrl->rx_get);
944 rx_put = readl(&buf_ctrl->rx_put);
945 rx_bufsize = readl(&buf_ctrl->rx_bufsize);
946 rx_bufaddr = readl(&buf_ctrl->rx_bufaddr);
947 if (rx_put >= rx_get)
948 char_count = rx_put - rx_get;
949 else
950 char_count = rx_put - rx_get + rx_bufsize;
951
952 if (char_count) {
953#ifdef CY_ENABLE_MONITORING
954 info->mon.int_count++;
955 info->mon.char_count += char_count;
956 if (char_count > info->mon.char_max)
957 info->mon.char_max = char_count;
958 info->mon.char_last = char_count;
959#endif
960 if (tty == NULL) {
961
962 new_rx_get = (new_rx_get + char_count) &
963 (rx_bufsize - 1);
964 info->rflush_count++;
965 } else {
966#ifdef BLOCKMOVE
967
968
969
970 while (1) {
971 len = tty_prepare_flip_string(tty, &buf,
972 char_count);
973 if (!len)
974 break;
975
976 len = min_t(unsigned int, min(len, char_count),
977 rx_bufsize - new_rx_get);
978
979 memcpy_fromio(buf, cinfo->base_addr +
980 rx_bufaddr + new_rx_get, len);
981
982 new_rx_get = (new_rx_get + len) &
983 (rx_bufsize - 1);
984 char_count -= len;
985 info->icount.rx += len;
986 info->idle_stats.recv_bytes += len;
987 }
988#else
989 len = tty_buffer_request_room(tty, char_count);
990 while (len--) {
991 data = readb(cinfo->base_addr + rx_bufaddr +
992 new_rx_get);
993 new_rx_get = (new_rx_get + 1) &
994 (rx_bufsize - 1);
995 tty_insert_flip_char(tty, data, TTY_NORMAL);
996 info->idle_stats.recv_bytes++;
997 info->icount.rx++;
998 }
999#endif
1000#ifdef CONFIG_CYZ_INTR
1001
1002
1003 rx_put = readl(&buf_ctrl->rx_put);
1004 if (rx_put >= rx_get)
1005 char_count = rx_put - rx_get;
1006 else
1007 char_count = rx_put - rx_get + rx_bufsize;
1008 if (char_count >= readl(&buf_ctrl->rx_threshold) &&
1009 !timer_pending(&cyz_rx_full_timer[
1010 info->line]))
1011 mod_timer(&cyz_rx_full_timer[info->line],
1012 jiffies + 1);
1013#endif
1014 info->idle_stats.recv_idle = jiffies;
1015 tty_schedule_flip(tty);
1016 }
1017
1018 cy_writel(&buf_ctrl->rx_get, new_rx_get);
1019 }
1020}
1021
1022static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty)
1023{
1024 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
1025 struct cyclades_card *cinfo = info->card;
1026 u8 data;
1027 unsigned int char_count;
1028#ifdef BLOCKMOVE
1029 int small_count;
1030#endif
1031 __u32 tx_put, tx_get, tx_bufsize, tx_bufaddr;
1032
1033 if (info->xmit_cnt <= 0)
1034 return;
1035
1036 tx_get = readl(&buf_ctrl->tx_get);
1037 tx_put = readl(&buf_ctrl->tx_put);
1038 tx_bufsize = readl(&buf_ctrl->tx_bufsize);
1039 tx_bufaddr = readl(&buf_ctrl->tx_bufaddr);
1040 if (tx_put >= tx_get)
1041 char_count = tx_get - tx_put - 1 + tx_bufsize;
1042 else
1043 char_count = tx_get - tx_put - 1;
1044
1045 if (char_count) {
1046
1047 if (tty == NULL)
1048 goto ztxdone;
1049
1050 if (info->x_char) {
1051 data = info->x_char;
1052
1053 cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
1054 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1055 info->x_char = 0;
1056 char_count--;
1057 info->icount.tx++;
1058 }
1059#ifdef BLOCKMOVE
1060 while (0 < (small_count = min_t(unsigned int,
1061 tx_bufsize - tx_put, min_t(unsigned int,
1062 (SERIAL_XMIT_SIZE - info->xmit_tail),
1063 min_t(unsigned int, info->xmit_cnt,
1064 char_count))))) {
1065
1066 memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr +
1067 tx_put),
1068 &info->port.xmit_buf[info->xmit_tail],
1069 small_count);
1070
1071 tx_put = (tx_put + small_count) & (tx_bufsize - 1);
1072 char_count -= small_count;
1073 info->icount.tx += small_count;
1074 info->xmit_cnt -= small_count;
1075 info->xmit_tail = (info->xmit_tail + small_count) &
1076 (SERIAL_XMIT_SIZE - 1);
1077 }
1078#else
1079 while (info->xmit_cnt && char_count) {
1080 data = info->port.xmit_buf[info->xmit_tail];
1081 info->xmit_cnt--;
1082 info->xmit_tail = (info->xmit_tail + 1) &
1083 (SERIAL_XMIT_SIZE - 1);
1084
1085 cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
1086 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1087 char_count--;
1088 info->icount.tx++;
1089 }
1090#endif
1091 tty_wakeup(tty);
1092ztxdone:
1093
1094 cy_writel(&buf_ctrl->tx_put, tx_put);
1095 }
1096}
1097
1098static void cyz_handle_cmd(struct cyclades_card *cinfo)
1099{
1100 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
1101 struct tty_struct *tty;
1102 struct cyclades_port *info;
1103 __u32 channel, param, fw_ver;
1104 __u8 cmd;
1105 int special_count;
1106 int delta_count;
1107
1108 fw_ver = readl(&board_ctrl->fw_version);
1109
1110 while (cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) {
1111 special_count = 0;
1112 delta_count = 0;
1113 info = &cinfo->ports[channel];
1114 tty = tty_port_tty_get(&info->port);
1115 if (tty == NULL)
1116 continue;
1117
1118 switch (cmd) {
1119 case C_CM_PR_ERROR:
1120 tty_insert_flip_char(tty, 0, TTY_PARITY);
1121 info->icount.rx++;
1122 special_count++;
1123 break;
1124 case C_CM_FR_ERROR:
1125 tty_insert_flip_char(tty, 0, TTY_FRAME);
1126 info->icount.rx++;
1127 special_count++;
1128 break;
1129 case C_CM_RXBRK:
1130 tty_insert_flip_char(tty, 0, TTY_BREAK);
1131 info->icount.rx++;
1132 special_count++;
1133 break;
1134 case C_CM_MDCD:
1135 info->icount.dcd++;
1136 delta_count++;
1137 if (info->port.flags & ASYNC_CHECK_CD) {
1138 u32 dcd = fw_ver > 241 ? param :
1139 readl(&info->u.cyz.ch_ctrl->rs_status);
1140 if (dcd & C_RS_DCD)
1141 wake_up_interruptible(&info->port.open_wait);
1142 else
1143 tty_hangup(tty);
1144 }
1145 break;
1146 case C_CM_MCTS:
1147 info->icount.cts++;
1148 delta_count++;
1149 break;
1150 case C_CM_MRI:
1151 info->icount.rng++;
1152 delta_count++;
1153 break;
1154 case C_CM_MDSR:
1155 info->icount.dsr++;
1156 delta_count++;
1157 break;
1158#ifdef Z_WAKE
1159 case C_CM_IOCTLW:
1160 complete(&info->shutdown_wait);
1161 break;
1162#endif
1163#ifdef CONFIG_CYZ_INTR
1164 case C_CM_RXHIWM:
1165 case C_CM_RXNNDT:
1166 case C_CM_INTBACK2:
1167
1168#ifdef CY_DEBUG_INTERRUPTS
1169 printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
1170 "port %ld\n", info->card, channel);
1171#endif
1172 cyz_handle_rx(info, tty);
1173 break;
1174 case C_CM_TXBEMPTY:
1175 case C_CM_TXLOWWM:
1176 case C_CM_INTBACK:
1177
1178#ifdef CY_DEBUG_INTERRUPTS
1179 printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
1180 "port %ld\n", info->card, channel);
1181#endif
1182 cyz_handle_tx(info, tty);
1183 break;
1184#endif
1185 case C_CM_FATAL:
1186
1187 break;
1188 default:
1189 break;
1190 }
1191 if (delta_count)
1192 wake_up_interruptible(&info->port.delta_msr_wait);
1193 if (special_count)
1194 tty_schedule_flip(tty);
1195 tty_kref_put(tty);
1196 }
1197}
1198
1199#ifdef CONFIG_CYZ_INTR
1200static irqreturn_t cyz_interrupt(int irq, void *dev_id)
1201{
1202 struct cyclades_card *cinfo = dev_id;
1203
1204 if (unlikely(!cyz_is_loaded(cinfo))) {
1205#ifdef CY_DEBUG_INTERRUPTS
1206 printk(KERN_DEBUG "cyz_interrupt: board not yet loaded "
1207 "(IRQ%d).\n", irq);
1208#endif
1209 return IRQ_NONE;
1210 }
1211
1212
1213 cyz_handle_cmd(cinfo);
1214
1215 return IRQ_HANDLED;
1216}
1217
1218static void cyz_rx_restart(unsigned long arg)
1219{
1220 struct cyclades_port *info = (struct cyclades_port *)arg;
1221 struct cyclades_card *card = info->card;
1222 int retval;
1223 __u32 channel = info->line - card->first_line;
1224 unsigned long flags;
1225
1226 spin_lock_irqsave(&card->card_lock, flags);
1227 retval = cyz_issue_cmd(card, channel, C_CM_INTBACK2, 0L);
1228 if (retval != 0) {
1229 printk(KERN_ERR "cyc:cyz_rx_restart retval on ttyC%d was %x\n",
1230 info->line, retval);
1231 }
1232 spin_unlock_irqrestore(&card->card_lock, flags);
1233}
1234
1235#else
1236
1237static void cyz_poll(unsigned long arg)
1238{
1239 struct cyclades_card *cinfo;
1240 struct cyclades_port *info;
1241 unsigned long expires = jiffies + HZ;
1242 unsigned int port, card;
1243
1244 for (card = 0; card < NR_CARDS; card++) {
1245 cinfo = &cy_card[card];
1246
1247 if (!cy_is_Z(cinfo))
1248 continue;
1249 if (!cyz_is_loaded(cinfo))
1250 continue;
1251
1252
1253 if (!cinfo->intr_enabled) {
1254 cinfo->intr_enabled = 1;
1255 continue;
1256 }
1257
1258 cyz_handle_cmd(cinfo);
1259
1260 for (port = 0; port < cinfo->nports; port++) {
1261 struct tty_struct *tty;
1262
1263 info = &cinfo->ports[port];
1264 tty = tty_port_tty_get(&info->port);
1265
1266
1267
1268 if (!info->throttle)
1269 cyz_handle_rx(info, tty);
1270 cyz_handle_tx(info, tty);
1271 tty_kref_put(tty);
1272 }
1273
1274 expires = jiffies + cyz_polling_cycle;
1275 }
1276 mod_timer(&cyz_timerlist, expires);
1277}
1278
1279#endif
1280
1281
1282
1283
1284
1285
1286
1287static int cy_startup(struct cyclades_port *info, struct tty_struct *tty)
1288{
1289 struct cyclades_card *card;
1290 unsigned long flags;
1291 int retval = 0;
1292 int channel;
1293 unsigned long page;
1294
1295 card = info->card;
1296 channel = info->line - card->first_line;
1297
1298 page = get_zeroed_page(GFP_KERNEL);
1299 if (!page)
1300 return -ENOMEM;
1301
1302 spin_lock_irqsave(&card->card_lock, flags);
1303
1304 if (info->port.flags & ASYNC_INITIALIZED)
1305 goto errout;
1306
1307 if (!info->type) {
1308 set_bit(TTY_IO_ERROR, &tty->flags);
1309 goto errout;
1310 }
1311
1312 if (info->port.xmit_buf)
1313 free_page(page);
1314 else
1315 info->port.xmit_buf = (unsigned char *)page;
1316
1317 spin_unlock_irqrestore(&card->card_lock, flags);
1318
1319 cy_set_line_char(info, tty);
1320
1321 if (!cy_is_Z(card)) {
1322 channel &= 0x03;
1323
1324 spin_lock_irqsave(&card->card_lock, flags);
1325
1326 cyy_writeb(info, CyCAR, channel);
1327
1328 cyy_writeb(info, CyRTPR,
1329 (info->default_timeout ? info->default_timeout : 0x02));
1330
1331
1332 cyy_issue_cmd(info, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR);
1333
1334 cyy_change_rts_dtr(info, TIOCM_RTS | TIOCM_DTR, 0);
1335
1336 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyRxData);
1337 } else {
1338 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
1339
1340 if (!cyz_is_loaded(card))
1341 return -ENODEV;
1342
1343#ifdef CY_DEBUG_OPEN
1344 printk(KERN_DEBUG "cyc startup Z card %d, channel %d, "
1345 "base_addr %p\n", card, channel, card->base_addr);
1346#endif
1347 spin_lock_irqsave(&card->card_lock, flags);
1348
1349 cy_writel(&ch_ctrl->op_mode, C_CH_ENABLE);
1350#ifdef Z_WAKE
1351#ifdef CONFIG_CYZ_INTR
1352 cy_writel(&ch_ctrl->intr_enable,
1353 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
1354 C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD);
1355#else
1356 cy_writel(&ch_ctrl->intr_enable,
1357 C_IN_IOCTLW | C_IN_MDCD);
1358#endif
1359#else
1360#ifdef CONFIG_CYZ_INTR
1361 cy_writel(&ch_ctrl->intr_enable,
1362 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
1363 C_IN_RXNNDT | C_IN_MDCD);
1364#else
1365 cy_writel(&ch_ctrl->intr_enable, C_IN_MDCD);
1366#endif
1367#endif
1368
1369 retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L);
1370 if (retval != 0) {
1371 printk(KERN_ERR "cyc:startup(1) retval on ttyC%d was "
1372 "%x\n", info->line, retval);
1373 }
1374
1375
1376 retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_RX, 0L);
1377 if (retval != 0) {
1378 printk(KERN_ERR "cyc:startup(2) retval on ttyC%d was "
1379 "%x\n", info->line, retval);
1380 }
1381
1382
1383
1384 tty_port_raise_dtr_rts(&info->port);
1385
1386
1387 }
1388
1389 info->port.flags |= ASYNC_INITIALIZED;
1390
1391 clear_bit(TTY_IO_ERROR, &tty->flags);
1392 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1393 info->breakon = info->breakoff = 0;
1394 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
1395 info->idle_stats.in_use =
1396 info->idle_stats.recv_idle =
1397 info->idle_stats.xmit_idle = jiffies;
1398
1399 spin_unlock_irqrestore(&card->card_lock, flags);
1400
1401#ifdef CY_DEBUG_OPEN
1402 printk(KERN_DEBUG "cyc startup done\n");
1403#endif
1404 return 0;
1405
1406errout:
1407 spin_unlock_irqrestore(&card->card_lock, flags);
1408 free_page(page);
1409 return retval;
1410}
1411
1412static void start_xmit(struct cyclades_port *info)
1413{
1414 struct cyclades_card *card = info->card;
1415 unsigned long flags;
1416 int channel = info->line - card->first_line;
1417
1418 if (!cy_is_Z(card)) {
1419 spin_lock_irqsave(&card->card_lock, flags);
1420 cyy_writeb(info, CyCAR, channel & 0x03);
1421 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy);
1422 spin_unlock_irqrestore(&card->card_lock, flags);
1423 } else {
1424#ifdef CONFIG_CYZ_INTR
1425 int retval;
1426
1427 spin_lock_irqsave(&card->card_lock, flags);
1428 retval = cyz_issue_cmd(card, channel, C_CM_INTBACK, 0L);
1429 if (retval != 0) {
1430 printk(KERN_ERR "cyc:start_xmit retval on ttyC%d was "
1431 "%x\n", info->line, retval);
1432 }
1433 spin_unlock_irqrestore(&card->card_lock, flags);
1434#else
1435
1436#endif
1437 }
1438}
1439
1440
1441
1442
1443
1444static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
1445{
1446 struct cyclades_card *card;
1447 unsigned long flags;
1448 int channel;
1449
1450 if (!(info->port.flags & ASYNC_INITIALIZED))
1451 return;
1452
1453 card = info->card;
1454 channel = info->line - card->first_line;
1455 if (!cy_is_Z(card)) {
1456 spin_lock_irqsave(&card->card_lock, flags);
1457
1458
1459 wake_up_interruptible(&info->port.delta_msr_wait);
1460
1461 if (info->port.xmit_buf) {
1462 unsigned char *temp;
1463 temp = info->port.xmit_buf;
1464 info->port.xmit_buf = NULL;
1465 free_page((unsigned long)temp);
1466 }
1467 if (tty->termios->c_cflag & HUPCL)
1468 cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR);
1469
1470 cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR);
1471
1472
1473
1474 set_bit(TTY_IO_ERROR, &tty->flags);
1475 info->port.flags &= ~ASYNC_INITIALIZED;
1476 spin_unlock_irqrestore(&card->card_lock, flags);
1477 } else {
1478#ifdef CY_DEBUG_OPEN
1479 printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
1480 "base_addr %p\n", card, channel, card->base_addr);
1481#endif
1482
1483 if (!cyz_is_loaded(card))
1484 return;
1485
1486 spin_lock_irqsave(&card->card_lock, flags);
1487
1488 if (info->port.xmit_buf) {
1489 unsigned char *temp;
1490 temp = info->port.xmit_buf;
1491 info->port.xmit_buf = NULL;
1492 free_page((unsigned long)temp);
1493 }
1494
1495 if (tty->termios->c_cflag & HUPCL)
1496 tty_port_lower_dtr_rts(&info->port);
1497
1498 set_bit(TTY_IO_ERROR, &tty->flags);
1499 info->port.flags &= ~ASYNC_INITIALIZED;
1500
1501 spin_unlock_irqrestore(&card->card_lock, flags);
1502 }
1503
1504#ifdef CY_DEBUG_OPEN
1505 printk(KERN_DEBUG "cyc shutdown done\n");
1506#endif
1507}
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519static int cy_open(struct tty_struct *tty, struct file *filp)
1520{
1521 struct cyclades_port *info;
1522 unsigned int i, line;
1523 int retval;
1524
1525 line = tty->index;
1526 if (tty->index < 0 || NR_PORTS <= line)
1527 return -ENODEV;
1528
1529 for (i = 0; i < NR_CARDS; i++)
1530 if (line < cy_card[i].first_line + cy_card[i].nports &&
1531 line >= cy_card[i].first_line)
1532 break;
1533 if (i >= NR_CARDS)
1534 return -ENODEV;
1535 info = &cy_card[i].ports[line - cy_card[i].first_line];
1536 if (info->line < 0)
1537 return -ENODEV;
1538
1539
1540
1541
1542
1543 if (cy_is_Z(info->card)) {
1544 struct cyclades_card *cinfo = info->card;
1545 struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS;
1546
1547 if (!cyz_is_loaded(cinfo)) {
1548 if (cinfo->hw_ver == ZE_V1 && cyz_fpga_loaded(cinfo) &&
1549 readl(&firm_id->signature) ==
1550 ZFIRM_HLT) {
1551 printk(KERN_ERR "cyc:Cyclades-Z Error: you "
1552 "need an external power supply for "
1553 "this number of ports.\nFirmware "
1554 "halted.\n");
1555 } else {
1556 printk(KERN_ERR "cyc:Cyclades-Z firmware not "
1557 "yet loaded\n");
1558 }
1559 return -ENODEV;
1560 }
1561#ifdef CONFIG_CYZ_INTR
1562 else {
1563
1564
1565
1566 if (!cinfo->intr_enabled) {
1567 u16 intr;
1568
1569
1570 intr = readw(&cinfo->ctl_addr.p9060->
1571 intr_ctrl_stat) | 0x0900;
1572 cy_writew(&cinfo->ctl_addr.p9060->
1573 intr_ctrl_stat, intr);
1574
1575 retval = cyz_issue_cmd(cinfo, 0,
1576 C_CM_IRQ_ENBL, 0L);
1577 if (retval != 0) {
1578 printk(KERN_ERR "cyc:IRQ enable retval "
1579 "was %x\n", retval);
1580 }
1581 cinfo->intr_enabled = 1;
1582 }
1583 }
1584#endif
1585
1586 if (info->line > (cinfo->first_line + cinfo->nports - 1))
1587 return -ENODEV;
1588 }
1589#ifdef CY_DEBUG_OTHER
1590 printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line);
1591#endif
1592 tty->driver_data = info;
1593 if (serial_paranoia_check(info, tty->name, "cy_open"))
1594 return -ENODEV;
1595
1596#ifdef CY_DEBUG_OPEN
1597 printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line,
1598 info->port.count);
1599#endif
1600 info->port.count++;
1601#ifdef CY_DEBUG_COUNT
1602 printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n",
1603 current->pid, info->port.count);
1604#endif
1605
1606
1607
1608
1609 if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
1610 wait_event_interruptible_tty(info->port.close_wait,
1611 !(info->port.flags & ASYNC_CLOSING));
1612 return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
1613 }
1614
1615
1616
1617
1618 retval = cy_startup(info, tty);
1619 if (retval)
1620 return retval;
1621
1622 retval = tty_port_block_til_ready(&info->port, tty, filp);
1623 if (retval) {
1624#ifdef CY_DEBUG_OPEN
1625 printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready "
1626 "with %d\n", retval);
1627#endif
1628 return retval;
1629 }
1630
1631 info->throttle = 0;
1632 tty_port_tty_set(&info->port, tty);
1633
1634#ifdef CY_DEBUG_OPEN
1635 printk(KERN_DEBUG "cyc:cy_open done\n");
1636#endif
1637 return 0;
1638}
1639
1640
1641
1642
1643static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
1644{
1645 struct cyclades_card *card;
1646 struct cyclades_port *info = tty->driver_data;
1647 unsigned long orig_jiffies;
1648 int char_time;
1649
1650 if (serial_paranoia_check(info, tty->name, "cy_wait_until_sent"))
1651 return;
1652
1653 if (info->xmit_fifo_size == 0)
1654 return;
1655
1656 orig_jiffies = jiffies;
1657
1658
1659
1660
1661
1662
1663
1664
1665 char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size;
1666 char_time = char_time / 5;
1667 if (char_time <= 0)
1668 char_time = 1;
1669 if (timeout < 0)
1670 timeout = 0;
1671 if (timeout)
1672 char_time = min(char_time, timeout);
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682 if (!timeout || timeout > 2 * info->timeout)
1683 timeout = 2 * info->timeout;
1684#ifdef CY_DEBUG_WAIT_UNTIL_SENT
1685 printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...",
1686 timeout, char_time, jiffies);
1687#endif
1688 card = info->card;
1689 if (!cy_is_Z(card)) {
1690 while (cyy_readb(info, CySRER) & CyTxRdy) {
1691#ifdef CY_DEBUG_WAIT_UNTIL_SENT
1692 printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies);
1693#endif
1694 if (msleep_interruptible(jiffies_to_msecs(char_time)))
1695 break;
1696 if (timeout && time_after(jiffies, orig_jiffies +
1697 timeout))
1698 break;
1699 }
1700 }
1701
1702 msleep_interruptible(jiffies_to_msecs(char_time * 5));
1703#ifdef CY_DEBUG_WAIT_UNTIL_SENT
1704 printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies);
1705#endif
1706}
1707
1708static void cy_flush_buffer(struct tty_struct *tty)
1709{
1710 struct cyclades_port *info = tty->driver_data;
1711 struct cyclades_card *card;
1712 int channel, retval;
1713 unsigned long flags;
1714
1715#ifdef CY_DEBUG_IO
1716 printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line);
1717#endif
1718
1719 if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
1720 return;
1721
1722 card = info->card;
1723 channel = info->line - card->first_line;
1724
1725 spin_lock_irqsave(&card->card_lock, flags);
1726 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1727 spin_unlock_irqrestore(&card->card_lock, flags);
1728
1729 if (cy_is_Z(card)) {
1730
1731 spin_lock_irqsave(&card->card_lock, flags);
1732 retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L);
1733 if (retval != 0) {
1734 printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d "
1735 "was %x\n", info->line, retval);
1736 }
1737 spin_unlock_irqrestore(&card->card_lock, flags);
1738 }
1739 tty_wakeup(tty);
1740}
1741
1742
1743static void cy_do_close(struct tty_port *port)
1744{
1745 struct cyclades_port *info = container_of(port, struct cyclades_port,
1746 port);
1747 struct cyclades_card *card;
1748 unsigned long flags;
1749 int channel;
1750
1751 card = info->card;
1752 channel = info->line - card->first_line;
1753 spin_lock_irqsave(&card->card_lock, flags);
1754
1755 if (!cy_is_Z(card)) {
1756
1757 cyy_writeb(info, CyCAR, channel & 0x03);
1758 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData);
1759 if (info->port.flags & ASYNC_INITIALIZED) {
1760
1761
1762 spin_unlock_irqrestore(&card->card_lock, flags);
1763 cy_wait_until_sent(port->tty, info->timeout);
1764 spin_lock_irqsave(&card->card_lock, flags);
1765 }
1766 } else {
1767#ifdef Z_WAKE
1768
1769
1770 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
1771 int retval;
1772
1773 if (readl(&ch_ctrl->flow_status) != C_FS_TXIDLE) {
1774 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L);
1775 if (retval != 0) {
1776 printk(KERN_DEBUG "cyc:cy_close retval on "
1777 "ttyC%d was %x\n", info->line, retval);
1778 }
1779 spin_unlock_irqrestore(&card->card_lock, flags);
1780 wait_for_completion_interruptible(&info->shutdown_wait);
1781 spin_lock_irqsave(&card->card_lock, flags);
1782 }
1783#endif
1784 }
1785 spin_unlock_irqrestore(&card->card_lock, flags);
1786 cy_shutdown(info, port->tty);
1787}
1788
1789
1790
1791
1792static void cy_close(struct tty_struct *tty, struct file *filp)
1793{
1794 struct cyclades_port *info = tty->driver_data;
1795 if (!info || serial_paranoia_check(info, tty->name, "cy_close"))
1796 return;
1797 tty_port_close(&info->port, tty, filp);
1798}
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
1814{
1815 struct cyclades_port *info = tty->driver_data;
1816 unsigned long flags;
1817 int c, ret = 0;
1818
1819#ifdef CY_DEBUG_IO
1820 printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line);
1821#endif
1822
1823 if (serial_paranoia_check(info, tty->name, "cy_write"))
1824 return 0;
1825
1826 if (!info->port.xmit_buf)
1827 return 0;
1828
1829 spin_lock_irqsave(&info->card->card_lock, flags);
1830 while (1) {
1831 c = min(count, (int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1));
1832 c = min(c, (int)(SERIAL_XMIT_SIZE - info->xmit_head));
1833
1834 if (c <= 0)
1835 break;
1836
1837 memcpy(info->port.xmit_buf + info->xmit_head, buf, c);
1838 info->xmit_head = (info->xmit_head + c) &
1839 (SERIAL_XMIT_SIZE - 1);
1840 info->xmit_cnt += c;
1841 buf += c;
1842 count -= c;
1843 ret += c;
1844 }
1845 spin_unlock_irqrestore(&info->card->card_lock, flags);
1846
1847 info->idle_stats.xmit_bytes += ret;
1848 info->idle_stats.xmit_idle = jiffies;
1849
1850 if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped)
1851 start_xmit(info);
1852
1853 return ret;
1854}
1855
1856
1857
1858
1859
1860
1861
1862
1863static int cy_put_char(struct tty_struct *tty, unsigned char ch)
1864{
1865 struct cyclades_port *info = tty->driver_data;
1866 unsigned long flags;
1867
1868#ifdef CY_DEBUG_IO
1869 printk(KERN_DEBUG "cyc:cy_put_char ttyC%d\n", info->line);
1870#endif
1871
1872 if (serial_paranoia_check(info, tty->name, "cy_put_char"))
1873 return 0;
1874
1875 if (!info->port.xmit_buf)
1876 return 0;
1877
1878 spin_lock_irqsave(&info->card->card_lock, flags);
1879 if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) {
1880 spin_unlock_irqrestore(&info->card->card_lock, flags);
1881 return 0;
1882 }
1883
1884 info->port.xmit_buf[info->xmit_head++] = ch;
1885 info->xmit_head &= SERIAL_XMIT_SIZE - 1;
1886 info->xmit_cnt++;
1887 info->idle_stats.xmit_bytes++;
1888 info->idle_stats.xmit_idle = jiffies;
1889 spin_unlock_irqrestore(&info->card->card_lock, flags);
1890 return 1;
1891}
1892
1893
1894
1895
1896
1897static void cy_flush_chars(struct tty_struct *tty)
1898{
1899 struct cyclades_port *info = tty->driver_data;
1900
1901#ifdef CY_DEBUG_IO
1902 printk(KERN_DEBUG "cyc:cy_flush_chars ttyC%d\n", info->line);
1903#endif
1904
1905 if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
1906 return;
1907
1908 if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1909 !info->port.xmit_buf)
1910 return;
1911
1912 start_xmit(info);
1913}
1914
1915
1916
1917
1918
1919
1920
1921static int cy_write_room(struct tty_struct *tty)
1922{
1923 struct cyclades_port *info = tty->driver_data;
1924 int ret;
1925
1926#ifdef CY_DEBUG_IO
1927 printk(KERN_DEBUG "cyc:cy_write_room ttyC%d\n", info->line);
1928#endif
1929
1930 if (serial_paranoia_check(info, tty->name, "cy_write_room"))
1931 return 0;
1932 ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
1933 if (ret < 0)
1934 ret = 0;
1935 return ret;
1936}
1937
1938static int cy_chars_in_buffer(struct tty_struct *tty)
1939{
1940 struct cyclades_port *info = tty->driver_data;
1941
1942 if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
1943 return 0;
1944
1945#ifdef Z_EXT_CHARS_IN_BUFFER
1946 if (!cy_is_Z(info->card)) {
1947#endif
1948#ifdef CY_DEBUG_IO
1949 printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
1950 info->line, info->xmit_cnt);
1951#endif
1952 return info->xmit_cnt;
1953#ifdef Z_EXT_CHARS_IN_BUFFER
1954 } else {
1955 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
1956 int char_count;
1957 __u32 tx_put, tx_get, tx_bufsize;
1958
1959 tx_get = readl(&buf_ctrl->tx_get);
1960 tx_put = readl(&buf_ctrl->tx_put);
1961 tx_bufsize = readl(&buf_ctrl->tx_bufsize);
1962 if (tx_put >= tx_get)
1963 char_count = tx_put - tx_get;
1964 else
1965 char_count = tx_put - tx_get + tx_bufsize;
1966#ifdef CY_DEBUG_IO
1967 printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
1968 info->line, info->xmit_cnt + char_count);
1969#endif
1970 return info->xmit_cnt + char_count;
1971 }
1972#endif
1973}
1974
1975
1976
1977
1978
1979
1980
1981static void cyy_baud_calc(struct cyclades_port *info, __u32 baud)
1982{
1983 int co, co_val, bpr;
1984 __u32 cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 :
1985 25000000);
1986
1987 if (baud == 0) {
1988 info->tbpr = info->tco = info->rbpr = info->rco = 0;
1989 return;
1990 }
1991
1992
1993 for (co = 4, co_val = 2048; co; co--, co_val >>= 2) {
1994 if (cy_clock / co_val / baud > 63)
1995 break;
1996 }
1997
1998 bpr = (cy_clock / co_val * 2 / baud + 1) / 2;
1999 if (bpr > 255)
2000 bpr = 255;
2001
2002 info->tbpr = info->rbpr = bpr;
2003 info->tco = info->rco = co;
2004}
2005
2006
2007
2008
2009
2010static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
2011{
2012 struct cyclades_card *card;
2013 unsigned long flags;
2014 int channel;
2015 unsigned cflag, iflag;
2016 int baud, baud_rate = 0;
2017 int i;
2018
2019 if (!tty->termios)
2020 return;
2021
2022 if (info->line == -1)
2023 return;
2024
2025 cflag = tty->termios->c_cflag;
2026 iflag = tty->termios->c_iflag;
2027
2028
2029
2030
2031 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
2032 tty->alt_speed = 57600;
2033 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
2034 tty->alt_speed = 115200;
2035 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
2036 tty->alt_speed = 230400;
2037 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
2038 tty->alt_speed = 460800;
2039
2040 card = info->card;
2041 channel = info->line - card->first_line;
2042
2043 if (!cy_is_Z(card)) {
2044 u32 cflags;
2045
2046
2047 baud = tty_get_baud_rate(tty);
2048 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
2049 ASYNC_SPD_CUST) {
2050 if (info->custom_divisor)
2051 baud_rate = info->baud / info->custom_divisor;
2052 else
2053 baud_rate = info->baud;
2054 } else if (baud > CD1400_MAX_SPEED) {
2055 baud = CD1400_MAX_SPEED;
2056 }
2057
2058 for (i = 0; i < 20; i++) {
2059 if (baud == baud_table[i])
2060 break;
2061 }
2062 if (i == 20)
2063 i = 19;
2064
2065 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
2066 ASYNC_SPD_CUST) {
2067 cyy_baud_calc(info, baud_rate);
2068 } else {
2069 if (info->chip_rev >= CD1400_REV_J) {
2070
2071 info->tbpr = baud_bpr_60[i];
2072 info->tco = baud_co_60[i];
2073 info->rbpr = baud_bpr_60[i];
2074 info->rco = baud_co_60[i];
2075 } else {
2076 info->tbpr = baud_bpr_25[i];
2077 info->tco = baud_co_25[i];
2078 info->rbpr = baud_bpr_25[i];
2079 info->rco = baud_co_25[i];
2080 }
2081 }
2082 if (baud_table[i] == 134) {
2083
2084 info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) +
2085 2;
2086 } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
2087 ASYNC_SPD_CUST) {
2088 info->timeout = (info->xmit_fifo_size * HZ * 15 /
2089 baud_rate) + 2;
2090 } else if (baud_table[i]) {
2091 info->timeout = (info->xmit_fifo_size * HZ * 15 /
2092 baud_table[i]) + 2;
2093
2094 } else {
2095 info->timeout = 0;
2096 }
2097
2098
2099
2100
2101
2102 info->cor5 = 0;
2103 info->cor4 = 0;
2104
2105 info->cor3 = (info->default_threshold ?
2106 info->default_threshold : baud_cor3[i]);
2107 info->cor2 = CyETC;
2108 switch (cflag & CSIZE) {
2109 case CS5:
2110 info->cor1 = Cy_5_BITS;
2111 break;
2112 case CS6:
2113 info->cor1 = Cy_6_BITS;
2114 break;
2115 case CS7:
2116 info->cor1 = Cy_7_BITS;
2117 break;
2118 case CS8:
2119 info->cor1 = Cy_8_BITS;
2120 break;
2121 }
2122 if (cflag & CSTOPB)
2123 info->cor1 |= Cy_2_STOP;
2124
2125 if (cflag & PARENB) {
2126 if (cflag & PARODD)
2127 info->cor1 |= CyPARITY_O;
2128 else
2129 info->cor1 |= CyPARITY_E;
2130 } else
2131 info->cor1 |= CyPARITY_NONE;
2132
2133
2134 if (cflag & CRTSCTS) {
2135 info->port.flags |= ASYNC_CTS_FLOW;
2136 info->cor2 |= CyCtsAE;
2137 } else {
2138 info->port.flags &= ~ASYNC_CTS_FLOW;
2139 info->cor2 &= ~CyCtsAE;
2140 }
2141 if (cflag & CLOCAL)
2142 info->port.flags &= ~ASYNC_CHECK_CD;
2143 else
2144 info->port.flags |= ASYNC_CHECK_CD;
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156 channel &= 0x03;
2157
2158 spin_lock_irqsave(&card->card_lock, flags);
2159 cyy_writeb(info, CyCAR, channel);
2160
2161
2162
2163 cyy_writeb(info, CyTCOR, info->tco);
2164 cyy_writeb(info, CyTBPR, info->tbpr);
2165 cyy_writeb(info, CyRCOR, info->rco);
2166 cyy_writeb(info, CyRBPR, info->rbpr);
2167
2168
2169
2170 cyy_writeb(info, CySCHR1, START_CHAR(tty));
2171 cyy_writeb(info, CySCHR2, STOP_CHAR(tty));
2172 cyy_writeb(info, CyCOR1, info->cor1);
2173 cyy_writeb(info, CyCOR2, info->cor2);
2174 cyy_writeb(info, CyCOR3, info->cor3);
2175 cyy_writeb(info, CyCOR4, info->cor4);
2176 cyy_writeb(info, CyCOR5, info->cor5);
2177
2178 cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch |
2179 CyCOR3ch);
2180
2181
2182 cyy_writeb(info, CyCAR, channel);
2183 cyy_writeb(info, CyRTPR,
2184 (info->default_timeout ? info->default_timeout : 0x02));
2185
2186
2187 cflags = CyCTS;
2188 if (!C_CLOCAL(tty))
2189 cflags |= CyDSR | CyRI | CyDCD;
2190
2191 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyMdmCh);
2192
2193 if ((cflag & CRTSCTS) && info->rflow)
2194 cyy_writeb(info, CyMCOR1, cflags | rflow_thr[i]);
2195 else
2196 cyy_writeb(info, CyMCOR1, cflags);
2197
2198 cyy_writeb(info, CyMCOR2, cflags);
2199
2200 if (i == 0)
2201 cyy_change_rts_dtr(info, 0, TIOCM_DTR);
2202 else
2203 cyy_change_rts_dtr(info, TIOCM_DTR, 0);
2204
2205 clear_bit(TTY_IO_ERROR, &tty->flags);
2206 spin_unlock_irqrestore(&card->card_lock, flags);
2207
2208 } else {
2209 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
2210 __u32 sw_flow;
2211 int retval;
2212
2213 if (!cyz_is_loaded(card))
2214 return;
2215
2216
2217 baud = tty_get_baud_rate(tty);
2218 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
2219 ASYNC_SPD_CUST) {
2220 if (info->custom_divisor)
2221 baud_rate = info->baud / info->custom_divisor;
2222 else
2223 baud_rate = info->baud;
2224 } else if (baud > CYZ_MAX_SPEED) {
2225 baud = CYZ_MAX_SPEED;
2226 }
2227 cy_writel(&ch_ctrl->comm_baud, baud);
2228
2229 if (baud == 134) {
2230
2231 info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) +
2232 2;
2233 } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
2234 ASYNC_SPD_CUST) {
2235 info->timeout = (info->xmit_fifo_size * HZ * 15 /
2236 baud_rate) + 2;
2237 } else if (baud) {
2238 info->timeout = (info->xmit_fifo_size * HZ * 15 /
2239 baud) + 2;
2240
2241 } else {
2242 info->timeout = 0;
2243 }
2244
2245
2246 switch (cflag & CSIZE) {
2247 case CS5:
2248 cy_writel(&ch_ctrl->comm_data_l, C_DL_CS5);
2249 break;
2250 case CS6:
2251 cy_writel(&ch_ctrl->comm_data_l, C_DL_CS6);
2252 break;
2253 case CS7:
2254 cy_writel(&ch_ctrl->comm_data_l, C_DL_CS7);
2255 break;
2256 case CS8:
2257 cy_writel(&ch_ctrl->comm_data_l, C_DL_CS8);
2258 break;
2259 }
2260 if (cflag & CSTOPB) {
2261 cy_writel(&ch_ctrl->comm_data_l,
2262 readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
2263 } else {
2264 cy_writel(&ch_ctrl->comm_data_l,
2265 readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
2266 }
2267 if (cflag & PARENB) {
2268 if (cflag & PARODD)
2269 cy_writel(&ch_ctrl->comm_parity, C_PR_ODD);
2270 else
2271 cy_writel(&ch_ctrl->comm_parity, C_PR_EVEN);
2272 } else
2273 cy_writel(&ch_ctrl->comm_parity, C_PR_NONE);
2274
2275
2276 if (cflag & CRTSCTS) {
2277 cy_writel(&ch_ctrl->hw_flow,
2278 readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS);
2279 } else {
2280 cy_writel(&ch_ctrl->hw_flow, readl(&ch_ctrl->hw_flow) &
2281 ~(C_RS_CTS | C_RS_RTS));
2282 }
2283
2284
2285 info->port.flags &= ~ASYNC_CTS_FLOW;
2286
2287
2288 sw_flow = 0;
2289 if (iflag & IXON) {
2290 sw_flow |= C_FL_OXX;
2291 if (iflag & IXANY)
2292 sw_flow |= C_FL_OIXANY;
2293 }
2294 cy_writel(&ch_ctrl->sw_flow, sw_flow);
2295
2296 retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L);
2297 if (retval != 0) {
2298 printk(KERN_ERR "cyc:set_line_char retval on ttyC%d "
2299 "was %x\n", info->line, retval);
2300 }
2301
2302
2303 if (cflag & CLOCAL)
2304 info->port.flags &= ~ASYNC_CHECK_CD;
2305 else
2306 info->port.flags |= ASYNC_CHECK_CD;
2307
2308 if (baud == 0) {
2309 cy_writel(&ch_ctrl->rs_control,
2310 readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
2311#ifdef CY_DEBUG_DTR
2312 printk(KERN_DEBUG "cyc:set_line_char dropping Z DTR\n");
2313#endif
2314 } else {
2315 cy_writel(&ch_ctrl->rs_control,
2316 readl(&ch_ctrl->rs_control) | C_RS_DTR);
2317#ifdef CY_DEBUG_DTR
2318 printk(KERN_DEBUG "cyc:set_line_char raising Z DTR\n");
2319#endif
2320 }
2321
2322 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
2323 if (retval != 0) {
2324 printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d "
2325 "was %x\n", info->line, retval);
2326 }
2327
2328 clear_bit(TTY_IO_ERROR, &tty->flags);
2329 }
2330}
2331
2332static int cy_get_serial_info(struct cyclades_port *info,
2333 struct serial_struct __user *retinfo)
2334{
2335 struct cyclades_card *cinfo = info->card;
2336 struct serial_struct tmp = {
2337 .type = info->type,
2338 .line = info->line,
2339 .port = (info->card - cy_card) * 0x100 + info->line -
2340 cinfo->first_line,
2341 .irq = cinfo->irq,
2342 .flags = info->port.flags,
2343 .close_delay = info->port.close_delay,
2344 .closing_wait = info->port.closing_wait,
2345 .baud_base = info->baud,
2346 .custom_divisor = info->custom_divisor,
2347 .hub6 = 0,
2348 };
2349 return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
2350}
2351
2352static int
2353cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty,
2354 struct serial_struct __user *new_info)
2355{
2356 struct serial_struct new_serial;
2357 int ret;
2358
2359 if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
2360 return -EFAULT;
2361
2362 mutex_lock(&info->port.mutex);
2363 if (!capable(CAP_SYS_ADMIN)) {
2364 if (new_serial.close_delay != info->port.close_delay ||
2365 new_serial.baud_base != info->baud ||
2366 (new_serial.flags & ASYNC_FLAGS &
2367 ~ASYNC_USR_MASK) !=
2368 (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))
2369 {
2370 mutex_unlock(&info->port.mutex);
2371 return -EPERM;
2372 }
2373 info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) |
2374 (new_serial.flags & ASYNC_USR_MASK);
2375 info->baud = new_serial.baud_base;
2376 info->custom_divisor = new_serial.custom_divisor;
2377 goto check_and_exit;
2378 }
2379
2380
2381
2382
2383
2384
2385 info->baud = new_serial.baud_base;
2386 info->custom_divisor = new_serial.custom_divisor;
2387 info->port.flags = (info->port.flags & ~ASYNC_FLAGS) |
2388 (new_serial.flags & ASYNC_FLAGS);
2389 info->port.close_delay = new_serial.close_delay * HZ / 100;
2390 info->port.closing_wait = new_serial.closing_wait * HZ / 100;
2391
2392check_and_exit:
2393 if (info->port.flags & ASYNC_INITIALIZED) {
2394 cy_set_line_char(info, tty);
2395 ret = 0;
2396 } else {
2397 ret = cy_startup(info, tty);
2398 }
2399 mutex_unlock(&info->port.mutex);
2400 return ret;
2401}
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value)
2414{
2415 struct cyclades_card *card = info->card;
2416 unsigned int result;
2417 unsigned long flags;
2418 u8 status;
2419
2420 if (!cy_is_Z(card)) {
2421 spin_lock_irqsave(&card->card_lock, flags);
2422 status = cyy_readb(info, CySRER) & (CyTxRdy | CyTxMpty);
2423 spin_unlock_irqrestore(&card->card_lock, flags);
2424 result = (status ? 0 : TIOCSER_TEMT);
2425 } else {
2426
2427 return -EINVAL;
2428 }
2429 return put_user(result, (unsigned long __user *)value);
2430}
2431
2432static int cy_tiocmget(struct tty_struct *tty, struct file *file)
2433{
2434 struct cyclades_port *info = tty->driver_data;
2435 struct cyclades_card *card;
2436 int result;
2437
2438 if (serial_paranoia_check(info, tty->name, __func__))
2439 return -ENODEV;
2440
2441 card = info->card;
2442
2443 if (!cy_is_Z(card)) {
2444 unsigned long flags;
2445 int channel = info->line - card->first_line;
2446 u8 status;
2447
2448 spin_lock_irqsave(&card->card_lock, flags);
2449 cyy_writeb(info, CyCAR, channel & 0x03);
2450 status = cyy_readb(info, CyMSVR1);
2451 status |= cyy_readb(info, CyMSVR2);
2452 spin_unlock_irqrestore(&card->card_lock, flags);
2453
2454 if (info->rtsdtr_inv) {
2455 result = ((status & CyRTS) ? TIOCM_DTR : 0) |
2456 ((status & CyDTR) ? TIOCM_RTS : 0);
2457 } else {
2458 result = ((status & CyRTS) ? TIOCM_RTS : 0) |
2459 ((status & CyDTR) ? TIOCM_DTR : 0);
2460 }
2461 result |= ((status & CyDCD) ? TIOCM_CAR : 0) |
2462 ((status & CyRI) ? TIOCM_RNG : 0) |
2463 ((status & CyDSR) ? TIOCM_DSR : 0) |
2464 ((status & CyCTS) ? TIOCM_CTS : 0);
2465 } else {
2466 u32 lstatus;
2467
2468 if (!cyz_is_loaded(card)) {
2469 result = -ENODEV;
2470 goto end;
2471 }
2472
2473 lstatus = readl(&info->u.cyz.ch_ctrl->rs_status);
2474 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
2475 ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
2476 ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
2477 ((lstatus & C_RS_RI) ? TIOCM_RNG : 0) |
2478 ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) |
2479 ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
2480 }
2481end:
2482 return result;
2483}
2484
2485static int
2486cy_tiocmset(struct tty_struct *tty, struct file *file,
2487 unsigned int set, unsigned int clear)
2488{
2489 struct cyclades_port *info = tty->driver_data;
2490 struct cyclades_card *card;
2491 unsigned long flags;
2492
2493 if (serial_paranoia_check(info, tty->name, __func__))
2494 return -ENODEV;
2495
2496 card = info->card;
2497 if (!cy_is_Z(card)) {
2498 spin_lock_irqsave(&card->card_lock, flags);
2499 cyy_change_rts_dtr(info, set, clear);
2500 spin_unlock_irqrestore(&card->card_lock, flags);
2501 } else {
2502 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
2503 int retval, channel = info->line - card->first_line;
2504 u32 rs;
2505
2506 if (!cyz_is_loaded(card))
2507 return -ENODEV;
2508
2509 spin_lock_irqsave(&card->card_lock, flags);
2510 rs = readl(&ch_ctrl->rs_control);
2511 if (set & TIOCM_RTS)
2512 rs |= C_RS_RTS;
2513 if (clear & TIOCM_RTS)
2514 rs &= ~C_RS_RTS;
2515 if (set & TIOCM_DTR) {
2516 rs |= C_RS_DTR;
2517#ifdef CY_DEBUG_DTR
2518 printk(KERN_DEBUG "cyc:set_modem_info raising Z DTR\n");
2519#endif
2520 }
2521 if (clear & TIOCM_DTR) {
2522 rs &= ~C_RS_DTR;
2523#ifdef CY_DEBUG_DTR
2524 printk(KERN_DEBUG "cyc:set_modem_info clearing "
2525 "Z DTR\n");
2526#endif
2527 }
2528 cy_writel(&ch_ctrl->rs_control, rs);
2529 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
2530 spin_unlock_irqrestore(&card->card_lock, flags);
2531 if (retval != 0) {
2532 printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d "
2533 "was %x\n", info->line, retval);
2534 }
2535 }
2536 return 0;
2537}
2538
2539
2540
2541
2542static int cy_break(struct tty_struct *tty, int break_state)
2543{
2544 struct cyclades_port *info = tty->driver_data;
2545 struct cyclades_card *card;
2546 unsigned long flags;
2547 int retval = 0;
2548
2549 if (serial_paranoia_check(info, tty->name, "cy_break"))
2550 return -EINVAL;
2551
2552 card = info->card;
2553
2554 spin_lock_irqsave(&card->card_lock, flags);
2555 if (!cy_is_Z(card)) {
2556
2557
2558
2559 if (break_state == -1) {
2560 if (!info->breakon) {
2561 info->breakon = 1;
2562 if (!info->xmit_cnt) {
2563 spin_unlock_irqrestore(&card->card_lock, flags);
2564 start_xmit(info);
2565 spin_lock_irqsave(&card->card_lock, flags);
2566 }
2567 }
2568 } else {
2569 if (!info->breakoff) {
2570 info->breakoff = 1;
2571 if (!info->xmit_cnt) {
2572 spin_unlock_irqrestore(&card->card_lock, flags);
2573 start_xmit(info);
2574 spin_lock_irqsave(&card->card_lock, flags);
2575 }
2576 }
2577 }
2578 } else {
2579 if (break_state == -1) {
2580 retval = cyz_issue_cmd(card,
2581 info->line - card->first_line,
2582 C_CM_SET_BREAK, 0L);
2583 if (retval != 0) {
2584 printk(KERN_ERR "cyc:cy_break (set) retval on "
2585 "ttyC%d was %x\n", info->line, retval);
2586 }
2587 } else {
2588 retval = cyz_issue_cmd(card,
2589 info->line - card->first_line,
2590 C_CM_CLR_BREAK, 0L);
2591 if (retval != 0) {
2592 printk(KERN_DEBUG "cyc:cy_break (clr) retval "
2593 "on ttyC%d was %x\n", info->line,
2594 retval);
2595 }
2596 }
2597 }
2598 spin_unlock_irqrestore(&card->card_lock, flags);
2599 return retval;
2600}
2601
2602static int set_threshold(struct cyclades_port *info, unsigned long value)
2603{
2604 struct cyclades_card *card = info->card;
2605 unsigned long flags;
2606
2607 if (!cy_is_Z(card)) {
2608 info->cor3 &= ~CyREC_FIFO;
2609 info->cor3 |= value & CyREC_FIFO;
2610
2611 spin_lock_irqsave(&card->card_lock, flags);
2612 cyy_writeb(info, CyCOR3, info->cor3);
2613 cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR3ch);
2614 spin_unlock_irqrestore(&card->card_lock, flags);
2615 }
2616 return 0;
2617}
2618
2619static int get_threshold(struct cyclades_port *info,
2620 unsigned long __user *value)
2621{
2622 struct cyclades_card *card = info->card;
2623
2624 if (!cy_is_Z(card)) {
2625 u8 tmp = cyy_readb(info, CyCOR3) & CyREC_FIFO;
2626 return put_user(tmp, value);
2627 }
2628 return 0;
2629}
2630
2631static int set_timeout(struct cyclades_port *info, unsigned long value)
2632{
2633 struct cyclades_card *card = info->card;
2634 unsigned long flags;
2635
2636 if (!cy_is_Z(card)) {
2637 spin_lock_irqsave(&card->card_lock, flags);
2638 cyy_writeb(info, CyRTPR, value & 0xff);
2639 spin_unlock_irqrestore(&card->card_lock, flags);
2640 }
2641 return 0;
2642}
2643
2644static int get_timeout(struct cyclades_port *info,
2645 unsigned long __user *value)
2646{
2647 struct cyclades_card *card = info->card;
2648
2649 if (!cy_is_Z(card)) {
2650 u8 tmp = cyy_readb(info, CyRTPR);
2651 return put_user(tmp, value);
2652 }
2653 return 0;
2654}
2655
2656static int cy_cflags_changed(struct cyclades_port *info, unsigned long arg,
2657 struct cyclades_icount *cprev)
2658{
2659 struct cyclades_icount cnow;
2660 unsigned long flags;
2661 int ret;
2662
2663 spin_lock_irqsave(&info->card->card_lock, flags);
2664 cnow = info->icount;
2665 spin_unlock_irqrestore(&info->card->card_lock, flags);
2666
2667 ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) ||
2668 ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) ||
2669 ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) ||
2670 ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts));
2671
2672 *cprev = cnow;
2673
2674 return ret;
2675}
2676
2677
2678
2679
2680
2681
2682static int
2683cy_ioctl(struct tty_struct *tty, struct file *file,
2684 unsigned int cmd, unsigned long arg)
2685{
2686 struct cyclades_port *info = tty->driver_data;
2687 struct cyclades_icount cnow;
2688 int ret_val = 0;
2689 unsigned long flags;
2690 void __user *argp = (void __user *)arg;
2691
2692 if (serial_paranoia_check(info, tty->name, "cy_ioctl"))
2693 return -ENODEV;
2694
2695#ifdef CY_DEBUG_OTHER
2696 printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
2697 info->line, cmd, arg);
2698#endif
2699
2700 switch (cmd) {
2701 case CYGETMON:
2702 if (copy_to_user(argp, &info->mon, sizeof(info->mon))) {
2703 ret_val = -EFAULT;
2704 break;
2705 }
2706 memset(&info->mon, 0, sizeof(info->mon));
2707 break;
2708 case CYGETTHRESH:
2709 ret_val = get_threshold(info, argp);
2710 break;
2711 case CYSETTHRESH:
2712 ret_val = set_threshold(info, arg);
2713 break;
2714 case CYGETDEFTHRESH:
2715 ret_val = put_user(info->default_threshold,
2716 (unsigned long __user *)argp);
2717 break;
2718 case CYSETDEFTHRESH:
2719 info->default_threshold = arg & 0x0f;
2720 break;
2721 case CYGETTIMEOUT:
2722 ret_val = get_timeout(info, argp);
2723 break;
2724 case CYSETTIMEOUT:
2725 ret_val = set_timeout(info, arg);
2726 break;
2727 case CYGETDEFTIMEOUT:
2728 ret_val = put_user(info->default_timeout,
2729 (unsigned long __user *)argp);
2730 break;
2731 case CYSETDEFTIMEOUT:
2732 info->default_timeout = arg & 0xff;
2733 break;
2734 case CYSETRFLOW:
2735 info->rflow = (int)arg;
2736 break;
2737 case CYGETRFLOW:
2738 ret_val = info->rflow;
2739 break;
2740 case CYSETRTSDTR_INV:
2741 info->rtsdtr_inv = (int)arg;
2742 break;
2743 case CYGETRTSDTR_INV:
2744 ret_val = info->rtsdtr_inv;
2745 break;
2746 case CYGETCD1400VER:
2747 ret_val = info->chip_rev;
2748 break;
2749#ifndef CONFIG_CYZ_INTR
2750 case CYZSETPOLLCYCLE:
2751 cyz_polling_cycle = (arg * HZ) / 1000;
2752 break;
2753 case CYZGETPOLLCYCLE:
2754 ret_val = (cyz_polling_cycle * 1000) / HZ;
2755 break;
2756#endif
2757 case CYSETWAIT:
2758 info->port.closing_wait = (unsigned short)arg * HZ / 100;
2759 break;
2760 case CYGETWAIT:
2761 ret_val = info->port.closing_wait / (HZ / 100);
2762 break;
2763 case TIOCGSERIAL:
2764 ret_val = cy_get_serial_info(info, argp);
2765 break;
2766 case TIOCSSERIAL:
2767 ret_val = cy_set_serial_info(info, tty, argp);
2768 break;
2769 case TIOCSERGETLSR:
2770 ret_val = get_lsr_info(info, argp);
2771 break;
2772
2773
2774
2775
2776
2777
2778 case TIOCMIWAIT:
2779 spin_lock_irqsave(&info->card->card_lock, flags);
2780
2781 cnow = info->icount;
2782 spin_unlock_irqrestore(&info->card->card_lock, flags);
2783 ret_val = wait_event_interruptible(info->port.delta_msr_wait,
2784 cy_cflags_changed(info, arg, &cnow));
2785 break;
2786
2787
2788
2789
2790
2791
2792
2793 default:
2794 ret_val = -ENOIOCTLCMD;
2795 }
2796
2797#ifdef CY_DEBUG_OTHER
2798 printk(KERN_DEBUG "cyc:cy_ioctl done\n");
2799#endif
2800 return ret_val;
2801}
2802
2803static int cy_get_icount(struct tty_struct *tty,
2804 struct serial_icounter_struct *sic)
2805{
2806 struct cyclades_port *info = tty->driver_data;
2807 struct cyclades_icount cnow;
2808 unsigned long flags;
2809
2810 spin_lock_irqsave(&info->card->card_lock, flags);
2811 cnow = info->icount;
2812 spin_unlock_irqrestore(&info->card->card_lock, flags);
2813
2814 sic->cts = cnow.cts;
2815 sic->dsr = cnow.dsr;
2816 sic->rng = cnow.rng;
2817 sic->dcd = cnow.dcd;
2818 sic->rx = cnow.rx;
2819 sic->tx = cnow.tx;
2820 sic->frame = cnow.frame;
2821 sic->overrun = cnow.overrun;
2822 sic->parity = cnow.parity;
2823 sic->brk = cnow.brk;
2824 sic->buf_overrun = cnow.buf_overrun;
2825 return 0;
2826}
2827
2828
2829
2830
2831
2832
2833
2834static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
2835{
2836 struct cyclades_port *info = tty->driver_data;
2837
2838#ifdef CY_DEBUG_OTHER
2839 printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line);
2840#endif
2841
2842 cy_set_line_char(info, tty);
2843
2844 if ((old_termios->c_cflag & CRTSCTS) &&
2845 !(tty->termios->c_cflag & CRTSCTS)) {
2846 tty->hw_stopped = 0;
2847 cy_start(tty);
2848 }
2849#if 0
2850
2851
2852
2853
2854
2855
2856 if (!(old_termios->c_cflag & CLOCAL) &&
2857 (tty->termios->c_cflag & CLOCAL))
2858 wake_up_interruptible(&info->port.open_wait);
2859#endif
2860}
2861
2862
2863
2864
2865static void cy_send_xchar(struct tty_struct *tty, char ch)
2866{
2867 struct cyclades_port *info = tty->driver_data;
2868 struct cyclades_card *card;
2869 int channel;
2870
2871 if (serial_paranoia_check(info, tty->name, "cy_send_xchar"))
2872 return;
2873
2874 info->x_char = ch;
2875
2876 if (ch)
2877 cy_start(tty);
2878
2879 card = info->card;
2880 channel = info->line - card->first_line;
2881
2882 if (cy_is_Z(card)) {
2883 if (ch == STOP_CHAR(tty))
2884 cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L);
2885 else if (ch == START_CHAR(tty))
2886 cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L);
2887 }
2888}
2889
2890
2891
2892
2893
2894static void cy_throttle(struct tty_struct *tty)
2895{
2896 struct cyclades_port *info = tty->driver_data;
2897 struct cyclades_card *card;
2898 unsigned long flags;
2899
2900#ifdef CY_DEBUG_THROTTLE
2901 char buf[64];
2902
2903 printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf),
2904 tty->ldisc.chars_in_buffer(tty), info->line);
2905#endif
2906
2907 if (serial_paranoia_check(info, tty->name, "cy_throttle"))
2908 return;
2909
2910 card = info->card;
2911
2912 if (I_IXOFF(tty)) {
2913 if (!cy_is_Z(card))
2914 cy_send_xchar(tty, STOP_CHAR(tty));
2915 else
2916 info->throttle = 1;
2917 }
2918
2919 if (tty->termios->c_cflag & CRTSCTS) {
2920 if (!cy_is_Z(card)) {
2921 spin_lock_irqsave(&card->card_lock, flags);
2922 cyy_change_rts_dtr(info, 0, TIOCM_RTS);
2923 spin_unlock_irqrestore(&card->card_lock, flags);
2924 } else {
2925 info->throttle = 1;
2926 }
2927 }
2928}
2929
2930
2931
2932
2933
2934
2935static void cy_unthrottle(struct tty_struct *tty)
2936{
2937 struct cyclades_port *info = tty->driver_data;
2938 struct cyclades_card *card;
2939 unsigned long flags;
2940
2941#ifdef CY_DEBUG_THROTTLE
2942 char buf[64];
2943
2944 printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n",
2945 tty_name(tty, buf), tty_chars_in_buffer(tty), info->line);
2946#endif
2947
2948 if (serial_paranoia_check(info, tty->name, "cy_unthrottle"))
2949 return;
2950
2951 if (I_IXOFF(tty)) {
2952 if (info->x_char)
2953 info->x_char = 0;
2954 else
2955 cy_send_xchar(tty, START_CHAR(tty));
2956 }
2957
2958 if (tty->termios->c_cflag & CRTSCTS) {
2959 card = info->card;
2960 if (!cy_is_Z(card)) {
2961 spin_lock_irqsave(&card->card_lock, flags);
2962 cyy_change_rts_dtr(info, TIOCM_RTS, 0);
2963 spin_unlock_irqrestore(&card->card_lock, flags);
2964 } else {
2965 info->throttle = 0;
2966 }
2967 }
2968}
2969
2970
2971
2972
2973static void cy_stop(struct tty_struct *tty)
2974{
2975 struct cyclades_card *cinfo;
2976 struct cyclades_port *info = tty->driver_data;
2977 int channel;
2978 unsigned long flags;
2979
2980#ifdef CY_DEBUG_OTHER
2981 printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line);
2982#endif
2983
2984 if (serial_paranoia_check(info, tty->name, "cy_stop"))
2985 return;
2986
2987 cinfo = info->card;
2988 channel = info->line - cinfo->first_line;
2989 if (!cy_is_Z(cinfo)) {
2990 spin_lock_irqsave(&cinfo->card_lock, flags);
2991 cyy_writeb(info, CyCAR, channel & 0x03);
2992 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy);
2993 spin_unlock_irqrestore(&cinfo->card_lock, flags);
2994 }
2995}
2996
2997static void cy_start(struct tty_struct *tty)
2998{
2999 struct cyclades_card *cinfo;
3000 struct cyclades_port *info = tty->driver_data;
3001 int channel;
3002 unsigned long flags;
3003
3004#ifdef CY_DEBUG_OTHER
3005 printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line);
3006#endif
3007
3008 if (serial_paranoia_check(info, tty->name, "cy_start"))
3009 return;
3010
3011 cinfo = info->card;
3012 channel = info->line - cinfo->first_line;
3013 if (!cy_is_Z(cinfo)) {
3014 spin_lock_irqsave(&cinfo->card_lock, flags);
3015 cyy_writeb(info, CyCAR, channel & 0x03);
3016 cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy);
3017 spin_unlock_irqrestore(&cinfo->card_lock, flags);
3018 }
3019}
3020
3021
3022
3023
3024static void cy_hangup(struct tty_struct *tty)
3025{
3026 struct cyclades_port *info = tty->driver_data;
3027
3028#ifdef CY_DEBUG_OTHER
3029 printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line);
3030#endif
3031
3032 if (serial_paranoia_check(info, tty->name, "cy_hangup"))
3033 return;
3034
3035 cy_flush_buffer(tty);
3036 cy_shutdown(info, tty);
3037 tty_port_hangup(&info->port);
3038}
3039
3040static int cyy_carrier_raised(struct tty_port *port)
3041{
3042 struct cyclades_port *info = container_of(port, struct cyclades_port,
3043 port);
3044 struct cyclades_card *cinfo = info->card;
3045 unsigned long flags;
3046 int channel = info->line - cinfo->first_line;
3047 u32 cd;
3048
3049 spin_lock_irqsave(&cinfo->card_lock, flags);
3050 cyy_writeb(info, CyCAR, channel & 0x03);
3051 cd = cyy_readb(info, CyMSVR1) & CyDCD;
3052 spin_unlock_irqrestore(&cinfo->card_lock, flags);
3053
3054 return cd;
3055}
3056
3057static void cyy_dtr_rts(struct tty_port *port, int raise)
3058{
3059 struct cyclades_port *info = container_of(port, struct cyclades_port,
3060 port);
3061 struct cyclades_card *cinfo = info->card;
3062 unsigned long flags;
3063
3064 spin_lock_irqsave(&cinfo->card_lock, flags);
3065 cyy_change_rts_dtr(info, raise ? TIOCM_RTS | TIOCM_DTR : 0,
3066 raise ? 0 : TIOCM_RTS | TIOCM_DTR);
3067 spin_unlock_irqrestore(&cinfo->card_lock, flags);
3068}
3069
3070static int cyz_carrier_raised(struct tty_port *port)
3071{
3072 struct cyclades_port *info = container_of(port, struct cyclades_port,
3073 port);
3074
3075 return readl(&info->u.cyz.ch_ctrl->rs_status) & C_RS_DCD;
3076}
3077
3078static void cyz_dtr_rts(struct tty_port *port, int raise)
3079{
3080 struct cyclades_port *info = container_of(port, struct cyclades_port,
3081 port);
3082 struct cyclades_card *cinfo = info->card;
3083 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
3084 int ret, channel = info->line - cinfo->first_line;
3085 u32 rs;
3086
3087 rs = readl(&ch_ctrl->rs_control);
3088 if (raise)
3089 rs |= C_RS_RTS | C_RS_DTR;
3090 else
3091 rs &= ~(C_RS_RTS | C_RS_DTR);
3092 cy_writel(&ch_ctrl->rs_control, rs);
3093 ret = cyz_issue_cmd(cinfo, channel, C_CM_IOCTLM, 0L);
3094 if (ret != 0)
3095 printk(KERN_ERR "%s: retval on ttyC%d was %x\n",
3096 __func__, info->line, ret);
3097#ifdef CY_DEBUG_DTR
3098 printk(KERN_DEBUG "%s: raising Z DTR\n", __func__);
3099#endif
3100}
3101
3102static const struct tty_port_operations cyy_port_ops = {
3103 .carrier_raised = cyy_carrier_raised,
3104 .dtr_rts = cyy_dtr_rts,
3105 .shutdown = cy_do_close,
3106};
3107
3108static const struct tty_port_operations cyz_port_ops = {
3109 .carrier_raised = cyz_carrier_raised,
3110 .dtr_rts = cyz_dtr_rts,
3111 .shutdown = cy_do_close,
3112};
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122static int __devinit cy_init_card(struct cyclades_card *cinfo)
3123{
3124 struct cyclades_port *info;
3125 unsigned int channel, port;
3126
3127 spin_lock_init(&cinfo->card_lock);
3128 cinfo->intr_enabled = 0;
3129
3130 cinfo->ports = kcalloc(cinfo->nports, sizeof(*cinfo->ports),
3131 GFP_KERNEL);
3132 if (cinfo->ports == NULL) {
3133 printk(KERN_ERR "Cyclades: cannot allocate ports\n");
3134 return -ENOMEM;
3135 }
3136
3137 for (channel = 0, port = cinfo->first_line; channel < cinfo->nports;
3138 channel++, port++) {
3139 info = &cinfo->ports[channel];
3140 tty_port_init(&info->port);
3141 info->magic = CYCLADES_MAGIC;
3142 info->card = cinfo;
3143 info->line = port;
3144
3145 info->port.closing_wait = CLOSING_WAIT_DELAY;
3146 info->port.close_delay = 5 * HZ / 10;
3147 info->port.flags = STD_COM_FLAGS;
3148 init_completion(&info->shutdown_wait);
3149
3150 if (cy_is_Z(cinfo)) {
3151 struct FIRM_ID *firm_id = cinfo->base_addr + ID_ADDRESS;
3152 struct ZFW_CTRL *zfw_ctrl;
3153
3154 info->port.ops = &cyz_port_ops;
3155 info->type = PORT_STARTECH;
3156
3157 zfw_ctrl = cinfo->base_addr +
3158 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3159 info->u.cyz.ch_ctrl = &zfw_ctrl->ch_ctrl[channel];
3160 info->u.cyz.buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
3161
3162 if (cinfo->hw_ver == ZO_V1)
3163 info->xmit_fifo_size = CYZ_FIFO_SIZE;
3164 else
3165 info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
3166#ifdef CONFIG_CYZ_INTR
3167 setup_timer(&cyz_rx_full_timer[port],
3168 cyz_rx_restart, (unsigned long)info);
3169#endif
3170 } else {
3171 unsigned short chip_number;
3172 int index = cinfo->bus_index;
3173
3174 info->port.ops = &cyy_port_ops;
3175 info->type = PORT_CIRRUS;
3176 info->xmit_fifo_size = CyMAX_CHAR_FIFO;
3177 info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
3178 info->cor2 = CyETC;
3179 info->cor3 = 0x08;
3180
3181 chip_number = channel / CyPORTS_PER_CHIP;
3182 info->u.cyy.base_addr = cinfo->base_addr +
3183 (cy_chip_offset[chip_number] << index);
3184 info->chip_rev = cyy_readb(info, CyGFRCR);
3185
3186 if (info->chip_rev >= CD1400_REV_J) {
3187
3188 info->tbpr = baud_bpr_60[13];
3189 info->tco = baud_co_60[13];
3190 info->rbpr = baud_bpr_60[13];
3191 info->rco = baud_co_60[13];
3192 info->rtsdtr_inv = 1;
3193 } else {
3194 info->tbpr = baud_bpr_25[13];
3195 info->tco = baud_co_25[13];
3196 info->rbpr = baud_bpr_25[13];
3197 info->rco = baud_co_25[13];
3198 info->rtsdtr_inv = 0;
3199 }
3200 info->read_status_mask = CyTIMEOUT | CySPECHAR |
3201 CyBREAK | CyPARITY | CyFRAME | CyOVERRUN;
3202 }
3203
3204 }
3205
3206#ifndef CONFIG_CYZ_INTR
3207 if (cy_is_Z(cinfo) && !timer_pending(&cyz_timerlist)) {
3208 mod_timer(&cyz_timerlist, jiffies + 1);
3209#ifdef CY_PCI_DEBUG
3210 printk(KERN_DEBUG "Cyclades-Z polling initialized\n");
3211#endif
3212 }
3213#endif
3214 return 0;
3215}
3216
3217
3218
3219static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr,
3220 int index)
3221{
3222 unsigned int chip_number;
3223 void __iomem *base_addr;
3224
3225 cy_writeb(true_base_addr + (Cy_HwReset << index), 0);
3226
3227 cy_writeb(true_base_addr + (Cy_ClrIntr << index), 0);
3228
3229 udelay(500L);
3230
3231 for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD;
3232 chip_number++) {
3233 base_addr =
3234 true_base_addr + (cy_chip_offset[chip_number] << index);
3235 mdelay(1);
3236 if (readb(base_addr + (CyCCR << index)) != 0x00) {
3237
3238
3239
3240
3241 return chip_number;
3242 }
3243
3244 cy_writeb(base_addr + (CyGFRCR << index), 0);
3245 udelay(10L);
3246
3247
3248
3249
3250
3251
3252
3253 if (chip_number == 4 && readb(true_base_addr +
3254 (cy_chip_offset[0] << index) +
3255 (CyGFRCR << index)) == 0) {
3256 return chip_number;
3257 }
3258
3259 cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET);
3260 mdelay(1);
3261
3262 if (readb(base_addr + (CyGFRCR << index)) == 0x00) {
3263
3264
3265
3266
3267
3268 return chip_number;
3269 }
3270 if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) !=
3271 0x40) {
3272
3273
3274
3275
3276
3277
3278 return chip_number;
3279 }
3280 cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL);
3281 if (readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) {
3282
3283
3284
3285 cy_writeb(base_addr + (CyPPR << index), CyCLOCK_60_2MS);
3286 } else {
3287
3288 cy_writeb(base_addr + (CyPPR << index), CyCLOCK_25_5MS);
3289 }
3290
3291
3292
3293
3294
3295
3296 }
3297 return chip_number;
3298}
3299
3300
3301
3302
3303
3304
3305
3306static int __init cy_detect_isa(void)
3307{
3308#ifdef CONFIG_ISA
3309 unsigned short cy_isa_irq, nboard;
3310 void __iomem *cy_isa_address;
3311 unsigned short i, j, cy_isa_nchan;
3312 int isparam = 0;
3313
3314 nboard = 0;
3315
3316
3317 for (i = 0; i < NR_CARDS; i++) {
3318 if (maddr[i] || i) {
3319 isparam = 1;
3320 cy_isa_addresses[i] = maddr[i];
3321 }
3322 if (!maddr[i])
3323 break;
3324 }
3325
3326
3327 for (i = 0; i < NR_ISA_ADDRS; i++) {
3328 unsigned int isa_address = cy_isa_addresses[i];
3329 if (isa_address == 0x0000)
3330 return nboard;
3331
3332
3333 cy_isa_address = ioremap_nocache(isa_address, CyISA_Ywin);
3334 if (cy_isa_address == NULL) {
3335 printk(KERN_ERR "Cyclom-Y/ISA: can't remap base "
3336 "address\n");
3337 continue;
3338 }
3339 cy_isa_nchan = CyPORTS_PER_CHIP *
3340 cyy_init_card(cy_isa_address, 0);
3341 if (cy_isa_nchan == 0) {
3342 iounmap(cy_isa_address);
3343 continue;
3344 }
3345
3346 if (isparam && i < NR_CARDS && irq[i])
3347 cy_isa_irq = irq[i];
3348 else
3349
3350 cy_isa_irq = detect_isa_irq(cy_isa_address);
3351 if (cy_isa_irq == 0) {
3352 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but the "
3353 "IRQ could not be detected.\n",
3354 (unsigned long)cy_isa_address);
3355 iounmap(cy_isa_address);
3356 continue;
3357 }
3358
3359 if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) {
3360 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
3361 "more channels are available. Change NR_PORTS "
3362 "in cyclades.c and recompile kernel.\n",
3363 (unsigned long)cy_isa_address);
3364 iounmap(cy_isa_address);
3365 return nboard;
3366 }
3367
3368 for (j = 0; j < NR_CARDS; j++) {
3369 if (cy_card[j].base_addr == NULL)
3370 break;
3371 }
3372 if (j == NR_CARDS) {
3373 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
3374 "more cards can be used. Change NR_CARDS in "
3375 "cyclades.c and recompile kernel.\n",
3376 (unsigned long)cy_isa_address);
3377 iounmap(cy_isa_address);
3378 return nboard;
3379 }
3380
3381
3382 if (request_irq(cy_isa_irq, cyy_interrupt,
3383 IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) {
3384 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but "
3385 "could not allocate IRQ#%d.\n",
3386 (unsigned long)cy_isa_address, cy_isa_irq);
3387 iounmap(cy_isa_address);
3388 return nboard;
3389 }
3390
3391
3392 cy_card[j].base_addr = cy_isa_address;
3393 cy_card[j].ctl_addr.p9050 = NULL;
3394 cy_card[j].irq = (int)cy_isa_irq;
3395 cy_card[j].bus_index = 0;
3396 cy_card[j].first_line = cy_next_channel;
3397 cy_card[j].num_chips = cy_isa_nchan / CyPORTS_PER_CHIP;
3398 cy_card[j].nports = cy_isa_nchan;
3399 if (cy_init_card(&cy_card[j])) {
3400 cy_card[j].base_addr = NULL;
3401 free_irq(cy_isa_irq, &cy_card[j]);
3402 iounmap(cy_isa_address);
3403 continue;
3404 }
3405 nboard++;
3406
3407 printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: "
3408 "%d channels starting from port %d\n",
3409 j + 1, (unsigned long)cy_isa_address,
3410 (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)),
3411 cy_isa_irq, cy_isa_nchan, cy_next_channel);
3412
3413 for (j = cy_next_channel;
3414 j < cy_next_channel + cy_isa_nchan; j++)
3415 tty_register_device(cy_serial_driver, j, NULL);
3416 cy_next_channel += cy_isa_nchan;
3417 }
3418 return nboard;
3419#else
3420 return 0;
3421#endif
3422}
3423
3424#ifdef CONFIG_PCI
3425static inline int __devinit cyc_isfwstr(const char *str, unsigned int size)
3426{
3427 unsigned int a;
3428
3429 for (a = 0; a < size && *str; a++, str++)
3430 if (*str & 0x80)
3431 return -EINVAL;
3432
3433 for (; a < size; a++, str++)
3434 if (*str)
3435 return -EINVAL;
3436
3437 return 0;
3438}
3439
3440static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data,
3441 unsigned int size)
3442{
3443 for (; size > 0; size--) {
3444 cy_writel(fpga, *data++);
3445 udelay(10);
3446 }
3447}
3448
3449static void __devinit plx_init(struct pci_dev *pdev, int irq,
3450 struct RUNTIME_9060 __iomem *addr)
3451{
3452
3453 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) | 0x40000000);
3454 udelay(100L);
3455 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) & ~0x40000000);
3456
3457
3458 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) | 0x20000000);
3459 udelay(100L);
3460 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) & ~0x20000000);
3461
3462
3463
3464
3465
3466 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
3467}
3468
3469static int __devinit __cyz_load_fw(const struct firmware *fw,
3470 const char *name, const u32 mailbox, void __iomem *base,
3471 void __iomem *fpga)
3472{
3473 const void *ptr = fw->data;
3474 const struct zfile_header *h = ptr;
3475 const struct zfile_config *c, *cs;
3476 const struct zfile_block *b, *bs;
3477 unsigned int a, tmp, len = fw->size;
3478#define BAD_FW KERN_ERR "Bad firmware: "
3479 if (len < sizeof(*h)) {
3480 printk(BAD_FW "too short: %u<%zu\n", len, sizeof(*h));
3481 return -EINVAL;
3482 }
3483
3484 cs = ptr + h->config_offset;
3485 bs = ptr + h->block_offset;
3486
3487 if ((void *)(cs + h->n_config) > ptr + len ||
3488 (void *)(bs + h->n_blocks) > ptr + len) {
3489 printk(BAD_FW "too short");
3490 return -EINVAL;
3491 }
3492
3493 if (cyc_isfwstr(h->name, sizeof(h->name)) ||
3494 cyc_isfwstr(h->date, sizeof(h->date))) {
3495 printk(BAD_FW "bad formatted header string\n");
3496 return -EINVAL;
3497 }
3498
3499 if (strncmp(name, h->name, sizeof(h->name))) {
3500 printk(BAD_FW "bad name '%s' (expected '%s')\n", h->name, name);
3501 return -EINVAL;
3502 }
3503
3504 tmp = 0;
3505 for (c = cs; c < cs + h->n_config; c++) {
3506 for (a = 0; a < c->n_blocks; a++)
3507 if (c->block_list[a] > h->n_blocks) {
3508 printk(BAD_FW "bad block ref number in cfgs\n");
3509 return -EINVAL;
3510 }
3511 if (c->mailbox == mailbox && c->function == 0)
3512 tmp++;
3513 }
3514 if (!tmp) {
3515 printk(BAD_FW "nothing appropriate\n");
3516 return -EINVAL;
3517 }
3518
3519 for (b = bs; b < bs + h->n_blocks; b++)
3520 if (b->file_offset + b->size > len) {
3521 printk(BAD_FW "bad block data offset\n");
3522 return -EINVAL;
3523 }
3524
3525
3526 for (c = cs; c < cs + h->n_config; c++)
3527 if (c->mailbox == mailbox && c->function == 0)
3528 break;
3529
3530 for (a = 0; a < c->n_blocks; a++) {
3531 b = &bs[c->block_list[a]];
3532 if (b->type == ZBLOCK_FPGA) {
3533 if (fpga != NULL)
3534 cyz_fpga_copy(fpga, ptr + b->file_offset,
3535 b->size);
3536 } else {
3537 if (base != NULL)
3538 memcpy_toio(base + b->ram_offset,
3539 ptr + b->file_offset, b->size);
3540 }
3541 }
3542#undef BAD_FW
3543 return 0;
3544}
3545
3546static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
3547 struct RUNTIME_9060 __iomem *ctl_addr, int irq)
3548{
3549 const struct firmware *fw;
3550 struct FIRM_ID __iomem *fid = base_addr + ID_ADDRESS;
3551 struct CUSTOM_REG __iomem *cust = base_addr;
3552 struct ZFW_CTRL __iomem *pt_zfwctrl;
3553 void __iomem *tmp;
3554 u32 mailbox, status, nchan;
3555 unsigned int i;
3556 int retval;
3557
3558 retval = request_firmware(&fw, "cyzfirm.bin", &pdev->dev);
3559 if (retval) {
3560 dev_err(&pdev->dev, "can't get firmware\n");
3561 goto err;
3562 }
3563
3564
3565
3566 if (__cyz_fpga_loaded(ctl_addr) && readl(&fid->signature) == ZFIRM_ID) {
3567 u32 cntval = readl(base_addr + 0x190);
3568
3569 udelay(100);
3570 if (cntval != readl(base_addr + 0x190)) {
3571
3572 dev_dbg(&pdev->dev, "Cyclades-Z FW already loaded. "
3573 "Skipping board.\n");
3574 retval = 0;
3575 goto err_rel;
3576 }
3577 }
3578
3579
3580 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) &
3581 ~0x00030800UL);
3582
3583 mailbox = readl(&ctl_addr->mail_box_0);
3584
3585 if (mailbox == 0 || __cyz_fpga_loaded(ctl_addr)) {
3586
3587 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3588 cy_writel(&cust->cpu_stop, 0);
3589 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3590 udelay(100);
3591 }
3592
3593 plx_init(pdev, irq, ctl_addr);
3594
3595 if (mailbox != 0) {
3596
3597 retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, NULL,
3598 base_addr);
3599 if (retval)
3600 goto err_rel;
3601 if (!__cyz_fpga_loaded(ctl_addr)) {
3602 dev_err(&pdev->dev, "fw upload successful, but fw is "
3603 "not loaded\n");
3604 goto err_rel;
3605 }
3606 }
3607
3608
3609 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3610 cy_writel(&cust->cpu_stop, 0);
3611 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3612 udelay(100);
3613
3614
3615 for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++)
3616 cy_writeb(tmp, 255);
3617 if (mailbox != 0) {
3618
3619 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM + RAM_SIZE);
3620 for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++)
3621 cy_writeb(tmp, 255);
3622
3623 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3624 }
3625
3626 retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, base_addr, NULL);
3627 release_firmware(fw);
3628 if (retval)
3629 goto err;
3630
3631
3632 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3633 cy_writel(&cust->cpu_start, 0);
3634 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3635 i = 0;
3636 while ((status = readl(&fid->signature)) != ZFIRM_ID && i++ < 40)
3637 msleep(100);
3638 if (status != ZFIRM_ID) {
3639 if (status == ZFIRM_HLT) {
3640 dev_err(&pdev->dev, "you need an external power supply "
3641 "for this number of ports. Firmware halted and "
3642 "board reset.\n");
3643 retval = -EIO;
3644 goto err;
3645 }
3646 dev_warn(&pdev->dev, "fid->signature = 0x%x... Waiting "
3647 "some more time\n", status);
3648 while ((status = readl(&fid->signature)) != ZFIRM_ID &&
3649 i++ < 200)
3650 msleep(100);
3651 if (status != ZFIRM_ID) {
3652 dev_err(&pdev->dev, "Board not started in 20 seconds! "
3653 "Giving up. (fid->signature = 0x%x)\n",
3654 status);
3655 dev_info(&pdev->dev, "*** Warning ***: if you are "
3656 "upgrading the FW, please power cycle the "
3657 "system before loading the new FW to the "
3658 "Cyclades-Z.\n");
3659
3660 if (__cyz_fpga_loaded(ctl_addr))
3661 plx_init(pdev, irq, ctl_addr);
3662
3663 retval = -EIO;
3664 goto err;
3665 }
3666 dev_dbg(&pdev->dev, "Firmware started after %d seconds.\n",
3667 i / 10);
3668 }
3669 pt_zfwctrl = base_addr + readl(&fid->zfwctrl_addr);
3670
3671 dev_dbg(&pdev->dev, "fid=> %p, zfwctrl_addr=> %x, npt_zfwctrl=> %p\n",
3672 base_addr + ID_ADDRESS, readl(&fid->zfwctrl_addr),
3673 base_addr + readl(&fid->zfwctrl_addr));
3674
3675 nchan = readl(&pt_zfwctrl->board_ctrl.n_channel);
3676 dev_info(&pdev->dev, "Cyclades-Z FW loaded: version = %x, ports = %u\n",
3677 readl(&pt_zfwctrl->board_ctrl.fw_version), nchan);
3678
3679 if (nchan == 0) {
3680 dev_warn(&pdev->dev, "no Cyclades-Z ports were found. Please "
3681 "check the connection between the Z host card and the "
3682 "serial expanders.\n");
3683
3684 if (__cyz_fpga_loaded(ctl_addr))
3685 plx_init(pdev, irq, ctl_addr);
3686
3687 dev_info(&pdev->dev, "Null number of ports detected. Board "
3688 "reset.\n");
3689 retval = 0;
3690 goto err;
3691 }
3692
3693 cy_writel(&pt_zfwctrl->board_ctrl.op_system, C_OS_LINUX);
3694 cy_writel(&pt_zfwctrl->board_ctrl.dr_version, DRIVER_VERSION);
3695
3696
3697
3698
3699
3700 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) |
3701 (1 << 17));
3702 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) |
3703 0x00030800UL);
3704
3705 return nchan;
3706err_rel:
3707 release_firmware(fw);
3708err:
3709 return retval;
3710}
3711
3712static int __devinit cy_pci_probe(struct pci_dev *pdev,
3713 const struct pci_device_id *ent)
3714{
3715 void __iomem *addr0 = NULL, *addr2 = NULL;
3716 char *card_name = NULL;
3717 u32 uninitialized_var(mailbox);
3718 unsigned int device_id, nchan = 0, card_no, i;
3719 unsigned char plx_ver;
3720 int retval, irq;
3721
3722 retval = pci_enable_device(pdev);
3723 if (retval) {
3724 dev_err(&pdev->dev, "cannot enable device\n");
3725 goto err;
3726 }
3727
3728
3729 irq = pdev->irq;
3730 device_id = pdev->device & ~PCI_DEVICE_ID_MASK;
3731
3732#if defined(__alpha__)
3733 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) {
3734 dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low "
3735 "addresses on Alpha systems.\n");
3736 retval = -EIO;
3737 goto err_dis;
3738 }
3739#endif
3740 if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) {
3741 dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low "
3742 "addresses\n");
3743 retval = -EIO;
3744 goto err_dis;
3745 }
3746
3747 if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
3748 dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring "
3749 "it...\n");
3750 pdev->resource[2].flags &= ~IORESOURCE_IO;
3751 }
3752
3753 retval = pci_request_regions(pdev, "cyclades");
3754 if (retval) {
3755 dev_err(&pdev->dev, "failed to reserve resources\n");
3756 goto err_dis;
3757 }
3758
3759 retval = -EIO;
3760 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
3761 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
3762 card_name = "Cyclom-Y";
3763
3764 addr0 = ioremap_nocache(pci_resource_start(pdev, 0),
3765 CyPCI_Yctl);
3766 if (addr0 == NULL) {
3767 dev_err(&pdev->dev, "can't remap ctl region\n");
3768 goto err_reg;
3769 }
3770 addr2 = ioremap_nocache(pci_resource_start(pdev, 2),
3771 CyPCI_Ywin);
3772 if (addr2 == NULL) {
3773 dev_err(&pdev->dev, "can't remap base region\n");
3774 goto err_unmap;
3775 }
3776
3777 nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1);
3778 if (nchan == 0) {
3779 dev_err(&pdev->dev, "Cyclom-Y PCI host card with no "
3780 "Serial-Modules\n");
3781 goto err_unmap;
3782 }
3783 } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
3784 struct RUNTIME_9060 __iomem *ctl_addr;
3785
3786 ctl_addr = addr0 = ioremap_nocache(pci_resource_start(pdev, 0),
3787 CyPCI_Zctl);
3788 if (addr0 == NULL) {
3789 dev_err(&pdev->dev, "can't remap ctl region\n");
3790 goto err_reg;
3791 }
3792
3793
3794 cy_writew(&ctl_addr->intr_ctrl_stat,
3795 readw(&ctl_addr->intr_ctrl_stat) & ~0x0900);
3796
3797 plx_init(pdev, irq, addr0);
3798
3799 mailbox = readl(&ctl_addr->mail_box_0);
3800
3801 addr2 = ioremap_nocache(pci_resource_start(pdev, 2),
3802 mailbox == ZE_V1 ? CyPCI_Ze_win : CyPCI_Zwin);
3803 if (addr2 == NULL) {
3804 dev_err(&pdev->dev, "can't remap base region\n");
3805 goto err_unmap;
3806 }
3807
3808 if (mailbox == ZE_V1) {
3809 card_name = "Cyclades-Ze";
3810 } else {
3811 card_name = "Cyclades-8Zo";
3812#ifdef CY_PCI_DEBUG
3813 if (mailbox == ZO_V1) {
3814 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3815 dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA "
3816 "id %lx, ver %lx\n", (ulong)(0xff &
3817 readl(&((struct CUSTOM_REG *)addr2)->
3818 fpga_id)), (ulong)(0xff &
3819 readl(&((struct CUSTOM_REG *)addr2)->
3820 fpga_version)));
3821 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3822 } else {
3823 dev_info(&pdev->dev, "Cyclades-Z/PCI: New "
3824 "Cyclades-Z board. FPGA not loaded\n");
3825 }
3826#endif
3827
3828
3829
3830
3831 if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
3832 cy_writel(addr2 + ID_ADDRESS, 0L);
3833 }
3834
3835 retval = cyz_load_fw(pdev, addr2, addr0, irq);
3836 if (retval <= 0)
3837 goto err_unmap;
3838 nchan = retval;
3839 }
3840
3841 if ((cy_next_channel + nchan) > NR_PORTS) {
3842 dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
3843 "channels are available. Change NR_PORTS in "
3844 "cyclades.c and recompile kernel.\n");
3845 goto err_unmap;
3846 }
3847
3848 for (card_no = 0; card_no < NR_CARDS; card_no++) {
3849 if (cy_card[card_no].base_addr == NULL)
3850 break;
3851 }
3852 if (card_no == NR_CARDS) {
3853 dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
3854 "more cards can be used. Change NR_CARDS in "
3855 "cyclades.c and recompile kernel.\n");
3856 goto err_unmap;
3857 }
3858
3859 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
3860 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
3861
3862 retval = request_irq(irq, cyy_interrupt,
3863 IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]);
3864 if (retval) {
3865 dev_err(&pdev->dev, "could not allocate IRQ\n");
3866 goto err_unmap;
3867 }
3868 cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP;
3869 } else {
3870 struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS;
3871 struct ZFW_CTRL __iomem *zfw_ctrl;
3872
3873 zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3874
3875 cy_card[card_no].hw_ver = mailbox;
3876 cy_card[card_no].num_chips = (unsigned int)-1;
3877 cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl;
3878#ifdef CONFIG_CYZ_INTR
3879
3880 if (irq != 0 && irq != 255) {
3881 retval = request_irq(irq, cyz_interrupt,
3882 IRQF_SHARED, "Cyclades-Z",
3883 &cy_card[card_no]);
3884 if (retval) {
3885 dev_err(&pdev->dev, "could not allocate IRQ\n");
3886 goto err_unmap;
3887 }
3888 }
3889#endif
3890 }
3891
3892
3893 cy_card[card_no].base_addr = addr2;
3894 cy_card[card_no].ctl_addr.p9050 = addr0;
3895 cy_card[card_no].irq = irq;
3896 cy_card[card_no].bus_index = 1;
3897 cy_card[card_no].first_line = cy_next_channel;
3898 cy_card[card_no].nports = nchan;
3899 retval = cy_init_card(&cy_card[card_no]);
3900 if (retval)
3901 goto err_null;
3902
3903 pci_set_drvdata(pdev, &cy_card[card_no]);
3904
3905 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
3906 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
3907
3908 plx_ver = readb(addr2 + CyPLX_VER) & 0x0f;
3909 switch (plx_ver) {
3910 case PLX_9050:
3911 cy_writeb(addr0 + 0x4c, 0x43);
3912 break;
3913
3914 case PLX_9060:
3915 case PLX_9080:
3916 default:
3917 {
3918 struct RUNTIME_9060 __iomem *ctl_addr = addr0;
3919 plx_init(pdev, irq, ctl_addr);
3920 cy_writew(&ctl_addr->intr_ctrl_stat,
3921 readw(&ctl_addr->intr_ctrl_stat) | 0x0900);
3922 break;
3923 }
3924 }
3925 }
3926
3927 dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from "
3928 "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel);
3929 for (i = cy_next_channel; i < cy_next_channel + nchan; i++)
3930 tty_register_device(cy_serial_driver, i, &pdev->dev);
3931 cy_next_channel += nchan;
3932
3933 return 0;
3934err_null:
3935 cy_card[card_no].base_addr = NULL;
3936 free_irq(irq, &cy_card[card_no]);
3937err_unmap:
3938 iounmap(addr0);
3939 if (addr2)
3940 iounmap(addr2);
3941err_reg:
3942 pci_release_regions(pdev);
3943err_dis:
3944 pci_disable_device(pdev);
3945err:
3946 return retval;
3947}
3948
3949static void __devexit cy_pci_remove(struct pci_dev *pdev)
3950{
3951 struct cyclades_card *cinfo = pci_get_drvdata(pdev);
3952 unsigned int i;
3953
3954
3955 if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) ==
3956 PLX_9050)
3957 cy_writeb(cinfo->ctl_addr.p9050 + 0x4c, 0);
3958 else
3959#ifndef CONFIG_CYZ_INTR
3960 if (!cy_is_Z(cinfo))
3961#endif
3962 cy_writew(&cinfo->ctl_addr.p9060->intr_ctrl_stat,
3963 readw(&cinfo->ctl_addr.p9060->intr_ctrl_stat) &
3964 ~0x0900);
3965
3966 iounmap(cinfo->base_addr);
3967 if (cinfo->ctl_addr.p9050)
3968 iounmap(cinfo->ctl_addr.p9050);
3969 if (cinfo->irq
3970#ifndef CONFIG_CYZ_INTR
3971 && !cy_is_Z(cinfo)
3972#endif
3973 )
3974 free_irq(cinfo->irq, cinfo);
3975 pci_release_regions(pdev);
3976
3977 cinfo->base_addr = NULL;
3978 for (i = cinfo->first_line; i < cinfo->first_line +
3979 cinfo->nports; i++)
3980 tty_unregister_device(cy_serial_driver, i);
3981 cinfo->nports = 0;
3982 kfree(cinfo->ports);
3983}
3984
3985static struct pci_driver cy_pci_driver = {
3986 .name = "cyclades",
3987 .id_table = cy_pci_dev_id,
3988 .probe = cy_pci_probe,
3989 .remove = __devexit_p(cy_pci_remove)
3990};
3991#endif
3992
3993static int cyclades_proc_show(struct seq_file *m, void *v)
3994{
3995 struct cyclades_port *info;
3996 unsigned int i, j;
3997 __u32 cur_jifs = jiffies;
3998
3999 seq_puts(m, "Dev TimeOpen BytesOut IdleOut BytesIn "
4000 "IdleIn Overruns Ldisc\n");
4001
4002
4003 for (i = 0; i < NR_CARDS; i++)
4004 for (j = 0; j < cy_card[i].nports; j++) {
4005 info = &cy_card[i].ports[j];
4006
4007 if (info->port.count) {
4008
4009 struct tty_struct *tty;
4010 struct tty_ldisc *ld;
4011 int num = 0;
4012 tty = tty_port_tty_get(&info->port);
4013 if (tty) {
4014 ld = tty_ldisc_ref(tty);
4015 if (ld) {
4016 num = ld->ops->num;
4017 tty_ldisc_deref(ld);
4018 }
4019 tty_kref_put(tty);
4020 }
4021 seq_printf(m, "%3d %8lu %10lu %8lu "
4022 "%10lu %8lu %9lu %6d\n", info->line,
4023 (cur_jifs - info->idle_stats.in_use) /
4024 HZ, info->idle_stats.xmit_bytes,
4025 (cur_jifs - info->idle_stats.xmit_idle)/
4026 HZ, info->idle_stats.recv_bytes,
4027 (cur_jifs - info->idle_stats.recv_idle)/
4028 HZ, info->idle_stats.overruns,
4029 num);
4030 } else
4031 seq_printf(m, "%3d %8lu %10lu %8lu "
4032 "%10lu %8lu %9lu %6ld\n",
4033 info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
4034 }
4035 return 0;
4036}
4037
4038static int cyclades_proc_open(struct inode *inode, struct file *file)
4039{
4040 return single_open(file, cyclades_proc_show, NULL);
4041}
4042
4043static const struct file_operations cyclades_proc_fops = {
4044 .owner = THIS_MODULE,
4045 .open = cyclades_proc_open,
4046 .read = seq_read,
4047 .llseek = seq_lseek,
4048 .release = single_release,
4049};
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069static const struct tty_operations cy_ops = {
4070 .open = cy_open,
4071 .close = cy_close,
4072 .write = cy_write,
4073 .put_char = cy_put_char,
4074 .flush_chars = cy_flush_chars,
4075 .write_room = cy_write_room,
4076 .chars_in_buffer = cy_chars_in_buffer,
4077 .flush_buffer = cy_flush_buffer,
4078 .ioctl = cy_ioctl,
4079 .throttle = cy_throttle,
4080 .unthrottle = cy_unthrottle,
4081 .set_termios = cy_set_termios,
4082 .stop = cy_stop,
4083 .start = cy_start,
4084 .hangup = cy_hangup,
4085 .break_ctl = cy_break,
4086 .wait_until_sent = cy_wait_until_sent,
4087 .tiocmget = cy_tiocmget,
4088 .tiocmset = cy_tiocmset,
4089 .get_icount = cy_get_icount,
4090 .proc_fops = &cyclades_proc_fops,
4091};
4092
4093static int __init cy_init(void)
4094{
4095 unsigned int nboards;
4096 int retval = -ENOMEM;
4097
4098 cy_serial_driver = alloc_tty_driver(NR_PORTS);
4099 if (!cy_serial_driver)
4100 goto err;
4101
4102 printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n",
4103 __DATE__, __TIME__);
4104
4105
4106
4107 cy_serial_driver->owner = THIS_MODULE;
4108 cy_serial_driver->driver_name = "cyclades";
4109 cy_serial_driver->name = "ttyC";
4110 cy_serial_driver->major = CYCLADES_MAJOR;
4111 cy_serial_driver->minor_start = 0;
4112 cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
4113 cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
4114 cy_serial_driver->init_termios = tty_std_termios;
4115 cy_serial_driver->init_termios.c_cflag =
4116 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
4117 cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
4118 tty_set_operations(cy_serial_driver, &cy_ops);
4119
4120 retval = tty_register_driver(cy_serial_driver);
4121 if (retval) {
4122 printk(KERN_ERR "Couldn't register Cyclades serial driver\n");
4123 goto err_frtty;
4124 }
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134 nboards = cy_detect_isa();
4135
4136#ifdef CONFIG_PCI
4137
4138 retval = pci_register_driver(&cy_pci_driver);
4139 if (retval && !nboards) {
4140 tty_unregister_driver(cy_serial_driver);
4141 goto err_frtty;
4142 }
4143#endif
4144
4145 return 0;
4146err_frtty:
4147 put_tty_driver(cy_serial_driver);
4148err:
4149 return retval;
4150}
4151
4152static void __exit cy_cleanup_module(void)
4153{
4154 struct cyclades_card *card;
4155 unsigned int i, e1;
4156
4157#ifndef CONFIG_CYZ_INTR
4158 del_timer_sync(&cyz_timerlist);
4159#endif
4160
4161 e1 = tty_unregister_driver(cy_serial_driver);
4162 if (e1)
4163 printk(KERN_ERR "failed to unregister Cyclades serial "
4164 "driver(%d)\n", e1);
4165
4166#ifdef CONFIG_PCI
4167 pci_unregister_driver(&cy_pci_driver);
4168#endif
4169
4170 for (i = 0; i < NR_CARDS; i++) {
4171 card = &cy_card[i];
4172 if (card->base_addr) {
4173
4174 cy_writeb(card->base_addr + Cy_ClrIntr, 0);
4175 iounmap(card->base_addr);
4176 if (card->ctl_addr.p9050)
4177 iounmap(card->ctl_addr.p9050);
4178 if (card->irq
4179#ifndef CONFIG_CYZ_INTR
4180 && !cy_is_Z(card)
4181#endif
4182 )
4183 free_irq(card->irq, card);
4184 for (e1 = card->first_line; e1 < card->first_line +
4185 card->nports; e1++)
4186 tty_unregister_device(cy_serial_driver, e1);
4187 kfree(card->ports);
4188 }
4189 }
4190
4191 put_tty_driver(cy_serial_driver);
4192}
4193
4194module_init(cy_init);
4195module_exit(cy_cleanup_module);
4196
4197MODULE_LICENSE("GPL");
4198MODULE_VERSION(CY_VERSION);
4199MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR);
4200MODULE_FIRMWARE("cyzfirm.bin");
4201