[PATCH] Clarify help text of SKGE/SK98LIN/SKY2
[firewire-audio.git] / drivers / serial / icom.c
blob144a7a352b28c4fb2328a3b0857d90fc72da4e90
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/io.h>
60 #include <asm/irq.h>
61 #include <asm/uaccess.h>
63 #include "icom.h"
65 /*#define ICOM_TRACE enable port trace capabilities */
67 #define ICOM_DRIVER_NAME "icom"
68 #define ICOM_VERSION_STR "1.3.1"
69 #define NR_PORTS 128
70 #define ICOM_PORT ((struct icom_port *)port)
71 #define to_icom_adapter(d) container_of(d, struct icom_adapter, kobj)
73 static const struct pci_device_id icom_pci_table[] = {
75 .vendor = PCI_VENDOR_ID_IBM,
76 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
77 .subvendor = PCI_ANY_ID,
78 .subdevice = PCI_ANY_ID,
79 .driver_data = ADAPTER_V1,
82 .vendor = PCI_VENDOR_ID_IBM,
83 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
84 .subvendor = PCI_VENDOR_ID_IBM,
85 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
86 .driver_data = ADAPTER_V2,
89 .vendor = PCI_VENDOR_ID_IBM,
90 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
91 .subvendor = PCI_VENDOR_ID_IBM,
92 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
93 .driver_data = ADAPTER_V2,
96 .vendor = PCI_VENDOR_ID_IBM,
97 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
98 .subvendor = PCI_VENDOR_ID_IBM,
99 .subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
100 .driver_data = ADAPTER_V2,
105 struct lookup_proc_table start_proc[4] = {
106 {NULL, ICOM_CONTROL_START_A},
107 {NULL, ICOM_CONTROL_START_B},
108 {NULL, ICOM_CONTROL_START_C},
109 {NULL, ICOM_CONTROL_START_D}
113 struct lookup_proc_table stop_proc[4] = {
114 {NULL, ICOM_CONTROL_STOP_A},
115 {NULL, ICOM_CONTROL_STOP_B},
116 {NULL, ICOM_CONTROL_STOP_C},
117 {NULL, ICOM_CONTROL_STOP_D}
120 struct lookup_int_table int_mask_tbl[4] = {
121 {NULL, ICOM_INT_MASK_PRC_A},
122 {NULL, ICOM_INT_MASK_PRC_B},
123 {NULL, ICOM_INT_MASK_PRC_C},
124 {NULL, ICOM_INT_MASK_PRC_D},
128 MODULE_DEVICE_TABLE(pci, icom_pci_table);
130 static LIST_HEAD(icom_adapter_head);
132 /* spinlock for adapter initialization and changing adapter operations */
133 static spinlock_t icom_lock;
135 #ifdef ICOM_TRACE
136 static inline void trace(struct icom_port *, char *, unsigned long) {};
137 #else
138 static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
139 #endif
141 static void free_port_memory(struct icom_port *icom_port)
143 struct pci_dev *dev = icom_port->adapter->pci_dev;
145 trace(icom_port, "RET_PORT_MEM", 0);
146 if (icom_port->recv_buf) {
147 pci_free_consistent(dev, 4096, icom_port->recv_buf,
148 icom_port->recv_buf_pci);
149 icom_port->recv_buf = NULL;
151 if (icom_port->xmit_buf) {
152 pci_free_consistent(dev, 4096, icom_port->xmit_buf,
153 icom_port->xmit_buf_pci);
154 icom_port->xmit_buf = NULL;
156 if (icom_port->statStg) {
157 pci_free_consistent(dev, 4096, icom_port->statStg,
158 icom_port->statStg_pci);
159 icom_port->statStg = NULL;
162 if (icom_port->xmitRestart) {
163 pci_free_consistent(dev, 4096, icom_port->xmitRestart,
164 icom_port->xmitRestart_pci);
165 icom_port->xmitRestart = NULL;
169 static int __init get_port_memory(struct icom_port *icom_port)
171 int index;
172 unsigned long stgAddr;
173 unsigned long startStgAddr;
174 unsigned long offset;
175 struct pci_dev *dev = icom_port->adapter->pci_dev;
177 icom_port->xmit_buf =
178 pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
179 if (!icom_port->xmit_buf) {
180 dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
181 return -ENOMEM;
184 trace(icom_port, "GET_PORT_MEM",
185 (unsigned long) icom_port->xmit_buf);
187 icom_port->recv_buf =
188 pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
189 if (!icom_port->recv_buf) {
190 dev_err(&dev->dev, "Can not allocate Receive buffer\n");
191 free_port_memory(icom_port);
192 return -ENOMEM;
194 trace(icom_port, "GET_PORT_MEM",
195 (unsigned long) icom_port->recv_buf);
197 icom_port->statStg =
198 pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
199 if (!icom_port->statStg) {
200 dev_err(&dev->dev, "Can not allocate Status buffer\n");
201 free_port_memory(icom_port);
202 return -ENOMEM;
204 trace(icom_port, "GET_PORT_MEM",
205 (unsigned long) icom_port->statStg);
207 icom_port->xmitRestart =
208 pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
209 if (!icom_port->xmitRestart) {
210 dev_err(&dev->dev,
211 "Can not allocate xmit Restart buffer\n");
212 free_port_memory(icom_port);
213 return -ENOMEM;
216 memset(icom_port->statStg, 0, 4096);
218 /* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
219 indicates that frames are to be transmitted
222 stgAddr = (unsigned long) icom_port->statStg;
223 for (index = 0; index < NUM_XBUFFS; index++) {
224 trace(icom_port, "FOD_ADDR", stgAddr);
225 stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
226 if (index < (NUM_XBUFFS - 1)) {
227 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
228 icom_port->statStg->xmit[index].leLengthASD =
229 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
230 trace(icom_port, "FOD_ADDR", stgAddr);
231 trace(icom_port, "FOD_XBUFF",
232 (unsigned long) icom_port->xmit_buf);
233 icom_port->statStg->xmit[index].leBuffer =
234 cpu_to_le32(icom_port->xmit_buf_pci);
235 } else if (index == (NUM_XBUFFS - 1)) {
236 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
237 icom_port->statStg->xmit[index].leLengthASD =
238 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
239 trace(icom_port, "FOD_XBUFF",
240 (unsigned long) icom_port->xmit_buf);
241 icom_port->statStg->xmit[index].leBuffer =
242 cpu_to_le32(icom_port->xmit_buf_pci);
243 } else {
244 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
247 /* FIDs */
248 startStgAddr = stgAddr;
250 /* fill in every entry, even if no buffer */
251 for (index = 0; index < NUM_RBUFFS; index++) {
252 trace(icom_port, "FID_ADDR", stgAddr);
253 stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
254 icom_port->statStg->rcv[index].leLength = 0;
255 icom_port->statStg->rcv[index].WorkingLength =
256 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
257 if (index < (NUM_RBUFFS - 1) ) {
258 offset = stgAddr - (unsigned long) icom_port->statStg;
259 icom_port->statStg->rcv[index].leNext =
260 cpu_to_le32(icom_port-> statStg_pci + offset);
261 trace(icom_port, "FID_RBUFF",
262 (unsigned long) icom_port->recv_buf);
263 icom_port->statStg->rcv[index].leBuffer =
264 cpu_to_le32(icom_port->recv_buf_pci);
265 } else if (index == (NUM_RBUFFS -1) ) {
266 offset = startStgAddr - (unsigned long) icom_port->statStg;
267 icom_port->statStg->rcv[index].leNext =
268 cpu_to_le32(icom_port-> statStg_pci + offset);
269 trace(icom_port, "FID_RBUFF",
270 (unsigned long) icom_port->recv_buf + 2048);
271 icom_port->statStg->rcv[index].leBuffer =
272 cpu_to_le32(icom_port->recv_buf_pci + 2048);
273 } else {
274 icom_port->statStg->rcv[index].leNext = 0;
275 icom_port->statStg->rcv[index].leBuffer = 0;
279 return 0;
282 static void stop_processor(struct icom_port *icom_port)
284 unsigned long temp;
285 unsigned long flags;
286 int port;
288 spin_lock_irqsave(&icom_lock, flags);
290 port = icom_port->port;
291 if (port == 0 || port == 1)
292 stop_proc[port].global_control_reg = &icom_port->global_reg->control;
293 else
294 stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
297 if (port < 4) {
298 temp = readl(stop_proc[port].global_control_reg);
299 temp =
300 (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
301 writel(temp, stop_proc[port].global_control_reg);
303 /* write flush */
304 readl(stop_proc[port].global_control_reg);
305 } else {
306 dev_err(&icom_port->adapter->pci_dev->dev,
307 "Invalid port assignment\n");
310 spin_unlock_irqrestore(&icom_lock, flags);
313 static void start_processor(struct icom_port *icom_port)
315 unsigned long temp;
316 unsigned long flags;
317 int port;
319 spin_lock_irqsave(&icom_lock, flags);
321 port = icom_port->port;
322 if (port == 0 || port == 1)
323 start_proc[port].global_control_reg = &icom_port->global_reg->control;
324 else
325 start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
326 if (port < 4) {
327 temp = readl(start_proc[port].global_control_reg);
328 temp =
329 (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
330 writel(temp, start_proc[port].global_control_reg);
332 /* write flush */
333 readl(start_proc[port].global_control_reg);
334 } else {
335 dev_err(&icom_port->adapter->pci_dev->dev,
336 "Invalid port assignment\n");
339 spin_unlock_irqrestore(&icom_lock, flags);
342 static void load_code(struct icom_port *icom_port)
344 const struct firmware *fw;
345 char __iomem *iram_ptr;
346 int index;
347 int status = 0;
348 void __iomem *dram_ptr = icom_port->dram;
349 dma_addr_t temp_pci;
350 unsigned char *new_page = NULL;
351 unsigned char cable_id = NO_CABLE;
352 struct pci_dev *dev = icom_port->adapter->pci_dev;
354 /* Clear out any pending interrupts */
355 writew(0x3FFF, icom_port->int_reg);
357 trace(icom_port, "CLEAR_INTERRUPTS", 0);
359 /* Stop processor */
360 stop_processor(icom_port);
362 /* Zero out DRAM */
363 memset_io(dram_ptr, 0, 512);
365 /* Load Call Setup into Adapter */
366 if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
367 dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
368 status = -1;
369 goto load_code_exit;
372 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
373 dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
374 release_firmware(fw);
375 status = -1;
376 goto load_code_exit;
379 iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
380 for (index = 0; index < fw->size; index++)
381 writeb(fw->data[index], &iram_ptr[index]);
383 release_firmware(fw);
385 /* Load Resident DCE portion of Adapter */
386 if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
387 dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
388 status = -1;
389 goto load_code_exit;
392 if (fw->size > ICOM_IRAM_SIZE) {
393 dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
394 release_firmware(fw);
395 status = -1;
396 goto load_code_exit;
399 iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
400 for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
401 writeb(fw->data[index], &iram_ptr[index]);
403 release_firmware(fw);
405 /* Set Hardware level */
406 if ((icom_port->adapter->version | ADAPTER_V2) == ADAPTER_V2)
407 writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));
409 /* Start the processor in Adapter */
410 start_processor(icom_port);
412 writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
413 &(icom_port->dram->HDLCConfigReg));
414 writeb(0x04, &(icom_port->dram->FlagFillIdleTimer)); /* 0.5 seconds */
415 writeb(0x00, &(icom_port->dram->CmdReg));
416 writeb(0x10, &(icom_port->dram->async_config3));
417 writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
418 ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));
420 /*Set up data in icom DRAM to indicate where personality
421 *code is located and its length.
423 new_page = pci_alloc_consistent(dev, 4096, &temp_pci);
425 if (!new_page) {
426 dev_err(&dev->dev, "Can not allocate DMA buffer\n");
427 status = -1;
428 goto load_code_exit;
431 if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
432 dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
433 status = -1;
434 goto load_code_exit;
437 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
438 dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
439 release_firmware(fw);
440 status = -1;
441 goto load_code_exit;
444 for (index = 0; index < fw->size; index++)
445 new_page[index] = fw->data[index];
447 release_firmware(fw);
449 writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
450 writel(temp_pci, &icom_port->dram->mac_load_addr);
452 /*Setting the syncReg to 0x80 causes adapter to start downloading
453 the personality code into adapter instruction RAM.
454 Once code is loaded, it will begin executing and, based on
455 information provided above, will start DMAing data from
456 shared memory to adapter DRAM.
458 /* the wait loop below verifies this write operation has been done
459 and processed
461 writeb(START_DOWNLOAD, &icom_port->dram->sync);
463 /* Wait max 1 Sec for data download and processor to start */
464 for (index = 0; index < 10; index++) {
465 msleep(100);
466 if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
467 break;
470 if (index == 10)
471 status = -1;
474 * check Cable ID
476 cable_id = readb(&icom_port->dram->cable_id);
478 if (cable_id & ICOM_CABLE_ID_VALID) {
479 /* Get cable ID into the lower 4 bits (standard form) */
480 cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
481 icom_port->cable_id = cable_id;
482 } else {
483 dev_err(&dev->dev,"Invalid or no cable attached\n");
484 icom_port->cable_id = NO_CABLE;
487 load_code_exit:
489 if (status != 0) {
490 /* Clear out any pending interrupts */
491 writew(0x3FFF, icom_port->int_reg);
493 /* Turn off port */
494 writeb(ICOM_DISABLE, &(icom_port->dram->disable));
496 /* Stop processor */
497 stop_processor(icom_port);
499 dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
502 if (new_page != NULL)
503 pci_free_consistent(dev, 4096, new_page, temp_pci);
506 static int startup(struct icom_port *icom_port)
508 unsigned long temp;
509 unsigned char cable_id, raw_cable_id;
510 unsigned long flags;
511 int port;
513 trace(icom_port, "STARTUP", 0);
515 if (!icom_port->dram) {
516 /* should NEVER be NULL */
517 dev_err(&icom_port->adapter->pci_dev->dev,
518 "Unusable Port, port configuration missing\n");
519 return -ENODEV;
523 * check Cable ID
525 raw_cable_id = readb(&icom_port->dram->cable_id);
526 trace(icom_port, "CABLE_ID", raw_cable_id);
528 /* Get cable ID into the lower 4 bits (standard form) */
529 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
531 /* Check for valid Cable ID */
532 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
533 (cable_id != icom_port->cable_id)) {
535 /* reload adapter code, pick up any potential changes in cable id */
536 load_code(icom_port);
538 /* still no sign of cable, error out */
539 raw_cable_id = readb(&icom_port->dram->cable_id);
540 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
541 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
542 (icom_port->cable_id == NO_CABLE))
543 return -EIO;
547 * Finally, clear and enable interrupts
549 spin_lock_irqsave(&icom_lock, flags);
550 port = icom_port->port;
551 if (port == 0 || port == 1)
552 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
553 else
554 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
556 if (port == 0 || port == 2)
557 writew(0x00FF, icom_port->int_reg);
558 else
559 writew(0x3F00, icom_port->int_reg);
560 if (port < 4) {
561 temp = readl(int_mask_tbl[port].global_int_mask);
562 writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
564 /* write flush */
565 readl(int_mask_tbl[port].global_int_mask);
566 } else {
567 dev_err(&icom_port->adapter->pci_dev->dev,
568 "Invalid port assignment\n");
571 spin_unlock_irqrestore(&icom_lock, flags);
572 return 0;
575 static void shutdown(struct icom_port *icom_port)
577 unsigned long temp;
578 unsigned char cmdReg;
579 unsigned long flags;
580 int port;
582 spin_lock_irqsave(&icom_lock, flags);
583 trace(icom_port, "SHUTDOWN", 0);
586 * disable all interrupts
588 port = icom_port->port;
589 if (port == 0 || port == 1)
590 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
591 else
592 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
594 if (port < 4) {
595 temp = readl(int_mask_tbl[port].global_int_mask);
596 writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
598 /* write flush */
599 readl(int_mask_tbl[port].global_int_mask);
600 } else {
601 dev_err(&icom_port->adapter->pci_dev->dev,
602 "Invalid port assignment\n");
604 spin_unlock_irqrestore(&icom_lock, flags);
607 * disable break condition
609 cmdReg = readb(&icom_port->dram->CmdReg);
610 if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) {
611 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
615 static int icom_write(struct uart_port *port)
617 unsigned long data_count;
618 unsigned char cmdReg;
619 unsigned long offset;
620 int temp_tail = port->info->xmit.tail;
622 trace(ICOM_PORT, "WRITE", 0);
624 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
625 SA_FLAGS_READY_TO_XMIT) {
626 trace(ICOM_PORT, "WRITE_FULL", 0);
627 return 0;
630 data_count = 0;
631 while ((port->info->xmit.head != temp_tail) &&
632 (data_count <= XMIT_BUFF_SZ)) {
634 ICOM_PORT->xmit_buf[data_count++] =
635 port->info->xmit.buf[temp_tail];
637 temp_tail++;
638 temp_tail &= (UART_XMIT_SIZE - 1);
641 if (data_count) {
642 ICOM_PORT->statStg->xmit[0].flags =
643 cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
644 ICOM_PORT->statStg->xmit[0].leLength =
645 cpu_to_le16(data_count);
646 offset =
647 (unsigned long) &ICOM_PORT->statStg->xmit[0] -
648 (unsigned long) ICOM_PORT->statStg;
649 *ICOM_PORT->xmitRestart =
650 cpu_to_le32(ICOM_PORT->statStg_pci + offset);
651 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
652 writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
653 &ICOM_PORT->dram->CmdReg);
654 writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
655 trace(ICOM_PORT, "WRITE_START", data_count);
656 /* write flush */
657 readb(&ICOM_PORT->dram->StartXmitCmd);
660 return data_count;
663 static inline void check_modem_status(struct icom_port *icom_port)
665 static char old_status = 0;
666 char delta_status;
667 unsigned char status;
669 spin_lock(&icom_port->uart_port.lock);
671 /*modem input register */
672 status = readb(&icom_port->dram->isr);
673 trace(icom_port, "CHECK_MODEM", status);
674 delta_status = status ^ old_status;
675 if (delta_status) {
676 if (delta_status & ICOM_RI)
677 icom_port->uart_port.icount.rng++;
678 if (delta_status & ICOM_DSR)
679 icom_port->uart_port.icount.dsr++;
680 if (delta_status & ICOM_DCD)
681 uart_handle_dcd_change(&icom_port->uart_port,
682 delta_status & ICOM_DCD);
683 if (delta_status & ICOM_CTS)
684 uart_handle_cts_change(&icom_port->uart_port,
685 delta_status & ICOM_CTS);
687 wake_up_interruptible(&icom_port->uart_port.info->
688 delta_msr_wait);
689 old_status = status;
691 spin_unlock(&icom_port->uart_port.lock);
694 static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
696 unsigned short int count;
697 int i;
699 if (port_int_reg & (INT_XMIT_COMPLETED)) {
700 trace(icom_port, "XMIT_COMPLETE", 0);
702 /* clear buffer in use bit */
703 icom_port->statStg->xmit[0].flags &=
704 cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
706 count = (unsigned short int)
707 cpu_to_le16(icom_port->statStg->xmit[0].leLength);
708 icom_port->uart_port.icount.tx += count;
710 for (i=0; i<count &&
711 !uart_circ_empty(&icom_port->uart_port.info->xmit); i++) {
713 icom_port->uart_port.info->xmit.tail++;
714 icom_port->uart_port.info->xmit.tail &=
715 (UART_XMIT_SIZE - 1);
718 if (!icom_write(&icom_port->uart_port))
719 /* activate write queue */
720 uart_write_wakeup(&icom_port->uart_port);
721 } else
722 trace(icom_port, "XMIT_DISABLED", 0);
725 static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
727 short int count, rcv_buff;
728 struct tty_struct *tty = icom_port->uart_port.info->tty;
729 unsigned short int status;
730 struct uart_icount *icount;
731 unsigned long offset;
732 unsigned char flag;
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) {
739 int first = -1;
741 trace(icom_port, "FID_STATUS", status);
742 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
744 count = tty_buffer_request_room(tty, count);
745 trace(icom_port, "RCV_COUNT", 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 /* Block copy all but the last byte as this may have status */
754 if (count > 0) {
755 first = icom_port->recv_buf[offset];
756 tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1);
759 icount = &icom_port->uart_port.icount;
760 icount->rx += count;
762 /* Break detect logic */
763 if ((status & SA_FLAGS_FRAME_ERROR)
764 && first == 0) {
765 status &= ~SA_FLAGS_FRAME_ERROR;
766 status |= SA_FLAGS_BREAK_DET;
767 trace(icom_port, "BREAK_DET", 0);
770 flag = TTY_NORMAL;
772 if (status &
773 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
774 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
776 if (status & SA_FLAGS_BREAK_DET)
777 icount->brk++;
778 if (status & SA_FLAGS_PARITY_ERROR)
779 icount->parity++;
780 if (status & SA_FLAGS_FRAME_ERROR)
781 icount->frame++;
782 if (status & SA_FLAGS_OVERRUN)
783 icount->overrun++;
786 * Now check to see if character should be
787 * ignored, and mask off conditions which
788 * should be ignored.
790 if (status & icom_port->ignore_status_mask) {
791 trace(icom_port, "IGNORE_CHAR", 0);
792 goto ignore_char;
795 status &= icom_port->read_status_mask;
797 if (status & SA_FLAGS_BREAK_DET) {
798 flag = TTY_BREAK;
799 } else if (status & SA_FLAGS_PARITY_ERROR) {
800 trace(icom_port, "PARITY_ERROR", 0);
801 flag = TTY_PARITY;
802 } else if (status & SA_FLAGS_FRAME_ERROR)
803 flag = TTY_FRAME;
807 tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag);
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 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
816 ignore_char:
817 icom_port->statStg->rcv[rcv_buff].flags = 0;
818 icom_port->statStg->rcv[rcv_buff].leLength = 0;
819 icom_port->statStg->rcv[rcv_buff].WorkingLength =
820 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
822 rcv_buff++;
823 if (rcv_buff == NUM_RBUFFS)
824 rcv_buff = 0;
826 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
828 icom_port->next_rcv = rcv_buff;
829 tty_flip_buffer_push(tty);
832 static void process_interrupt(u16 port_int_reg,
833 struct icom_port *icom_port)
836 spin_lock(&icom_port->uart_port.lock);
837 trace(icom_port, "INTERRUPT", port_int_reg);
839 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
840 xmit_interrupt(port_int_reg, icom_port);
842 if (port_int_reg & INT_RCV_COMPLETED)
843 recv_interrupt(port_int_reg, icom_port);
845 spin_unlock(&icom_port->uart_port.lock);
848 static irqreturn_t icom_interrupt(int irq, void *dev_id,
849 struct pt_regs *regs)
851 void __iomem * int_reg;
852 u32 adapter_interrupts;
853 u16 port_int_reg;
854 struct icom_adapter *icom_adapter;
855 struct icom_port *icom_port;
857 /* find icom_port for this interrupt */
858 icom_adapter = (struct icom_adapter *) dev_id;
860 if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
861 int_reg = icom_adapter->base_addr + 0x8024;
863 adapter_interrupts = readl(int_reg);
865 if (adapter_interrupts & 0x00003FFF) {
866 /* port 2 interrupt, NOTE: for all ADAPTER_V2, port 2 will be active */
867 icom_port = &icom_adapter->port_info[2];
868 port_int_reg = (u16) adapter_interrupts;
869 process_interrupt(port_int_reg, icom_port);
870 check_modem_status(icom_port);
872 if (adapter_interrupts & 0x3FFF0000) {
873 /* port 3 interrupt */
874 icom_port = &icom_adapter->port_info[3];
875 if (icom_port->status == ICOM_PORT_ACTIVE) {
876 port_int_reg =
877 (u16) (adapter_interrupts >> 16);
878 process_interrupt(port_int_reg, icom_port);
879 check_modem_status(icom_port);
883 /* Clear out any pending interrupts */
884 writel(adapter_interrupts, int_reg);
886 int_reg = icom_adapter->base_addr + 0x8004;
887 } else {
888 int_reg = icom_adapter->base_addr + 0x4004;
891 adapter_interrupts = readl(int_reg);
893 if (adapter_interrupts & 0x00003FFF) {
894 /* port 0 interrupt, NOTE: for all adapters, port 0 will be active */
895 icom_port = &icom_adapter->port_info[0];
896 port_int_reg = (u16) adapter_interrupts;
897 process_interrupt(port_int_reg, icom_port);
898 check_modem_status(icom_port);
900 if (adapter_interrupts & 0x3FFF0000) {
901 /* port 1 interrupt */
902 icom_port = &icom_adapter->port_info[1];
903 if (icom_port->status == ICOM_PORT_ACTIVE) {
904 port_int_reg = (u16) (adapter_interrupts >> 16);
905 process_interrupt(port_int_reg, icom_port);
906 check_modem_status(icom_port);
910 /* Clear out any pending interrupts */
911 writel(adapter_interrupts, int_reg);
913 /* flush the write */
914 adapter_interrupts = readl(int_reg);
916 return IRQ_HANDLED;
920 * ------------------------------------------------------------------
921 * Begin serial-core API
922 * ------------------------------------------------------------------
924 static unsigned int icom_tx_empty(struct uart_port *port)
926 int ret;
927 unsigned long flags;
929 spin_lock_irqsave(&port->lock, flags);
930 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
931 SA_FLAGS_READY_TO_XMIT)
932 ret = TIOCSER_TEMT;
933 else
934 ret = 0;
936 spin_unlock_irqrestore(&port->lock, flags);
937 return ret;
940 static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
942 unsigned char local_osr;
944 trace(ICOM_PORT, "SET_MODEM", 0);
945 local_osr = readb(&ICOM_PORT->dram->osr);
947 if (mctrl & TIOCM_RTS) {
948 trace(ICOM_PORT, "RAISE_RTS", 0);
949 local_osr |= ICOM_RTS;
950 } else {
951 trace(ICOM_PORT, "LOWER_RTS", 0);
952 local_osr &= ~ICOM_RTS;
955 if (mctrl & TIOCM_DTR) {
956 trace(ICOM_PORT, "RAISE_DTR", 0);
957 local_osr |= ICOM_DTR;
958 } else {
959 trace(ICOM_PORT, "LOWER_DTR", 0);
960 local_osr &= ~ICOM_DTR;
963 writeb(local_osr, &ICOM_PORT->dram->osr);
966 static unsigned int icom_get_mctrl(struct uart_port *port)
968 unsigned char status;
969 unsigned int result;
971 trace(ICOM_PORT, "GET_MODEM", 0);
973 status = readb(&ICOM_PORT->dram->isr);
975 result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
976 | ((status & ICOM_RI) ? TIOCM_RNG : 0)
977 | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
978 | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
979 return result;
982 static void icom_stop_tx(struct uart_port *port)
984 unsigned char cmdReg;
986 trace(ICOM_PORT, "STOP", 0);
987 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
988 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
991 static void icom_start_tx(struct uart_port *port)
993 unsigned char cmdReg;
995 trace(ICOM_PORT, "START", 0);
996 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
997 if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
998 writeb(cmdReg & ~CMD_HOLD_XMIT,
999 &ICOM_PORT->dram->CmdReg);
1001 icom_write(port);
1004 static void icom_send_xchar(struct uart_port *port, char ch)
1006 unsigned char xdata;
1007 int index;
1008 unsigned long flags;
1010 trace(ICOM_PORT, "SEND_XCHAR", ch);
1012 /* wait .1 sec to send char */
1013 for (index = 0; index < 10; index++) {
1014 spin_lock_irqsave(&port->lock, flags);
1015 xdata = readb(&ICOM_PORT->dram->xchar);
1016 if (xdata == 0x00) {
1017 trace(ICOM_PORT, "QUICK_WRITE", 0);
1018 writeb(ch, &ICOM_PORT->dram->xchar);
1020 /* flush write operation */
1021 xdata = readb(&ICOM_PORT->dram->xchar);
1022 spin_unlock_irqrestore(&port->lock, flags);
1023 break;
1025 spin_unlock_irqrestore(&port->lock, flags);
1026 msleep(10);
1030 static void icom_stop_rx(struct uart_port *port)
1032 unsigned char cmdReg;
1034 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1035 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1038 static void icom_enable_ms(struct uart_port *port)
1040 /* no-op */
1043 static void icom_break(struct uart_port *port, int break_state)
1045 unsigned char cmdReg;
1046 unsigned long flags;
1048 spin_lock_irqsave(&port->lock, flags);
1049 trace(ICOM_PORT, "BREAK", 0);
1050 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1051 if (break_state == -1) {
1052 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1053 } else {
1054 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1056 spin_unlock_irqrestore(&port->lock, flags);
1059 static int icom_open(struct uart_port *port)
1061 int retval;
1063 kobject_get(&ICOM_PORT->adapter->kobj);
1064 retval = startup(ICOM_PORT);
1066 if (retval) {
1067 kobject_put(&ICOM_PORT->adapter->kobj);
1068 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1069 return retval;
1072 return 0;
1075 static void icom_close(struct uart_port *port)
1077 unsigned char cmdReg;
1079 trace(ICOM_PORT, "CLOSE", 0);
1081 /* stop receiver */
1082 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1083 writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1084 &ICOM_PORT->dram->CmdReg);
1086 shutdown(ICOM_PORT);
1088 kobject_put(&ICOM_PORT->adapter->kobj);
1091 static void icom_set_termios(struct uart_port *port,
1092 struct termios *termios,
1093 struct termios *old_termios)
1095 int baud;
1096 unsigned cflag, iflag;
1097 int bits;
1098 char new_config2;
1099 char new_config3 = 0;
1100 char tmp_byte;
1101 int index;
1102 int rcv_buff, xmit_buff;
1103 unsigned long offset;
1104 unsigned long flags;
1106 spin_lock_irqsave(&port->lock, flags);
1107 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1109 cflag = termios->c_cflag;
1110 iflag = termios->c_iflag;
1112 new_config2 = ICOM_ACFG_DRIVE1;
1114 /* byte size and parity */
1115 switch (cflag & CSIZE) {
1116 case CS5: /* 5 bits/char */
1117 new_config2 |= ICOM_ACFG_5BPC;
1118 bits = 7;
1119 break;
1120 case CS6: /* 6 bits/char */
1121 new_config2 |= ICOM_ACFG_6BPC;
1122 bits = 8;
1123 break;
1124 case CS7: /* 7 bits/char */
1125 new_config2 |= ICOM_ACFG_7BPC;
1126 bits = 9;
1127 break;
1128 case CS8: /* 8 bits/char */
1129 new_config2 |= ICOM_ACFG_8BPC;
1130 bits = 10;
1131 break;
1132 default:
1133 bits = 10;
1134 break;
1136 if (cflag & CSTOPB) {
1137 /* 2 stop bits */
1138 new_config2 |= ICOM_ACFG_2STOP_BIT;
1139 bits++;
1141 if (cflag & PARENB) {
1142 /* parity bit enabled */
1143 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1144 trace(ICOM_PORT, "PARENB", 0);
1145 bits++;
1147 if (cflag & PARODD) {
1148 /* odd parity */
1149 new_config2 |= ICOM_ACFG_PARITY_ODD;
1150 trace(ICOM_PORT, "PARODD", 0);
1153 /* Determine divisor based on baud rate */
1154 baud = uart_get_baud_rate(port, termios, old_termios,
1155 icom_acfg_baud[0],
1156 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1157 if (!baud)
1158 baud = 9600; /* B0 transition handled in rs_set_termios */
1160 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1161 if (icom_acfg_baud[index] == baud) {
1162 new_config3 = index;
1163 break;
1167 uart_update_timeout(port, cflag, baud);
1169 /* CTS flow control flag and modem status interrupts */
1170 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1171 if (cflag & CRTSCTS)
1172 tmp_byte |= HDLC_HDW_FLOW;
1173 else
1174 tmp_byte &= ~HDLC_HDW_FLOW;
1175 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1178 * Set up parity check flag
1180 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1181 if (iflag & INPCK)
1182 ICOM_PORT->read_status_mask |=
1183 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1185 if ((iflag & BRKINT) || (iflag & PARMRK))
1186 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1189 * Characters to ignore
1191 ICOM_PORT->ignore_status_mask = 0;
1192 if (iflag & IGNPAR)
1193 ICOM_PORT->ignore_status_mask |=
1194 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1195 if (iflag & IGNBRK) {
1196 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1198 * If we're ignore parity and break indicators, ignore
1199 * overruns too. (For real raw support).
1201 if (iflag & IGNPAR)
1202 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1206 * !!! ignore all characters if CREAD is not set
1208 if ((cflag & CREAD) == 0)
1209 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1211 /* Turn off Receiver to prepare for reset */
1212 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1214 for (index = 0; index < 10; index++) {
1215 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1216 break;
1220 /* clear all current buffers of data */
1221 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1222 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1223 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1224 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1225 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1228 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1229 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1232 /* activate changes and start xmit and receiver here */
1233 /* Enable the receiver */
1234 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1235 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1236 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1237 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1238 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1239 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer)); /* 0.5 seconds */
1240 writeb(0xFF, &(ICOM_PORT->dram->ier)); /* enable modem signal interrupts */
1242 /* reset processor */
1243 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1245 for (index = 0; index < 10; index++) {
1246 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1247 break;
1251 /* Enable Transmitter and Reciever */
1252 offset =
1253 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1254 (unsigned long) ICOM_PORT->statStg;
1255 writel(ICOM_PORT->statStg_pci + offset,
1256 &ICOM_PORT->dram->RcvStatusAddr);
1257 ICOM_PORT->next_rcv = 0;
1258 ICOM_PORT->put_length = 0;
1259 *ICOM_PORT->xmitRestart = 0;
1260 writel(ICOM_PORT->xmitRestart_pci,
1261 &ICOM_PORT->dram->XmitStatusAddr);
1262 trace(ICOM_PORT, "XR_ENAB", 0);
1263 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1265 spin_unlock_irqrestore(&port->lock, flags);
1268 static const char *icom_type(struct uart_port *port)
1270 return "icom";
1273 static void icom_release_port(struct uart_port *port)
1277 static int icom_request_port(struct uart_port *port)
1279 return 0;
1282 static void icom_config_port(struct uart_port *port, int flags)
1284 port->type = PORT_ICOM;
1287 static struct uart_ops icom_ops = {
1288 .tx_empty = icom_tx_empty,
1289 .set_mctrl = icom_set_mctrl,
1290 .get_mctrl = icom_get_mctrl,
1291 .stop_tx = icom_stop_tx,
1292 .start_tx = icom_start_tx,
1293 .send_xchar = icom_send_xchar,
1294 .stop_rx = icom_stop_rx,
1295 .enable_ms = icom_enable_ms,
1296 .break_ctl = icom_break,
1297 .startup = icom_open,
1298 .shutdown = icom_close,
1299 .set_termios = icom_set_termios,
1300 .type = icom_type,
1301 .release_port = icom_release_port,
1302 .request_port = icom_request_port,
1303 .config_port = icom_config_port,
1306 #define ICOM_CONSOLE NULL
1308 static struct uart_driver icom_uart_driver = {
1309 .owner = THIS_MODULE,
1310 .driver_name = ICOM_DRIVER_NAME,
1311 .dev_name = "ttyA",
1312 .major = ICOM_MAJOR,
1313 .minor = ICOM_MINOR_START,
1314 .nr = NR_PORTS,
1315 .cons = ICOM_CONSOLE,
1318 static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1320 u32 subsystem_id = icom_adapter->subsystem_id;
1321 int retval = 0;
1322 int i;
1323 struct icom_port *icom_port;
1325 if (icom_adapter->version == ADAPTER_V1) {
1326 icom_adapter->numb_ports = 2;
1328 for (i = 0; i < 2; i++) {
1329 icom_port = &icom_adapter->port_info[i];
1330 icom_port->port = i;
1331 icom_port->status = ICOM_PORT_ACTIVE;
1332 icom_port->imbed_modem = ICOM_UNKNOWN;
1334 } else {
1335 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1336 icom_adapter->numb_ports = 4;
1338 for (i = 0; i < 4; i++) {
1339 icom_port = &icom_adapter->port_info[i];
1341 icom_port->port = i;
1342 icom_port->status = ICOM_PORT_ACTIVE;
1343 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1345 } else {
1346 icom_adapter->numb_ports = 4;
1348 icom_adapter->port_info[0].port = 0;
1349 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1351 if (subsystem_id ==
1352 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1353 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1354 } else {
1355 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1358 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1360 icom_adapter->port_info[2].port = 2;
1361 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1362 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1363 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1367 return retval;
1370 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1372 if (icom_adapter->version == ADAPTER_V1) {
1373 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1374 icom_port->int_reg = icom_adapter->base_addr +
1375 0x4004 + 2 - 2 * port_num;
1376 } else {
1377 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1378 if (icom_port->port < 2)
1379 icom_port->int_reg = icom_adapter->base_addr +
1380 0x8004 + 2 - 2 * icom_port->port;
1381 else
1382 icom_port->int_reg = icom_adapter->base_addr +
1383 0x8024 + 2 - 2 * (icom_port->port - 2);
1386 static int __init icom_load_ports(struct icom_adapter *icom_adapter)
1388 struct icom_port *icom_port;
1389 int port_num;
1390 int retval;
1392 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1394 icom_port = &icom_adapter->port_info[port_num];
1396 if (icom_port->status == ICOM_PORT_ACTIVE) {
1397 icom_port_active(icom_port, icom_adapter, port_num);
1398 icom_port->dram = icom_adapter->base_addr +
1399 0x2000 * icom_port->port;
1401 icom_port->adapter = icom_adapter;
1403 /* get port memory */
1404 if ((retval = get_port_memory(icom_port)) != 0) {
1405 dev_err(&icom_port->adapter->pci_dev->dev,
1406 "Memory allocation for port FAILED\n");
1410 return 0;
1413 static int __devinit icom_alloc_adapter(struct icom_adapter
1414 **icom_adapter_ref)
1416 int adapter_count = 0;
1417 struct icom_adapter *icom_adapter;
1418 struct icom_adapter *cur_adapter_entry;
1419 struct list_head *tmp;
1421 icom_adapter = (struct icom_adapter *)
1422 kmalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1424 if (!icom_adapter) {
1425 return -ENOMEM;
1428 memset(icom_adapter, 0, sizeof(struct icom_adapter));
1430 list_for_each(tmp, &icom_adapter_head) {
1431 cur_adapter_entry =
1432 list_entry(tmp, struct icom_adapter,
1433 icom_adapter_entry);
1434 if (cur_adapter_entry->index != adapter_count) {
1435 break;
1437 adapter_count++;
1440 icom_adapter->index = adapter_count;
1441 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1443 *icom_adapter_ref = icom_adapter;
1444 return 0;
1447 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1449 list_del(&icom_adapter->icom_adapter_entry);
1450 kfree(icom_adapter);
1453 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1455 struct icom_port *icom_port;
1456 int index;
1458 for (index = 0; index < icom_adapter->numb_ports; index++) {
1459 icom_port = &icom_adapter->port_info[index];
1461 if (icom_port->status == ICOM_PORT_ACTIVE) {
1462 dev_info(&icom_adapter->pci_dev->dev,
1463 "Device removed\n");
1465 uart_remove_one_port(&icom_uart_driver,
1466 &icom_port->uart_port);
1468 /* be sure that DTR and RTS are dropped */
1469 writeb(0x00, &icom_port->dram->osr);
1471 /* Wait 0.1 Sec for simple Init to complete */
1472 msleep(100);
1474 /* Stop proccessor */
1475 stop_processor(icom_port);
1477 free_port_memory(icom_port);
1481 free_irq(icom_adapter->irq_number, (void *) icom_adapter);
1482 iounmap(icom_adapter->base_addr);
1483 icom_free_adapter(icom_adapter);
1484 pci_release_regions(icom_adapter->pci_dev);
1487 static void icom_kobj_release(struct kobject *kobj)
1489 struct icom_adapter *icom_adapter;
1491 icom_adapter = to_icom_adapter(kobj);
1492 icom_remove_adapter(icom_adapter);
1495 static struct kobj_type icom_kobj_type = {
1496 .release = icom_kobj_release,
1499 static int __devinit icom_probe(struct pci_dev *dev,
1500 const struct pci_device_id *ent)
1502 int index;
1503 unsigned int command_reg;
1504 int retval;
1505 struct icom_adapter *icom_adapter;
1506 struct icom_port *icom_port;
1508 retval = pci_enable_device(dev);
1509 if (retval) {
1510 dev_err(&dev->dev, "Device enable FAILED\n");
1511 return retval;
1514 if ( (retval = pci_request_regions(dev, "icom"))) {
1515 dev_err(&dev->dev, "pci_request_region FAILED\n");
1516 pci_disable_device(dev);
1517 return retval;
1520 pci_set_master(dev);
1522 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1523 dev_err(&dev->dev, "PCI Config read FAILED\n");
1524 return retval;
1527 pci_write_config_dword(dev, PCI_COMMAND,
1528 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1529 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1531 if (ent->driver_data == ADAPTER_V1) {
1532 pci_write_config_dword(dev, 0x44, 0x8300830A);
1533 } else {
1534 pci_write_config_dword(dev, 0x44, 0x42004200);
1535 pci_write_config_dword(dev, 0x48, 0x42004200);
1539 retval = icom_alloc_adapter(&icom_adapter);
1540 if (retval) {
1541 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1542 retval = -EIO;
1543 goto probe_exit0;
1546 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1547 icom_adapter->irq_number = dev->irq;
1548 icom_adapter->pci_dev = dev;
1549 icom_adapter->version = ent->driver_data;
1550 icom_adapter->subsystem_id = ent->subdevice;
1553 retval = icom_init_ports(icom_adapter);
1554 if (retval) {
1555 dev_err(&dev->dev, "Port configuration failed\n");
1556 goto probe_exit1;
1559 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1560 pci_resource_len(dev, 0));
1562 if (!icom_adapter->base_addr)
1563 goto probe_exit1;
1565 /* save off irq and request irq line */
1566 if ( (retval = request_irq(dev->irq, icom_interrupt,
1567 SA_INTERRUPT | SA_SHIRQ, ICOM_DRIVER_NAME,
1568 (void *) icom_adapter))) {
1569 goto probe_exit2;
1572 retval = icom_load_ports(icom_adapter);
1574 for (index = 0; index < icom_adapter->numb_ports; index++) {
1575 icom_port = &icom_adapter->port_info[index];
1577 if (icom_port->status == ICOM_PORT_ACTIVE) {
1578 icom_port->uart_port.irq = icom_port->adapter->irq_number;
1579 icom_port->uart_port.type = PORT_ICOM;
1580 icom_port->uart_port.iotype = UPIO_MEM;
1581 icom_port->uart_port.membase =
1582 (char *) icom_adapter->base_addr_pci;
1583 icom_port->uart_port.fifosize = 16;
1584 icom_port->uart_port.ops = &icom_ops;
1585 icom_port->uart_port.line =
1586 icom_port->port + icom_adapter->index * 4;
1587 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1588 icom_port->status = ICOM_PORT_OFF;
1589 dev_err(&dev->dev, "Device add failed\n");
1590 } else
1591 dev_info(&dev->dev, "Device added\n");
1595 kobject_init(&icom_adapter->kobj);
1596 icom_adapter->kobj.ktype = &icom_kobj_type;
1597 return 0;
1599 probe_exit2:
1600 iounmap(icom_adapter->base_addr);
1601 probe_exit1:
1602 icom_free_adapter(icom_adapter);
1604 probe_exit0:
1605 pci_release_regions(dev);
1606 pci_disable_device(dev);
1608 return retval;
1613 static void __devexit icom_remove(struct pci_dev *dev)
1615 struct icom_adapter *icom_adapter;
1616 struct list_head *tmp;
1618 list_for_each(tmp, &icom_adapter_head) {
1619 icom_adapter = list_entry(tmp, struct icom_adapter,
1620 icom_adapter_entry);
1621 if (icom_adapter->pci_dev == dev) {
1622 kobject_put(&icom_adapter->kobj);
1623 return;
1627 dev_err(&dev->dev, "Unable to find device to remove\n");
1630 static struct pci_driver icom_pci_driver = {
1631 .name = ICOM_DRIVER_NAME,
1632 .id_table = icom_pci_table,
1633 .probe = icom_probe,
1634 .remove = __devexit_p(icom_remove),
1637 static int __init icom_init(void)
1639 int ret;
1641 spin_lock_init(&icom_lock);
1643 ret = uart_register_driver(&icom_uart_driver);
1644 if (ret)
1645 return ret;
1647 ret = pci_register_driver(&icom_pci_driver);
1649 if (ret < 0)
1650 uart_unregister_driver(&icom_uart_driver);
1652 return ret;
1655 static void __exit icom_exit(void)
1657 pci_unregister_driver(&icom_pci_driver);
1658 uart_unregister_driver(&icom_uart_driver);
1661 module_init(icom_init);
1662 module_exit(icom_exit);
1664 #ifdef ICOM_TRACE
1665 static inline void trace(struct icom_port *icom_port, char *trace_pt,
1666 unsigned long trace_data)
1668 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1669 icom_port->port, trace_pt, trace_data);
1671 #endif
1673 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1674 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1675 MODULE_SUPPORTED_DEVICE
1676 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1677 MODULE_LICENSE("GPL");