- struct cyclades_port *info;
- struct cyclades_card *cinfo;
- int number_z_boards = 0;
- int board,port,i,index;
- unsigned long mailbox;
- unsigned short chip_number;
- int nports;
-
- cy_serial_driver = alloc_tty_driver(NR_PORTS);
- if (!cy_serial_driver)
- return -ENOMEM;
- show_version();
-
- /* Initialize the tty_driver structure */
-
- cy_serial_driver->owner = THIS_MODULE;
- cy_serial_driver->driver_name = "cyclades";
- cy_serial_driver->name = "ttyC";
- cy_serial_driver->major = CYCLADES_MAJOR;
- cy_serial_driver->minor_start = 0;
- cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
- cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
- cy_serial_driver->init_termios = tty_std_termios;
- cy_serial_driver->init_termios.c_cflag =
- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
- tty_set_operations(cy_serial_driver, &cy_ops);
-
- if (tty_register_driver(cy_serial_driver))
- panic("Couldn't register Cyclades serial driver\n");
-
- for (i = 0; i < NR_CARDS; i++) {
- /* base_addr=0 indicates board not found */
- cy_card[i].base_addr = NULL;
- }
-
- /* the code below is responsible to find the boards. Each different
- type of board has its own detection routine. If a board is found,
- the next cy_card structure available is set by the detection
- routine. These functions are responsible for checking the
- availability of cy_card and cy_port data structures and updating
- the cy_next_channel. */
-
- /* look for isa boards */
- cy_isa_nboard = cy_detect_isa();
-
- /* look for pci boards */
- cy_pci_nboard = cy_detect_pci();
-
- cy_nboard = cy_isa_nboard + cy_pci_nboard;
-
- /* invalidate remaining cy_card structures */
- for (i = 0 ; i < NR_CARDS ; i++) {
- if (cy_card[i].base_addr == 0) {
- cy_card[i].first_line = -1;
- cy_card[i].ctl_addr = NULL;
- cy_card[i].irq = 0;
- cy_card[i].bus_index = 0;
- cy_card[i].first_line = 0;
- cy_card[i].num_chips = 0;
- }
- }
- /* invalidate remaining cy_port structures */
- for (i = cy_next_channel ; i < NR_PORTS ; i++) {
- cy_port[i].line = -1;
- cy_port[i].magic = -1;
- }
-
- /* initialize per-port data structures for each valid board found */
- for (board = 0 ; board < cy_nboard ; board++) {
- cinfo = &cy_card[board];
- if (cinfo->num_chips == -1) { /* Cyclades-Z */
- number_z_boards++;
- mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *)
- cy_card[board].ctl_addr)->mail_box_0);
- nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
- cinfo->intr_enabled = 0;
- cinfo->nports = 0; /* Will be correctly set later, after
- Z FW is loaded */
- spin_lock_init(&cinfo->card_lock);
- for (port = cinfo->first_line ;
- port < cinfo->first_line + nports;
- port++)
- {
- info = &cy_port[port];
- info->magic = CYCLADES_MAGIC;
- info->type = PORT_STARTECH;
- info->card = board;
- info->line = port;
- info->chip_rev = 0;
- info->flags = STD_COM_FLAGS;
- info->tty = NULL;
- if (mailbox == ZO_V1)
- info->xmit_fifo_size = CYZ_FIFO_SIZE;
- else
- info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
- info->cor1 = 0;
- info->cor2 = 0;
- info->cor3 = 0;
- info->cor4 = 0;
- info->cor5 = 0;
- info->tbpr = 0;
- info->tco = 0;
- info->rbpr = 0;
- info->rco = 0;
- info->custom_divisor = 0;
- info->close_delay = 5*HZ/10;
- info->closing_wait = CLOSING_WAIT_DELAY;
- info->icount.cts = info->icount.dsr =
- info->icount.rng = info->icount.dcd = 0;
- info->icount.rx = info->icount.tx = 0;
- info->icount.frame = info->icount.parity = 0;
- info->icount.overrun = info->icount.brk = 0;
- info->x_char = 0;
- info->event = 0;
- info->count = 0;
- info->blocked_open = 0;
- info->default_threshold = 0;
- info->default_timeout = 0;
- INIT_WORK(&info->tqueue, do_softint, info);
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- init_waitqueue_head(&info->shutdown_wait);
- init_waitqueue_head(&info->delta_msr_wait);
- /* info->session */
- /* info->pgrp */
- info->read_status_mask = 0;
- /* info->timeout */
- /* Bentson's vars */
- info->jiffies[0] = 0;
- info->jiffies[1] = 0;
- info->jiffies[2] = 0;
- info->rflush_count = 0;
-#ifdef CONFIG_CYZ_INTR
- init_timer(&cyz_rx_full_timer[port]);
- cyz_rx_full_timer[port].function = NULL;
-#endif
- }
- continue;
- }else{ /* Cyclom-Y of some kind*/
- index = cinfo->bus_index;
- spin_lock_init(&cinfo->card_lock);
- cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
- for (port = cinfo->first_line ;
- port < cinfo->first_line + cinfo->nports ;
- port++)
- {
- info = &cy_port[port];
- info->magic = CYCLADES_MAGIC;
- info->type = PORT_CIRRUS;
- info->card = board;
- info->line = port;
- info->flags = STD_COM_FLAGS;
- info->tty = NULL;
- info->xmit_fifo_size = CyMAX_CHAR_FIFO;
- info->cor1 = CyPARITY_NONE|Cy_1_STOP|Cy_8_BITS;
- info->cor2 = CyETC;
- info->cor3 = 0x08; /* _very_ small rcv threshold */
- info->cor4 = 0;
- info->cor5 = 0;
- info->custom_divisor = 0;
- info->close_delay = 5*HZ/10;
- info->closing_wait = CLOSING_WAIT_DELAY;
- info->icount.cts = info->icount.dsr =
- info->icount.rng = info->icount.dcd = 0;
- info->icount.rx = info->icount.tx = 0;
- info->icount.frame = info->icount.parity = 0;
- info->icount.overrun = info->icount.brk = 0;
- chip_number = (port - cinfo->first_line) / 4;
- if ((info->chip_rev =
- cy_readb(cinfo->base_addr +
- (cy_chip_offset[chip_number]<<index) +
- (CyGFRCR<<index))) >= CD1400_REV_J) {
- /* It is a CD1400 rev. J or later */
- info->tbpr = baud_bpr_60[13]; /* Tx BPR */
- info->tco = baud_co_60[13]; /* Tx CO */
- info->rbpr = baud_bpr_60[13]; /* Rx BPR */
- info->rco = baud_co_60[13]; /* Rx CO */
- info->rflow = 0;
- info->rtsdtr_inv = 1;
- } else {
- info->tbpr = baud_bpr_25[13]; /* Tx BPR */
- info->tco = baud_co_25[13]; /* Tx CO */
- info->rbpr = baud_bpr_25[13]; /* Rx BPR */
- info->rco = baud_co_25[13]; /* Rx CO */
- info->rflow = 0;
- info->rtsdtr_inv = 0;
- }
- info->x_char = 0;
- info->event = 0;
- info->count = 0;
- info->blocked_open = 0;
- info->default_threshold = 0;
- info->default_timeout = 0;
- INIT_WORK(&info->tqueue, do_softint, info);
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- init_waitqueue_head(&info->shutdown_wait);
- init_waitqueue_head(&info->delta_msr_wait);
- /* info->session */
- /* info->pgrp */
- info->read_status_mask =
- CyTIMEOUT| CySPECHAR| CyBREAK
- | CyPARITY| CyFRAME| CyOVERRUN;
- /* info->timeout */
- }
- }
- }