cmd64x: don't clear the other channel's interrupt
[linux-2.6/linux-mips/linux-dm7025.git] / drivers / serial / icom.c
blob9d3105b64a7a597ba3f634ad4b270dd72d7e4ff9
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/kernel.h>
28 #include <linux/errno.h>
29 #include <linux/signal.h>
30 #include <linux/timer.h>
31 #include <linux/interrupt.h>
32 #include <linux/tty.h>
33 #include <linux/termios.h>
34 #include <linux/fs.h>
35 #include <linux/tty_flip.h>
36 #include <linux/serial.h>
37 #include <linux/serial_reg.h>
38 #include <linux/major.h>
39 #include <linux/string.h>
40 #include <linux/fcntl.h>
41 #include <linux/ptrace.h>
42 #include <linux/ioport.h>
43 #include <linux/mm.h>
44 #include <linux/slab.h>
45 #include <linux/init.h>
46 #include <linux/delay.h>
47 #include <linux/pci.h>
48 #include <linux/vmalloc.h>
49 #include <linux/smp.h>
50 #include <linux/spinlock.h>
51 #include <linux/kobject.h>
52 #include <linux/firmware.h>
53 #include <linux/bitops.h>
55 #include <asm/system.h>
56 #include <asm/io.h>
57 #include <asm/irq.h>
58 #include <asm/uaccess.h>
60 #include "icom.h"
62 /*#define ICOM_TRACE enable port trace capabilities */
64 #define ICOM_DRIVER_NAME "icom"
65 #define ICOM_VERSION_STR "1.3.1"
66 #define NR_PORTS 128
67 #define ICOM_PORT ((struct icom_port *)port)
68 #define to_icom_adapter(d) container_of(d, struct icom_adapter, kobj)
70 static const struct pci_device_id icom_pci_table[] = {
72 .vendor = PCI_VENDOR_ID_IBM,
73 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
74 .subvendor = PCI_ANY_ID,
75 .subdevice = PCI_ANY_ID,
76 .driver_data = ADAPTER_V1,
79 .vendor = PCI_VENDOR_ID_IBM,
80 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
81 .subvendor = PCI_VENDOR_ID_IBM,
82 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
83 .driver_data = ADAPTER_V2,
86 .vendor = PCI_VENDOR_ID_IBM,
87 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
88 .subvendor = PCI_VENDOR_ID_IBM,
89 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
90 .driver_data = ADAPTER_V2,
93 .vendor = PCI_VENDOR_ID_IBM,
94 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
95 .subvendor = PCI_VENDOR_ID_IBM,
96 .subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
97 .driver_data = ADAPTER_V2,
100 .vendor = PCI_VENDOR_ID_IBM,
101 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
102 .subvendor = PCI_VENDOR_ID_IBM,
103 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE,
104 .driver_data = ADAPTER_V2,
109 struct lookup_proc_table start_proc[4] = {
110 {NULL, ICOM_CONTROL_START_A},
111 {NULL, ICOM_CONTROL_START_B},
112 {NULL, ICOM_CONTROL_START_C},
113 {NULL, ICOM_CONTROL_START_D}
117 struct lookup_proc_table stop_proc[4] = {
118 {NULL, ICOM_CONTROL_STOP_A},
119 {NULL, ICOM_CONTROL_STOP_B},
120 {NULL, ICOM_CONTROL_STOP_C},
121 {NULL, ICOM_CONTROL_STOP_D}
124 struct lookup_int_table int_mask_tbl[4] = {
125 {NULL, ICOM_INT_MASK_PRC_A},
126 {NULL, ICOM_INT_MASK_PRC_B},
127 {NULL, ICOM_INT_MASK_PRC_C},
128 {NULL, ICOM_INT_MASK_PRC_D},
132 MODULE_DEVICE_TABLE(pci, icom_pci_table);
134 static LIST_HEAD(icom_adapter_head);
136 /* spinlock for adapter initialization and changing adapter operations */
137 static spinlock_t icom_lock;
139 #ifdef ICOM_TRACE
140 static inline void trace(struct icom_port *, char *, unsigned long) {};
141 #else
142 static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
143 #endif
145 static void free_port_memory(struct icom_port *icom_port)
147 struct pci_dev *dev = icom_port->adapter->pci_dev;
149 trace(icom_port, "RET_PORT_MEM", 0);
150 if (icom_port->recv_buf) {
151 pci_free_consistent(dev, 4096, icom_port->recv_buf,
152 icom_port->recv_buf_pci);
153 icom_port->recv_buf = NULL;
155 if (icom_port->xmit_buf) {
156 pci_free_consistent(dev, 4096, icom_port->xmit_buf,
157 icom_port->xmit_buf_pci);
158 icom_port->xmit_buf = NULL;
160 if (icom_port->statStg) {
161 pci_free_consistent(dev, 4096, icom_port->statStg,
162 icom_port->statStg_pci);
163 icom_port->statStg = NULL;
166 if (icom_port->xmitRestart) {
167 pci_free_consistent(dev, 4096, icom_port->xmitRestart,
168 icom_port->xmitRestart_pci);
169 icom_port->xmitRestart = NULL;
173 static int __devinit get_port_memory(struct icom_port *icom_port)
175 int index;
176 unsigned long stgAddr;
177 unsigned long startStgAddr;
178 unsigned long offset;
179 struct pci_dev *dev = icom_port->adapter->pci_dev;
181 icom_port->xmit_buf =
182 pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
183 if (!icom_port->xmit_buf) {
184 dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
185 return -ENOMEM;
188 trace(icom_port, "GET_PORT_MEM",
189 (unsigned long) icom_port->xmit_buf);
191 icom_port->recv_buf =
192 pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
193 if (!icom_port->recv_buf) {
194 dev_err(&dev->dev, "Can not allocate Receive buffer\n");
195 free_port_memory(icom_port);
196 return -ENOMEM;
198 trace(icom_port, "GET_PORT_MEM",
199 (unsigned long) icom_port->recv_buf);
201 icom_port->statStg =
202 pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
203 if (!icom_port->statStg) {
204 dev_err(&dev->dev, "Can not allocate Status buffer\n");
205 free_port_memory(icom_port);
206 return -ENOMEM;
208 trace(icom_port, "GET_PORT_MEM",
209 (unsigned long) icom_port->statStg);
211 icom_port->xmitRestart =
212 pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
213 if (!icom_port->xmitRestart) {
214 dev_err(&dev->dev,
215 "Can not allocate xmit Restart buffer\n");
216 free_port_memory(icom_port);
217 return -ENOMEM;
220 memset(icom_port->statStg, 0, 4096);
222 /* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
223 indicates that frames are to be transmitted
226 stgAddr = (unsigned long) icom_port->statStg;
227 for (index = 0; index < NUM_XBUFFS; index++) {
228 trace(icom_port, "FOD_ADDR", stgAddr);
229 stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
230 if (index < (NUM_XBUFFS - 1)) {
231 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
232 icom_port->statStg->xmit[index].leLengthASD =
233 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
234 trace(icom_port, "FOD_ADDR", stgAddr);
235 trace(icom_port, "FOD_XBUFF",
236 (unsigned long) icom_port->xmit_buf);
237 icom_port->statStg->xmit[index].leBuffer =
238 cpu_to_le32(icom_port->xmit_buf_pci);
239 } else if (index == (NUM_XBUFFS - 1)) {
240 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
241 icom_port->statStg->xmit[index].leLengthASD =
242 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
243 trace(icom_port, "FOD_XBUFF",
244 (unsigned long) icom_port->xmit_buf);
245 icom_port->statStg->xmit[index].leBuffer =
246 cpu_to_le32(icom_port->xmit_buf_pci);
247 } else {
248 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
251 /* FIDs */
252 startStgAddr = stgAddr;
254 /* fill in every entry, even if no buffer */
255 for (index = 0; index < NUM_RBUFFS; index++) {
256 trace(icom_port, "FID_ADDR", stgAddr);
257 stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
258 icom_port->statStg->rcv[index].leLength = 0;
259 icom_port->statStg->rcv[index].WorkingLength =
260 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
261 if (index < (NUM_RBUFFS - 1) ) {
262 offset = stgAddr - (unsigned long) icom_port->statStg;
263 icom_port->statStg->rcv[index].leNext =
264 cpu_to_le32(icom_port-> statStg_pci + offset);
265 trace(icom_port, "FID_RBUFF",
266 (unsigned long) icom_port->recv_buf);
267 icom_port->statStg->rcv[index].leBuffer =
268 cpu_to_le32(icom_port->recv_buf_pci);
269 } else if (index == (NUM_RBUFFS -1) ) {
270 offset = startStgAddr - (unsigned long) icom_port->statStg;
271 icom_port->statStg->rcv[index].leNext =
272 cpu_to_le32(icom_port-> statStg_pci + offset);
273 trace(icom_port, "FID_RBUFF",
274 (unsigned long) icom_port->recv_buf + 2048);
275 icom_port->statStg->rcv[index].leBuffer =
276 cpu_to_le32(icom_port->recv_buf_pci + 2048);
277 } else {
278 icom_port->statStg->rcv[index].leNext = 0;
279 icom_port->statStg->rcv[index].leBuffer = 0;
283 return 0;
286 static void stop_processor(struct icom_port *icom_port)
288 unsigned long temp;
289 unsigned long flags;
290 int port;
292 spin_lock_irqsave(&icom_lock, flags);
294 port = icom_port->port;
295 if (port == 0 || port == 1)
296 stop_proc[port].global_control_reg = &icom_port->global_reg->control;
297 else
298 stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
301 if (port < 4) {
302 temp = readl(stop_proc[port].global_control_reg);
303 temp =
304 (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
305 writel(temp, stop_proc[port].global_control_reg);
307 /* write flush */
308 readl(stop_proc[port].global_control_reg);
309 } else {
310 dev_err(&icom_port->adapter->pci_dev->dev,
311 "Invalid port assignment\n");
314 spin_unlock_irqrestore(&icom_lock, flags);
317 static void start_processor(struct icom_port *icom_port)
319 unsigned long temp;
320 unsigned long flags;
321 int port;
323 spin_lock_irqsave(&icom_lock, flags);
325 port = icom_port->port;
326 if (port == 0 || port == 1)
327 start_proc[port].global_control_reg = &icom_port->global_reg->control;
328 else
329 start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
330 if (port < 4) {
331 temp = readl(start_proc[port].global_control_reg);
332 temp =
333 (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
334 writel(temp, start_proc[port].global_control_reg);
336 /* write flush */
337 readl(start_proc[port].global_control_reg);
338 } else {
339 dev_err(&icom_port->adapter->pci_dev->dev,
340 "Invalid port assignment\n");
343 spin_unlock_irqrestore(&icom_lock, flags);
346 static void load_code(struct icom_port *icom_port)
348 const struct firmware *fw;
349 char __iomem *iram_ptr;
350 int index;
351 int status = 0;
352 void __iomem *dram_ptr = icom_port->dram;
353 dma_addr_t temp_pci;
354 unsigned char *new_page = NULL;
355 unsigned char cable_id = NO_CABLE;
356 struct pci_dev *dev = icom_port->adapter->pci_dev;
358 /* Clear out any pending interrupts */
359 writew(0x3FFF, icom_port->int_reg);
361 trace(icom_port, "CLEAR_INTERRUPTS", 0);
363 /* Stop processor */
364 stop_processor(icom_port);
366 /* Zero out DRAM */
367 memset_io(dram_ptr, 0, 512);
369 /* Load Call Setup into Adapter */
370 if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
371 dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
372 status = -1;
373 goto load_code_exit;
376 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
377 dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
378 release_firmware(fw);
379 status = -1;
380 goto load_code_exit;
383 iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
384 for (index = 0; index < fw->size; index++)
385 writeb(fw->data[index], &iram_ptr[index]);
387 release_firmware(fw);
389 /* Load Resident DCE portion of Adapter */
390 if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
391 dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
392 status = -1;
393 goto load_code_exit;
396 if (fw->size > ICOM_IRAM_SIZE) {
397 dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
398 release_firmware(fw);
399 status = -1;
400 goto load_code_exit;
403 iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
404 for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
405 writeb(fw->data[index], &iram_ptr[index]);
407 release_firmware(fw);
409 /* Set Hardware level */
410 if ((icom_port->adapter->version | ADAPTER_V2) == ADAPTER_V2)
411 writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));
413 /* Start the processor in Adapter */
414 start_processor(icom_port);
416 writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
417 &(icom_port->dram->HDLCConfigReg));
418 writeb(0x04, &(icom_port->dram->FlagFillIdleTimer)); /* 0.5 seconds */
419 writeb(0x00, &(icom_port->dram->CmdReg));
420 writeb(0x10, &(icom_port->dram->async_config3));
421 writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
422 ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));
424 /*Set up data in icom DRAM to indicate where personality
425 *code is located and its length.
427 new_page = pci_alloc_consistent(dev, 4096, &temp_pci);
429 if (!new_page) {
430 dev_err(&dev->dev, "Can not allocate DMA buffer\n");
431 status = -1;
432 goto load_code_exit;
435 if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
436 dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
437 status = -1;
438 goto load_code_exit;
441 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
442 dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
443 release_firmware(fw);
444 status = -1;
445 goto load_code_exit;
448 for (index = 0; index < fw->size; index++)
449 new_page[index] = fw->data[index];
451 release_firmware(fw);
453 writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
454 writel(temp_pci, &icom_port->dram->mac_load_addr);
456 /*Setting the syncReg to 0x80 causes adapter to start downloading
457 the personality code into adapter instruction RAM.
458 Once code is loaded, it will begin executing and, based on
459 information provided above, will start DMAing data from
460 shared memory to adapter DRAM.
462 /* the wait loop below verifies this write operation has been done
463 and processed
465 writeb(START_DOWNLOAD, &icom_port->dram->sync);
467 /* Wait max 1 Sec for data download and processor to start */
468 for (index = 0; index < 10; index++) {
469 msleep(100);
470 if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
471 break;
474 if (index == 10)
475 status = -1;
478 * check Cable ID
480 cable_id = readb(&icom_port->dram->cable_id);
482 if (cable_id & ICOM_CABLE_ID_VALID) {
483 /* Get cable ID into the lower 4 bits (standard form) */
484 cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
485 icom_port->cable_id = cable_id;
486 } else {
487 dev_err(&dev->dev,"Invalid or no cable attached\n");
488 icom_port->cable_id = NO_CABLE;
491 load_code_exit:
493 if (status != 0) {
494 /* Clear out any pending interrupts */
495 writew(0x3FFF, icom_port->int_reg);
497 /* Turn off port */
498 writeb(ICOM_DISABLE, &(icom_port->dram->disable));
500 /* Stop processor */
501 stop_processor(icom_port);
503 dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
506 if (new_page != NULL)
507 pci_free_consistent(dev, 4096, new_page, temp_pci);
510 static int startup(struct icom_port *icom_port)
512 unsigned long temp;
513 unsigned char cable_id, raw_cable_id;
514 unsigned long flags;
515 int port;
517 trace(icom_port, "STARTUP", 0);
519 if (!icom_port->dram) {
520 /* should NEVER be NULL */
521 dev_err(&icom_port->adapter->pci_dev->dev,
522 "Unusable Port, port configuration missing\n");
523 return -ENODEV;
527 * check Cable ID
529 raw_cable_id = readb(&icom_port->dram->cable_id);
530 trace(icom_port, "CABLE_ID", raw_cable_id);
532 /* Get cable ID into the lower 4 bits (standard form) */
533 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
535 /* Check for valid Cable ID */
536 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
537 (cable_id != icom_port->cable_id)) {
539 /* reload adapter code, pick up any potential changes in cable id */
540 load_code(icom_port);
542 /* still no sign of cable, error out */
543 raw_cable_id = readb(&icom_port->dram->cable_id);
544 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
545 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
546 (icom_port->cable_id == NO_CABLE))
547 return -EIO;
551 * Finally, clear and enable interrupts
553 spin_lock_irqsave(&icom_lock, flags);
554 port = icom_port->port;
555 if (port == 0 || port == 1)
556 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
557 else
558 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
560 if (port == 0 || port == 2)
561 writew(0x00FF, icom_port->int_reg);
562 else
563 writew(0x3F00, icom_port->int_reg);
564 if (port < 4) {
565 temp = readl(int_mask_tbl[port].global_int_mask);
566 writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
568 /* write flush */
569 readl(int_mask_tbl[port].global_int_mask);
570 } else {
571 dev_err(&icom_port->adapter->pci_dev->dev,
572 "Invalid port assignment\n");
575 spin_unlock_irqrestore(&icom_lock, flags);
576 return 0;
579 static void shutdown(struct icom_port *icom_port)
581 unsigned long temp;
582 unsigned char cmdReg;
583 unsigned long flags;
584 int port;
586 spin_lock_irqsave(&icom_lock, flags);
587 trace(icom_port, "SHUTDOWN", 0);
590 * disable all interrupts
592 port = icom_port->port;
593 if (port == 0 || port == 1)
594 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
595 else
596 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
598 if (port < 4) {
599 temp = readl(int_mask_tbl[port].global_int_mask);
600 writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
602 /* write flush */
603 readl(int_mask_tbl[port].global_int_mask);
604 } else {
605 dev_err(&icom_port->adapter->pci_dev->dev,
606 "Invalid port assignment\n");
608 spin_unlock_irqrestore(&icom_lock, flags);
611 * disable break condition
613 cmdReg = readb(&icom_port->dram->CmdReg);
614 if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) {
615 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
619 static int icom_write(struct uart_port *port)
621 unsigned long data_count;
622 unsigned char cmdReg;
623 unsigned long offset;
624 int temp_tail = port->info->xmit.tail;
626 trace(ICOM_PORT, "WRITE", 0);
628 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
629 SA_FLAGS_READY_TO_XMIT) {
630 trace(ICOM_PORT, "WRITE_FULL", 0);
631 return 0;
634 data_count = 0;
635 while ((port->info->xmit.head != temp_tail) &&
636 (data_count <= XMIT_BUFF_SZ)) {
638 ICOM_PORT->xmit_buf[data_count++] =
639 port->info->xmit.buf[temp_tail];
641 temp_tail++;
642 temp_tail &= (UART_XMIT_SIZE - 1);
645 if (data_count) {
646 ICOM_PORT->statStg->xmit[0].flags =
647 cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
648 ICOM_PORT->statStg->xmit[0].leLength =
649 cpu_to_le16(data_count);
650 offset =
651 (unsigned long) &ICOM_PORT->statStg->xmit[0] -
652 (unsigned long) ICOM_PORT->statStg;
653 *ICOM_PORT->xmitRestart =
654 cpu_to_le32(ICOM_PORT->statStg_pci + offset);
655 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
656 writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
657 &ICOM_PORT->dram->CmdReg);
658 writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
659 trace(ICOM_PORT, "WRITE_START", data_count);
660 /* write flush */
661 readb(&ICOM_PORT->dram->StartXmitCmd);
664 return data_count;
667 static inline void check_modem_status(struct icom_port *icom_port)
669 static char old_status = 0;
670 char delta_status;
671 unsigned char status;
673 spin_lock(&icom_port->uart_port.lock);
675 /*modem input register */
676 status = readb(&icom_port->dram->isr);
677 trace(icom_port, "CHECK_MODEM", status);
678 delta_status = status ^ old_status;
679 if (delta_status) {
680 if (delta_status & ICOM_RI)
681 icom_port->uart_port.icount.rng++;
682 if (delta_status & ICOM_DSR)
683 icom_port->uart_port.icount.dsr++;
684 if (delta_status & ICOM_DCD)
685 uart_handle_dcd_change(&icom_port->uart_port,
686 delta_status & ICOM_DCD);
687 if (delta_status & ICOM_CTS)
688 uart_handle_cts_change(&icom_port->uart_port,
689 delta_status & ICOM_CTS);
691 wake_up_interruptible(&icom_port->uart_port.info->
692 delta_msr_wait);
693 old_status = status;
695 spin_unlock(&icom_port->uart_port.lock);
698 static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
700 unsigned short int count;
701 int i;
703 if (port_int_reg & (INT_XMIT_COMPLETED)) {
704 trace(icom_port, "XMIT_COMPLETE", 0);
706 /* clear buffer in use bit */
707 icom_port->statStg->xmit[0].flags &=
708 cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
710 count = (unsigned short int)
711 cpu_to_le16(icom_port->statStg->xmit[0].leLength);
712 icom_port->uart_port.icount.tx += count;
714 for (i=0; i<count &&
715 !uart_circ_empty(&icom_port->uart_port.info->xmit); i++) {
717 icom_port->uart_port.info->xmit.tail++;
718 icom_port->uart_port.info->xmit.tail &=
719 (UART_XMIT_SIZE - 1);
722 if (!icom_write(&icom_port->uart_port))
723 /* activate write queue */
724 uart_write_wakeup(&icom_port->uart_port);
725 } else
726 trace(icom_port, "XMIT_DISABLED", 0);
729 static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
731 short int count, rcv_buff;
732 struct tty_struct *tty = icom_port->uart_port.info->tty;
733 unsigned short int status;
734 struct uart_icount *icount;
735 unsigned long offset;
736 unsigned char flag;
738 trace(icom_port, "RCV_COMPLETE", 0);
739 rcv_buff = icom_port->next_rcv;
741 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
742 while (status & SA_FL_RCV_DONE) {
743 int first = -1;
745 trace(icom_port, "FID_STATUS", status);
746 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
748 count = tty_buffer_request_room(tty, count);
749 trace(icom_port, "RCV_COUNT", count);
751 trace(icom_port, "REAL_COUNT", count);
753 offset =
754 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
755 icom_port->recv_buf_pci;
757 /* Block copy all but the last byte as this may have status */
758 if (count > 0) {
759 first = icom_port->recv_buf[offset];
760 tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1);
763 icount = &icom_port->uart_port.icount;
764 icount->rx += count;
766 /* Break detect logic */
767 if ((status & SA_FLAGS_FRAME_ERROR)
768 && first == 0) {
769 status &= ~SA_FLAGS_FRAME_ERROR;
770 status |= SA_FLAGS_BREAK_DET;
771 trace(icom_port, "BREAK_DET", 0);
774 flag = TTY_NORMAL;
776 if (status &
777 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
778 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
780 if (status & SA_FLAGS_BREAK_DET)
781 icount->brk++;
782 if (status & SA_FLAGS_PARITY_ERROR)
783 icount->parity++;
784 if (status & SA_FLAGS_FRAME_ERROR)
785 icount->frame++;
786 if (status & SA_FLAGS_OVERRUN)
787 icount->overrun++;
790 * Now check to see if character should be
791 * ignored, and mask off conditions which
792 * should be ignored.
794 if (status & icom_port->ignore_status_mask) {
795 trace(icom_port, "IGNORE_CHAR", 0);
796 goto ignore_char;
799 status &= icom_port->read_status_mask;
801 if (status & SA_FLAGS_BREAK_DET) {
802 flag = TTY_BREAK;
803 } else if (status & SA_FLAGS_PARITY_ERROR) {
804 trace(icom_port, "PARITY_ERROR", 0);
805 flag = TTY_PARITY;
806 } else if (status & SA_FLAGS_FRAME_ERROR)
807 flag = TTY_FRAME;
811 tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag);
813 if (status & SA_FLAGS_OVERRUN)
815 * Overrun is special, since it's
816 * reported immediately, and doesn't
817 * affect the current character
819 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
820 ignore_char:
821 icom_port->statStg->rcv[rcv_buff].flags = 0;
822 icom_port->statStg->rcv[rcv_buff].leLength = 0;
823 icom_port->statStg->rcv[rcv_buff].WorkingLength =
824 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
826 rcv_buff++;
827 if (rcv_buff == NUM_RBUFFS)
828 rcv_buff = 0;
830 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
832 icom_port->next_rcv = rcv_buff;
833 tty_flip_buffer_push(tty);
836 static void process_interrupt(u16 port_int_reg,
837 struct icom_port *icom_port)
840 spin_lock(&icom_port->uart_port.lock);
841 trace(icom_port, "INTERRUPT", port_int_reg);
843 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
844 xmit_interrupt(port_int_reg, icom_port);
846 if (port_int_reg & INT_RCV_COMPLETED)
847 recv_interrupt(port_int_reg, icom_port);
849 spin_unlock(&icom_port->uart_port.lock);
852 static irqreturn_t icom_interrupt(int irq, void *dev_id)
854 void __iomem * int_reg;
855 u32 adapter_interrupts;
856 u16 port_int_reg;
857 struct icom_adapter *icom_adapter;
858 struct icom_port *icom_port;
860 /* find icom_port for this interrupt */
861 icom_adapter = (struct icom_adapter *) dev_id;
863 if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
864 int_reg = icom_adapter->base_addr + 0x8024;
866 adapter_interrupts = readl(int_reg);
868 if (adapter_interrupts & 0x00003FFF) {
869 /* port 2 interrupt, NOTE: for all ADAPTER_V2, port 2 will be active */
870 icom_port = &icom_adapter->port_info[2];
871 port_int_reg = (u16) adapter_interrupts;
872 process_interrupt(port_int_reg, icom_port);
873 check_modem_status(icom_port);
875 if (adapter_interrupts & 0x3FFF0000) {
876 /* port 3 interrupt */
877 icom_port = &icom_adapter->port_info[3];
878 if (icom_port->status == ICOM_PORT_ACTIVE) {
879 port_int_reg =
880 (u16) (adapter_interrupts >> 16);
881 process_interrupt(port_int_reg, icom_port);
882 check_modem_status(icom_port);
886 /* Clear out any pending interrupts */
887 writel(adapter_interrupts, int_reg);
889 int_reg = icom_adapter->base_addr + 0x8004;
890 } else {
891 int_reg = icom_adapter->base_addr + 0x4004;
894 adapter_interrupts = readl(int_reg);
896 if (adapter_interrupts & 0x00003FFF) {
897 /* port 0 interrupt, NOTE: for all adapters, port 0 will be active */
898 icom_port = &icom_adapter->port_info[0];
899 port_int_reg = (u16) adapter_interrupts;
900 process_interrupt(port_int_reg, icom_port);
901 check_modem_status(icom_port);
903 if (adapter_interrupts & 0x3FFF0000) {
904 /* port 1 interrupt */
905 icom_port = &icom_adapter->port_info[1];
906 if (icom_port->status == ICOM_PORT_ACTIVE) {
907 port_int_reg = (u16) (adapter_interrupts >> 16);
908 process_interrupt(port_int_reg, icom_port);
909 check_modem_status(icom_port);
913 /* Clear out any pending interrupts */
914 writel(adapter_interrupts, int_reg);
916 /* flush the write */
917 adapter_interrupts = readl(int_reg);
919 return IRQ_HANDLED;
923 * ------------------------------------------------------------------
924 * Begin serial-core API
925 * ------------------------------------------------------------------
927 static unsigned int icom_tx_empty(struct uart_port *port)
929 int ret;
930 unsigned long flags;
932 spin_lock_irqsave(&port->lock, flags);
933 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
934 SA_FLAGS_READY_TO_XMIT)
935 ret = TIOCSER_TEMT;
936 else
937 ret = 0;
939 spin_unlock_irqrestore(&port->lock, flags);
940 return ret;
943 static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
945 unsigned char local_osr;
947 trace(ICOM_PORT, "SET_MODEM", 0);
948 local_osr = readb(&ICOM_PORT->dram->osr);
950 if (mctrl & TIOCM_RTS) {
951 trace(ICOM_PORT, "RAISE_RTS", 0);
952 local_osr |= ICOM_RTS;
953 } else {
954 trace(ICOM_PORT, "LOWER_RTS", 0);
955 local_osr &= ~ICOM_RTS;
958 if (mctrl & TIOCM_DTR) {
959 trace(ICOM_PORT, "RAISE_DTR", 0);
960 local_osr |= ICOM_DTR;
961 } else {
962 trace(ICOM_PORT, "LOWER_DTR", 0);
963 local_osr &= ~ICOM_DTR;
966 writeb(local_osr, &ICOM_PORT->dram->osr);
969 static unsigned int icom_get_mctrl(struct uart_port *port)
971 unsigned char status;
972 unsigned int result;
974 trace(ICOM_PORT, "GET_MODEM", 0);
976 status = readb(&ICOM_PORT->dram->isr);
978 result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
979 | ((status & ICOM_RI) ? TIOCM_RNG : 0)
980 | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
981 | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
982 return result;
985 static void icom_stop_tx(struct uart_port *port)
987 unsigned char cmdReg;
989 trace(ICOM_PORT, "STOP", 0);
990 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
991 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
994 static void icom_start_tx(struct uart_port *port)
996 unsigned char cmdReg;
998 trace(ICOM_PORT, "START", 0);
999 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1000 if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
1001 writeb(cmdReg & ~CMD_HOLD_XMIT,
1002 &ICOM_PORT->dram->CmdReg);
1004 icom_write(port);
1007 static void icom_send_xchar(struct uart_port *port, char ch)
1009 unsigned char xdata;
1010 int index;
1011 unsigned long flags;
1013 trace(ICOM_PORT, "SEND_XCHAR", ch);
1015 /* wait .1 sec to send char */
1016 for (index = 0; index < 10; index++) {
1017 spin_lock_irqsave(&port->lock, flags);
1018 xdata = readb(&ICOM_PORT->dram->xchar);
1019 if (xdata == 0x00) {
1020 trace(ICOM_PORT, "QUICK_WRITE", 0);
1021 writeb(ch, &ICOM_PORT->dram->xchar);
1023 /* flush write operation */
1024 xdata = readb(&ICOM_PORT->dram->xchar);
1025 spin_unlock_irqrestore(&port->lock, flags);
1026 break;
1028 spin_unlock_irqrestore(&port->lock, flags);
1029 msleep(10);
1033 static void icom_stop_rx(struct uart_port *port)
1035 unsigned char cmdReg;
1037 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1038 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1041 static void icom_enable_ms(struct uart_port *port)
1043 /* no-op */
1046 static void icom_break(struct uart_port *port, int break_state)
1048 unsigned char cmdReg;
1049 unsigned long flags;
1051 spin_lock_irqsave(&port->lock, flags);
1052 trace(ICOM_PORT, "BREAK", 0);
1053 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1054 if (break_state == -1) {
1055 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1056 } else {
1057 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1059 spin_unlock_irqrestore(&port->lock, flags);
1062 static int icom_open(struct uart_port *port)
1064 int retval;
1066 kobject_get(&ICOM_PORT->adapter->kobj);
1067 retval = startup(ICOM_PORT);
1069 if (retval) {
1070 kobject_put(&ICOM_PORT->adapter->kobj);
1071 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1072 return retval;
1075 return 0;
1078 static void icom_close(struct uart_port *port)
1080 unsigned char cmdReg;
1082 trace(ICOM_PORT, "CLOSE", 0);
1084 /* stop receiver */
1085 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1086 writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1087 &ICOM_PORT->dram->CmdReg);
1089 shutdown(ICOM_PORT);
1091 kobject_put(&ICOM_PORT->adapter->kobj);
1094 static void icom_set_termios(struct uart_port *port,
1095 struct ktermios *termios,
1096 struct ktermios *old_termios)
1098 int baud;
1099 unsigned cflag, iflag;
1100 int bits;
1101 char new_config2;
1102 char new_config3 = 0;
1103 char tmp_byte;
1104 int index;
1105 int rcv_buff, xmit_buff;
1106 unsigned long offset;
1107 unsigned long flags;
1109 spin_lock_irqsave(&port->lock, flags);
1110 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1112 cflag = termios->c_cflag;
1113 iflag = termios->c_iflag;
1115 new_config2 = ICOM_ACFG_DRIVE1;
1117 /* byte size and parity */
1118 switch (cflag & CSIZE) {
1119 case CS5: /* 5 bits/char */
1120 new_config2 |= ICOM_ACFG_5BPC;
1121 bits = 7;
1122 break;
1123 case CS6: /* 6 bits/char */
1124 new_config2 |= ICOM_ACFG_6BPC;
1125 bits = 8;
1126 break;
1127 case CS7: /* 7 bits/char */
1128 new_config2 |= ICOM_ACFG_7BPC;
1129 bits = 9;
1130 break;
1131 case CS8: /* 8 bits/char */
1132 new_config2 |= ICOM_ACFG_8BPC;
1133 bits = 10;
1134 break;
1135 default:
1136 bits = 10;
1137 break;
1139 if (cflag & CSTOPB) {
1140 /* 2 stop bits */
1141 new_config2 |= ICOM_ACFG_2STOP_BIT;
1142 bits++;
1144 if (cflag & PARENB) {
1145 /* parity bit enabled */
1146 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1147 trace(ICOM_PORT, "PARENB", 0);
1148 bits++;
1150 if (cflag & PARODD) {
1151 /* odd parity */
1152 new_config2 |= ICOM_ACFG_PARITY_ODD;
1153 trace(ICOM_PORT, "PARODD", 0);
1156 /* Determine divisor based on baud rate */
1157 baud = uart_get_baud_rate(port, termios, old_termios,
1158 icom_acfg_baud[0],
1159 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1160 if (!baud)
1161 baud = 9600; /* B0 transition handled in rs_set_termios */
1163 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1164 if (icom_acfg_baud[index] == baud) {
1165 new_config3 = index;
1166 break;
1170 uart_update_timeout(port, cflag, baud);
1172 /* CTS flow control flag and modem status interrupts */
1173 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1174 if (cflag & CRTSCTS)
1175 tmp_byte |= HDLC_HDW_FLOW;
1176 else
1177 tmp_byte &= ~HDLC_HDW_FLOW;
1178 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1181 * Set up parity check flag
1183 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1184 if (iflag & INPCK)
1185 ICOM_PORT->read_status_mask |=
1186 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1188 if ((iflag & BRKINT) || (iflag & PARMRK))
1189 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1192 * Characters to ignore
1194 ICOM_PORT->ignore_status_mask = 0;
1195 if (iflag & IGNPAR)
1196 ICOM_PORT->ignore_status_mask |=
1197 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1198 if (iflag & IGNBRK) {
1199 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1201 * If we're ignore parity and break indicators, ignore
1202 * overruns too. (For real raw support).
1204 if (iflag & IGNPAR)
1205 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1209 * !!! ignore all characters if CREAD is not set
1211 if ((cflag & CREAD) == 0)
1212 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1214 /* Turn off Receiver to prepare for reset */
1215 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1217 for (index = 0; index < 10; index++) {
1218 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1219 break;
1223 /* clear all current buffers of data */
1224 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1225 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1226 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1227 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1228 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1231 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1232 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1235 /* activate changes and start xmit and receiver here */
1236 /* Enable the receiver */
1237 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1238 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1239 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1240 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1241 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1242 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer)); /* 0.5 seconds */
1243 writeb(0xFF, &(ICOM_PORT->dram->ier)); /* enable modem signal interrupts */
1245 /* reset processor */
1246 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1248 for (index = 0; index < 10; index++) {
1249 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1250 break;
1254 /* Enable Transmitter and Reciever */
1255 offset =
1256 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1257 (unsigned long) ICOM_PORT->statStg;
1258 writel(ICOM_PORT->statStg_pci + offset,
1259 &ICOM_PORT->dram->RcvStatusAddr);
1260 ICOM_PORT->next_rcv = 0;
1261 ICOM_PORT->put_length = 0;
1262 *ICOM_PORT->xmitRestart = 0;
1263 writel(ICOM_PORT->xmitRestart_pci,
1264 &ICOM_PORT->dram->XmitStatusAddr);
1265 trace(ICOM_PORT, "XR_ENAB", 0);
1266 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1268 spin_unlock_irqrestore(&port->lock, flags);
1271 static const char *icom_type(struct uart_port *port)
1273 return "icom";
1276 static void icom_release_port(struct uart_port *port)
1280 static int icom_request_port(struct uart_port *port)
1282 return 0;
1285 static void icom_config_port(struct uart_port *port, int flags)
1287 port->type = PORT_ICOM;
1290 static struct uart_ops icom_ops = {
1291 .tx_empty = icom_tx_empty,
1292 .set_mctrl = icom_set_mctrl,
1293 .get_mctrl = icom_get_mctrl,
1294 .stop_tx = icom_stop_tx,
1295 .start_tx = icom_start_tx,
1296 .send_xchar = icom_send_xchar,
1297 .stop_rx = icom_stop_rx,
1298 .enable_ms = icom_enable_ms,
1299 .break_ctl = icom_break,
1300 .startup = icom_open,
1301 .shutdown = icom_close,
1302 .set_termios = icom_set_termios,
1303 .type = icom_type,
1304 .release_port = icom_release_port,
1305 .request_port = icom_request_port,
1306 .config_port = icom_config_port,
1309 #define ICOM_CONSOLE NULL
1311 static struct uart_driver icom_uart_driver = {
1312 .owner = THIS_MODULE,
1313 .driver_name = ICOM_DRIVER_NAME,
1314 .dev_name = "ttyA",
1315 .major = ICOM_MAJOR,
1316 .minor = ICOM_MINOR_START,
1317 .nr = NR_PORTS,
1318 .cons = ICOM_CONSOLE,
1321 static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1323 u32 subsystem_id = icom_adapter->subsystem_id;
1324 int retval = 0;
1325 int i;
1326 struct icom_port *icom_port;
1328 if (icom_adapter->version == ADAPTER_V1) {
1329 icom_adapter->numb_ports = 2;
1331 for (i = 0; i < 2; i++) {
1332 icom_port = &icom_adapter->port_info[i];
1333 icom_port->port = i;
1334 icom_port->status = ICOM_PORT_ACTIVE;
1335 icom_port->imbed_modem = ICOM_UNKNOWN;
1337 } else {
1338 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1339 icom_adapter->numb_ports = 4;
1341 for (i = 0; i < 4; i++) {
1342 icom_port = &icom_adapter->port_info[i];
1344 icom_port->port = i;
1345 icom_port->status = ICOM_PORT_ACTIVE;
1346 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1348 } else {
1349 icom_adapter->numb_ports = 4;
1351 icom_adapter->port_info[0].port = 0;
1352 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1354 if (subsystem_id ==
1355 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1356 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1357 } else {
1358 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1361 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1363 icom_adapter->port_info[2].port = 2;
1364 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1365 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1366 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1370 return retval;
1373 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1375 if (icom_adapter->version == ADAPTER_V1) {
1376 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1377 icom_port->int_reg = icom_adapter->base_addr +
1378 0x4004 + 2 - 2 * port_num;
1379 } else {
1380 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1381 if (icom_port->port < 2)
1382 icom_port->int_reg = icom_adapter->base_addr +
1383 0x8004 + 2 - 2 * icom_port->port;
1384 else
1385 icom_port->int_reg = icom_adapter->base_addr +
1386 0x8024 + 2 - 2 * (icom_port->port - 2);
1389 static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
1391 struct icom_port *icom_port;
1392 int port_num;
1393 int retval;
1395 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1397 icom_port = &icom_adapter->port_info[port_num];
1399 if (icom_port->status == ICOM_PORT_ACTIVE) {
1400 icom_port_active(icom_port, icom_adapter, port_num);
1401 icom_port->dram = icom_adapter->base_addr +
1402 0x2000 * icom_port->port;
1404 icom_port->adapter = icom_adapter;
1406 /* get port memory */
1407 if ((retval = get_port_memory(icom_port)) != 0) {
1408 dev_err(&icom_port->adapter->pci_dev->dev,
1409 "Memory allocation for port FAILED\n");
1413 return 0;
1416 static int __devinit icom_alloc_adapter(struct icom_adapter
1417 **icom_adapter_ref)
1419 int adapter_count = 0;
1420 struct icom_adapter *icom_adapter;
1421 struct icom_adapter *cur_adapter_entry;
1422 struct list_head *tmp;
1424 icom_adapter = (struct icom_adapter *)
1425 kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1427 if (!icom_adapter) {
1428 return -ENOMEM;
1431 list_for_each(tmp, &icom_adapter_head) {
1432 cur_adapter_entry =
1433 list_entry(tmp, struct icom_adapter,
1434 icom_adapter_entry);
1435 if (cur_adapter_entry->index != adapter_count) {
1436 break;
1438 adapter_count++;
1441 icom_adapter->index = adapter_count;
1442 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1444 *icom_adapter_ref = icom_adapter;
1445 return 0;
1448 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1450 list_del(&icom_adapter->icom_adapter_entry);
1451 kfree(icom_adapter);
1454 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1456 struct icom_port *icom_port;
1457 int index;
1459 for (index = 0; index < icom_adapter->numb_ports; index++) {
1460 icom_port = &icom_adapter->port_info[index];
1462 if (icom_port->status == ICOM_PORT_ACTIVE) {
1463 dev_info(&icom_adapter->pci_dev->dev,
1464 "Device removed\n");
1466 uart_remove_one_port(&icom_uart_driver,
1467 &icom_port->uart_port);
1469 /* be sure that DTR and RTS are dropped */
1470 writeb(0x00, &icom_port->dram->osr);
1472 /* Wait 0.1 Sec for simple Init to complete */
1473 msleep(100);
1475 /* Stop proccessor */
1476 stop_processor(icom_port);
1478 free_port_memory(icom_port);
1482 free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
1483 iounmap(icom_adapter->base_addr);
1484 icom_free_adapter(icom_adapter);
1485 pci_release_regions(icom_adapter->pci_dev);
1488 static void icom_kobj_release(struct kobject *kobj)
1490 struct icom_adapter *icom_adapter;
1492 icom_adapter = to_icom_adapter(kobj);
1493 icom_remove_adapter(icom_adapter);
1496 static struct kobj_type icom_kobj_type = {
1497 .release = icom_kobj_release,
1500 static int __devinit icom_probe(struct pci_dev *dev,
1501 const struct pci_device_id *ent)
1503 int index;
1504 unsigned int command_reg;
1505 int retval;
1506 struct icom_adapter *icom_adapter;
1507 struct icom_port *icom_port;
1509 retval = pci_enable_device(dev);
1510 if (retval) {
1511 dev_err(&dev->dev, "Device enable FAILED\n");
1512 return retval;
1515 if ( (retval = pci_request_regions(dev, "icom"))) {
1516 dev_err(&dev->dev, "pci_request_regions FAILED\n");
1517 pci_disable_device(dev);
1518 return retval;
1521 pci_set_master(dev);
1523 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1524 dev_err(&dev->dev, "PCI Config read FAILED\n");
1525 return retval;
1528 pci_write_config_dword(dev, PCI_COMMAND,
1529 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1530 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1532 if (ent->driver_data == ADAPTER_V1) {
1533 pci_write_config_dword(dev, 0x44, 0x8300830A);
1534 } else {
1535 pci_write_config_dword(dev, 0x44, 0x42004200);
1536 pci_write_config_dword(dev, 0x48, 0x42004200);
1540 retval = icom_alloc_adapter(&icom_adapter);
1541 if (retval) {
1542 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1543 retval = -EIO;
1544 goto probe_exit0;
1547 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1548 icom_adapter->pci_dev = dev;
1549 icom_adapter->version = ent->driver_data;
1550 icom_adapter->subsystem_id = ent->subdevice;
1553 retval = icom_init_ports(icom_adapter);
1554 if (retval) {
1555 dev_err(&dev->dev, "Port configuration failed\n");
1556 goto probe_exit1;
1559 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1560 pci_resource_len(dev, 0));
1562 if (!icom_adapter->base_addr)
1563 goto probe_exit1;
1565 /* save off irq and request irq line */
1566 if ( (retval = request_irq(dev->irq, icom_interrupt,
1567 IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
1568 (void *) icom_adapter))) {
1569 goto probe_exit2;
1572 retval = icom_load_ports(icom_adapter);
1574 for (index = 0; index < icom_adapter->numb_ports; index++) {
1575 icom_port = &icom_adapter->port_info[index];
1577 if (icom_port->status == ICOM_PORT_ACTIVE) {
1578 icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
1579 icom_port->uart_port.type = PORT_ICOM;
1580 icom_port->uart_port.iotype = UPIO_MEM;
1581 icom_port->uart_port.membase =
1582 (char *) icom_adapter->base_addr_pci;
1583 icom_port->uart_port.fifosize = 16;
1584 icom_port->uart_port.ops = &icom_ops;
1585 icom_port->uart_port.line =
1586 icom_port->port + icom_adapter->index * 4;
1587 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1588 icom_port->status = ICOM_PORT_OFF;
1589 dev_err(&dev->dev, "Device add failed\n");
1590 } else
1591 dev_info(&dev->dev, "Device added\n");
1595 kobject_init(&icom_adapter->kobj);
1596 icom_adapter->kobj.ktype = &icom_kobj_type;
1597 return 0;
1599 probe_exit2:
1600 iounmap(icom_adapter->base_addr);
1601 probe_exit1:
1602 icom_free_adapter(icom_adapter);
1604 probe_exit0:
1605 pci_release_regions(dev);
1606 pci_disable_device(dev);
1608 return retval;
1613 static void __devexit icom_remove(struct pci_dev *dev)
1615 struct icom_adapter *icom_adapter;
1616 struct list_head *tmp;
1618 list_for_each(tmp, &icom_adapter_head) {
1619 icom_adapter = list_entry(tmp, struct icom_adapter,
1620 icom_adapter_entry);
1621 if (icom_adapter->pci_dev == dev) {
1622 kobject_put(&icom_adapter->kobj);
1623 return;
1627 dev_err(&dev->dev, "Unable to find device to remove\n");
1630 static struct pci_driver icom_pci_driver = {
1631 .name = ICOM_DRIVER_NAME,
1632 .id_table = icom_pci_table,
1633 .probe = icom_probe,
1634 .remove = __devexit_p(icom_remove),
1637 static int __init icom_init(void)
1639 int ret;
1641 spin_lock_init(&icom_lock);
1643 ret = uart_register_driver(&icom_uart_driver);
1644 if (ret)
1645 return ret;
1647 ret = pci_register_driver(&icom_pci_driver);
1649 if (ret < 0)
1650 uart_unregister_driver(&icom_uart_driver);
1652 return ret;
1655 static void __exit icom_exit(void)
1657 pci_unregister_driver(&icom_pci_driver);
1658 uart_unregister_driver(&icom_uart_driver);
1661 module_init(icom_init);
1662 module_exit(icom_exit);
1664 #ifdef ICOM_TRACE
1665 static inline void trace(struct icom_port *icom_port, char *trace_pt,
1666 unsigned long trace_data)
1668 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1669 icom_port->port, trace_pt, trace_data);
1671 #endif
1673 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1674 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1675 MODULE_SUPPORTED_DEVICE
1676 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1677 MODULE_LICENSE("GPL");