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