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