MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / serial / icom.c
blobc15c8a0aac58a985a8c252481099be9539a64ae8
1 /*
2 * icom.c
4 * Copyright (C) 2001 IBM Corporation. All rights reserved.
6 * Serial device driver.
8 * Based on code from serial.c
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #define SERIAL_DO_RESTART
26 #include <linux/module.h>
27 #include <linux/config.h>
28 #include <linux/version.h>
29 #include <linux/kernel.h>
30 #include <linux/errno.h>
31 #include <linux/signal.h>
32 #include <linux/sched.h>
33 #include <linux/timer.h>
34 #include <linux/interrupt.h>
35 #include <linux/tty.h>
36 #include <linux/termios.h>
37 #include <linux/fs.h>
38 #include <linux/tty_flip.h>
39 #include <linux/serial.h>
40 #include <linux/serial_reg.h>
41 #include <linux/major.h>
42 #include <linux/string.h>
43 #include <linux/fcntl.h>
44 #include <linux/ptrace.h>
45 #include <linux/ioport.h>
46 #include <linux/mm.h>
47 #include <linux/slab.h>
48 #include <linux/init.h>
49 #include <linux/delay.h>
50 #include <linux/pci.h>
51 #include <linux/vmalloc.h>
52 #include <linux/smp.h>
53 #include <linux/smp_lock.h>
54 #include <linux/spinlock.h>
55 #include <linux/kobject.h>
56 #include <linux/firmware.h>
58 #include <asm/system.h>
59 #include <asm/segment.h>
60 #include <asm/io.h>
61 #include <asm/irq.h>
62 #include <asm/uaccess.h>
63 #include <asm/bitops.h>
65 #include "icom.h"
67 /*#define ICOM_TRACE enable port trace capabilities */
69 #define ICOM_DRIVER_NAME "icom"
70 #define ICOM_VERSION_STR "1.3.1"
71 #define NR_PORTS 128
72 #define ICOM_PORT ((struct icom_port *)port)
73 #define to_icom_adapter(d) container_of(d, struct icom_adapter, kobj)
75 static const struct pci_device_id icom_pci_table[] = {
77 .vendor = PCI_VENDOR_ID_IBM,
78 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
79 .subvendor = PCI_ANY_ID,
80 .subdevice = PCI_ANY_ID,
81 .driver_data = ADAPTER_V1,
84 .vendor = PCI_VENDOR_ID_IBM,
85 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
86 .subvendor = PCI_VENDOR_ID_IBM,
87 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
88 .driver_data = ADAPTER_V2,
91 .vendor = PCI_VENDOR_ID_IBM,
92 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
93 .subvendor = PCI_VENDOR_ID_IBM,
94 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
95 .driver_data = ADAPTER_V2,
98 .vendor = PCI_VENDOR_ID_IBM,
99 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
100 .subvendor = PCI_VENDOR_ID_IBM,
101 .subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
102 .driver_data = ADAPTER_V2,
107 struct lookup_proc_table start_proc[4] = {
108 {0, ICOM_CONTROL_START_A},
109 {0, ICOM_CONTROL_START_B},
110 {0, ICOM_CONTROL_START_C},
111 {0, ICOM_CONTROL_START_D}
115 struct lookup_proc_table stop_proc[4] = {
116 {0, ICOM_CONTROL_STOP_A},
117 {0, ICOM_CONTROL_STOP_B},
118 {0, ICOM_CONTROL_STOP_C},
119 {0, ICOM_CONTROL_STOP_D}
122 struct lookup_int_table int_mask_tbl[4] = {
123 {0, ICOM_INT_MASK_PRC_A},
124 {0, ICOM_INT_MASK_PRC_B},
125 {0, ICOM_INT_MASK_PRC_C},
126 {0, ICOM_INT_MASK_PRC_D},
130 MODULE_DEVICE_TABLE(pci, icom_pci_table);
132 static LIST_HEAD(icom_adapter_head);
134 /* spinlock for adapter initialization and changing adapter operations */
135 static spinlock_t icom_lock;
137 #ifdef ICOM_TRACE
138 static inline void trace(struct icom_port *, char *, unsigned long) {};
139 #else
140 static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
141 #endif
143 static void msleep(unsigned long msecs)
145 set_current_state(TASK_UNINTERRUPTIBLE);
146 schedule_timeout(MSECS_TO_JIFFIES(msecs));
149 static void free_port_memory(struct icom_port *icom_port)
151 struct pci_dev *dev = icom_port->adapter->pci_dev;
153 trace(icom_port, "RET_PORT_MEM", 0);
154 if (icom_port->recv_buf) {
155 pci_free_consistent(dev, 4096, icom_port->recv_buf,
156 icom_port->recv_buf_pci);
157 icom_port->recv_buf = 0;
159 if (icom_port->xmit_buf) {
160 pci_free_consistent(dev, 4096, icom_port->xmit_buf,
161 icom_port->xmit_buf_pci);
162 icom_port->xmit_buf = 0;
164 if (icom_port->statStg) {
165 pci_free_consistent(dev, 4096, icom_port->statStg,
166 icom_port->statStg_pci);
167 icom_port->statStg = 0;
170 if (icom_port->xmitRestart) {
171 pci_free_consistent(dev, 4096, icom_port->xmitRestart,
172 icom_port->xmitRestart_pci);
173 icom_port->xmitRestart = 0;
177 static int __init get_port_memory(struct icom_port *icom_port)
179 int index;
180 unsigned long stgAddr;
181 unsigned long startStgAddr;
182 unsigned long offset;
183 struct pci_dev *dev = icom_port->adapter->pci_dev;
185 icom_port->xmit_buf =
186 pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
187 if (!icom_port->xmit_buf) {
188 dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
189 return -ENOMEM;
192 trace(icom_port, "GET_PORT_MEM",
193 (unsigned long) icom_port->xmit_buf);
195 icom_port->recv_buf =
196 pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
197 if (!icom_port->recv_buf) {
198 dev_err(&dev->dev, "Can not allocate Receive buffer\n");
199 free_port_memory(icom_port);
200 return -ENOMEM;
202 trace(icom_port, "GET_PORT_MEM",
203 (unsigned long) icom_port->recv_buf);
205 icom_port->statStg =
206 pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
207 if (!icom_port->statStg) {
208 dev_err(&dev->dev, "Can not allocate Status buffer\n");
209 free_port_memory(icom_port);
210 return -ENOMEM;
212 trace(icom_port, "GET_PORT_MEM",
213 (unsigned long) icom_port->statStg);
215 icom_port->xmitRestart =
216 pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
217 if (!icom_port->xmitRestart) {
218 dev_err(&dev->dev,
219 "Can not allocate xmit Restart buffer\n");
220 free_port_memory(icom_port);
221 return -ENOMEM;
224 memset(icom_port->statStg, 0, 4096);
226 /* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
227 indicates that frames are to be transmitted
230 stgAddr = (unsigned long) icom_port->statStg;
231 for (index = 0; index < NUM_XBUFFS; index++) {
232 trace(icom_port, "FOD_ADDR", stgAddr);
233 stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
234 if (index < (NUM_XBUFFS - 1)) {
235 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
236 icom_port->statStg->xmit[index].leLengthASD =
237 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
238 trace(icom_port, "FOD_ADDR", stgAddr);
239 trace(icom_port, "FOD_XBUFF",
240 (unsigned long) icom_port->xmit_buf);
241 icom_port->statStg->xmit[index].leBuffer =
242 cpu_to_le32(icom_port->xmit_buf_pci);
243 } else if (index == (NUM_XBUFFS - 1)) {
244 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
245 icom_port->statStg->xmit[index].leLengthASD =
246 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
247 trace(icom_port, "FOD_XBUFF",
248 (unsigned long) icom_port->xmit_buf);
249 icom_port->statStg->xmit[index].leBuffer =
250 cpu_to_le32(icom_port->xmit_buf_pci);
251 } else {
252 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
255 /* FIDs */
256 startStgAddr = stgAddr;
258 /* fill in every entry, even if no buffer */
259 for (index = 0; index < NUM_RBUFFS; index++) {
260 trace(icom_port, "FID_ADDR", stgAddr);
261 stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
262 icom_port->statStg->rcv[index].leLength = 0;
263 icom_port->statStg->rcv[index].WorkingLength =
264 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
265 if (index < (NUM_RBUFFS - 1) ) {
266 offset = stgAddr - (unsigned long) icom_port->statStg;
267 icom_port->statStg->rcv[index].leNext =
268 cpu_to_le32(icom_port-> statStg_pci + offset);
269 trace(icom_port, "FID_RBUFF",
270 (unsigned long) icom_port->recv_buf);
271 icom_port->statStg->rcv[index].leBuffer =
272 cpu_to_le32(icom_port->recv_buf_pci);
273 } else if (index == (NUM_RBUFFS -1) ) {
274 offset = startStgAddr - (unsigned long) icom_port->statStg;
275 icom_port->statStg->rcv[index].leNext =
276 cpu_to_le32(icom_port-> statStg_pci + offset);
277 trace(icom_port, "FID_RBUFF",
278 (unsigned long) icom_port->recv_buf + 2048);
279 icom_port->statStg->rcv[index].leBuffer =
280 cpu_to_le32(icom_port->recv_buf_pci + 2048);
281 } else {
282 icom_port->statStg->rcv[index].leNext = 0;
283 icom_port->statStg->rcv[index].leBuffer = 0;
287 return 0;
290 static void stop_processor(struct icom_port *icom_port)
292 unsigned long temp;
293 unsigned long flags;
294 int port;
296 spin_lock_irqsave(&icom_lock, flags);
298 port = icom_port->port;
299 if (port == 0 || port == 1)
300 stop_proc[port].global_control_reg = &icom_port->global_reg->control;
301 else
302 stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
305 if (port < 4) {
306 temp = readl(stop_proc[port].global_control_reg);
307 temp =
308 (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
309 writel(temp, stop_proc[port].global_control_reg);
311 /* write flush */
312 readl(stop_proc[port].global_control_reg);
313 } else {
314 dev_err(&icom_port->adapter->pci_dev->dev,
315 "Invalid port assignment\n");
318 spin_unlock_irqrestore(&icom_lock, flags);
321 static void start_processor(struct icom_port *icom_port)
323 unsigned long temp;
324 unsigned long flags;
325 int port;
327 spin_lock_irqsave(&icom_lock, flags);
329 port = icom_port->port;
330 if (port == 0 || port == 1)
331 start_proc[port].global_control_reg = &icom_port->global_reg->control;
332 else
333 start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
334 if (port < 4) {
335 temp = readl(start_proc[port].global_control_reg);
336 temp =
337 (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
338 writel(temp, start_proc[port].global_control_reg);
340 /* write flush */
341 readl(start_proc[port].global_control_reg);
342 } else {
343 dev_err(&icom_port->adapter->pci_dev->dev,
344 "Invalid port assignment\n");
347 spin_unlock_irqrestore(&icom_lock, flags);
350 static void load_code(struct icom_port *icom_port)
352 const struct firmware *fw;
353 char *iram_ptr;
354 int index;
355 int status = 0;
356 char *dram_ptr = (char *) icom_port->dram;
357 dma_addr_t temp_pci;
358 unsigned char *new_page = NULL;
359 unsigned char cable_id = NO_CABLE;
360 struct pci_dev *dev = icom_port->adapter->pci_dev;
362 /* Clear out any pending interrupts */
363 writew(0x3FFF, (void *) icom_port->int_reg);
365 trace(icom_port, "CLEAR_INTERRUPTS", 0);
367 /* Stop processor */
368 stop_processor(icom_port);
370 /* Zero out DRAM */
371 memset_io(dram_ptr, 0, 512);
373 /* Load Call Setup into Adapter */
374 if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
375 dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
376 status = -1;
377 goto load_code_exit;
380 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
381 dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
382 release_firmware(fw);
383 status = -1;
384 goto load_code_exit;
387 iram_ptr = (char *) icom_port->dram + ICOM_IRAM_OFFSET;
388 for (index = 0; index < fw->size; index++)
389 writeb(fw->data[index], &iram_ptr[index]);
391 release_firmware(fw);
393 /* Load Resident DCE portion of Adapter */
394 if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
395 dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
396 status = -1;
397 goto load_code_exit;
400 if (fw->size > ICOM_IRAM_SIZE) {
401 dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
402 release_firmware(fw);
403 status = -1;
404 goto load_code_exit;
407 iram_ptr = (char *) icom_port->dram + ICOM_IRAM_OFFSET;
408 for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
409 writeb(fw->data[index], &iram_ptr[index]);
411 release_firmware(fw);
413 /* Set Hardware level */
414 if ((icom_port->adapter->version | ADAPTER_V2) == ADAPTER_V2)
415 writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));
417 /* Start the processor in Adapter */
418 start_processor(icom_port);
420 writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
421 &(icom_port->dram->HDLCConfigReg));
422 writeb(0x04, &(icom_port->dram->FlagFillIdleTimer)); /* 0.5 seconds */
423 writeb(0x00, &(icom_port->dram->CmdReg));
424 writeb(0x10, &(icom_port->dram->async_config3));
425 writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
426 ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));
428 /*Set up data in icom DRAM to indicate where personality
429 *code is located and its length.
431 new_page = pci_alloc_consistent(dev, 4096, &temp_pci);
433 if (!new_page) {
434 dev_err(&dev->dev, "Can not allocate DMA buffer\n");
435 status = -1;
436 goto load_code_exit;
439 if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
440 dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
441 status = -1;
442 goto load_code_exit;
445 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
446 dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
447 release_firmware(fw);
448 status = -1;
449 goto load_code_exit;
452 for (index = 0; index < fw->size; index++)
453 new_page[index] = fw->data[index];
455 release_firmware(fw);
457 writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
458 writel(temp_pci, &icom_port->dram->mac_load_addr);
460 /*Setting the syncReg to 0x80 causes adapter to start downloading
461 the personality code into adapter instruction RAM.
462 Once code is loaded, it will begin executing and, based on
463 information provided above, will start DMAing data from
464 shared memory to adapter DRAM.
466 /* the wait loop below verifies this write operation has been done
467 and processed
469 writeb(START_DOWNLOAD, &icom_port->dram->sync);
471 /* Wait max 1 Sec for data download and processor to start */
472 for (index = 0; index < 10; index++) {
473 msleep(100);
474 if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
475 break;
478 if (index == 10)
479 status = -1;
482 * check Cable ID
484 cable_id = readb(&icom_port->dram->cable_id);
486 if (cable_id & ICOM_CABLE_ID_VALID) {
487 /* Get cable ID into the lower 4 bits (standard form) */
488 cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
489 icom_port->cable_id = cable_id;
490 } else {
491 dev_err(&dev->dev,"Invalid or no cable attached\n");
492 icom_port->cable_id = NO_CABLE;
495 load_code_exit:
497 if (status != 0) {
498 /* Clear out any pending interrupts */
499 writew(0x3FFF, (void *) icom_port->int_reg);
501 /* Turn off port */
502 writeb(ICOM_DISABLE, &(icom_port->dram->disable));
504 /* Stop processor */
505 stop_processor(icom_port);
507 dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
510 if (new_page != NULL)
511 pci_free_consistent(dev, 4096, new_page, temp_pci);
514 static int startup(struct icom_port *icom_port)
516 unsigned long temp;
517 unsigned char cable_id, raw_cable_id;
518 unsigned long flags;
519 int port;
521 trace(icom_port, "STARTUP", 0);
523 if (icom_port->dram == 0x00000000) {
524 /* should NEVER be zero */
525 dev_err(&icom_port->adapter->pci_dev->dev,
526 "Unusable Port, port configuration missing\n");
527 return -ENODEV;
531 * check Cable ID
533 raw_cable_id = readb(&icom_port->dram->cable_id);
534 trace(icom_port, "CABLE_ID", raw_cable_id);
536 /* Get cable ID into the lower 4 bits (standard form) */
537 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
539 /* Check for valid Cable ID */
540 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
541 (cable_id != icom_port->cable_id)) {
543 /* reload adapter code, pick up any potential changes in cable id */
544 load_code(icom_port);
546 /* still no sign of cable, error out */
547 raw_cable_id = readb(&icom_port->dram->cable_id);
548 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
549 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
550 (icom_port->cable_id == NO_CABLE))
551 return -EIO;
555 * Finally, clear and enable interrupts
557 spin_lock_irqsave(&icom_lock, flags);
558 port = icom_port->port;
559 if (port == 0 || port == 1)
560 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
561 else
562 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
564 if (port == 0 || port == 2)
565 writew(0x00FF,(void *) icom_port->int_reg);
566 else
567 writew(0x3F00,(void *) icom_port->int_reg);
568 if (port < 4) {
569 temp = readl(int_mask_tbl[port].global_int_mask);
570 writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
572 /* write flush */
573 readl(int_mask_tbl[port].global_int_mask);
574 } else {
575 dev_err(&icom_port->adapter->pci_dev->dev,
576 "Invalid port assignment\n");
579 spin_unlock_irqrestore(&icom_lock, flags);
580 return 0;
583 static void shutdown(struct icom_port *icom_port)
585 unsigned long temp;
586 unsigned char cmdReg;
587 unsigned long flags;
588 int port;
590 spin_lock_irqsave(&icom_lock, flags);
591 trace(icom_port, "SHUTDOWN", 0);
594 * disable all interrupts
596 port = icom_port->port;
597 if (port == 0 || port == 1)
598 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
599 else
600 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
602 if (port < 4) {
603 temp = readl(int_mask_tbl[port].global_int_mask);
604 writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
606 /* write flush */
607 readl(int_mask_tbl[port].global_int_mask);
608 } else {
609 dev_err(&icom_port->adapter->pci_dev->dev,
610 "Invalid port assignment\n");
612 spin_unlock_irqrestore(&icom_lock, flags);
615 * disable break condition
617 cmdReg = readb(&icom_port->dram->CmdReg);
618 if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) {
619 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
623 static int icom_write(struct uart_port *port)
625 unsigned long data_count;
626 unsigned char cmdReg;
627 unsigned long offset;
628 int temp_tail = port->info->xmit.tail;
630 trace(ICOM_PORT, "WRITE", 0);
632 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
633 SA_FLAGS_READY_TO_XMIT) {
634 trace(ICOM_PORT, "WRITE_FULL", 0);
635 return 0;
638 data_count = 0;
639 while ((port->info->xmit.head != temp_tail) &&
640 (data_count <= XMIT_BUFF_SZ)) {
642 ICOM_PORT->xmit_buf[data_count++] =
643 port->info->xmit.buf[temp_tail];
645 temp_tail++;
646 temp_tail &= (UART_XMIT_SIZE - 1);
649 if (data_count) {
650 ICOM_PORT->statStg->xmit[0].flags =
651 cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
652 ICOM_PORT->statStg->xmit[0].leLength =
653 cpu_to_le16(data_count);
654 offset =
655 (unsigned long) &ICOM_PORT->statStg->xmit[0] -
656 (unsigned long) ICOM_PORT->statStg;
657 *ICOM_PORT->xmitRestart =
658 cpu_to_le32(ICOM_PORT->statStg_pci + offset);
659 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
660 writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
661 &ICOM_PORT->dram->CmdReg);
662 writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
663 trace(ICOM_PORT, "WRITE_START", data_count);
664 /* write flush */
665 readb(&ICOM_PORT->dram->StartXmitCmd);
668 return data_count;
671 static inline void check_modem_status(struct icom_port *icom_port)
673 static char old_status = 0;
674 char delta_status;
675 unsigned char status;
677 spin_lock(&icom_port->uart_port.lock);
679 /*modem input register */
680 status = readb(&icom_port->dram->isr);
681 trace(icom_port, "CHECK_MODEM", status);
682 delta_status = status ^ old_status;
683 if (delta_status) {
684 if (delta_status & ICOM_RI)
685 icom_port->uart_port.icount.rng++;
686 if (delta_status & ICOM_DSR)
687 icom_port->uart_port.icount.dsr++;
688 if (delta_status & ICOM_DCD)
689 uart_handle_dcd_change(&icom_port->uart_port,
690 delta_status & ICOM_DCD);
691 if (delta_status & ICOM_CTS)
692 uart_handle_cts_change(&icom_port->uart_port,
693 delta_status & ICOM_CTS);
695 wake_up_interruptible(&icom_port->uart_port.info->
696 delta_msr_wait);
697 old_status = status;
699 spin_unlock(&icom_port->uart_port.lock);
702 static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
704 unsigned short int count;
705 int i;
707 if (port_int_reg & (INT_XMIT_COMPLETED)) {
708 trace(icom_port, "XMIT_COMPLETE", 0);
710 /* clear buffer in use bit */
711 icom_port->statStg->xmit[0].flags &=
712 cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
714 count = (unsigned short int)
715 cpu_to_le16(icom_port->statStg->xmit[0].leLength);
716 icom_port->uart_port.icount.tx += count;
718 for (i=0; i<count &&
719 !uart_circ_empty(&icom_port->uart_port.info->xmit); i++) {
721 icom_port->uart_port.info->xmit.tail++;
722 icom_port->uart_port.info->xmit.tail &=
723 (UART_XMIT_SIZE - 1);
726 if (!icom_write(&icom_port->uart_port))
727 /* activate write queue */
728 uart_write_wakeup(&icom_port->uart_port);
729 } else
730 trace(icom_port, "XMIT_DISABLED", 0);
733 static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
735 short int count, rcv_buff;
736 struct tty_struct *tty = icom_port->uart_port.info->tty;
737 unsigned short int status;
738 struct uart_icount *icount;
739 unsigned long offset;
741 trace(icom_port, "RCV_COMPLETE", 0);
742 rcv_buff = icom_port->next_rcv;
744 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
745 while (status & SA_FL_RCV_DONE) {
747 trace(icom_port, "FID_STATUS", status);
748 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
750 trace(icom_port, "RCV_COUNT", count);
751 if (count > (TTY_FLIPBUF_SIZE - tty->flip.count))
752 count = TTY_FLIPBUF_SIZE - tty->flip.count;
754 trace(icom_port, "REAL_COUNT", count);
756 offset =
757 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
758 icom_port->recv_buf_pci;
760 memcpy(tty->flip.char_buf_ptr,(unsigned char *)
761 ((unsigned long)icom_port->recv_buf + offset), count);
763 if (count > 0) {
764 tty->flip.count += count - 1;
765 tty->flip.char_buf_ptr += count - 1;
767 memset(tty->flip.flag_buf_ptr, 0, count);
768 tty->flip.flag_buf_ptr += count - 1;
771 icount = &icom_port->uart_port.icount;
772 icount->rx += count;
774 /* Break detect logic */
775 if ((status & SA_FLAGS_FRAME_ERROR)
776 && (tty->flip.char_buf_ptr[0] == 0x00)) {
777 status &= ~SA_FLAGS_FRAME_ERROR;
778 status |= SA_FLAGS_BREAK_DET;
779 trace(icom_port, "BREAK_DET", 0);
782 if (status &
783 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
784 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
786 if (status & SA_FLAGS_BREAK_DET)
787 icount->brk++;
788 if (status & SA_FLAGS_PARITY_ERROR)
789 icount->parity++;
790 if (status & SA_FLAGS_FRAME_ERROR)
791 icount->frame++;
792 if (status & SA_FLAGS_OVERRUN)
793 icount->overrun++;
796 * Now check to see if character should be
797 * ignored, and mask off conditions which
798 * should be ignored.
800 if (status & icom_port->ignore_status_mask) {
801 trace(icom_port, "IGNORE_CHAR", 0);
802 goto ignore_char;
805 status &= icom_port->read_status_mask;
807 if (status & SA_FLAGS_BREAK_DET) {
808 *tty->flip.flag_buf_ptr = TTY_BREAK;
809 } else if (status & SA_FLAGS_PARITY_ERROR) {
810 trace(icom_port, "PARITY_ERROR", 0);
811 *tty->flip.flag_buf_ptr = TTY_PARITY;
812 } else if (status & SA_FLAGS_FRAME_ERROR)
813 *tty->flip.flag_buf_ptr = TTY_FRAME;
815 if (status & SA_FLAGS_OVERRUN) {
817 * Overrun is special, since it's
818 * reported immediately, and doesn't
819 * affect the current character
821 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
822 tty->flip.count++;
823 tty->flip.flag_buf_ptr++;
824 tty->flip.char_buf_ptr++;
825 *tty->flip.flag_buf_ptr = TTY_OVERRUN;
830 tty->flip.flag_buf_ptr++;
831 tty->flip.char_buf_ptr++;
832 tty->flip.count++;
833 ignore_char:
834 icom_port->statStg->rcv[rcv_buff].flags = 0;
835 icom_port->statStg->rcv[rcv_buff].leLength = 0;
836 icom_port->statStg->rcv[rcv_buff].WorkingLength =
837 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
839 rcv_buff++;
840 if (rcv_buff == NUM_RBUFFS)
841 rcv_buff = 0;
843 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
845 icom_port->next_rcv = rcv_buff;
846 tty_flip_buffer_push(tty);
849 static void process_interrupt(u16 port_int_reg,
850 struct icom_port *icom_port)
853 spin_lock(&icom_port->uart_port.lock);
854 trace(icom_port, "INTERRUPT", port_int_reg);
856 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
857 xmit_interrupt(port_int_reg, icom_port);
859 if (port_int_reg & INT_RCV_COMPLETED)
860 recv_interrupt(port_int_reg, icom_port);
862 spin_unlock(&icom_port->uart_port.lock);
865 static irqreturn_t icom_interrupt(int irq, void *dev_id,
866 struct pt_regs *regs)
868 unsigned long int_reg;
869 u32 adapter_interrupts;
870 u16 port_int_reg;
871 struct icom_adapter *icom_adapter;
872 struct icom_port *icom_port;
874 /* find icom_port for this interrupt */
875 icom_adapter = (struct icom_adapter *) dev_id;
877 if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
878 int_reg = icom_adapter->base_addr + 0x8024;
880 adapter_interrupts = readl((void *) int_reg);
882 if (adapter_interrupts & 0x00003FFF) {
883 /* port 2 interrupt, NOTE: for all ADAPTER_V2, port 2 will be active */
884 icom_port = &icom_adapter->port_info[2];
885 port_int_reg = (u16) adapter_interrupts;
886 process_interrupt(port_int_reg, icom_port);
887 check_modem_status(icom_port);
889 if (adapter_interrupts & 0x3FFF0000) {
890 /* port 3 interrupt */
891 icom_port = &icom_adapter->port_info[3];
892 if (icom_port->status == ICOM_PORT_ACTIVE) {
893 port_int_reg =
894 (u16) (adapter_interrupts >> 16);
895 process_interrupt(port_int_reg, icom_port);
896 check_modem_status(icom_port);
900 /* Clear out any pending interrupts */
901 writel(adapter_interrupts, (void *) int_reg);
903 int_reg = icom_adapter->base_addr + 0x8004;
904 } else {
905 int_reg = icom_adapter->base_addr + 0x4004;
908 adapter_interrupts = readl((void *) int_reg);
910 if (adapter_interrupts & 0x00003FFF) {
911 /* port 0 interrupt, NOTE: for all adapters, port 0 will be active */
912 icom_port = &icom_adapter->port_info[0];
913 port_int_reg = (u16) adapter_interrupts;
914 process_interrupt(port_int_reg, icom_port);
915 check_modem_status(icom_port);
917 if (adapter_interrupts & 0x3FFF0000) {
918 /* port 1 interrupt */
919 icom_port = &icom_adapter->port_info[1];
920 if (icom_port->status == ICOM_PORT_ACTIVE) {
921 port_int_reg = (u16) (adapter_interrupts >> 16);
922 process_interrupt(port_int_reg, icom_port);
923 check_modem_status(icom_port);
927 /* Clear out any pending interrupts */
928 writel(adapter_interrupts, (void *) int_reg);
930 /* flush the write */
931 adapter_interrupts = readl((void *) int_reg);
933 return IRQ_HANDLED;
937 * ------------------------------------------------------------------
938 * Begin serial-core API
939 * ------------------------------------------------------------------
941 static unsigned int icom_tx_empty(struct uart_port *port)
943 int ret;
944 unsigned long flags;
946 spin_lock_irqsave(&port->lock, flags);
947 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
948 SA_FLAGS_READY_TO_XMIT)
949 ret = TIOCSER_TEMT;
950 else
951 ret = 0;
953 spin_unlock_irqrestore(&port->lock, flags);
954 return ret;
957 static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
959 unsigned char local_osr;
961 trace(ICOM_PORT, "SET_MODEM", 0);
962 local_osr = readb(&ICOM_PORT->dram->osr);
964 if (mctrl & TIOCM_RTS) {
965 trace(ICOM_PORT, "RAISE_RTS", 0);
966 local_osr |= ICOM_RTS;
967 } else {
968 trace(ICOM_PORT, "LOWER_RTS", 0);
969 local_osr &= ~ICOM_RTS;
972 if (mctrl & TIOCM_DTR) {
973 trace(ICOM_PORT, "RAISE_DTR", 0);
974 local_osr |= ICOM_DTR;
975 } else {
976 trace(ICOM_PORT, "LOWER_DTR", 0);
977 local_osr &= ~ICOM_DTR;
980 writeb(local_osr, &ICOM_PORT->dram->osr);
983 static unsigned int icom_get_mctrl(struct uart_port *port)
985 unsigned char status;
986 unsigned int result;
988 trace(ICOM_PORT, "GET_MODEM", 0);
990 status = readb(&ICOM_PORT->dram->isr);
992 result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
993 | ((status & ICOM_RI) ? TIOCM_RNG : 0)
994 | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
995 | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
996 return result;
999 static void icom_stop_tx(struct uart_port *port, unsigned int tty_stop)
1001 unsigned char cmdReg;
1003 if (tty_stop) {
1004 trace(ICOM_PORT, "STOP", 0);
1005 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1006 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
1010 static void icom_start_tx(struct uart_port *port, unsigned int tty_start)
1012 unsigned char cmdReg;
1014 trace(ICOM_PORT, "START", 0);
1015 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1016 if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
1017 writeb(cmdReg & ~CMD_HOLD_XMIT,
1018 &ICOM_PORT->dram->CmdReg);
1020 icom_write(port);
1023 static void icom_send_xchar(struct uart_port *port, char ch)
1025 unsigned char xdata;
1026 int index;
1027 unsigned long flags;
1029 trace(ICOM_PORT, "SEND_XCHAR", ch);
1031 /* wait .1 sec to send char */
1032 for (index = 0; index < 10; index++) {
1033 spin_lock_irqsave(&port->lock, flags);
1034 xdata = readb(&ICOM_PORT->dram->xchar);
1035 if (xdata == 0x00) {
1036 trace(ICOM_PORT, "QUICK_WRITE", 0);
1037 writeb(ch, &ICOM_PORT->dram->xchar);
1039 /* flush write operation */
1040 xdata = readb(&ICOM_PORT->dram->xchar);
1041 spin_unlock_irqrestore(&port->lock, flags);
1042 break;
1044 spin_unlock_irqrestore(&port->lock, flags);
1045 msleep(10);
1049 static void icom_stop_rx(struct uart_port *port)
1051 unsigned char cmdReg;
1053 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1054 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1057 static void icom_enable_ms(struct uart_port *port)
1059 /* no-op */
1062 static void icom_break(struct uart_port *port, int break_state)
1064 unsigned char cmdReg;
1065 unsigned long flags;
1067 spin_lock_irqsave(&port->lock, flags);
1068 trace(ICOM_PORT, "BREAK", 0);
1069 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1070 if (break_state == -1) {
1071 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1072 } else {
1073 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1075 spin_unlock_irqrestore(&port->lock, flags);
1078 static int icom_open(struct uart_port *port)
1080 int retval;
1082 kobject_get(&ICOM_PORT->adapter->kobj);
1083 retval = startup(ICOM_PORT);
1085 if (retval) {
1086 kobject_put(&ICOM_PORT->adapter->kobj);
1087 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1088 return retval;
1091 return 0;
1094 static void icom_close(struct uart_port *port)
1096 unsigned char cmdReg;
1098 trace(ICOM_PORT, "CLOSE", 0);
1100 /* stop receiver */
1101 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1102 writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1103 &ICOM_PORT->dram->CmdReg);
1105 shutdown(ICOM_PORT);
1107 kobject_put(&ICOM_PORT->adapter->kobj);
1110 static void icom_set_termios(struct uart_port *port,
1111 struct termios *termios,
1112 struct termios *old_termios)
1114 int baud;
1115 unsigned cflag, iflag;
1116 int bits;
1117 char new_config2;
1118 char new_config3 = 0;
1119 char tmp_byte;
1120 int index;
1121 int rcv_buff, xmit_buff;
1122 unsigned long offset;
1123 unsigned long flags;
1125 spin_lock_irqsave(&port->lock, flags);
1126 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1128 cflag = termios->c_cflag;
1129 iflag = termios->c_iflag;
1131 new_config2 = ICOM_ACFG_DRIVE1;
1133 /* byte size and parity */
1134 switch (cflag & CSIZE) {
1135 case CS5: /* 5 bits/char */
1136 new_config2 |= ICOM_ACFG_5BPC;
1137 bits = 7;
1138 break;
1139 case CS6: /* 6 bits/char */
1140 new_config2 |= ICOM_ACFG_6BPC;
1141 bits = 8;
1142 break;
1143 case CS7: /* 7 bits/char */
1144 new_config2 |= ICOM_ACFG_7BPC;
1145 bits = 9;
1146 break;
1147 case CS8: /* 8 bits/char */
1148 new_config2 |= ICOM_ACFG_8BPC;
1149 bits = 10;
1150 break;
1151 default:
1152 bits = 10;
1153 break;
1155 if (cflag & CSTOPB) {
1156 /* 2 stop bits */
1157 new_config2 |= ICOM_ACFG_2STOP_BIT;
1158 bits++;
1160 if (cflag & PARENB) {
1161 /* parity bit enabled */
1162 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1163 trace(ICOM_PORT, "PARENB", 0);
1164 bits++;
1166 if (cflag & PARODD) {
1167 /* odd parity */
1168 new_config2 |= ICOM_ACFG_PARITY_ODD;
1169 trace(ICOM_PORT, "PARODD", 0);
1172 /* Determine divisor based on baud rate */
1173 baud = uart_get_baud_rate(port, termios, old_termios,
1174 icom_acfg_baud[0],
1175 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1176 if (!baud)
1177 baud = 9600; /* B0 transition handled in rs_set_termios */
1179 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1180 if (icom_acfg_baud[index] == baud) {
1181 new_config3 = index;
1182 break;
1186 uart_update_timeout(port, cflag, baud);
1188 /* CTS flow control flag and modem status interrupts */
1189 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1190 if (cflag & CRTSCTS)
1191 tmp_byte |= HDLC_HDW_FLOW;
1192 else
1193 tmp_byte &= ~HDLC_HDW_FLOW;
1194 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1197 * Set up parity check flag
1199 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1200 if (iflag & INPCK)
1201 ICOM_PORT->read_status_mask |=
1202 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1204 if ((iflag & BRKINT) || (iflag & PARMRK))
1205 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1208 * Characters to ignore
1210 ICOM_PORT->ignore_status_mask = 0;
1211 if (iflag & IGNPAR)
1212 ICOM_PORT->ignore_status_mask |=
1213 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1214 if (iflag & IGNBRK) {
1215 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1217 * If we're ignore parity and break indicators, ignore
1218 * overruns too. (For real raw support).
1220 if (iflag & IGNPAR)
1221 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1225 * !!! ignore all characters if CREAD is not set
1227 if ((cflag & CREAD) == 0)
1228 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1230 /* Turn off Receiver to prepare for reset */
1231 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1233 for (index = 0; index < 10; index++) {
1234 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1235 break;
1239 /* clear all current buffers of data */
1240 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1241 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1242 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1243 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1244 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1247 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1248 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1251 /* activate changes and start xmit and receiver here */
1252 /* Enable the receiver */
1253 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1254 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1255 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1256 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1257 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1258 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer)); /* 0.5 seconds */
1259 writeb(0xFF, &(ICOM_PORT->dram->ier)); /* enable modem signal interrupts */
1261 /* reset processor */
1262 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1264 for (index = 0; index < 10; index++) {
1265 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1266 break;
1270 /* Enable Transmitter and Reciever */
1271 offset =
1272 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1273 (unsigned long) ICOM_PORT->statStg;
1274 writel(ICOM_PORT->statStg_pci + offset,
1275 &ICOM_PORT->dram->RcvStatusAddr);
1276 ICOM_PORT->next_rcv = 0;
1277 ICOM_PORT->put_length = 0;
1278 *ICOM_PORT->xmitRestart = 0;
1279 writel(ICOM_PORT->xmitRestart_pci,
1280 &ICOM_PORT->dram->XmitStatusAddr);
1281 trace(ICOM_PORT, "XR_ENAB", 0);
1282 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1284 spin_unlock_irqrestore(&port->lock, flags);
1287 static const char *icom_type(struct uart_port *port)
1289 return "icom";
1292 static void icom_release_port(struct uart_port *port)
1296 static int icom_request_port(struct uart_port *port)
1298 return 0;
1301 static void icom_config_port(struct uart_port *port, int flags)
1303 port->type = PORT_ICOM;
1306 static struct uart_ops icom_ops = {
1307 .tx_empty = icom_tx_empty,
1308 .set_mctrl = icom_set_mctrl,
1309 .get_mctrl = icom_get_mctrl,
1310 .stop_tx = icom_stop_tx,
1311 .start_tx = icom_start_tx,
1312 .send_xchar = icom_send_xchar,
1313 .stop_rx = icom_stop_rx,
1314 .enable_ms = icom_enable_ms,
1315 .break_ctl = icom_break,
1316 .startup = icom_open,
1317 .shutdown = icom_close,
1318 .set_termios = icom_set_termios,
1319 .type = icom_type,
1320 .release_port = icom_release_port,
1321 .request_port = icom_request_port,
1322 .config_port = icom_config_port,
1325 #define ICOM_CONSOLE NULL
1327 static struct uart_driver icom_uart_driver = {
1328 .owner = THIS_MODULE,
1329 .driver_name = ICOM_DRIVER_NAME,
1330 .dev_name = "ttyA",
1331 .major = ICOM_MAJOR,
1332 .minor = ICOM_MINOR_START,
1333 .nr = NR_PORTS,
1334 .cons = ICOM_CONSOLE,
1337 static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1339 u32 subsystem_id = icom_adapter->subsystem_id;
1340 int retval = 0;
1341 int i;
1342 struct icom_port *icom_port;
1344 if (icom_adapter->version == ADAPTER_V1) {
1345 icom_adapter->numb_ports = 2;
1347 for (i = 0; i < 2; i++) {
1348 icom_port = &icom_adapter->port_info[i];
1349 icom_port->port = i;
1350 icom_port->status = ICOM_PORT_ACTIVE;
1351 icom_port->imbed_modem = ICOM_UNKNOWN;
1353 } else {
1354 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1355 icom_adapter->numb_ports = 4;
1357 for (i = 0; i < 4; i++) {
1358 icom_port = &icom_adapter->port_info[i];
1360 icom_port->port = i;
1361 icom_port->status = ICOM_PORT_ACTIVE;
1362 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1364 } else {
1365 icom_adapter->numb_ports = 4;
1367 icom_adapter->port_info[0].port = 0;
1368 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1370 if (subsystem_id ==
1371 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1372 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1373 } else {
1374 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1377 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1379 icom_adapter->port_info[2].port = 2;
1380 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1381 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1382 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1386 return retval;
1389 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1391 if (icom_adapter->version == ADAPTER_V1) {
1392 icom_port->global_reg = (struct icom_regs *) ((char *)
1393 icom_adapter->base_addr + 0x4000);
1394 icom_port->int_reg = (unsigned long) icom_adapter->base_addr +
1395 0x4004 + 2 - 2 * port_num;
1396 } else {
1397 icom_port->global_reg = (struct icom_regs *) ((char *)
1398 icom_adapter->base_addr + 0x8000);
1399 if (icom_port->port < 2)
1400 icom_port->int_reg = (unsigned long) icom_adapter->base_addr +
1401 0x8004 + 2 - 2 * icom_port->port;
1402 else
1403 icom_port->int_reg = (unsigned long) icom_adapter->base_addr +
1404 0x8024 + 2 - 2 * (icom_port->port - 2);
1407 static int __init icom_load_ports(struct icom_adapter *icom_adapter)
1409 struct icom_port *icom_port;
1410 int port_num;
1411 int retval;
1413 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1415 icom_port = &icom_adapter->port_info[port_num];
1417 if (icom_port->status == ICOM_PORT_ACTIVE) {
1418 icom_port_active(icom_port, icom_adapter, port_num);
1419 icom_port->dram = (struct func_dram *) ((char *)
1420 icom_adapter->base_addr +
1421 0x2000 * icom_port->port);
1423 icom_port->adapter = icom_adapter;
1425 /* get port memory */
1426 if ((retval = get_port_memory(icom_port)) != 0) {
1427 dev_err(&icom_port->adapter->pci_dev->dev,
1428 "Memory allocation for port FAILED\n");
1432 return 0;
1435 static int __devinit icom_alloc_adapter(struct icom_adapter
1436 **icom_adapter_ref)
1438 int adapter_count = 0;
1439 struct icom_adapter *icom_adapter;
1440 struct icom_adapter *cur_adapter_entry;
1441 struct list_head *tmp;
1443 icom_adapter = (struct icom_adapter *)
1444 kmalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1446 if (!icom_adapter) {
1447 return -ENOMEM;
1450 memset(icom_adapter, 0, sizeof(struct icom_adapter));
1452 list_for_each(tmp, &icom_adapter_head) {
1453 cur_adapter_entry =
1454 list_entry(tmp, struct icom_adapter,
1455 icom_adapter_entry);
1456 if (cur_adapter_entry->index != adapter_count) {
1457 break;
1459 adapter_count++;
1462 icom_adapter->index = adapter_count;
1463 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1465 *icom_adapter_ref = icom_adapter;
1466 return 0;
1469 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1471 list_del(&icom_adapter->icom_adapter_entry);
1472 kfree(icom_adapter);
1475 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1477 struct icom_port *icom_port;
1478 int index;
1480 for (index = 0; index < icom_adapter->numb_ports; index++) {
1481 icom_port = &icom_adapter->port_info[index];
1483 if (icom_port->status == ICOM_PORT_ACTIVE) {
1484 dev_info(&icom_adapter->pci_dev->dev,
1485 "Device removed\n");
1487 uart_remove_one_port(&icom_uart_driver,
1488 &icom_port->uart_port);
1490 /* be sure that DTR and RTS are dropped */
1491 writeb(0x00, &icom_port->dram->osr);
1493 /* Wait 0.1 Sec for simple Init to complete */
1494 msleep(100);
1496 /* Stop proccessor */
1497 stop_processor(icom_port);
1499 free_port_memory(icom_port);
1503 free_irq(icom_adapter->irq_number, (void *) icom_adapter);
1504 iounmap((void *) icom_adapter->base_addr);
1505 icom_free_adapter(icom_adapter);
1506 pci_release_regions(icom_adapter->pci_dev);
1509 static void icom_kobj_release(struct kobject *kobj)
1511 struct icom_adapter *icom_adapter;
1513 icom_adapter = to_icom_adapter(kobj);
1514 icom_remove_adapter(icom_adapter);
1517 static struct kobj_type icom_kobj_type = {
1518 .release = icom_kobj_release,
1521 static int __devinit icom_probe(struct pci_dev *dev,
1522 const struct pci_device_id *ent)
1524 int index;
1525 unsigned int command_reg;
1526 int retval;
1527 struct icom_adapter *icom_adapter;
1528 struct icom_port *icom_port;
1530 retval = pci_enable_device(dev);
1531 if (retval) {
1532 dev_err(&dev->dev, "Device enable FAILED\n");
1533 return retval;
1536 if ( (retval = pci_request_regions(dev, "icom"))) {
1537 dev_err(&dev->dev, "pci_request_region FAILED\n");
1538 pci_disable_device(dev);
1539 return retval;
1542 pci_set_master(dev);
1544 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1545 dev_err(&dev->dev, "PCI Config read FAILED\n");
1546 return retval;
1549 pci_write_config_dword(dev, PCI_COMMAND,
1550 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1551 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1553 if (ent->driver_data == ADAPTER_V1) {
1554 pci_write_config_dword(dev, 0x44, 0x8300830A);
1555 } else {
1556 pci_write_config_dword(dev, 0x44, 0x42004200);
1557 pci_write_config_dword(dev, 0x48, 0x42004200);
1561 retval = icom_alloc_adapter(&icom_adapter);
1562 if (retval) {
1563 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1564 retval = -EIO;
1565 goto probe_exit0;
1568 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1569 icom_adapter->irq_number = dev->irq;
1570 icom_adapter->pci_dev = dev;
1571 icom_adapter->version = ent->driver_data;
1572 icom_adapter->subsystem_id = ent->subdevice;
1575 retval = icom_init_ports(icom_adapter);
1576 if (retval) {
1577 dev_err(&dev->dev, "Port configuration failed\n");
1578 goto probe_exit1;
1581 icom_adapter->base_addr =
1582 (unsigned long) ioremap(icom_adapter->base_addr_pci,
1583 pci_resource_len(dev, 0));
1585 if (!icom_adapter->base_addr)
1586 goto probe_exit1;
1588 /* save off irq and request irq line */
1589 if ( (retval = request_irq(dev->irq, icom_interrupt,
1590 SA_INTERRUPT | SA_SHIRQ, ICOM_DRIVER_NAME,
1591 (void *) icom_adapter))) {
1592 goto probe_exit2;
1595 retval = icom_load_ports(icom_adapter);
1597 for (index = 0; index < icom_adapter->numb_ports; index++) {
1598 icom_port = &icom_adapter->port_info[index];
1600 if (icom_port->status == ICOM_PORT_ACTIVE) {
1601 icom_port->uart_port.irq = icom_port->adapter->irq_number;
1602 icom_port->uart_port.type = PORT_ICOM;
1603 icom_port->uart_port.iotype = UPIO_MEM;
1604 icom_port->uart_port.membase =
1605 (char *) icom_adapter->base_addr_pci;
1606 icom_port->uart_port.fifosize = 16;
1607 icom_port->uart_port.ops = &icom_ops;
1608 icom_port->uart_port.line =
1609 icom_port->port + icom_adapter->index * 4;
1610 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1611 icom_port->status = ICOM_PORT_OFF;
1612 dev_err(&dev->dev, "Device add failed\n");
1613 } else
1614 dev_info(&dev->dev, "Device added\n");
1618 kobject_init(&icom_adapter->kobj);
1619 icom_adapter->kobj.ktype = &icom_kobj_type;
1620 return 0;
1622 probe_exit2:
1623 iounmap((void *) icom_adapter->base_addr);
1624 probe_exit1:
1625 icom_free_adapter(icom_adapter);
1627 probe_exit0:
1628 pci_release_regions(dev);
1629 pci_disable_device(dev);
1631 return retval;
1636 static void __devexit icom_remove(struct pci_dev *dev)
1638 struct icom_adapter *icom_adapter;
1639 struct list_head *tmp;
1641 list_for_each(tmp, &icom_adapter_head) {
1642 icom_adapter = list_entry(tmp, struct icom_adapter,
1643 icom_adapter_entry);
1644 if (icom_adapter->pci_dev == dev) {
1645 kobject_put(&icom_adapter->kobj);
1646 return;
1650 dev_err(&dev->dev, "Unable to find device to remove\n");
1653 static struct pci_driver icom_pci_driver = {
1654 .name = ICOM_DRIVER_NAME,
1655 .id_table = icom_pci_table,
1656 .probe = icom_probe,
1657 .remove = __devexit_p(icom_remove),
1660 static int __init icom_init(void)
1662 int ret;
1664 spin_lock_init(&icom_lock);
1665 icom_lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
1667 ret = uart_register_driver(&icom_uart_driver);
1668 if (ret)
1669 return ret;
1671 ret = pci_register_driver(&icom_pci_driver);
1673 if (ret < 0)
1674 uart_unregister_driver(&icom_uart_driver);
1676 return ret;
1679 static void __exit icom_exit(void)
1681 pci_unregister_driver(&icom_pci_driver);
1682 uart_unregister_driver(&icom_uart_driver);
1685 module_init(icom_init);
1686 module_exit(icom_exit);
1688 #ifdef ICOM_TRACE
1689 static inline void trace(struct icom_port *icom_port, char *trace_pt,
1690 unsigned long trace_data)
1692 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1693 icom_port->port, trace_pt, trace_data);
1695 #endif
1697 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1698 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1699 MODULE_SUPPORTED_DEVICE
1700 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1701 MODULE_LICENSE("GPL");