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