[TG3]: Add tagged status support.
[linux-2.6/verdex.git] / drivers / serial / icom.c
blob546a0bc77e1e16f97e754e667218f4eb6e767097
1 /*
2 * icom.c
4 * Copyright (C) 2001 IBM Corporation. All rights reserved.
6 * Serial device driver.
8 * Based on code from serial.c
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #define SERIAL_DO_RESTART
26 #include <linux/module.h>
27 #include <linux/config.h>
28 #include <linux/version.h>
29 #include <linux/kernel.h>
30 #include <linux/errno.h>
31 #include <linux/signal.h>
32 #include <linux/sched.h>
33 #include <linux/timer.h>
34 #include <linux/interrupt.h>
35 #include <linux/tty.h>
36 #include <linux/termios.h>
37 #include <linux/fs.h>
38 #include <linux/tty_flip.h>
39 #include <linux/serial.h>
40 #include <linux/serial_reg.h>
41 #include <linux/major.h>
42 #include <linux/string.h>
43 #include <linux/fcntl.h>
44 #include <linux/ptrace.h>
45 #include <linux/ioport.h>
46 #include <linux/mm.h>
47 #include <linux/slab.h>
48 #include <linux/init.h>
49 #include <linux/delay.h>
50 #include <linux/pci.h>
51 #include <linux/vmalloc.h>
52 #include <linux/smp.h>
53 #include <linux/smp_lock.h>
54 #include <linux/spinlock.h>
55 #include <linux/kobject.h>
56 #include <linux/firmware.h>
57 #include <linux/bitops.h>
59 #include <asm/system.h>
60 #include <asm/segment.h>
61 #include <asm/io.h>
62 #include <asm/irq.h>
63 #include <asm/uaccess.h>
65 #include "icom.h"
67 /*#define ICOM_TRACE enable port trace capabilities */
69 #define ICOM_DRIVER_NAME "icom"
70 #define ICOM_VERSION_STR "1.3.1"
71 #define NR_PORTS 128
72 #define ICOM_PORT ((struct icom_port *)port)
73 #define to_icom_adapter(d) container_of(d, struct icom_adapter, kobj)
75 static const struct pci_device_id icom_pci_table[] = {
77 .vendor = PCI_VENDOR_ID_IBM,
78 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
79 .subvendor = PCI_ANY_ID,
80 .subdevice = PCI_ANY_ID,
81 .driver_data = ADAPTER_V1,
84 .vendor = PCI_VENDOR_ID_IBM,
85 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
86 .subvendor = PCI_VENDOR_ID_IBM,
87 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
88 .driver_data = ADAPTER_V2,
91 .vendor = PCI_VENDOR_ID_IBM,
92 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
93 .subvendor = PCI_VENDOR_ID_IBM,
94 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
95 .driver_data = ADAPTER_V2,
98 .vendor = PCI_VENDOR_ID_IBM,
99 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
100 .subvendor = PCI_VENDOR_ID_IBM,
101 .subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
102 .driver_data = ADAPTER_V2,
107 struct lookup_proc_table start_proc[4] = {
108 {NULL, ICOM_CONTROL_START_A},
109 {NULL, ICOM_CONTROL_START_B},
110 {NULL, ICOM_CONTROL_START_C},
111 {NULL, ICOM_CONTROL_START_D}
115 struct lookup_proc_table stop_proc[4] = {
116 {NULL, ICOM_CONTROL_STOP_A},
117 {NULL, ICOM_CONTROL_STOP_B},
118 {NULL, ICOM_CONTROL_STOP_C},
119 {NULL, ICOM_CONTROL_STOP_D}
122 struct lookup_int_table int_mask_tbl[4] = {
123 {NULL, ICOM_INT_MASK_PRC_A},
124 {NULL, ICOM_INT_MASK_PRC_B},
125 {NULL, ICOM_INT_MASK_PRC_C},
126 {NULL, ICOM_INT_MASK_PRC_D},
130 MODULE_DEVICE_TABLE(pci, icom_pci_table);
132 static LIST_HEAD(icom_adapter_head);
134 /* spinlock for adapter initialization and changing adapter operations */
135 static spinlock_t icom_lock;
137 #ifdef ICOM_TRACE
138 static inline void trace(struct icom_port *, char *, unsigned long) {};
139 #else
140 static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
141 #endif
143 static void free_port_memory(struct icom_port *icom_port)
145 struct pci_dev *dev = icom_port->adapter->pci_dev;
147 trace(icom_port, "RET_PORT_MEM", 0);
148 if (icom_port->recv_buf) {
149 pci_free_consistent(dev, 4096, icom_port->recv_buf,
150 icom_port->recv_buf_pci);
151 icom_port->recv_buf = NULL;
153 if (icom_port->xmit_buf) {
154 pci_free_consistent(dev, 4096, icom_port->xmit_buf,
155 icom_port->xmit_buf_pci);
156 icom_port->xmit_buf = NULL;
158 if (icom_port->statStg) {
159 pci_free_consistent(dev, 4096, icom_port->statStg,
160 icom_port->statStg_pci);
161 icom_port->statStg = NULL;
164 if (icom_port->xmitRestart) {
165 pci_free_consistent(dev, 4096, icom_port->xmitRestart,
166 icom_port->xmitRestart_pci);
167 icom_port->xmitRestart = NULL;
171 static int __init get_port_memory(struct icom_port *icom_port)
173 int index;
174 unsigned long stgAddr;
175 unsigned long startStgAddr;
176 unsigned long offset;
177 struct pci_dev *dev = icom_port->adapter->pci_dev;
179 icom_port->xmit_buf =
180 pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
181 if (!icom_port->xmit_buf) {
182 dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
183 return -ENOMEM;
186 trace(icom_port, "GET_PORT_MEM",
187 (unsigned long) icom_port->xmit_buf);
189 icom_port->recv_buf =
190 pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
191 if (!icom_port->recv_buf) {
192 dev_err(&dev->dev, "Can not allocate Receive buffer\n");
193 free_port_memory(icom_port);
194 return -ENOMEM;
196 trace(icom_port, "GET_PORT_MEM",
197 (unsigned long) icom_port->recv_buf);
199 icom_port->statStg =
200 pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
201 if (!icom_port->statStg) {
202 dev_err(&dev->dev, "Can not allocate Status buffer\n");
203 free_port_memory(icom_port);
204 return -ENOMEM;
206 trace(icom_port, "GET_PORT_MEM",
207 (unsigned long) icom_port->statStg);
209 icom_port->xmitRestart =
210 pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
211 if (!icom_port->xmitRestart) {
212 dev_err(&dev->dev,
213 "Can not allocate xmit Restart buffer\n");
214 free_port_memory(icom_port);
215 return -ENOMEM;
218 memset(icom_port->statStg, 0, 4096);
220 /* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
221 indicates that frames are to be transmitted
224 stgAddr = (unsigned long) icom_port->statStg;
225 for (index = 0; index < NUM_XBUFFS; index++) {
226 trace(icom_port, "FOD_ADDR", stgAddr);
227 stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
228 if (index < (NUM_XBUFFS - 1)) {
229 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
230 icom_port->statStg->xmit[index].leLengthASD =
231 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
232 trace(icom_port, "FOD_ADDR", stgAddr);
233 trace(icom_port, "FOD_XBUFF",
234 (unsigned long) icom_port->xmit_buf);
235 icom_port->statStg->xmit[index].leBuffer =
236 cpu_to_le32(icom_port->xmit_buf_pci);
237 } else if (index == (NUM_XBUFFS - 1)) {
238 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
239 icom_port->statStg->xmit[index].leLengthASD =
240 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
241 trace(icom_port, "FOD_XBUFF",
242 (unsigned long) icom_port->xmit_buf);
243 icom_port->statStg->xmit[index].leBuffer =
244 cpu_to_le32(icom_port->xmit_buf_pci);
245 } else {
246 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
249 /* FIDs */
250 startStgAddr = stgAddr;
252 /* fill in every entry, even if no buffer */
253 for (index = 0; index < NUM_RBUFFS; index++) {
254 trace(icom_port, "FID_ADDR", stgAddr);
255 stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
256 icom_port->statStg->rcv[index].leLength = 0;
257 icom_port->statStg->rcv[index].WorkingLength =
258 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
259 if (index < (NUM_RBUFFS - 1) ) {
260 offset = stgAddr - (unsigned long) icom_port->statStg;
261 icom_port->statStg->rcv[index].leNext =
262 cpu_to_le32(icom_port-> statStg_pci + offset);
263 trace(icom_port, "FID_RBUFF",
264 (unsigned long) icom_port->recv_buf);
265 icom_port->statStg->rcv[index].leBuffer =
266 cpu_to_le32(icom_port->recv_buf_pci);
267 } else if (index == (NUM_RBUFFS -1) ) {
268 offset = startStgAddr - (unsigned long) icom_port->statStg;
269 icom_port->statStg->rcv[index].leNext =
270 cpu_to_le32(icom_port-> statStg_pci + offset);
271 trace(icom_port, "FID_RBUFF",
272 (unsigned long) icom_port->recv_buf + 2048);
273 icom_port->statStg->rcv[index].leBuffer =
274 cpu_to_le32(icom_port->recv_buf_pci + 2048);
275 } else {
276 icom_port->statStg->rcv[index].leNext = 0;
277 icom_port->statStg->rcv[index].leBuffer = 0;
281 return 0;
284 static void stop_processor(struct icom_port *icom_port)
286 unsigned long temp;
287 unsigned long flags;
288 int port;
290 spin_lock_irqsave(&icom_lock, flags);
292 port = icom_port->port;
293 if (port == 0 || port == 1)
294 stop_proc[port].global_control_reg = &icom_port->global_reg->control;
295 else
296 stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
299 if (port < 4) {
300 temp = readl(stop_proc[port].global_control_reg);
301 temp =
302 (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
303 writel(temp, stop_proc[port].global_control_reg);
305 /* write flush */
306 readl(stop_proc[port].global_control_reg);
307 } else {
308 dev_err(&icom_port->adapter->pci_dev->dev,
309 "Invalid port assignment\n");
312 spin_unlock_irqrestore(&icom_lock, flags);
315 static void start_processor(struct icom_port *icom_port)
317 unsigned long temp;
318 unsigned long flags;
319 int port;
321 spin_lock_irqsave(&icom_lock, flags);
323 port = icom_port->port;
324 if (port == 0 || port == 1)
325 start_proc[port].global_control_reg = &icom_port->global_reg->control;
326 else
327 start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
328 if (port < 4) {
329 temp = readl(start_proc[port].global_control_reg);
330 temp =
331 (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
332 writel(temp, start_proc[port].global_control_reg);
334 /* write flush */
335 readl(start_proc[port].global_control_reg);
336 } else {
337 dev_err(&icom_port->adapter->pci_dev->dev,
338 "Invalid port assignment\n");
341 spin_unlock_irqrestore(&icom_lock, flags);
344 static void load_code(struct icom_port *icom_port)
346 const struct firmware *fw;
347 char __iomem *iram_ptr;
348 int index;
349 int status = 0;
350 void __iomem *dram_ptr = icom_port->dram;
351 dma_addr_t temp_pci;
352 unsigned char *new_page = NULL;
353 unsigned char cable_id = NO_CABLE;
354 struct pci_dev *dev = icom_port->adapter->pci_dev;
356 /* Clear out any pending interrupts */
357 writew(0x3FFF, icom_port->int_reg);
359 trace(icom_port, "CLEAR_INTERRUPTS", 0);
361 /* Stop processor */
362 stop_processor(icom_port);
364 /* Zero out DRAM */
365 memset_io(dram_ptr, 0, 512);
367 /* Load Call Setup into Adapter */
368 if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
369 dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
370 status = -1;
371 goto load_code_exit;
374 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
375 dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
376 release_firmware(fw);
377 status = -1;
378 goto load_code_exit;
381 iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
382 for (index = 0; index < fw->size; index++)
383 writeb(fw->data[index], &iram_ptr[index]);
385 release_firmware(fw);
387 /* Load Resident DCE portion of Adapter */
388 if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
389 dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
390 status = -1;
391 goto load_code_exit;
394 if (fw->size > ICOM_IRAM_SIZE) {
395 dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
396 release_firmware(fw);
397 status = -1;
398 goto load_code_exit;
401 iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
402 for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
403 writeb(fw->data[index], &iram_ptr[index]);
405 release_firmware(fw);
407 /* Set Hardware level */
408 if ((icom_port->adapter->version | ADAPTER_V2) == ADAPTER_V2)
409 writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));
411 /* Start the processor in Adapter */
412 start_processor(icom_port);
414 writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
415 &(icom_port->dram->HDLCConfigReg));
416 writeb(0x04, &(icom_port->dram->FlagFillIdleTimer)); /* 0.5 seconds */
417 writeb(0x00, &(icom_port->dram->CmdReg));
418 writeb(0x10, &(icom_port->dram->async_config3));
419 writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
420 ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));
422 /*Set up data in icom DRAM to indicate where personality
423 *code is located and its length.
425 new_page = pci_alloc_consistent(dev, 4096, &temp_pci);
427 if (!new_page) {
428 dev_err(&dev->dev, "Can not allocate DMA buffer\n");
429 status = -1;
430 goto load_code_exit;
433 if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
434 dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
435 status = -1;
436 goto load_code_exit;
439 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
440 dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
441 release_firmware(fw);
442 status = -1;
443 goto load_code_exit;
446 for (index = 0; index < fw->size; index++)
447 new_page[index] = fw->data[index];
449 release_firmware(fw);
451 writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
452 writel(temp_pci, &icom_port->dram->mac_load_addr);
454 /*Setting the syncReg to 0x80 causes adapter to start downloading
455 the personality code into adapter instruction RAM.
456 Once code is loaded, it will begin executing and, based on
457 information provided above, will start DMAing data from
458 shared memory to adapter DRAM.
460 /* the wait loop below verifies this write operation has been done
461 and processed
463 writeb(START_DOWNLOAD, &icom_port->dram->sync);
465 /* Wait max 1 Sec for data download and processor to start */
466 for (index = 0; index < 10; index++) {
467 msleep(100);
468 if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
469 break;
472 if (index == 10)
473 status = -1;
476 * check Cable ID
478 cable_id = readb(&icom_port->dram->cable_id);
480 if (cable_id & ICOM_CABLE_ID_VALID) {
481 /* Get cable ID into the lower 4 bits (standard form) */
482 cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
483 icom_port->cable_id = cable_id;
484 } else {
485 dev_err(&dev->dev,"Invalid or no cable attached\n");
486 icom_port->cable_id = NO_CABLE;
489 load_code_exit:
491 if (status != 0) {
492 /* Clear out any pending interrupts */
493 writew(0x3FFF, icom_port->int_reg);
495 /* Turn off port */
496 writeb(ICOM_DISABLE, &(icom_port->dram->disable));
498 /* Stop processor */
499 stop_processor(icom_port);
501 dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
504 if (new_page != NULL)
505 pci_free_consistent(dev, 4096, new_page, temp_pci);
508 static int startup(struct icom_port *icom_port)
510 unsigned long temp;
511 unsigned char cable_id, raw_cable_id;
512 unsigned long flags;
513 int port;
515 trace(icom_port, "STARTUP", 0);
517 if (!icom_port->dram) {
518 /* should NEVER be NULL */
519 dev_err(&icom_port->adapter->pci_dev->dev,
520 "Unusable Port, port configuration missing\n");
521 return -ENODEV;
525 * check Cable ID
527 raw_cable_id = readb(&icom_port->dram->cable_id);
528 trace(icom_port, "CABLE_ID", raw_cable_id);
530 /* Get cable ID into the lower 4 bits (standard form) */
531 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
533 /* Check for valid Cable ID */
534 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
535 (cable_id != icom_port->cable_id)) {
537 /* reload adapter code, pick up any potential changes in cable id */
538 load_code(icom_port);
540 /* still no sign of cable, error out */
541 raw_cable_id = readb(&icom_port->dram->cable_id);
542 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
543 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
544 (icom_port->cable_id == NO_CABLE))
545 return -EIO;
549 * Finally, clear and enable interrupts
551 spin_lock_irqsave(&icom_lock, flags);
552 port = icom_port->port;
553 if (port == 0 || port == 1)
554 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
555 else
556 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
558 if (port == 0 || port == 2)
559 writew(0x00FF, icom_port->int_reg);
560 else
561 writew(0x3F00, icom_port->int_reg);
562 if (port < 4) {
563 temp = readl(int_mask_tbl[port].global_int_mask);
564 writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
566 /* write flush */
567 readl(int_mask_tbl[port].global_int_mask);
568 } else {
569 dev_err(&icom_port->adapter->pci_dev->dev,
570 "Invalid port assignment\n");
573 spin_unlock_irqrestore(&icom_lock, flags);
574 return 0;
577 static void shutdown(struct icom_port *icom_port)
579 unsigned long temp;
580 unsigned char cmdReg;
581 unsigned long flags;
582 int port;
584 spin_lock_irqsave(&icom_lock, flags);
585 trace(icom_port, "SHUTDOWN", 0);
588 * disable all interrupts
590 port = icom_port->port;
591 if (port == 0 || port == 1)
592 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
593 else
594 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
596 if (port < 4) {
597 temp = readl(int_mask_tbl[port].global_int_mask);
598 writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
600 /* write flush */
601 readl(int_mask_tbl[port].global_int_mask);
602 } else {
603 dev_err(&icom_port->adapter->pci_dev->dev,
604 "Invalid port assignment\n");
606 spin_unlock_irqrestore(&icom_lock, flags);
609 * disable break condition
611 cmdReg = readb(&icom_port->dram->CmdReg);
612 if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) {
613 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
617 static int icom_write(struct uart_port *port)
619 unsigned long data_count;
620 unsigned char cmdReg;
621 unsigned long offset;
622 int temp_tail = port->info->xmit.tail;
624 trace(ICOM_PORT, "WRITE", 0);
626 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
627 SA_FLAGS_READY_TO_XMIT) {
628 trace(ICOM_PORT, "WRITE_FULL", 0);
629 return 0;
632 data_count = 0;
633 while ((port->info->xmit.head != temp_tail) &&
634 (data_count <= XMIT_BUFF_SZ)) {
636 ICOM_PORT->xmit_buf[data_count++] =
637 port->info->xmit.buf[temp_tail];
639 temp_tail++;
640 temp_tail &= (UART_XMIT_SIZE - 1);
643 if (data_count) {
644 ICOM_PORT->statStg->xmit[0].flags =
645 cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
646 ICOM_PORT->statStg->xmit[0].leLength =
647 cpu_to_le16(data_count);
648 offset =
649 (unsigned long) &ICOM_PORT->statStg->xmit[0] -
650 (unsigned long) ICOM_PORT->statStg;
651 *ICOM_PORT->xmitRestart =
652 cpu_to_le32(ICOM_PORT->statStg_pci + offset);
653 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
654 writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
655 &ICOM_PORT->dram->CmdReg);
656 writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
657 trace(ICOM_PORT, "WRITE_START", data_count);
658 /* write flush */
659 readb(&ICOM_PORT->dram->StartXmitCmd);
662 return data_count;
665 static inline void check_modem_status(struct icom_port *icom_port)
667 static char old_status = 0;
668 char delta_status;
669 unsigned char status;
671 spin_lock(&icom_port->uart_port.lock);
673 /*modem input register */
674 status = readb(&icom_port->dram->isr);
675 trace(icom_port, "CHECK_MODEM", status);
676 delta_status = status ^ old_status;
677 if (delta_status) {
678 if (delta_status & ICOM_RI)
679 icom_port->uart_port.icount.rng++;
680 if (delta_status & ICOM_DSR)
681 icom_port->uart_port.icount.dsr++;
682 if (delta_status & ICOM_DCD)
683 uart_handle_dcd_change(&icom_port->uart_port,
684 delta_status & ICOM_DCD);
685 if (delta_status & ICOM_CTS)
686 uart_handle_cts_change(&icom_port->uart_port,
687 delta_status & ICOM_CTS);
689 wake_up_interruptible(&icom_port->uart_port.info->
690 delta_msr_wait);
691 old_status = status;
693 spin_unlock(&icom_port->uart_port.lock);
696 static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
698 unsigned short int count;
699 int i;
701 if (port_int_reg & (INT_XMIT_COMPLETED)) {
702 trace(icom_port, "XMIT_COMPLETE", 0);
704 /* clear buffer in use bit */
705 icom_port->statStg->xmit[0].flags &=
706 cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
708 count = (unsigned short int)
709 cpu_to_le16(icom_port->statStg->xmit[0].leLength);
710 icom_port->uart_port.icount.tx += count;
712 for (i=0; i<count &&
713 !uart_circ_empty(&icom_port->uart_port.info->xmit); i++) {
715 icom_port->uart_port.info->xmit.tail++;
716 icom_port->uart_port.info->xmit.tail &=
717 (UART_XMIT_SIZE - 1);
720 if (!icom_write(&icom_port->uart_port))
721 /* activate write queue */
722 uart_write_wakeup(&icom_port->uart_port);
723 } else
724 trace(icom_port, "XMIT_DISABLED", 0);
727 static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
729 short int count, rcv_buff;
730 struct tty_struct *tty = icom_port->uart_port.info->tty;
731 unsigned short int status;
732 struct uart_icount *icount;
733 unsigned long offset;
735 trace(icom_port, "RCV_COMPLETE", 0);
736 rcv_buff = icom_port->next_rcv;
738 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
739 while (status & SA_FL_RCV_DONE) {
741 trace(icom_port, "FID_STATUS", status);
742 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
744 trace(icom_port, "RCV_COUNT", count);
745 if (count > (TTY_FLIPBUF_SIZE - tty->flip.count))
746 count = TTY_FLIPBUF_SIZE - tty->flip.count;
748 trace(icom_port, "REAL_COUNT", count);
750 offset =
751 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
752 icom_port->recv_buf_pci;
754 memcpy(tty->flip.char_buf_ptr,(unsigned char *)
755 ((unsigned long)icom_port->recv_buf + offset), count);
757 if (count > 0) {
758 tty->flip.count += count - 1;
759 tty->flip.char_buf_ptr += count - 1;
761 memset(tty->flip.flag_buf_ptr, 0, count);
762 tty->flip.flag_buf_ptr += count - 1;
765 icount = &icom_port->uart_port.icount;
766 icount->rx += count;
768 /* Break detect logic */
769 if ((status & SA_FLAGS_FRAME_ERROR)
770 && (tty->flip.char_buf_ptr[0] == 0x00)) {
771 status &= ~SA_FLAGS_FRAME_ERROR;
772 status |= SA_FLAGS_BREAK_DET;
773 trace(icom_port, "BREAK_DET", 0);
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 *tty->flip.flag_buf_ptr = TTY_BREAK;
803 } else if (status & SA_FLAGS_PARITY_ERROR) {
804 trace(icom_port, "PARITY_ERROR", 0);
805 *tty->flip.flag_buf_ptr = TTY_PARITY;
806 } else if (status & SA_FLAGS_FRAME_ERROR)
807 *tty->flip.flag_buf_ptr = TTY_FRAME;
809 if (status & SA_FLAGS_OVERRUN) {
811 * Overrun is special, since it's
812 * reported immediately, and doesn't
813 * affect the current character
815 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
816 tty->flip.count++;
817 tty->flip.flag_buf_ptr++;
818 tty->flip.char_buf_ptr++;
819 *tty->flip.flag_buf_ptr = TTY_OVERRUN;
824 tty->flip.flag_buf_ptr++;
825 tty->flip.char_buf_ptr++;
826 tty->flip.count++;
827 ignore_char:
828 icom_port->statStg->rcv[rcv_buff].flags = 0;
829 icom_port->statStg->rcv[rcv_buff].leLength = 0;
830 icom_port->statStg->rcv[rcv_buff].WorkingLength =
831 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
833 rcv_buff++;
834 if (rcv_buff == NUM_RBUFFS)
835 rcv_buff = 0;
837 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
839 icom_port->next_rcv = rcv_buff;
840 tty_flip_buffer_push(tty);
843 static void process_interrupt(u16 port_int_reg,
844 struct icom_port *icom_port)
847 spin_lock(&icom_port->uart_port.lock);
848 trace(icom_port, "INTERRUPT", port_int_reg);
850 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
851 xmit_interrupt(port_int_reg, icom_port);
853 if (port_int_reg & INT_RCV_COMPLETED)
854 recv_interrupt(port_int_reg, icom_port);
856 spin_unlock(&icom_port->uart_port.lock);
859 static irqreturn_t icom_interrupt(int irq, void *dev_id,
860 struct pt_regs *regs)
862 void __iomem * int_reg;
863 u32 adapter_interrupts;
864 u16 port_int_reg;
865 struct icom_adapter *icom_adapter;
866 struct icom_port *icom_port;
868 /* find icom_port for this interrupt */
869 icom_adapter = (struct icom_adapter *) dev_id;
871 if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
872 int_reg = icom_adapter->base_addr + 0x8024;
874 adapter_interrupts = readl(int_reg);
876 if (adapter_interrupts & 0x00003FFF) {
877 /* port 2 interrupt, NOTE: for all ADAPTER_V2, port 2 will be active */
878 icom_port = &icom_adapter->port_info[2];
879 port_int_reg = (u16) adapter_interrupts;
880 process_interrupt(port_int_reg, icom_port);
881 check_modem_status(icom_port);
883 if (adapter_interrupts & 0x3FFF0000) {
884 /* port 3 interrupt */
885 icom_port = &icom_adapter->port_info[3];
886 if (icom_port->status == ICOM_PORT_ACTIVE) {
887 port_int_reg =
888 (u16) (adapter_interrupts >> 16);
889 process_interrupt(port_int_reg, icom_port);
890 check_modem_status(icom_port);
894 /* Clear out any pending interrupts */
895 writel(adapter_interrupts, int_reg);
897 int_reg = icom_adapter->base_addr + 0x8004;
898 } else {
899 int_reg = icom_adapter->base_addr + 0x4004;
902 adapter_interrupts = readl(int_reg);
904 if (adapter_interrupts & 0x00003FFF) {
905 /* port 0 interrupt, NOTE: for all adapters, port 0 will be active */
906 icom_port = &icom_adapter->port_info[0];
907 port_int_reg = (u16) adapter_interrupts;
908 process_interrupt(port_int_reg, icom_port);
909 check_modem_status(icom_port);
911 if (adapter_interrupts & 0x3FFF0000) {
912 /* port 1 interrupt */
913 icom_port = &icom_adapter->port_info[1];
914 if (icom_port->status == ICOM_PORT_ACTIVE) {
915 port_int_reg = (u16) (adapter_interrupts >> 16);
916 process_interrupt(port_int_reg, icom_port);
917 check_modem_status(icom_port);
921 /* Clear out any pending interrupts */
922 writel(adapter_interrupts, int_reg);
924 /* flush the write */
925 adapter_interrupts = readl(int_reg);
927 return IRQ_HANDLED;
931 * ------------------------------------------------------------------
932 * Begin serial-core API
933 * ------------------------------------------------------------------
935 static unsigned int icom_tx_empty(struct uart_port *port)
937 int ret;
938 unsigned long flags;
940 spin_lock_irqsave(&port->lock, flags);
941 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
942 SA_FLAGS_READY_TO_XMIT)
943 ret = TIOCSER_TEMT;
944 else
945 ret = 0;
947 spin_unlock_irqrestore(&port->lock, flags);
948 return ret;
951 static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
953 unsigned char local_osr;
955 trace(ICOM_PORT, "SET_MODEM", 0);
956 local_osr = readb(&ICOM_PORT->dram->osr);
958 if (mctrl & TIOCM_RTS) {
959 trace(ICOM_PORT, "RAISE_RTS", 0);
960 local_osr |= ICOM_RTS;
961 } else {
962 trace(ICOM_PORT, "LOWER_RTS", 0);
963 local_osr &= ~ICOM_RTS;
966 if (mctrl & TIOCM_DTR) {
967 trace(ICOM_PORT, "RAISE_DTR", 0);
968 local_osr |= ICOM_DTR;
969 } else {
970 trace(ICOM_PORT, "LOWER_DTR", 0);
971 local_osr &= ~ICOM_DTR;
974 writeb(local_osr, &ICOM_PORT->dram->osr);
977 static unsigned int icom_get_mctrl(struct uart_port *port)
979 unsigned char status;
980 unsigned int result;
982 trace(ICOM_PORT, "GET_MODEM", 0);
984 status = readb(&ICOM_PORT->dram->isr);
986 result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
987 | ((status & ICOM_RI) ? TIOCM_RNG : 0)
988 | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
989 | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
990 return result;
993 static void icom_stop_tx(struct uart_port *port, unsigned int tty_stop)
995 unsigned char cmdReg;
997 if (tty_stop) {
998 trace(ICOM_PORT, "STOP", 0);
999 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1000 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
1004 static void icom_start_tx(struct uart_port *port, unsigned int tty_start)
1006 unsigned char cmdReg;
1008 trace(ICOM_PORT, "START", 0);
1009 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1010 if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
1011 writeb(cmdReg & ~CMD_HOLD_XMIT,
1012 &ICOM_PORT->dram->CmdReg);
1014 icom_write(port);
1017 static void icom_send_xchar(struct uart_port *port, char ch)
1019 unsigned char xdata;
1020 int index;
1021 unsigned long flags;
1023 trace(ICOM_PORT, "SEND_XCHAR", ch);
1025 /* wait .1 sec to send char */
1026 for (index = 0; index < 10; index++) {
1027 spin_lock_irqsave(&port->lock, flags);
1028 xdata = readb(&ICOM_PORT->dram->xchar);
1029 if (xdata == 0x00) {
1030 trace(ICOM_PORT, "QUICK_WRITE", 0);
1031 writeb(ch, &ICOM_PORT->dram->xchar);
1033 /* flush write operation */
1034 xdata = readb(&ICOM_PORT->dram->xchar);
1035 spin_unlock_irqrestore(&port->lock, flags);
1036 break;
1038 spin_unlock_irqrestore(&port->lock, flags);
1039 msleep(10);
1043 static void icom_stop_rx(struct uart_port *port)
1045 unsigned char cmdReg;
1047 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1048 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1051 static void icom_enable_ms(struct uart_port *port)
1053 /* no-op */
1056 static void icom_break(struct uart_port *port, int break_state)
1058 unsigned char cmdReg;
1059 unsigned long flags;
1061 spin_lock_irqsave(&port->lock, flags);
1062 trace(ICOM_PORT, "BREAK", 0);
1063 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1064 if (break_state == -1) {
1065 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1066 } else {
1067 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1069 spin_unlock_irqrestore(&port->lock, flags);
1072 static int icom_open(struct uart_port *port)
1074 int retval;
1076 kobject_get(&ICOM_PORT->adapter->kobj);
1077 retval = startup(ICOM_PORT);
1079 if (retval) {
1080 kobject_put(&ICOM_PORT->adapter->kobj);
1081 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1082 return retval;
1085 return 0;
1088 static void icom_close(struct uart_port *port)
1090 unsigned char cmdReg;
1092 trace(ICOM_PORT, "CLOSE", 0);
1094 /* stop receiver */
1095 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1096 writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1097 &ICOM_PORT->dram->CmdReg);
1099 shutdown(ICOM_PORT);
1101 kobject_put(&ICOM_PORT->adapter->kobj);
1104 static void icom_set_termios(struct uart_port *port,
1105 struct termios *termios,
1106 struct termios *old_termios)
1108 int baud;
1109 unsigned cflag, iflag;
1110 int bits;
1111 char new_config2;
1112 char new_config3 = 0;
1113 char tmp_byte;
1114 int index;
1115 int rcv_buff, xmit_buff;
1116 unsigned long offset;
1117 unsigned long flags;
1119 spin_lock_irqsave(&port->lock, flags);
1120 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1122 cflag = termios->c_cflag;
1123 iflag = termios->c_iflag;
1125 new_config2 = ICOM_ACFG_DRIVE1;
1127 /* byte size and parity */
1128 switch (cflag & CSIZE) {
1129 case CS5: /* 5 bits/char */
1130 new_config2 |= ICOM_ACFG_5BPC;
1131 bits = 7;
1132 break;
1133 case CS6: /* 6 bits/char */
1134 new_config2 |= ICOM_ACFG_6BPC;
1135 bits = 8;
1136 break;
1137 case CS7: /* 7 bits/char */
1138 new_config2 |= ICOM_ACFG_7BPC;
1139 bits = 9;
1140 break;
1141 case CS8: /* 8 bits/char */
1142 new_config2 |= ICOM_ACFG_8BPC;
1143 bits = 10;
1144 break;
1145 default:
1146 bits = 10;
1147 break;
1149 if (cflag & CSTOPB) {
1150 /* 2 stop bits */
1151 new_config2 |= ICOM_ACFG_2STOP_BIT;
1152 bits++;
1154 if (cflag & PARENB) {
1155 /* parity bit enabled */
1156 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1157 trace(ICOM_PORT, "PARENB", 0);
1158 bits++;
1160 if (cflag & PARODD) {
1161 /* odd parity */
1162 new_config2 |= ICOM_ACFG_PARITY_ODD;
1163 trace(ICOM_PORT, "PARODD", 0);
1166 /* Determine divisor based on baud rate */
1167 baud = uart_get_baud_rate(port, termios, old_termios,
1168 icom_acfg_baud[0],
1169 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1170 if (!baud)
1171 baud = 9600; /* B0 transition handled in rs_set_termios */
1173 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1174 if (icom_acfg_baud[index] == baud) {
1175 new_config3 = index;
1176 break;
1180 uart_update_timeout(port, cflag, baud);
1182 /* CTS flow control flag and modem status interrupts */
1183 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1184 if (cflag & CRTSCTS)
1185 tmp_byte |= HDLC_HDW_FLOW;
1186 else
1187 tmp_byte &= ~HDLC_HDW_FLOW;
1188 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1191 * Set up parity check flag
1193 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1194 if (iflag & INPCK)
1195 ICOM_PORT->read_status_mask |=
1196 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1198 if ((iflag & BRKINT) || (iflag & PARMRK))
1199 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1202 * Characters to ignore
1204 ICOM_PORT->ignore_status_mask = 0;
1205 if (iflag & IGNPAR)
1206 ICOM_PORT->ignore_status_mask |=
1207 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1208 if (iflag & IGNBRK) {
1209 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1211 * If we're ignore parity and break indicators, ignore
1212 * overruns too. (For real raw support).
1214 if (iflag & IGNPAR)
1215 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1219 * !!! ignore all characters if CREAD is not set
1221 if ((cflag & CREAD) == 0)
1222 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1224 /* Turn off Receiver to prepare for reset */
1225 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1227 for (index = 0; index < 10; index++) {
1228 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1229 break;
1233 /* clear all current buffers of data */
1234 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1235 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1236 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1237 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1238 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1241 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1242 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1245 /* activate changes and start xmit and receiver here */
1246 /* Enable the receiver */
1247 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1248 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1249 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1250 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1251 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1252 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer)); /* 0.5 seconds */
1253 writeb(0xFF, &(ICOM_PORT->dram->ier)); /* enable modem signal interrupts */
1255 /* reset processor */
1256 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1258 for (index = 0; index < 10; index++) {
1259 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1260 break;
1264 /* Enable Transmitter and Reciever */
1265 offset =
1266 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1267 (unsigned long) ICOM_PORT->statStg;
1268 writel(ICOM_PORT->statStg_pci + offset,
1269 &ICOM_PORT->dram->RcvStatusAddr);
1270 ICOM_PORT->next_rcv = 0;
1271 ICOM_PORT->put_length = 0;
1272 *ICOM_PORT->xmitRestart = 0;
1273 writel(ICOM_PORT->xmitRestart_pci,
1274 &ICOM_PORT->dram->XmitStatusAddr);
1275 trace(ICOM_PORT, "XR_ENAB", 0);
1276 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1278 spin_unlock_irqrestore(&port->lock, flags);
1281 static const char *icom_type(struct uart_port *port)
1283 return "icom";
1286 static void icom_release_port(struct uart_port *port)
1290 static int icom_request_port(struct uart_port *port)
1292 return 0;
1295 static void icom_config_port(struct uart_port *port, int flags)
1297 port->type = PORT_ICOM;
1300 static struct uart_ops icom_ops = {
1301 .tx_empty = icom_tx_empty,
1302 .set_mctrl = icom_set_mctrl,
1303 .get_mctrl = icom_get_mctrl,
1304 .stop_tx = icom_stop_tx,
1305 .start_tx = icom_start_tx,
1306 .send_xchar = icom_send_xchar,
1307 .stop_rx = icom_stop_rx,
1308 .enable_ms = icom_enable_ms,
1309 .break_ctl = icom_break,
1310 .startup = icom_open,
1311 .shutdown = icom_close,
1312 .set_termios = icom_set_termios,
1313 .type = icom_type,
1314 .release_port = icom_release_port,
1315 .request_port = icom_request_port,
1316 .config_port = icom_config_port,
1319 #define ICOM_CONSOLE NULL
1321 static struct uart_driver icom_uart_driver = {
1322 .owner = THIS_MODULE,
1323 .driver_name = ICOM_DRIVER_NAME,
1324 .dev_name = "ttyA",
1325 .major = ICOM_MAJOR,
1326 .minor = ICOM_MINOR_START,
1327 .nr = NR_PORTS,
1328 .cons = ICOM_CONSOLE,
1331 static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1333 u32 subsystem_id = icom_adapter->subsystem_id;
1334 int retval = 0;
1335 int i;
1336 struct icom_port *icom_port;
1338 if (icom_adapter->version == ADAPTER_V1) {
1339 icom_adapter->numb_ports = 2;
1341 for (i = 0; i < 2; i++) {
1342 icom_port = &icom_adapter->port_info[i];
1343 icom_port->port = i;
1344 icom_port->status = ICOM_PORT_ACTIVE;
1345 icom_port->imbed_modem = ICOM_UNKNOWN;
1347 } else {
1348 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1349 icom_adapter->numb_ports = 4;
1351 for (i = 0; i < 4; i++) {
1352 icom_port = &icom_adapter->port_info[i];
1354 icom_port->port = i;
1355 icom_port->status = ICOM_PORT_ACTIVE;
1356 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1358 } else {
1359 icom_adapter->numb_ports = 4;
1361 icom_adapter->port_info[0].port = 0;
1362 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1364 if (subsystem_id ==
1365 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1366 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1367 } else {
1368 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1371 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1373 icom_adapter->port_info[2].port = 2;
1374 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1375 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1376 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1380 return retval;
1383 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1385 if (icom_adapter->version == ADAPTER_V1) {
1386 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1387 icom_port->int_reg = icom_adapter->base_addr +
1388 0x4004 + 2 - 2 * port_num;
1389 } else {
1390 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1391 if (icom_port->port < 2)
1392 icom_port->int_reg = icom_adapter->base_addr +
1393 0x8004 + 2 - 2 * icom_port->port;
1394 else
1395 icom_port->int_reg = icom_adapter->base_addr +
1396 0x8024 + 2 - 2 * (icom_port->port - 2);
1399 static int __init icom_load_ports(struct icom_adapter *icom_adapter)
1401 struct icom_port *icom_port;
1402 int port_num;
1403 int retval;
1405 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1407 icom_port = &icom_adapter->port_info[port_num];
1409 if (icom_port->status == ICOM_PORT_ACTIVE) {
1410 icom_port_active(icom_port, icom_adapter, port_num);
1411 icom_port->dram = icom_adapter->base_addr +
1412 0x2000 * icom_port->port;
1414 icom_port->adapter = icom_adapter;
1416 /* get port memory */
1417 if ((retval = get_port_memory(icom_port)) != 0) {
1418 dev_err(&icom_port->adapter->pci_dev->dev,
1419 "Memory allocation for port FAILED\n");
1423 return 0;
1426 static int __devinit icom_alloc_adapter(struct icom_adapter
1427 **icom_adapter_ref)
1429 int adapter_count = 0;
1430 struct icom_adapter *icom_adapter;
1431 struct icom_adapter *cur_adapter_entry;
1432 struct list_head *tmp;
1434 icom_adapter = (struct icom_adapter *)
1435 kmalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1437 if (!icom_adapter) {
1438 return -ENOMEM;
1441 memset(icom_adapter, 0, sizeof(struct icom_adapter));
1443 list_for_each(tmp, &icom_adapter_head) {
1444 cur_adapter_entry =
1445 list_entry(tmp, struct icom_adapter,
1446 icom_adapter_entry);
1447 if (cur_adapter_entry->index != adapter_count) {
1448 break;
1450 adapter_count++;
1453 icom_adapter->index = adapter_count;
1454 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1456 *icom_adapter_ref = icom_adapter;
1457 return 0;
1460 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1462 list_del(&icom_adapter->icom_adapter_entry);
1463 kfree(icom_adapter);
1466 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1468 struct icom_port *icom_port;
1469 int index;
1471 for (index = 0; index < icom_adapter->numb_ports; index++) {
1472 icom_port = &icom_adapter->port_info[index];
1474 if (icom_port->status == ICOM_PORT_ACTIVE) {
1475 dev_info(&icom_adapter->pci_dev->dev,
1476 "Device removed\n");
1478 uart_remove_one_port(&icom_uart_driver,
1479 &icom_port->uart_port);
1481 /* be sure that DTR and RTS are dropped */
1482 writeb(0x00, &icom_port->dram->osr);
1484 /* Wait 0.1 Sec for simple Init to complete */
1485 msleep(100);
1487 /* Stop proccessor */
1488 stop_processor(icom_port);
1490 free_port_memory(icom_port);
1494 free_irq(icom_adapter->irq_number, (void *) icom_adapter);
1495 iounmap(icom_adapter->base_addr);
1496 icom_free_adapter(icom_adapter);
1497 pci_release_regions(icom_adapter->pci_dev);
1500 static void icom_kobj_release(struct kobject *kobj)
1502 struct icom_adapter *icom_adapter;
1504 icom_adapter = to_icom_adapter(kobj);
1505 icom_remove_adapter(icom_adapter);
1508 static struct kobj_type icom_kobj_type = {
1509 .release = icom_kobj_release,
1512 static int __devinit icom_probe(struct pci_dev *dev,
1513 const struct pci_device_id *ent)
1515 int index;
1516 unsigned int command_reg;
1517 int retval;
1518 struct icom_adapter *icom_adapter;
1519 struct icom_port *icom_port;
1521 retval = pci_enable_device(dev);
1522 if (retval) {
1523 dev_err(&dev->dev, "Device enable FAILED\n");
1524 return retval;
1527 if ( (retval = pci_request_regions(dev, "icom"))) {
1528 dev_err(&dev->dev, "pci_request_region FAILED\n");
1529 pci_disable_device(dev);
1530 return retval;
1533 pci_set_master(dev);
1535 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1536 dev_err(&dev->dev, "PCI Config read FAILED\n");
1537 return retval;
1540 pci_write_config_dword(dev, PCI_COMMAND,
1541 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1542 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1544 if (ent->driver_data == ADAPTER_V1) {
1545 pci_write_config_dword(dev, 0x44, 0x8300830A);
1546 } else {
1547 pci_write_config_dword(dev, 0x44, 0x42004200);
1548 pci_write_config_dword(dev, 0x48, 0x42004200);
1552 retval = icom_alloc_adapter(&icom_adapter);
1553 if (retval) {
1554 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1555 retval = -EIO;
1556 goto probe_exit0;
1559 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1560 icom_adapter->irq_number = dev->irq;
1561 icom_adapter->pci_dev = dev;
1562 icom_adapter->version = ent->driver_data;
1563 icom_adapter->subsystem_id = ent->subdevice;
1566 retval = icom_init_ports(icom_adapter);
1567 if (retval) {
1568 dev_err(&dev->dev, "Port configuration failed\n");
1569 goto probe_exit1;
1572 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1573 pci_resource_len(dev, 0));
1575 if (!icom_adapter->base_addr)
1576 goto probe_exit1;
1578 /* save off irq and request irq line */
1579 if ( (retval = request_irq(dev->irq, icom_interrupt,
1580 SA_INTERRUPT | SA_SHIRQ, ICOM_DRIVER_NAME,
1581 (void *) icom_adapter))) {
1582 goto probe_exit2;
1585 retval = icom_load_ports(icom_adapter);
1587 for (index = 0; index < icom_adapter->numb_ports; index++) {
1588 icom_port = &icom_adapter->port_info[index];
1590 if (icom_port->status == ICOM_PORT_ACTIVE) {
1591 icom_port->uart_port.irq = icom_port->adapter->irq_number;
1592 icom_port->uart_port.type = PORT_ICOM;
1593 icom_port->uart_port.iotype = UPIO_MEM;
1594 icom_port->uart_port.membase =
1595 (char *) icom_adapter->base_addr_pci;
1596 icom_port->uart_port.fifosize = 16;
1597 icom_port->uart_port.ops = &icom_ops;
1598 icom_port->uart_port.line =
1599 icom_port->port + icom_adapter->index * 4;
1600 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1601 icom_port->status = ICOM_PORT_OFF;
1602 dev_err(&dev->dev, "Device add failed\n");
1603 } else
1604 dev_info(&dev->dev, "Device added\n");
1608 kobject_init(&icom_adapter->kobj);
1609 icom_adapter->kobj.ktype = &icom_kobj_type;
1610 return 0;
1612 probe_exit2:
1613 iounmap(icom_adapter->base_addr);
1614 probe_exit1:
1615 icom_free_adapter(icom_adapter);
1617 probe_exit0:
1618 pci_release_regions(dev);
1619 pci_disable_device(dev);
1621 return retval;
1626 static void __devexit icom_remove(struct pci_dev *dev)
1628 struct icom_adapter *icom_adapter;
1629 struct list_head *tmp;
1631 list_for_each(tmp, &icom_adapter_head) {
1632 icom_adapter = list_entry(tmp, struct icom_adapter,
1633 icom_adapter_entry);
1634 if (icom_adapter->pci_dev == dev) {
1635 kobject_put(&icom_adapter->kobj);
1636 return;
1640 dev_err(&dev->dev, "Unable to find device to remove\n");
1643 static struct pci_driver icom_pci_driver = {
1644 .name = ICOM_DRIVER_NAME,
1645 .id_table = icom_pci_table,
1646 .probe = icom_probe,
1647 .remove = __devexit_p(icom_remove),
1650 static int __init icom_init(void)
1652 int ret;
1654 spin_lock_init(&icom_lock);
1656 ret = uart_register_driver(&icom_uart_driver);
1657 if (ret)
1658 return ret;
1660 ret = pci_register_driver(&icom_pci_driver);
1662 if (ret < 0)
1663 uart_unregister_driver(&icom_uart_driver);
1665 return ret;
1668 static void __exit icom_exit(void)
1670 pci_unregister_driver(&icom_pci_driver);
1671 uart_unregister_driver(&icom_uart_driver);
1674 module_init(icom_init);
1675 module_exit(icom_exit);
1677 #ifdef ICOM_TRACE
1678 static inline void trace(struct icom_port *icom_port, char *trace_pt,
1679 unsigned long trace_data)
1681 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1682 icom_port->port, trace_pt, trace_data);
1684 #endif
1686 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1687 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1688 MODULE_SUPPORTED_DEVICE
1689 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1690 MODULE_LICENSE("GPL");