sis900: come alive after temporary memory shortage
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / serial / icom.c
blobeb31125c6a30f84de2416f80c939bc1eae412fc8
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;
733 trace(icom_port, "RCV_COMPLETE", 0);
734 rcv_buff = icom_port->next_rcv;
736 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
737 while (status & SA_FL_RCV_DONE) {
739 trace(icom_port, "FID_STATUS", status);
740 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
742 trace(icom_port, "RCV_COUNT", count);
743 if (count > (TTY_FLIPBUF_SIZE - tty->flip.count))
744 count = TTY_FLIPBUF_SIZE - tty->flip.count;
746 trace(icom_port, "REAL_COUNT", count);
748 offset =
749 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
750 icom_port->recv_buf_pci;
752 memcpy(tty->flip.char_buf_ptr,(unsigned char *)
753 ((unsigned long)icom_port->recv_buf + offset), count);
755 if (count > 0) {
756 tty->flip.count += count - 1;
757 tty->flip.char_buf_ptr += count - 1;
759 memset(tty->flip.flag_buf_ptr, 0, count);
760 tty->flip.flag_buf_ptr += count - 1;
763 icount = &icom_port->uart_port.icount;
764 icount->rx += count;
766 /* Break detect logic */
767 if ((status & SA_FLAGS_FRAME_ERROR)
768 && (tty->flip.char_buf_ptr[0] == 0x00)) {
769 status &= ~SA_FLAGS_FRAME_ERROR;
770 status |= SA_FLAGS_BREAK_DET;
771 trace(icom_port, "BREAK_DET", 0);
774 if (status &
775 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
776 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
778 if (status & SA_FLAGS_BREAK_DET)
779 icount->brk++;
780 if (status & SA_FLAGS_PARITY_ERROR)
781 icount->parity++;
782 if (status & SA_FLAGS_FRAME_ERROR)
783 icount->frame++;
784 if (status & SA_FLAGS_OVERRUN)
785 icount->overrun++;
788 * Now check to see if character should be
789 * ignored, and mask off conditions which
790 * should be ignored.
792 if (status & icom_port->ignore_status_mask) {
793 trace(icom_port, "IGNORE_CHAR", 0);
794 goto ignore_char;
797 status &= icom_port->read_status_mask;
799 if (status & SA_FLAGS_BREAK_DET) {
800 *tty->flip.flag_buf_ptr = TTY_BREAK;
801 } else if (status & SA_FLAGS_PARITY_ERROR) {
802 trace(icom_port, "PARITY_ERROR", 0);
803 *tty->flip.flag_buf_ptr = TTY_PARITY;
804 } else if (status & SA_FLAGS_FRAME_ERROR)
805 *tty->flip.flag_buf_ptr = TTY_FRAME;
807 if (status & SA_FLAGS_OVERRUN) {
809 * Overrun is special, since it's
810 * reported immediately, and doesn't
811 * affect the current character
813 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
814 tty->flip.count++;
815 tty->flip.flag_buf_ptr++;
816 tty->flip.char_buf_ptr++;
817 *tty->flip.flag_buf_ptr = TTY_OVERRUN;
822 tty->flip.flag_buf_ptr++;
823 tty->flip.char_buf_ptr++;
824 tty->flip.count++;
825 ignore_char:
826 icom_port->statStg->rcv[rcv_buff].flags = 0;
827 icom_port->statStg->rcv[rcv_buff].leLength = 0;
828 icom_port->statStg->rcv[rcv_buff].WorkingLength =
829 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
831 rcv_buff++;
832 if (rcv_buff == NUM_RBUFFS)
833 rcv_buff = 0;
835 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
837 icom_port->next_rcv = rcv_buff;
838 tty_flip_buffer_push(tty);
841 static void process_interrupt(u16 port_int_reg,
842 struct icom_port *icom_port)
845 spin_lock(&icom_port->uart_port.lock);
846 trace(icom_port, "INTERRUPT", port_int_reg);
848 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
849 xmit_interrupt(port_int_reg, icom_port);
851 if (port_int_reg & INT_RCV_COMPLETED)
852 recv_interrupt(port_int_reg, icom_port);
854 spin_unlock(&icom_port->uart_port.lock);
857 static irqreturn_t icom_interrupt(int irq, void *dev_id,
858 struct pt_regs *regs)
860 void __iomem * int_reg;
861 u32 adapter_interrupts;
862 u16 port_int_reg;
863 struct icom_adapter *icom_adapter;
864 struct icom_port *icom_port;
866 /* find icom_port for this interrupt */
867 icom_adapter = (struct icom_adapter *) dev_id;
869 if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
870 int_reg = icom_adapter->base_addr + 0x8024;
872 adapter_interrupts = readl(int_reg);
874 if (adapter_interrupts & 0x00003FFF) {
875 /* port 2 interrupt, NOTE: for all ADAPTER_V2, port 2 will be active */
876 icom_port = &icom_adapter->port_info[2];
877 port_int_reg = (u16) adapter_interrupts;
878 process_interrupt(port_int_reg, icom_port);
879 check_modem_status(icom_port);
881 if (adapter_interrupts & 0x3FFF0000) {
882 /* port 3 interrupt */
883 icom_port = &icom_adapter->port_info[3];
884 if (icom_port->status == ICOM_PORT_ACTIVE) {
885 port_int_reg =
886 (u16) (adapter_interrupts >> 16);
887 process_interrupt(port_int_reg, icom_port);
888 check_modem_status(icom_port);
892 /* Clear out any pending interrupts */
893 writel(adapter_interrupts, int_reg);
895 int_reg = icom_adapter->base_addr + 0x8004;
896 } else {
897 int_reg = icom_adapter->base_addr + 0x4004;
900 adapter_interrupts = readl(int_reg);
902 if (adapter_interrupts & 0x00003FFF) {
903 /* port 0 interrupt, NOTE: for all adapters, port 0 will be active */
904 icom_port = &icom_adapter->port_info[0];
905 port_int_reg = (u16) adapter_interrupts;
906 process_interrupt(port_int_reg, icom_port);
907 check_modem_status(icom_port);
909 if (adapter_interrupts & 0x3FFF0000) {
910 /* port 1 interrupt */
911 icom_port = &icom_adapter->port_info[1];
912 if (icom_port->status == ICOM_PORT_ACTIVE) {
913 port_int_reg = (u16) (adapter_interrupts >> 16);
914 process_interrupt(port_int_reg, icom_port);
915 check_modem_status(icom_port);
919 /* Clear out any pending interrupts */
920 writel(adapter_interrupts, int_reg);
922 /* flush the write */
923 adapter_interrupts = readl(int_reg);
925 return IRQ_HANDLED;
929 * ------------------------------------------------------------------
930 * Begin serial-core API
931 * ------------------------------------------------------------------
933 static unsigned int icom_tx_empty(struct uart_port *port)
935 int ret;
936 unsigned long flags;
938 spin_lock_irqsave(&port->lock, flags);
939 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
940 SA_FLAGS_READY_TO_XMIT)
941 ret = TIOCSER_TEMT;
942 else
943 ret = 0;
945 spin_unlock_irqrestore(&port->lock, flags);
946 return ret;
949 static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
951 unsigned char local_osr;
953 trace(ICOM_PORT, "SET_MODEM", 0);
954 local_osr = readb(&ICOM_PORT->dram->osr);
956 if (mctrl & TIOCM_RTS) {
957 trace(ICOM_PORT, "RAISE_RTS", 0);
958 local_osr |= ICOM_RTS;
959 } else {
960 trace(ICOM_PORT, "LOWER_RTS", 0);
961 local_osr &= ~ICOM_RTS;
964 if (mctrl & TIOCM_DTR) {
965 trace(ICOM_PORT, "RAISE_DTR", 0);
966 local_osr |= ICOM_DTR;
967 } else {
968 trace(ICOM_PORT, "LOWER_DTR", 0);
969 local_osr &= ~ICOM_DTR;
972 writeb(local_osr, &ICOM_PORT->dram->osr);
975 static unsigned int icom_get_mctrl(struct uart_port *port)
977 unsigned char status;
978 unsigned int result;
980 trace(ICOM_PORT, "GET_MODEM", 0);
982 status = readb(&ICOM_PORT->dram->isr);
984 result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
985 | ((status & ICOM_RI) ? TIOCM_RNG : 0)
986 | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
987 | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
988 return result;
991 static void icom_stop_tx(struct uart_port *port)
993 unsigned char cmdReg;
995 trace(ICOM_PORT, "STOP", 0);
996 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
997 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
1000 static void icom_start_tx(struct uart_port *port)
1002 unsigned char cmdReg;
1004 trace(ICOM_PORT, "START", 0);
1005 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1006 if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
1007 writeb(cmdReg & ~CMD_HOLD_XMIT,
1008 &ICOM_PORT->dram->CmdReg);
1010 icom_write(port);
1013 static void icom_send_xchar(struct uart_port *port, char ch)
1015 unsigned char xdata;
1016 int index;
1017 unsigned long flags;
1019 trace(ICOM_PORT, "SEND_XCHAR", ch);
1021 /* wait .1 sec to send char */
1022 for (index = 0; index < 10; index++) {
1023 spin_lock_irqsave(&port->lock, flags);
1024 xdata = readb(&ICOM_PORT->dram->xchar);
1025 if (xdata == 0x00) {
1026 trace(ICOM_PORT, "QUICK_WRITE", 0);
1027 writeb(ch, &ICOM_PORT->dram->xchar);
1029 /* flush write operation */
1030 xdata = readb(&ICOM_PORT->dram->xchar);
1031 spin_unlock_irqrestore(&port->lock, flags);
1032 break;
1034 spin_unlock_irqrestore(&port->lock, flags);
1035 msleep(10);
1039 static void icom_stop_rx(struct uart_port *port)
1041 unsigned char cmdReg;
1043 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1044 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1047 static void icom_enable_ms(struct uart_port *port)
1049 /* no-op */
1052 static void icom_break(struct uart_port *port, int break_state)
1054 unsigned char cmdReg;
1055 unsigned long flags;
1057 spin_lock_irqsave(&port->lock, flags);
1058 trace(ICOM_PORT, "BREAK", 0);
1059 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1060 if (break_state == -1) {
1061 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1062 } else {
1063 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1065 spin_unlock_irqrestore(&port->lock, flags);
1068 static int icom_open(struct uart_port *port)
1070 int retval;
1072 kobject_get(&ICOM_PORT->adapter->kobj);
1073 retval = startup(ICOM_PORT);
1075 if (retval) {
1076 kobject_put(&ICOM_PORT->adapter->kobj);
1077 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1078 return retval;
1081 return 0;
1084 static void icom_close(struct uart_port *port)
1086 unsigned char cmdReg;
1088 trace(ICOM_PORT, "CLOSE", 0);
1090 /* stop receiver */
1091 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1092 writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1093 &ICOM_PORT->dram->CmdReg);
1095 shutdown(ICOM_PORT);
1097 kobject_put(&ICOM_PORT->adapter->kobj);
1100 static void icom_set_termios(struct uart_port *port,
1101 struct termios *termios,
1102 struct termios *old_termios)
1104 int baud;
1105 unsigned cflag, iflag;
1106 int bits;
1107 char new_config2;
1108 char new_config3 = 0;
1109 char tmp_byte;
1110 int index;
1111 int rcv_buff, xmit_buff;
1112 unsigned long offset;
1113 unsigned long flags;
1115 spin_lock_irqsave(&port->lock, flags);
1116 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1118 cflag = termios->c_cflag;
1119 iflag = termios->c_iflag;
1121 new_config2 = ICOM_ACFG_DRIVE1;
1123 /* byte size and parity */
1124 switch (cflag & CSIZE) {
1125 case CS5: /* 5 bits/char */
1126 new_config2 |= ICOM_ACFG_5BPC;
1127 bits = 7;
1128 break;
1129 case CS6: /* 6 bits/char */
1130 new_config2 |= ICOM_ACFG_6BPC;
1131 bits = 8;
1132 break;
1133 case CS7: /* 7 bits/char */
1134 new_config2 |= ICOM_ACFG_7BPC;
1135 bits = 9;
1136 break;
1137 case CS8: /* 8 bits/char */
1138 new_config2 |= ICOM_ACFG_8BPC;
1139 bits = 10;
1140 break;
1141 default:
1142 bits = 10;
1143 break;
1145 if (cflag & CSTOPB) {
1146 /* 2 stop bits */
1147 new_config2 |= ICOM_ACFG_2STOP_BIT;
1148 bits++;
1150 if (cflag & PARENB) {
1151 /* parity bit enabled */
1152 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1153 trace(ICOM_PORT, "PARENB", 0);
1154 bits++;
1156 if (cflag & PARODD) {
1157 /* odd parity */
1158 new_config2 |= ICOM_ACFG_PARITY_ODD;
1159 trace(ICOM_PORT, "PARODD", 0);
1162 /* Determine divisor based on baud rate */
1163 baud = uart_get_baud_rate(port, termios, old_termios,
1164 icom_acfg_baud[0],
1165 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1166 if (!baud)
1167 baud = 9600; /* B0 transition handled in rs_set_termios */
1169 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1170 if (icom_acfg_baud[index] == baud) {
1171 new_config3 = index;
1172 break;
1176 uart_update_timeout(port, cflag, baud);
1178 /* CTS flow control flag and modem status interrupts */
1179 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1180 if (cflag & CRTSCTS)
1181 tmp_byte |= HDLC_HDW_FLOW;
1182 else
1183 tmp_byte &= ~HDLC_HDW_FLOW;
1184 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1187 * Set up parity check flag
1189 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1190 if (iflag & INPCK)
1191 ICOM_PORT->read_status_mask |=
1192 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1194 if ((iflag & BRKINT) || (iflag & PARMRK))
1195 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1198 * Characters to ignore
1200 ICOM_PORT->ignore_status_mask = 0;
1201 if (iflag & IGNPAR)
1202 ICOM_PORT->ignore_status_mask |=
1203 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1204 if (iflag & IGNBRK) {
1205 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1207 * If we're ignore parity and break indicators, ignore
1208 * overruns too. (For real raw support).
1210 if (iflag & IGNPAR)
1211 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1215 * !!! ignore all characters if CREAD is not set
1217 if ((cflag & CREAD) == 0)
1218 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1220 /* Turn off Receiver to prepare for reset */
1221 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1223 for (index = 0; index < 10; index++) {
1224 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1225 break;
1229 /* clear all current buffers of data */
1230 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1231 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1232 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1233 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1234 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1237 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1238 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1241 /* activate changes and start xmit and receiver here */
1242 /* Enable the receiver */
1243 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1244 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1245 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1246 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1247 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1248 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer)); /* 0.5 seconds */
1249 writeb(0xFF, &(ICOM_PORT->dram->ier)); /* enable modem signal interrupts */
1251 /* reset processor */
1252 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1254 for (index = 0; index < 10; index++) {
1255 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1256 break;
1260 /* Enable Transmitter and Reciever */
1261 offset =
1262 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1263 (unsigned long) ICOM_PORT->statStg;
1264 writel(ICOM_PORT->statStg_pci + offset,
1265 &ICOM_PORT->dram->RcvStatusAddr);
1266 ICOM_PORT->next_rcv = 0;
1267 ICOM_PORT->put_length = 0;
1268 *ICOM_PORT->xmitRestart = 0;
1269 writel(ICOM_PORT->xmitRestart_pci,
1270 &ICOM_PORT->dram->XmitStatusAddr);
1271 trace(ICOM_PORT, "XR_ENAB", 0);
1272 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1274 spin_unlock_irqrestore(&port->lock, flags);
1277 static const char *icom_type(struct uart_port *port)
1279 return "icom";
1282 static void icom_release_port(struct uart_port *port)
1286 static int icom_request_port(struct uart_port *port)
1288 return 0;
1291 static void icom_config_port(struct uart_port *port, int flags)
1293 port->type = PORT_ICOM;
1296 static struct uart_ops icom_ops = {
1297 .tx_empty = icom_tx_empty,
1298 .set_mctrl = icom_set_mctrl,
1299 .get_mctrl = icom_get_mctrl,
1300 .stop_tx = icom_stop_tx,
1301 .start_tx = icom_start_tx,
1302 .send_xchar = icom_send_xchar,
1303 .stop_rx = icom_stop_rx,
1304 .enable_ms = icom_enable_ms,
1305 .break_ctl = icom_break,
1306 .startup = icom_open,
1307 .shutdown = icom_close,
1308 .set_termios = icom_set_termios,
1309 .type = icom_type,
1310 .release_port = icom_release_port,
1311 .request_port = icom_request_port,
1312 .config_port = icom_config_port,
1315 #define ICOM_CONSOLE NULL
1317 static struct uart_driver icom_uart_driver = {
1318 .owner = THIS_MODULE,
1319 .driver_name = ICOM_DRIVER_NAME,
1320 .dev_name = "ttyA",
1321 .major = ICOM_MAJOR,
1322 .minor = ICOM_MINOR_START,
1323 .nr = NR_PORTS,
1324 .cons = ICOM_CONSOLE,
1327 static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1329 u32 subsystem_id = icom_adapter->subsystem_id;
1330 int retval = 0;
1331 int i;
1332 struct icom_port *icom_port;
1334 if (icom_adapter->version == ADAPTER_V1) {
1335 icom_adapter->numb_ports = 2;
1337 for (i = 0; i < 2; i++) {
1338 icom_port = &icom_adapter->port_info[i];
1339 icom_port->port = i;
1340 icom_port->status = ICOM_PORT_ACTIVE;
1341 icom_port->imbed_modem = ICOM_UNKNOWN;
1343 } else {
1344 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1345 icom_adapter->numb_ports = 4;
1347 for (i = 0; i < 4; i++) {
1348 icom_port = &icom_adapter->port_info[i];
1350 icom_port->port = i;
1351 icom_port->status = ICOM_PORT_ACTIVE;
1352 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1354 } else {
1355 icom_adapter->numb_ports = 4;
1357 icom_adapter->port_info[0].port = 0;
1358 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1360 if (subsystem_id ==
1361 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1362 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1363 } else {
1364 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1367 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1369 icom_adapter->port_info[2].port = 2;
1370 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1371 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1372 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1376 return retval;
1379 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1381 if (icom_adapter->version == ADAPTER_V1) {
1382 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1383 icom_port->int_reg = icom_adapter->base_addr +
1384 0x4004 + 2 - 2 * port_num;
1385 } else {
1386 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1387 if (icom_port->port < 2)
1388 icom_port->int_reg = icom_adapter->base_addr +
1389 0x8004 + 2 - 2 * icom_port->port;
1390 else
1391 icom_port->int_reg = icom_adapter->base_addr +
1392 0x8024 + 2 - 2 * (icom_port->port - 2);
1395 static int __init icom_load_ports(struct icom_adapter *icom_adapter)
1397 struct icom_port *icom_port;
1398 int port_num;
1399 int retval;
1401 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1403 icom_port = &icom_adapter->port_info[port_num];
1405 if (icom_port->status == ICOM_PORT_ACTIVE) {
1406 icom_port_active(icom_port, icom_adapter, port_num);
1407 icom_port->dram = icom_adapter->base_addr +
1408 0x2000 * icom_port->port;
1410 icom_port->adapter = icom_adapter;
1412 /* get port memory */
1413 if ((retval = get_port_memory(icom_port)) != 0) {
1414 dev_err(&icom_port->adapter->pci_dev->dev,
1415 "Memory allocation for port FAILED\n");
1419 return 0;
1422 static int __devinit icom_alloc_adapter(struct icom_adapter
1423 **icom_adapter_ref)
1425 int adapter_count = 0;
1426 struct icom_adapter *icom_adapter;
1427 struct icom_adapter *cur_adapter_entry;
1428 struct list_head *tmp;
1430 icom_adapter = (struct icom_adapter *)
1431 kmalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1433 if (!icom_adapter) {
1434 return -ENOMEM;
1437 memset(icom_adapter, 0, sizeof(struct icom_adapter));
1439 list_for_each(tmp, &icom_adapter_head) {
1440 cur_adapter_entry =
1441 list_entry(tmp, struct icom_adapter,
1442 icom_adapter_entry);
1443 if (cur_adapter_entry->index != adapter_count) {
1444 break;
1446 adapter_count++;
1449 icom_adapter->index = adapter_count;
1450 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1452 *icom_adapter_ref = icom_adapter;
1453 return 0;
1456 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1458 list_del(&icom_adapter->icom_adapter_entry);
1459 kfree(icom_adapter);
1462 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1464 struct icom_port *icom_port;
1465 int index;
1467 for (index = 0; index < icom_adapter->numb_ports; index++) {
1468 icom_port = &icom_adapter->port_info[index];
1470 if (icom_port->status == ICOM_PORT_ACTIVE) {
1471 dev_info(&icom_adapter->pci_dev->dev,
1472 "Device removed\n");
1474 uart_remove_one_port(&icom_uart_driver,
1475 &icom_port->uart_port);
1477 /* be sure that DTR and RTS are dropped */
1478 writeb(0x00, &icom_port->dram->osr);
1480 /* Wait 0.1 Sec for simple Init to complete */
1481 msleep(100);
1483 /* Stop proccessor */
1484 stop_processor(icom_port);
1486 free_port_memory(icom_port);
1490 free_irq(icom_adapter->irq_number, (void *) icom_adapter);
1491 iounmap(icom_adapter->base_addr);
1492 icom_free_adapter(icom_adapter);
1493 pci_release_regions(icom_adapter->pci_dev);
1496 static void icom_kobj_release(struct kobject *kobj)
1498 struct icom_adapter *icom_adapter;
1500 icom_adapter = to_icom_adapter(kobj);
1501 icom_remove_adapter(icom_adapter);
1504 static struct kobj_type icom_kobj_type = {
1505 .release = icom_kobj_release,
1508 static int __devinit icom_probe(struct pci_dev *dev,
1509 const struct pci_device_id *ent)
1511 int index;
1512 unsigned int command_reg;
1513 int retval;
1514 struct icom_adapter *icom_adapter;
1515 struct icom_port *icom_port;
1517 retval = pci_enable_device(dev);
1518 if (retval) {
1519 dev_err(&dev->dev, "Device enable FAILED\n");
1520 return retval;
1523 if ( (retval = pci_request_regions(dev, "icom"))) {
1524 dev_err(&dev->dev, "pci_request_region FAILED\n");
1525 pci_disable_device(dev);
1526 return retval;
1529 pci_set_master(dev);
1531 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1532 dev_err(&dev->dev, "PCI Config read FAILED\n");
1533 return retval;
1536 pci_write_config_dword(dev, PCI_COMMAND,
1537 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1538 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1540 if (ent->driver_data == ADAPTER_V1) {
1541 pci_write_config_dword(dev, 0x44, 0x8300830A);
1542 } else {
1543 pci_write_config_dword(dev, 0x44, 0x42004200);
1544 pci_write_config_dword(dev, 0x48, 0x42004200);
1548 retval = icom_alloc_adapter(&icom_adapter);
1549 if (retval) {
1550 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1551 retval = -EIO;
1552 goto probe_exit0;
1555 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1556 icom_adapter->irq_number = dev->irq;
1557 icom_adapter->pci_dev = dev;
1558 icom_adapter->version = ent->driver_data;
1559 icom_adapter->subsystem_id = ent->subdevice;
1562 retval = icom_init_ports(icom_adapter);
1563 if (retval) {
1564 dev_err(&dev->dev, "Port configuration failed\n");
1565 goto probe_exit1;
1568 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1569 pci_resource_len(dev, 0));
1571 if (!icom_adapter->base_addr)
1572 goto probe_exit1;
1574 /* save off irq and request irq line */
1575 if ( (retval = request_irq(dev->irq, icom_interrupt,
1576 SA_INTERRUPT | SA_SHIRQ, ICOM_DRIVER_NAME,
1577 (void *) icom_adapter))) {
1578 goto probe_exit2;
1581 retval = icom_load_ports(icom_adapter);
1583 for (index = 0; index < icom_adapter->numb_ports; index++) {
1584 icom_port = &icom_adapter->port_info[index];
1586 if (icom_port->status == ICOM_PORT_ACTIVE) {
1587 icom_port->uart_port.irq = icom_port->adapter->irq_number;
1588 icom_port->uart_port.type = PORT_ICOM;
1589 icom_port->uart_port.iotype = UPIO_MEM;
1590 icom_port->uart_port.membase =
1591 (char *) icom_adapter->base_addr_pci;
1592 icom_port->uart_port.fifosize = 16;
1593 icom_port->uart_port.ops = &icom_ops;
1594 icom_port->uart_port.line =
1595 icom_port->port + icom_adapter->index * 4;
1596 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1597 icom_port->status = ICOM_PORT_OFF;
1598 dev_err(&dev->dev, "Device add failed\n");
1599 } else
1600 dev_info(&dev->dev, "Device added\n");
1604 kobject_init(&icom_adapter->kobj);
1605 icom_adapter->kobj.ktype = &icom_kobj_type;
1606 return 0;
1608 probe_exit2:
1609 iounmap(icom_adapter->base_addr);
1610 probe_exit1:
1611 icom_free_adapter(icom_adapter);
1613 probe_exit0:
1614 pci_release_regions(dev);
1615 pci_disable_device(dev);
1617 return retval;
1622 static void __devexit icom_remove(struct pci_dev *dev)
1624 struct icom_adapter *icom_adapter;
1625 struct list_head *tmp;
1627 list_for_each(tmp, &icom_adapter_head) {
1628 icom_adapter = list_entry(tmp, struct icom_adapter,
1629 icom_adapter_entry);
1630 if (icom_adapter->pci_dev == dev) {
1631 kobject_put(&icom_adapter->kobj);
1632 return;
1636 dev_err(&dev->dev, "Unable to find device to remove\n");
1639 static struct pci_driver icom_pci_driver = {
1640 .name = ICOM_DRIVER_NAME,
1641 .id_table = icom_pci_table,
1642 .probe = icom_probe,
1643 .remove = __devexit_p(icom_remove),
1646 static int __init icom_init(void)
1648 int ret;
1650 spin_lock_init(&icom_lock);
1652 ret = uart_register_driver(&icom_uart_driver);
1653 if (ret)
1654 return ret;
1656 ret = pci_register_driver(&icom_pci_driver);
1658 if (ret < 0)
1659 uart_unregister_driver(&icom_uart_driver);
1661 return ret;
1664 static void __exit icom_exit(void)
1666 pci_unregister_driver(&icom_pci_driver);
1667 uart_unregister_driver(&icom_uart_driver);
1670 module_init(icom_init);
1671 module_exit(icom_exit);
1673 #ifdef ICOM_TRACE
1674 static inline void trace(struct icom_port *icom_port, char *trace_pt,
1675 unsigned long trace_data)
1677 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1678 icom_port->port, trace_pt, trace_data);
1680 #endif
1682 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1683 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1684 MODULE_SUPPORTED_DEVICE
1685 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1686 MODULE_LICENSE("GPL");