[PATCH] fbdev: colormap fixes fix
[linux-2.6/suspend2-2.6.18.git] / drivers / serial / icom.c
blobc112b32764e8ceb3045ebcbe7933d25eb7d3aa22
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/kernel.h>
29 #include <linux/errno.h>
30 #include <linux/signal.h>
31 #include <linux/sched.h>
32 #include <linux/timer.h>
33 #include <linux/interrupt.h>
34 #include <linux/tty.h>
35 #include <linux/termios.h>
36 #include <linux/fs.h>
37 #include <linux/tty_flip.h>
38 #include <linux/serial.h>
39 #include <linux/serial_reg.h>
40 #include <linux/major.h>
41 #include <linux/string.h>
42 #include <linux/fcntl.h>
43 #include <linux/ptrace.h>
44 #include <linux/ioport.h>
45 #include <linux/mm.h>
46 #include <linux/slab.h>
47 #include <linux/init.h>
48 #include <linux/delay.h>
49 #include <linux/pci.h>
50 #include <linux/vmalloc.h>
51 #include <linux/smp.h>
52 #include <linux/smp_lock.h>
53 #include <linux/spinlock.h>
54 #include <linux/kobject.h>
55 #include <linux/firmware.h>
56 #include <linux/bitops.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>
64 #include "icom.h"
66 /*#define ICOM_TRACE enable port trace capabilities */
68 #define ICOM_DRIVER_NAME "icom"
69 #define ICOM_VERSION_STR "1.3.1"
70 #define NR_PORTS 128
71 #define ICOM_PORT ((struct icom_port *)port)
72 #define to_icom_adapter(d) container_of(d, struct icom_adapter, kobj)
74 static const struct pci_device_id icom_pci_table[] = {
76 .vendor = PCI_VENDOR_ID_IBM,
77 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
78 .subvendor = PCI_ANY_ID,
79 .subdevice = PCI_ANY_ID,
80 .driver_data = ADAPTER_V1,
83 .vendor = PCI_VENDOR_ID_IBM,
84 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
85 .subvendor = PCI_VENDOR_ID_IBM,
86 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
87 .driver_data = ADAPTER_V2,
90 .vendor = PCI_VENDOR_ID_IBM,
91 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
92 .subvendor = PCI_VENDOR_ID_IBM,
93 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
94 .driver_data = ADAPTER_V2,
97 .vendor = PCI_VENDOR_ID_IBM,
98 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
99 .subvendor = PCI_VENDOR_ID_IBM,
100 .subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
101 .driver_data = ADAPTER_V2,
106 struct lookup_proc_table start_proc[4] = {
107 {NULL, ICOM_CONTROL_START_A},
108 {NULL, ICOM_CONTROL_START_B},
109 {NULL, ICOM_CONTROL_START_C},
110 {NULL, ICOM_CONTROL_START_D}
114 struct lookup_proc_table stop_proc[4] = {
115 {NULL, ICOM_CONTROL_STOP_A},
116 {NULL, ICOM_CONTROL_STOP_B},
117 {NULL, ICOM_CONTROL_STOP_C},
118 {NULL, ICOM_CONTROL_STOP_D}
121 struct lookup_int_table int_mask_tbl[4] = {
122 {NULL, ICOM_INT_MASK_PRC_A},
123 {NULL, ICOM_INT_MASK_PRC_B},
124 {NULL, ICOM_INT_MASK_PRC_C},
125 {NULL, ICOM_INT_MASK_PRC_D},
129 MODULE_DEVICE_TABLE(pci, icom_pci_table);
131 static LIST_HEAD(icom_adapter_head);
133 /* spinlock for adapter initialization and changing adapter operations */
134 static spinlock_t icom_lock;
136 #ifdef ICOM_TRACE
137 static inline void trace(struct icom_port *, char *, unsigned long) {};
138 #else
139 static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
140 #endif
142 static void free_port_memory(struct icom_port *icom_port)
144 struct pci_dev *dev = icom_port->adapter->pci_dev;
146 trace(icom_port, "RET_PORT_MEM", 0);
147 if (icom_port->recv_buf) {
148 pci_free_consistent(dev, 4096, icom_port->recv_buf,
149 icom_port->recv_buf_pci);
150 icom_port->recv_buf = NULL;
152 if (icom_port->xmit_buf) {
153 pci_free_consistent(dev, 4096, icom_port->xmit_buf,
154 icom_port->xmit_buf_pci);
155 icom_port->xmit_buf = NULL;
157 if (icom_port->statStg) {
158 pci_free_consistent(dev, 4096, icom_port->statStg,
159 icom_port->statStg_pci);
160 icom_port->statStg = NULL;
163 if (icom_port->xmitRestart) {
164 pci_free_consistent(dev, 4096, icom_port->xmitRestart,
165 icom_port->xmitRestart_pci);
166 icom_port->xmitRestart = NULL;
170 static int __init get_port_memory(struct icom_port *icom_port)
172 int index;
173 unsigned long stgAddr;
174 unsigned long startStgAddr;
175 unsigned long offset;
176 struct pci_dev *dev = icom_port->adapter->pci_dev;
178 icom_port->xmit_buf =
179 pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
180 if (!icom_port->xmit_buf) {
181 dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
182 return -ENOMEM;
185 trace(icom_port, "GET_PORT_MEM",
186 (unsigned long) icom_port->xmit_buf);
188 icom_port->recv_buf =
189 pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
190 if (!icom_port->recv_buf) {
191 dev_err(&dev->dev, "Can not allocate Receive buffer\n");
192 free_port_memory(icom_port);
193 return -ENOMEM;
195 trace(icom_port, "GET_PORT_MEM",
196 (unsigned long) icom_port->recv_buf);
198 icom_port->statStg =
199 pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
200 if (!icom_port->statStg) {
201 dev_err(&dev->dev, "Can not allocate Status buffer\n");
202 free_port_memory(icom_port);
203 return -ENOMEM;
205 trace(icom_port, "GET_PORT_MEM",
206 (unsigned long) icom_port->statStg);
208 icom_port->xmitRestart =
209 pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
210 if (!icom_port->xmitRestart) {
211 dev_err(&dev->dev,
212 "Can not allocate xmit Restart buffer\n");
213 free_port_memory(icom_port);
214 return -ENOMEM;
217 memset(icom_port->statStg, 0, 4096);
219 /* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
220 indicates that frames are to be transmitted
223 stgAddr = (unsigned long) icom_port->statStg;
224 for (index = 0; index < NUM_XBUFFS; index++) {
225 trace(icom_port, "FOD_ADDR", stgAddr);
226 stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
227 if (index < (NUM_XBUFFS - 1)) {
228 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
229 icom_port->statStg->xmit[index].leLengthASD =
230 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
231 trace(icom_port, "FOD_ADDR", stgAddr);
232 trace(icom_port, "FOD_XBUFF",
233 (unsigned long) icom_port->xmit_buf);
234 icom_port->statStg->xmit[index].leBuffer =
235 cpu_to_le32(icom_port->xmit_buf_pci);
236 } else if (index == (NUM_XBUFFS - 1)) {
237 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
238 icom_port->statStg->xmit[index].leLengthASD =
239 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
240 trace(icom_port, "FOD_XBUFF",
241 (unsigned long) icom_port->xmit_buf);
242 icom_port->statStg->xmit[index].leBuffer =
243 cpu_to_le32(icom_port->xmit_buf_pci);
244 } else {
245 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
248 /* FIDs */
249 startStgAddr = stgAddr;
251 /* fill in every entry, even if no buffer */
252 for (index = 0; index < NUM_RBUFFS; index++) {
253 trace(icom_port, "FID_ADDR", stgAddr);
254 stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
255 icom_port->statStg->rcv[index].leLength = 0;
256 icom_port->statStg->rcv[index].WorkingLength =
257 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
258 if (index < (NUM_RBUFFS - 1) ) {
259 offset = stgAddr - (unsigned long) icom_port->statStg;
260 icom_port->statStg->rcv[index].leNext =
261 cpu_to_le32(icom_port-> statStg_pci + offset);
262 trace(icom_port, "FID_RBUFF",
263 (unsigned long) icom_port->recv_buf);
264 icom_port->statStg->rcv[index].leBuffer =
265 cpu_to_le32(icom_port->recv_buf_pci);
266 } else if (index == (NUM_RBUFFS -1) ) {
267 offset = startStgAddr - (unsigned long) icom_port->statStg;
268 icom_port->statStg->rcv[index].leNext =
269 cpu_to_le32(icom_port-> statStg_pci + offset);
270 trace(icom_port, "FID_RBUFF",
271 (unsigned long) icom_port->recv_buf + 2048);
272 icom_port->statStg->rcv[index].leBuffer =
273 cpu_to_le32(icom_port->recv_buf_pci + 2048);
274 } else {
275 icom_port->statStg->rcv[index].leNext = 0;
276 icom_port->statStg->rcv[index].leBuffer = 0;
280 return 0;
283 static void stop_processor(struct icom_port *icom_port)
285 unsigned long temp;
286 unsigned long flags;
287 int port;
289 spin_lock_irqsave(&icom_lock, flags);
291 port = icom_port->port;
292 if (port == 0 || port == 1)
293 stop_proc[port].global_control_reg = &icom_port->global_reg->control;
294 else
295 stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
298 if (port < 4) {
299 temp = readl(stop_proc[port].global_control_reg);
300 temp =
301 (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
302 writel(temp, stop_proc[port].global_control_reg);
304 /* write flush */
305 readl(stop_proc[port].global_control_reg);
306 } else {
307 dev_err(&icom_port->adapter->pci_dev->dev,
308 "Invalid port assignment\n");
311 spin_unlock_irqrestore(&icom_lock, flags);
314 static void start_processor(struct icom_port *icom_port)
316 unsigned long temp;
317 unsigned long flags;
318 int port;
320 spin_lock_irqsave(&icom_lock, flags);
322 port = icom_port->port;
323 if (port == 0 || port == 1)
324 start_proc[port].global_control_reg = &icom_port->global_reg->control;
325 else
326 start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
327 if (port < 4) {
328 temp = readl(start_proc[port].global_control_reg);
329 temp =
330 (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
331 writel(temp, start_proc[port].global_control_reg);
333 /* write flush */
334 readl(start_proc[port].global_control_reg);
335 } else {
336 dev_err(&icom_port->adapter->pci_dev->dev,
337 "Invalid port assignment\n");
340 spin_unlock_irqrestore(&icom_lock, flags);
343 static void load_code(struct icom_port *icom_port)
345 const struct firmware *fw;
346 char __iomem *iram_ptr;
347 int index;
348 int status = 0;
349 void __iomem *dram_ptr = icom_port->dram;
350 dma_addr_t temp_pci;
351 unsigned char *new_page = NULL;
352 unsigned char cable_id = NO_CABLE;
353 struct pci_dev *dev = icom_port->adapter->pci_dev;
355 /* Clear out any pending interrupts */
356 writew(0x3FFF, icom_port->int_reg);
358 trace(icom_port, "CLEAR_INTERRUPTS", 0);
360 /* Stop processor */
361 stop_processor(icom_port);
363 /* Zero out DRAM */
364 memset_io(dram_ptr, 0, 512);
366 /* Load Call Setup into Adapter */
367 if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
368 dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
369 status = -1;
370 goto load_code_exit;
373 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
374 dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
375 release_firmware(fw);
376 status = -1;
377 goto load_code_exit;
380 iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
381 for (index = 0; index < fw->size; index++)
382 writeb(fw->data[index], &iram_ptr[index]);
384 release_firmware(fw);
386 /* Load Resident DCE portion of Adapter */
387 if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
388 dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
389 status = -1;
390 goto load_code_exit;
393 if (fw->size > ICOM_IRAM_SIZE) {
394 dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
395 release_firmware(fw);
396 status = -1;
397 goto load_code_exit;
400 iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
401 for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
402 writeb(fw->data[index], &iram_ptr[index]);
404 release_firmware(fw);
406 /* Set Hardware level */
407 if ((icom_port->adapter->version | ADAPTER_V2) == ADAPTER_V2)
408 writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));
410 /* Start the processor in Adapter */
411 start_processor(icom_port);
413 writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
414 &(icom_port->dram->HDLCConfigReg));
415 writeb(0x04, &(icom_port->dram->FlagFillIdleTimer)); /* 0.5 seconds */
416 writeb(0x00, &(icom_port->dram->CmdReg));
417 writeb(0x10, &(icom_port->dram->async_config3));
418 writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
419 ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));
421 /*Set up data in icom DRAM to indicate where personality
422 *code is located and its length.
424 new_page = pci_alloc_consistent(dev, 4096, &temp_pci);
426 if (!new_page) {
427 dev_err(&dev->dev, "Can not allocate DMA buffer\n");
428 status = -1;
429 goto load_code_exit;
432 if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
433 dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
434 status = -1;
435 goto load_code_exit;
438 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
439 dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
440 release_firmware(fw);
441 status = -1;
442 goto load_code_exit;
445 for (index = 0; index < fw->size; index++)
446 new_page[index] = fw->data[index];
448 release_firmware(fw);
450 writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
451 writel(temp_pci, &icom_port->dram->mac_load_addr);
453 /*Setting the syncReg to 0x80 causes adapter to start downloading
454 the personality code into adapter instruction RAM.
455 Once code is loaded, it will begin executing and, based on
456 information provided above, will start DMAing data from
457 shared memory to adapter DRAM.
459 /* the wait loop below verifies this write operation has been done
460 and processed
462 writeb(START_DOWNLOAD, &icom_port->dram->sync);
464 /* Wait max 1 Sec for data download and processor to start */
465 for (index = 0; index < 10; index++) {
466 msleep(100);
467 if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
468 break;
471 if (index == 10)
472 status = -1;
475 * check Cable ID
477 cable_id = readb(&icom_port->dram->cable_id);
479 if (cable_id & ICOM_CABLE_ID_VALID) {
480 /* Get cable ID into the lower 4 bits (standard form) */
481 cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
482 icom_port->cable_id = cable_id;
483 } else {
484 dev_err(&dev->dev,"Invalid or no cable attached\n");
485 icom_port->cable_id = NO_CABLE;
488 load_code_exit:
490 if (status != 0) {
491 /* Clear out any pending interrupts */
492 writew(0x3FFF, icom_port->int_reg);
494 /* Turn off port */
495 writeb(ICOM_DISABLE, &(icom_port->dram->disable));
497 /* Stop processor */
498 stop_processor(icom_port);
500 dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
503 if (new_page != NULL)
504 pci_free_consistent(dev, 4096, new_page, temp_pci);
507 static int startup(struct icom_port *icom_port)
509 unsigned long temp;
510 unsigned char cable_id, raw_cable_id;
511 unsigned long flags;
512 int port;
514 trace(icom_port, "STARTUP", 0);
516 if (!icom_port->dram) {
517 /* should NEVER be NULL */
518 dev_err(&icom_port->adapter->pci_dev->dev,
519 "Unusable Port, port configuration missing\n");
520 return -ENODEV;
524 * check Cable ID
526 raw_cable_id = readb(&icom_port->dram->cable_id);
527 trace(icom_port, "CABLE_ID", raw_cable_id);
529 /* Get cable ID into the lower 4 bits (standard form) */
530 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
532 /* Check for valid Cable ID */
533 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
534 (cable_id != icom_port->cable_id)) {
536 /* reload adapter code, pick up any potential changes in cable id */
537 load_code(icom_port);
539 /* still no sign of cable, error out */
540 raw_cable_id = readb(&icom_port->dram->cable_id);
541 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
542 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
543 (icom_port->cable_id == NO_CABLE))
544 return -EIO;
548 * Finally, clear and enable interrupts
550 spin_lock_irqsave(&icom_lock, flags);
551 port = icom_port->port;
552 if (port == 0 || port == 1)
553 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
554 else
555 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
557 if (port == 0 || port == 2)
558 writew(0x00FF, icom_port->int_reg);
559 else
560 writew(0x3F00, icom_port->int_reg);
561 if (port < 4) {
562 temp = readl(int_mask_tbl[port].global_int_mask);
563 writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
565 /* write flush */
566 readl(int_mask_tbl[port].global_int_mask);
567 } else {
568 dev_err(&icom_port->adapter->pci_dev->dev,
569 "Invalid port assignment\n");
572 spin_unlock_irqrestore(&icom_lock, flags);
573 return 0;
576 static void shutdown(struct icom_port *icom_port)
578 unsigned long temp;
579 unsigned char cmdReg;
580 unsigned long flags;
581 int port;
583 spin_lock_irqsave(&icom_lock, flags);
584 trace(icom_port, "SHUTDOWN", 0);
587 * disable all interrupts
589 port = icom_port->port;
590 if (port == 0 || port == 1)
591 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
592 else
593 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
595 if (port < 4) {
596 temp = readl(int_mask_tbl[port].global_int_mask);
597 writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
599 /* write flush */
600 readl(int_mask_tbl[port].global_int_mask);
601 } else {
602 dev_err(&icom_port->adapter->pci_dev->dev,
603 "Invalid port assignment\n");
605 spin_unlock_irqrestore(&icom_lock, flags);
608 * disable break condition
610 cmdReg = readb(&icom_port->dram->CmdReg);
611 if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) {
612 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
616 static int icom_write(struct uart_port *port)
618 unsigned long data_count;
619 unsigned char cmdReg;
620 unsigned long offset;
621 int temp_tail = port->info->xmit.tail;
623 trace(ICOM_PORT, "WRITE", 0);
625 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
626 SA_FLAGS_READY_TO_XMIT) {
627 trace(ICOM_PORT, "WRITE_FULL", 0);
628 return 0;
631 data_count = 0;
632 while ((port->info->xmit.head != temp_tail) &&
633 (data_count <= XMIT_BUFF_SZ)) {
635 ICOM_PORT->xmit_buf[data_count++] =
636 port->info->xmit.buf[temp_tail];
638 temp_tail++;
639 temp_tail &= (UART_XMIT_SIZE - 1);
642 if (data_count) {
643 ICOM_PORT->statStg->xmit[0].flags =
644 cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
645 ICOM_PORT->statStg->xmit[0].leLength =
646 cpu_to_le16(data_count);
647 offset =
648 (unsigned long) &ICOM_PORT->statStg->xmit[0] -
649 (unsigned long) ICOM_PORT->statStg;
650 *ICOM_PORT->xmitRestart =
651 cpu_to_le32(ICOM_PORT->statStg_pci + offset);
652 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
653 writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
654 &ICOM_PORT->dram->CmdReg);
655 writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
656 trace(ICOM_PORT, "WRITE_START", data_count);
657 /* write flush */
658 readb(&ICOM_PORT->dram->StartXmitCmd);
661 return data_count;
664 static inline void check_modem_status(struct icom_port *icom_port)
666 static char old_status = 0;
667 char delta_status;
668 unsigned char status;
670 spin_lock(&icom_port->uart_port.lock);
672 /*modem input register */
673 status = readb(&icom_port->dram->isr);
674 trace(icom_port, "CHECK_MODEM", status);
675 delta_status = status ^ old_status;
676 if (delta_status) {
677 if (delta_status & ICOM_RI)
678 icom_port->uart_port.icount.rng++;
679 if (delta_status & ICOM_DSR)
680 icom_port->uart_port.icount.dsr++;
681 if (delta_status & ICOM_DCD)
682 uart_handle_dcd_change(&icom_port->uart_port,
683 delta_status & ICOM_DCD);
684 if (delta_status & ICOM_CTS)
685 uart_handle_cts_change(&icom_port->uart_port,
686 delta_status & ICOM_CTS);
688 wake_up_interruptible(&icom_port->uart_port.info->
689 delta_msr_wait);
690 old_status = status;
692 spin_unlock(&icom_port->uart_port.lock);
695 static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
697 unsigned short int count;
698 int i;
700 if (port_int_reg & (INT_XMIT_COMPLETED)) {
701 trace(icom_port, "XMIT_COMPLETE", 0);
703 /* clear buffer in use bit */
704 icom_port->statStg->xmit[0].flags &=
705 cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
707 count = (unsigned short int)
708 cpu_to_le16(icom_port->statStg->xmit[0].leLength);
709 icom_port->uart_port.icount.tx += count;
711 for (i=0; i<count &&
712 !uart_circ_empty(&icom_port->uart_port.info->xmit); i++) {
714 icom_port->uart_port.info->xmit.tail++;
715 icom_port->uart_port.info->xmit.tail &=
716 (UART_XMIT_SIZE - 1);
719 if (!icom_write(&icom_port->uart_port))
720 /* activate write queue */
721 uart_write_wakeup(&icom_port->uart_port);
722 } else
723 trace(icom_port, "XMIT_DISABLED", 0);
726 static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
728 short int count, rcv_buff;
729 struct tty_struct *tty = icom_port->uart_port.info->tty;
730 unsigned short int status;
731 struct uart_icount *icount;
732 unsigned long offset;
734 trace(icom_port, "RCV_COMPLETE", 0);
735 rcv_buff = icom_port->next_rcv;
737 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
738 while (status & SA_FL_RCV_DONE) {
740 trace(icom_port, "FID_STATUS", status);
741 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
743 trace(icom_port, "RCV_COUNT", count);
744 if (count > (TTY_FLIPBUF_SIZE - tty->flip.count))
745 count = TTY_FLIPBUF_SIZE - tty->flip.count;
747 trace(icom_port, "REAL_COUNT", count);
749 offset =
750 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
751 icom_port->recv_buf_pci;
753 memcpy(tty->flip.char_buf_ptr,(unsigned char *)
754 ((unsigned long)icom_port->recv_buf + offset), count);
756 if (count > 0) {
757 tty->flip.count += count - 1;
758 tty->flip.char_buf_ptr += count - 1;
760 memset(tty->flip.flag_buf_ptr, 0, count);
761 tty->flip.flag_buf_ptr += count - 1;
764 icount = &icom_port->uart_port.icount;
765 icount->rx += count;
767 /* Break detect logic */
768 if ((status & SA_FLAGS_FRAME_ERROR)
769 && (tty->flip.char_buf_ptr[0] == 0x00)) {
770 status &= ~SA_FLAGS_FRAME_ERROR;
771 status |= SA_FLAGS_BREAK_DET;
772 trace(icom_port, "BREAK_DET", 0);
775 if (status &
776 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
777 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
779 if (status & SA_FLAGS_BREAK_DET)
780 icount->brk++;
781 if (status & SA_FLAGS_PARITY_ERROR)
782 icount->parity++;
783 if (status & SA_FLAGS_FRAME_ERROR)
784 icount->frame++;
785 if (status & SA_FLAGS_OVERRUN)
786 icount->overrun++;
789 * Now check to see if character should be
790 * ignored, and mask off conditions which
791 * should be ignored.
793 if (status & icom_port->ignore_status_mask) {
794 trace(icom_port, "IGNORE_CHAR", 0);
795 goto ignore_char;
798 status &= icom_port->read_status_mask;
800 if (status & SA_FLAGS_BREAK_DET) {
801 *tty->flip.flag_buf_ptr = TTY_BREAK;
802 } else if (status & SA_FLAGS_PARITY_ERROR) {
803 trace(icom_port, "PARITY_ERROR", 0);
804 *tty->flip.flag_buf_ptr = TTY_PARITY;
805 } else if (status & SA_FLAGS_FRAME_ERROR)
806 *tty->flip.flag_buf_ptr = TTY_FRAME;
808 if (status & SA_FLAGS_OVERRUN) {
810 * Overrun is special, since it's
811 * reported immediately, and doesn't
812 * affect the current character
814 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
815 tty->flip.count++;
816 tty->flip.flag_buf_ptr++;
817 tty->flip.char_buf_ptr++;
818 *tty->flip.flag_buf_ptr = TTY_OVERRUN;
823 tty->flip.flag_buf_ptr++;
824 tty->flip.char_buf_ptr++;
825 tty->flip.count++;
826 ignore_char:
827 icom_port->statStg->rcv[rcv_buff].flags = 0;
828 icom_port->statStg->rcv[rcv_buff].leLength = 0;
829 icom_port->statStg->rcv[rcv_buff].WorkingLength =
830 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
832 rcv_buff++;
833 if (rcv_buff == NUM_RBUFFS)
834 rcv_buff = 0;
836 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
838 icom_port->next_rcv = rcv_buff;
839 tty_flip_buffer_push(tty);
842 static void process_interrupt(u16 port_int_reg,
843 struct icom_port *icom_port)
846 spin_lock(&icom_port->uart_port.lock);
847 trace(icom_port, "INTERRUPT", port_int_reg);
849 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
850 xmit_interrupt(port_int_reg, icom_port);
852 if (port_int_reg & INT_RCV_COMPLETED)
853 recv_interrupt(port_int_reg, icom_port);
855 spin_unlock(&icom_port->uart_port.lock);
858 static irqreturn_t icom_interrupt(int irq, void *dev_id,
859 struct pt_regs *regs)
861 void __iomem * int_reg;
862 u32 adapter_interrupts;
863 u16 port_int_reg;
864 struct icom_adapter *icom_adapter;
865 struct icom_port *icom_port;
867 /* find icom_port for this interrupt */
868 icom_adapter = (struct icom_adapter *) dev_id;
870 if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
871 int_reg = icom_adapter->base_addr + 0x8024;
873 adapter_interrupts = readl(int_reg);
875 if (adapter_interrupts & 0x00003FFF) {
876 /* port 2 interrupt, NOTE: for all ADAPTER_V2, port 2 will be active */
877 icom_port = &icom_adapter->port_info[2];
878 port_int_reg = (u16) adapter_interrupts;
879 process_interrupt(port_int_reg, icom_port);
880 check_modem_status(icom_port);
882 if (adapter_interrupts & 0x3FFF0000) {
883 /* port 3 interrupt */
884 icom_port = &icom_adapter->port_info[3];
885 if (icom_port->status == ICOM_PORT_ACTIVE) {
886 port_int_reg =
887 (u16) (adapter_interrupts >> 16);
888 process_interrupt(port_int_reg, icom_port);
889 check_modem_status(icom_port);
893 /* Clear out any pending interrupts */
894 writel(adapter_interrupts, int_reg);
896 int_reg = icom_adapter->base_addr + 0x8004;
897 } else {
898 int_reg = icom_adapter->base_addr + 0x4004;
901 adapter_interrupts = readl(int_reg);
903 if (adapter_interrupts & 0x00003FFF) {
904 /* port 0 interrupt, NOTE: for all adapters, port 0 will be active */
905 icom_port = &icom_adapter->port_info[0];
906 port_int_reg = (u16) adapter_interrupts;
907 process_interrupt(port_int_reg, icom_port);
908 check_modem_status(icom_port);
910 if (adapter_interrupts & 0x3FFF0000) {
911 /* port 1 interrupt */
912 icom_port = &icom_adapter->port_info[1];
913 if (icom_port->status == ICOM_PORT_ACTIVE) {
914 port_int_reg = (u16) (adapter_interrupts >> 16);
915 process_interrupt(port_int_reg, icom_port);
916 check_modem_status(icom_port);
920 /* Clear out any pending interrupts */
921 writel(adapter_interrupts, int_reg);
923 /* flush the write */
924 adapter_interrupts = readl(int_reg);
926 return IRQ_HANDLED;
930 * ------------------------------------------------------------------
931 * Begin serial-core API
932 * ------------------------------------------------------------------
934 static unsigned int icom_tx_empty(struct uart_port *port)
936 int ret;
937 unsigned long flags;
939 spin_lock_irqsave(&port->lock, flags);
940 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
941 SA_FLAGS_READY_TO_XMIT)
942 ret = TIOCSER_TEMT;
943 else
944 ret = 0;
946 spin_unlock_irqrestore(&port->lock, flags);
947 return ret;
950 static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
952 unsigned char local_osr;
954 trace(ICOM_PORT, "SET_MODEM", 0);
955 local_osr = readb(&ICOM_PORT->dram->osr);
957 if (mctrl & TIOCM_RTS) {
958 trace(ICOM_PORT, "RAISE_RTS", 0);
959 local_osr |= ICOM_RTS;
960 } else {
961 trace(ICOM_PORT, "LOWER_RTS", 0);
962 local_osr &= ~ICOM_RTS;
965 if (mctrl & TIOCM_DTR) {
966 trace(ICOM_PORT, "RAISE_DTR", 0);
967 local_osr |= ICOM_DTR;
968 } else {
969 trace(ICOM_PORT, "LOWER_DTR", 0);
970 local_osr &= ~ICOM_DTR;
973 writeb(local_osr, &ICOM_PORT->dram->osr);
976 static unsigned int icom_get_mctrl(struct uart_port *port)
978 unsigned char status;
979 unsigned int result;
981 trace(ICOM_PORT, "GET_MODEM", 0);
983 status = readb(&ICOM_PORT->dram->isr);
985 result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
986 | ((status & ICOM_RI) ? TIOCM_RNG : 0)
987 | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
988 | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
989 return result;
992 static void icom_stop_tx(struct uart_port *port, unsigned int tty_stop)
994 unsigned char cmdReg;
996 if (tty_stop) {
997 trace(ICOM_PORT, "STOP", 0);
998 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
999 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
1003 static void icom_start_tx(struct uart_port *port, unsigned int tty_start)
1005 unsigned char cmdReg;
1007 trace(ICOM_PORT, "START", 0);
1008 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1009 if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
1010 writeb(cmdReg & ~CMD_HOLD_XMIT,
1011 &ICOM_PORT->dram->CmdReg);
1013 icom_write(port);
1016 static void icom_send_xchar(struct uart_port *port, char ch)
1018 unsigned char xdata;
1019 int index;
1020 unsigned long flags;
1022 trace(ICOM_PORT, "SEND_XCHAR", ch);
1024 /* wait .1 sec to send char */
1025 for (index = 0; index < 10; index++) {
1026 spin_lock_irqsave(&port->lock, flags);
1027 xdata = readb(&ICOM_PORT->dram->xchar);
1028 if (xdata == 0x00) {
1029 trace(ICOM_PORT, "QUICK_WRITE", 0);
1030 writeb(ch, &ICOM_PORT->dram->xchar);
1032 /* flush write operation */
1033 xdata = readb(&ICOM_PORT->dram->xchar);
1034 spin_unlock_irqrestore(&port->lock, flags);
1035 break;
1037 spin_unlock_irqrestore(&port->lock, flags);
1038 msleep(10);
1042 static void icom_stop_rx(struct uart_port *port)
1044 unsigned char cmdReg;
1046 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1047 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1050 static void icom_enable_ms(struct uart_port *port)
1052 /* no-op */
1055 static void icom_break(struct uart_port *port, int break_state)
1057 unsigned char cmdReg;
1058 unsigned long flags;
1060 spin_lock_irqsave(&port->lock, flags);
1061 trace(ICOM_PORT, "BREAK", 0);
1062 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1063 if (break_state == -1) {
1064 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1065 } else {
1066 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1068 spin_unlock_irqrestore(&port->lock, flags);
1071 static int icom_open(struct uart_port *port)
1073 int retval;
1075 kobject_get(&ICOM_PORT->adapter->kobj);
1076 retval = startup(ICOM_PORT);
1078 if (retval) {
1079 kobject_put(&ICOM_PORT->adapter->kobj);
1080 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1081 return retval;
1084 return 0;
1087 static void icom_close(struct uart_port *port)
1089 unsigned char cmdReg;
1091 trace(ICOM_PORT, "CLOSE", 0);
1093 /* stop receiver */
1094 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1095 writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1096 &ICOM_PORT->dram->CmdReg);
1098 shutdown(ICOM_PORT);
1100 kobject_put(&ICOM_PORT->adapter->kobj);
1103 static void icom_set_termios(struct uart_port *port,
1104 struct termios *termios,
1105 struct termios *old_termios)
1107 int baud;
1108 unsigned cflag, iflag;
1109 int bits;
1110 char new_config2;
1111 char new_config3 = 0;
1112 char tmp_byte;
1113 int index;
1114 int rcv_buff, xmit_buff;
1115 unsigned long offset;
1116 unsigned long flags;
1118 spin_lock_irqsave(&port->lock, flags);
1119 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1121 cflag = termios->c_cflag;
1122 iflag = termios->c_iflag;
1124 new_config2 = ICOM_ACFG_DRIVE1;
1126 /* byte size and parity */
1127 switch (cflag & CSIZE) {
1128 case CS5: /* 5 bits/char */
1129 new_config2 |= ICOM_ACFG_5BPC;
1130 bits = 7;
1131 break;
1132 case CS6: /* 6 bits/char */
1133 new_config2 |= ICOM_ACFG_6BPC;
1134 bits = 8;
1135 break;
1136 case CS7: /* 7 bits/char */
1137 new_config2 |= ICOM_ACFG_7BPC;
1138 bits = 9;
1139 break;
1140 case CS8: /* 8 bits/char */
1141 new_config2 |= ICOM_ACFG_8BPC;
1142 bits = 10;
1143 break;
1144 default:
1145 bits = 10;
1146 break;
1148 if (cflag & CSTOPB) {
1149 /* 2 stop bits */
1150 new_config2 |= ICOM_ACFG_2STOP_BIT;
1151 bits++;
1153 if (cflag & PARENB) {
1154 /* parity bit enabled */
1155 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1156 trace(ICOM_PORT, "PARENB", 0);
1157 bits++;
1159 if (cflag & PARODD) {
1160 /* odd parity */
1161 new_config2 |= ICOM_ACFG_PARITY_ODD;
1162 trace(ICOM_PORT, "PARODD", 0);
1165 /* Determine divisor based on baud rate */
1166 baud = uart_get_baud_rate(port, termios, old_termios,
1167 icom_acfg_baud[0],
1168 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1169 if (!baud)
1170 baud = 9600; /* B0 transition handled in rs_set_termios */
1172 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1173 if (icom_acfg_baud[index] == baud) {
1174 new_config3 = index;
1175 break;
1179 uart_update_timeout(port, cflag, baud);
1181 /* CTS flow control flag and modem status interrupts */
1182 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1183 if (cflag & CRTSCTS)
1184 tmp_byte |= HDLC_HDW_FLOW;
1185 else
1186 tmp_byte &= ~HDLC_HDW_FLOW;
1187 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1190 * Set up parity check flag
1192 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1193 if (iflag & INPCK)
1194 ICOM_PORT->read_status_mask |=
1195 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1197 if ((iflag & BRKINT) || (iflag & PARMRK))
1198 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1201 * Characters to ignore
1203 ICOM_PORT->ignore_status_mask = 0;
1204 if (iflag & IGNPAR)
1205 ICOM_PORT->ignore_status_mask |=
1206 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1207 if (iflag & IGNBRK) {
1208 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1210 * If we're ignore parity and break indicators, ignore
1211 * overruns too. (For real raw support).
1213 if (iflag & IGNPAR)
1214 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1218 * !!! ignore all characters if CREAD is not set
1220 if ((cflag & CREAD) == 0)
1221 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1223 /* Turn off Receiver to prepare for reset */
1224 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1226 for (index = 0; index < 10; index++) {
1227 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1228 break;
1232 /* clear all current buffers of data */
1233 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1234 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1235 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1236 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1237 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1240 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1241 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1244 /* activate changes and start xmit and receiver here */
1245 /* Enable the receiver */
1246 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1247 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1248 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1249 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1250 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1251 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer)); /* 0.5 seconds */
1252 writeb(0xFF, &(ICOM_PORT->dram->ier)); /* enable modem signal interrupts */
1254 /* reset processor */
1255 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1257 for (index = 0; index < 10; index++) {
1258 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1259 break;
1263 /* Enable Transmitter and Reciever */
1264 offset =
1265 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1266 (unsigned long) ICOM_PORT->statStg;
1267 writel(ICOM_PORT->statStg_pci + offset,
1268 &ICOM_PORT->dram->RcvStatusAddr);
1269 ICOM_PORT->next_rcv = 0;
1270 ICOM_PORT->put_length = 0;
1271 *ICOM_PORT->xmitRestart = 0;
1272 writel(ICOM_PORT->xmitRestart_pci,
1273 &ICOM_PORT->dram->XmitStatusAddr);
1274 trace(ICOM_PORT, "XR_ENAB", 0);
1275 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1277 spin_unlock_irqrestore(&port->lock, flags);
1280 static const char *icom_type(struct uart_port *port)
1282 return "icom";
1285 static void icom_release_port(struct uart_port *port)
1289 static int icom_request_port(struct uart_port *port)
1291 return 0;
1294 static void icom_config_port(struct uart_port *port, int flags)
1296 port->type = PORT_ICOM;
1299 static struct uart_ops icom_ops = {
1300 .tx_empty = icom_tx_empty,
1301 .set_mctrl = icom_set_mctrl,
1302 .get_mctrl = icom_get_mctrl,
1303 .stop_tx = icom_stop_tx,
1304 .start_tx = icom_start_tx,
1305 .send_xchar = icom_send_xchar,
1306 .stop_rx = icom_stop_rx,
1307 .enable_ms = icom_enable_ms,
1308 .break_ctl = icom_break,
1309 .startup = icom_open,
1310 .shutdown = icom_close,
1311 .set_termios = icom_set_termios,
1312 .type = icom_type,
1313 .release_port = icom_release_port,
1314 .request_port = icom_request_port,
1315 .config_port = icom_config_port,
1318 #define ICOM_CONSOLE NULL
1320 static struct uart_driver icom_uart_driver = {
1321 .owner = THIS_MODULE,
1322 .driver_name = ICOM_DRIVER_NAME,
1323 .dev_name = "ttyA",
1324 .major = ICOM_MAJOR,
1325 .minor = ICOM_MINOR_START,
1326 .nr = NR_PORTS,
1327 .cons = ICOM_CONSOLE,
1330 static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1332 u32 subsystem_id = icom_adapter->subsystem_id;
1333 int retval = 0;
1334 int i;
1335 struct icom_port *icom_port;
1337 if (icom_adapter->version == ADAPTER_V1) {
1338 icom_adapter->numb_ports = 2;
1340 for (i = 0; i < 2; i++) {
1341 icom_port = &icom_adapter->port_info[i];
1342 icom_port->port = i;
1343 icom_port->status = ICOM_PORT_ACTIVE;
1344 icom_port->imbed_modem = ICOM_UNKNOWN;
1346 } else {
1347 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1348 icom_adapter->numb_ports = 4;
1350 for (i = 0; i < 4; i++) {
1351 icom_port = &icom_adapter->port_info[i];
1353 icom_port->port = i;
1354 icom_port->status = ICOM_PORT_ACTIVE;
1355 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1357 } else {
1358 icom_adapter->numb_ports = 4;
1360 icom_adapter->port_info[0].port = 0;
1361 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1363 if (subsystem_id ==
1364 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1365 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1366 } else {
1367 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1370 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1372 icom_adapter->port_info[2].port = 2;
1373 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1374 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1375 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1379 return retval;
1382 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1384 if (icom_adapter->version == ADAPTER_V1) {
1385 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1386 icom_port->int_reg = icom_adapter->base_addr +
1387 0x4004 + 2 - 2 * port_num;
1388 } else {
1389 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1390 if (icom_port->port < 2)
1391 icom_port->int_reg = icom_adapter->base_addr +
1392 0x8004 + 2 - 2 * icom_port->port;
1393 else
1394 icom_port->int_reg = icom_adapter->base_addr +
1395 0x8024 + 2 - 2 * (icom_port->port - 2);
1398 static int __init icom_load_ports(struct icom_adapter *icom_adapter)
1400 struct icom_port *icom_port;
1401 int port_num;
1402 int retval;
1404 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1406 icom_port = &icom_adapter->port_info[port_num];
1408 if (icom_port->status == ICOM_PORT_ACTIVE) {
1409 icom_port_active(icom_port, icom_adapter, port_num);
1410 icom_port->dram = icom_adapter->base_addr +
1411 0x2000 * icom_port->port;
1413 icom_port->adapter = icom_adapter;
1415 /* get port memory */
1416 if ((retval = get_port_memory(icom_port)) != 0) {
1417 dev_err(&icom_port->adapter->pci_dev->dev,
1418 "Memory allocation for port FAILED\n");
1422 return 0;
1425 static int __devinit icom_alloc_adapter(struct icom_adapter
1426 **icom_adapter_ref)
1428 int adapter_count = 0;
1429 struct icom_adapter *icom_adapter;
1430 struct icom_adapter *cur_adapter_entry;
1431 struct list_head *tmp;
1433 icom_adapter = (struct icom_adapter *)
1434 kmalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1436 if (!icom_adapter) {
1437 return -ENOMEM;
1440 memset(icom_adapter, 0, sizeof(struct icom_adapter));
1442 list_for_each(tmp, &icom_adapter_head) {
1443 cur_adapter_entry =
1444 list_entry(tmp, struct icom_adapter,
1445 icom_adapter_entry);
1446 if (cur_adapter_entry->index != adapter_count) {
1447 break;
1449 adapter_count++;
1452 icom_adapter->index = adapter_count;
1453 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1455 *icom_adapter_ref = icom_adapter;
1456 return 0;
1459 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1461 list_del(&icom_adapter->icom_adapter_entry);
1462 kfree(icom_adapter);
1465 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1467 struct icom_port *icom_port;
1468 int index;
1470 for (index = 0; index < icom_adapter->numb_ports; index++) {
1471 icom_port = &icom_adapter->port_info[index];
1473 if (icom_port->status == ICOM_PORT_ACTIVE) {
1474 dev_info(&icom_adapter->pci_dev->dev,
1475 "Device removed\n");
1477 uart_remove_one_port(&icom_uart_driver,
1478 &icom_port->uart_port);
1480 /* be sure that DTR and RTS are dropped */
1481 writeb(0x00, &icom_port->dram->osr);
1483 /* Wait 0.1 Sec for simple Init to complete */
1484 msleep(100);
1486 /* Stop proccessor */
1487 stop_processor(icom_port);
1489 free_port_memory(icom_port);
1493 free_irq(icom_adapter->irq_number, (void *) icom_adapter);
1494 iounmap(icom_adapter->base_addr);
1495 icom_free_adapter(icom_adapter);
1496 pci_release_regions(icom_adapter->pci_dev);
1499 static void icom_kobj_release(struct kobject *kobj)
1501 struct icom_adapter *icom_adapter;
1503 icom_adapter = to_icom_adapter(kobj);
1504 icom_remove_adapter(icom_adapter);
1507 static struct kobj_type icom_kobj_type = {
1508 .release = icom_kobj_release,
1511 static int __devinit icom_probe(struct pci_dev *dev,
1512 const struct pci_device_id *ent)
1514 int index;
1515 unsigned int command_reg;
1516 int retval;
1517 struct icom_adapter *icom_adapter;
1518 struct icom_port *icom_port;
1520 retval = pci_enable_device(dev);
1521 if (retval) {
1522 dev_err(&dev->dev, "Device enable FAILED\n");
1523 return retval;
1526 if ( (retval = pci_request_regions(dev, "icom"))) {
1527 dev_err(&dev->dev, "pci_request_region FAILED\n");
1528 pci_disable_device(dev);
1529 return retval;
1532 pci_set_master(dev);
1534 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1535 dev_err(&dev->dev, "PCI Config read FAILED\n");
1536 return retval;
1539 pci_write_config_dword(dev, PCI_COMMAND,
1540 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1541 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1543 if (ent->driver_data == ADAPTER_V1) {
1544 pci_write_config_dword(dev, 0x44, 0x8300830A);
1545 } else {
1546 pci_write_config_dword(dev, 0x44, 0x42004200);
1547 pci_write_config_dword(dev, 0x48, 0x42004200);
1551 retval = icom_alloc_adapter(&icom_adapter);
1552 if (retval) {
1553 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1554 retval = -EIO;
1555 goto probe_exit0;
1558 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1559 icom_adapter->irq_number = dev->irq;
1560 icom_adapter->pci_dev = dev;
1561 icom_adapter->version = ent->driver_data;
1562 icom_adapter->subsystem_id = ent->subdevice;
1565 retval = icom_init_ports(icom_adapter);
1566 if (retval) {
1567 dev_err(&dev->dev, "Port configuration failed\n");
1568 goto probe_exit1;
1571 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1572 pci_resource_len(dev, 0));
1574 if (!icom_adapter->base_addr)
1575 goto probe_exit1;
1577 /* save off irq and request irq line */
1578 if ( (retval = request_irq(dev->irq, icom_interrupt,
1579 SA_INTERRUPT | SA_SHIRQ, ICOM_DRIVER_NAME,
1580 (void *) icom_adapter))) {
1581 goto probe_exit2;
1584 retval = icom_load_ports(icom_adapter);
1586 for (index = 0; index < icom_adapter->numb_ports; index++) {
1587 icom_port = &icom_adapter->port_info[index];
1589 if (icom_port->status == ICOM_PORT_ACTIVE) {
1590 icom_port->uart_port.irq = icom_port->adapter->irq_number;
1591 icom_port->uart_port.type = PORT_ICOM;
1592 icom_port->uart_port.iotype = UPIO_MEM;
1593 icom_port->uart_port.membase =
1594 (char *) icom_adapter->base_addr_pci;
1595 icom_port->uart_port.fifosize = 16;
1596 icom_port->uart_port.ops = &icom_ops;
1597 icom_port->uart_port.line =
1598 icom_port->port + icom_adapter->index * 4;
1599 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1600 icom_port->status = ICOM_PORT_OFF;
1601 dev_err(&dev->dev, "Device add failed\n");
1602 } else
1603 dev_info(&dev->dev, "Device added\n");
1607 kobject_init(&icom_adapter->kobj);
1608 icom_adapter->kobj.ktype = &icom_kobj_type;
1609 return 0;
1611 probe_exit2:
1612 iounmap(icom_adapter->base_addr);
1613 probe_exit1:
1614 icom_free_adapter(icom_adapter);
1616 probe_exit0:
1617 pci_release_regions(dev);
1618 pci_disable_device(dev);
1620 return retval;
1625 static void __devexit icom_remove(struct pci_dev *dev)
1627 struct icom_adapter *icom_adapter;
1628 struct list_head *tmp;
1630 list_for_each(tmp, &icom_adapter_head) {
1631 icom_adapter = list_entry(tmp, struct icom_adapter,
1632 icom_adapter_entry);
1633 if (icom_adapter->pci_dev == dev) {
1634 kobject_put(&icom_adapter->kobj);
1635 return;
1639 dev_err(&dev->dev, "Unable to find device to remove\n");
1642 static struct pci_driver icom_pci_driver = {
1643 .name = ICOM_DRIVER_NAME,
1644 .id_table = icom_pci_table,
1645 .probe = icom_probe,
1646 .remove = __devexit_p(icom_remove),
1649 static int __init icom_init(void)
1651 int ret;
1653 spin_lock_init(&icom_lock);
1655 ret = uart_register_driver(&icom_uart_driver);
1656 if (ret)
1657 return ret;
1659 ret = pci_register_driver(&icom_pci_driver);
1661 if (ret < 0)
1662 uart_unregister_driver(&icom_uart_driver);
1664 return ret;
1667 static void __exit icom_exit(void)
1669 pci_unregister_driver(&icom_pci_driver);
1670 uart_unregister_driver(&icom_uart_driver);
1673 module_init(icom_init);
1674 module_exit(icom_exit);
1676 #ifdef ICOM_TRACE
1677 static inline void trace(struct icom_port *icom_port, char *trace_pt,
1678 unsigned long trace_data)
1680 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1681 icom_port->port, trace_pt, trace_data);
1683 #endif
1685 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1686 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1687 MODULE_SUPPORTED_DEVICE
1688 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1689 MODULE_LICENSE("GPL");