Revert "tty: hvc: Fix data abort due to race in hvc_open"
[linux/fpc-iii.git] / drivers / tty / serial / icom.c
blob624f3d541c6875c7f805a1dec4db0454604702af
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * icom.c
5 * Copyright (C) 2001 IBM Corporation. All rights reserved.
7 * Serial device driver.
9 * Based on code from serial.c
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/signal.h>
15 #include <linux/timer.h>
16 #include <linux/interrupt.h>
17 #include <linux/tty.h>
18 #include <linux/termios.h>
19 #include <linux/fs.h>
20 #include <linux/tty_flip.h>
21 #include <linux/serial.h>
22 #include <linux/serial_reg.h>
23 #include <linux/major.h>
24 #include <linux/string.h>
25 #include <linux/fcntl.h>
26 #include <linux/ptrace.h>
27 #include <linux/ioport.h>
28 #include <linux/mm.h>
29 #include <linux/slab.h>
30 #include <linux/init.h>
31 #include <linux/delay.h>
32 #include <linux/pci.h>
33 #include <linux/vmalloc.h>
34 #include <linux/smp.h>
35 #include <linux/spinlock.h>
36 #include <linux/kref.h>
37 #include <linux/firmware.h>
38 #include <linux/bitops.h>
40 #include <asm/io.h>
41 #include <asm/irq.h>
42 #include <linux/uaccess.h>
44 #include "icom.h"
46 /*#define ICOM_TRACE enable port trace capabilities */
48 #define ICOM_DRIVER_NAME "icom"
49 #define ICOM_VERSION_STR "1.3.1"
50 #define NR_PORTS 128
51 #define ICOM_PORT ((struct icom_port *)port)
52 #define to_icom_adapter(d) container_of(d, struct icom_adapter, kref)
54 static const struct pci_device_id icom_pci_table[] = {
56 .vendor = PCI_VENDOR_ID_IBM,
57 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
58 .subvendor = PCI_ANY_ID,
59 .subdevice = PCI_ANY_ID,
60 .driver_data = ADAPTER_V1,
63 .vendor = PCI_VENDOR_ID_IBM,
64 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
65 .subvendor = PCI_VENDOR_ID_IBM,
66 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
67 .driver_data = ADAPTER_V2,
70 .vendor = PCI_VENDOR_ID_IBM,
71 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
72 .subvendor = PCI_VENDOR_ID_IBM,
73 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
74 .driver_data = ADAPTER_V2,
77 .vendor = PCI_VENDOR_ID_IBM,
78 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
79 .subvendor = PCI_VENDOR_ID_IBM,
80 .subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
81 .driver_data = ADAPTER_V2,
84 .vendor = PCI_VENDOR_ID_IBM,
85 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
86 .subvendor = PCI_VENDOR_ID_IBM,
87 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE,
88 .driver_data = ADAPTER_V2,
93 static struct lookup_proc_table start_proc[4] = {
94 {NULL, ICOM_CONTROL_START_A},
95 {NULL, ICOM_CONTROL_START_B},
96 {NULL, ICOM_CONTROL_START_C},
97 {NULL, ICOM_CONTROL_START_D}
101 static struct lookup_proc_table stop_proc[4] = {
102 {NULL, ICOM_CONTROL_STOP_A},
103 {NULL, ICOM_CONTROL_STOP_B},
104 {NULL, ICOM_CONTROL_STOP_C},
105 {NULL, ICOM_CONTROL_STOP_D}
108 static struct lookup_int_table int_mask_tbl[4] = {
109 {NULL, ICOM_INT_MASK_PRC_A},
110 {NULL, ICOM_INT_MASK_PRC_B},
111 {NULL, ICOM_INT_MASK_PRC_C},
112 {NULL, ICOM_INT_MASK_PRC_D},
116 MODULE_DEVICE_TABLE(pci, icom_pci_table);
118 static LIST_HEAD(icom_adapter_head);
120 /* spinlock for adapter initialization and changing adapter operations */
121 static spinlock_t icom_lock;
123 #ifdef ICOM_TRACE
124 static inline void trace(struct icom_port *icom_port, char *trace_pt,
125 unsigned long trace_data)
127 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
128 icom_port->port, trace_pt, trace_data);
130 #else
131 static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
132 #endif
133 static void icom_kref_release(struct kref *kref);
135 static void free_port_memory(struct icom_port *icom_port)
137 struct pci_dev *dev = icom_port->adapter->pci_dev;
139 trace(icom_port, "RET_PORT_MEM", 0);
140 if (icom_port->recv_buf) {
141 pci_free_consistent(dev, 4096, icom_port->recv_buf,
142 icom_port->recv_buf_pci);
143 icom_port->recv_buf = NULL;
145 if (icom_port->xmit_buf) {
146 pci_free_consistent(dev, 4096, icom_port->xmit_buf,
147 icom_port->xmit_buf_pci);
148 icom_port->xmit_buf = NULL;
150 if (icom_port->statStg) {
151 pci_free_consistent(dev, 4096, icom_port->statStg,
152 icom_port->statStg_pci);
153 icom_port->statStg = NULL;
156 if (icom_port->xmitRestart) {
157 pci_free_consistent(dev, 4096, icom_port->xmitRestart,
158 icom_port->xmitRestart_pci);
159 icom_port->xmitRestart = NULL;
163 static int get_port_memory(struct icom_port *icom_port)
165 int index;
166 unsigned long stgAddr;
167 unsigned long startStgAddr;
168 unsigned long offset;
169 struct pci_dev *dev = icom_port->adapter->pci_dev;
171 icom_port->xmit_buf =
172 pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
173 if (!icom_port->xmit_buf) {
174 dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
175 return -ENOMEM;
178 trace(icom_port, "GET_PORT_MEM",
179 (unsigned long) icom_port->xmit_buf);
181 icom_port->recv_buf =
182 pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
183 if (!icom_port->recv_buf) {
184 dev_err(&dev->dev, "Can not allocate Receive buffer\n");
185 free_port_memory(icom_port);
186 return -ENOMEM;
188 trace(icom_port, "GET_PORT_MEM",
189 (unsigned long) icom_port->recv_buf);
191 icom_port->statStg =
192 pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
193 if (!icom_port->statStg) {
194 dev_err(&dev->dev, "Can not allocate Status buffer\n");
195 free_port_memory(icom_port);
196 return -ENOMEM;
198 trace(icom_port, "GET_PORT_MEM",
199 (unsigned long) icom_port->statStg);
201 icom_port->xmitRestart =
202 pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
203 if (!icom_port->xmitRestart) {
204 dev_err(&dev->dev,
205 "Can not allocate xmit Restart buffer\n");
206 free_port_memory(icom_port);
207 return -ENOMEM;
210 /* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
211 indicates that frames are to be transmitted
214 stgAddr = (unsigned long) icom_port->statStg;
215 for (index = 0; index < NUM_XBUFFS; index++) {
216 trace(icom_port, "FOD_ADDR", stgAddr);
217 stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
218 if (index < (NUM_XBUFFS - 1)) {
219 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
220 icom_port->statStg->xmit[index].leLengthASD =
221 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
222 trace(icom_port, "FOD_ADDR", stgAddr);
223 trace(icom_port, "FOD_XBUFF",
224 (unsigned long) icom_port->xmit_buf);
225 icom_port->statStg->xmit[index].leBuffer =
226 cpu_to_le32(icom_port->xmit_buf_pci);
227 } else if (index == (NUM_XBUFFS - 1)) {
228 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
229 icom_port->statStg->xmit[index].leLengthASD =
230 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
231 trace(icom_port, "FOD_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 {
236 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
239 /* FIDs */
240 startStgAddr = stgAddr;
242 /* fill in every entry, even if no buffer */
243 for (index = 0; index < NUM_RBUFFS; index++) {
244 trace(icom_port, "FID_ADDR", stgAddr);
245 stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
246 icom_port->statStg->rcv[index].leLength = 0;
247 icom_port->statStg->rcv[index].WorkingLength =
248 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
249 if (index < (NUM_RBUFFS - 1) ) {
250 offset = stgAddr - (unsigned long) icom_port->statStg;
251 icom_port->statStg->rcv[index].leNext =
252 cpu_to_le32(icom_port-> statStg_pci + offset);
253 trace(icom_port, "FID_RBUFF",
254 (unsigned long) icom_port->recv_buf);
255 icom_port->statStg->rcv[index].leBuffer =
256 cpu_to_le32(icom_port->recv_buf_pci);
257 } else if (index == (NUM_RBUFFS -1) ) {
258 offset = startStgAddr - (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 + 2048);
263 icom_port->statStg->rcv[index].leBuffer =
264 cpu_to_le32(icom_port->recv_buf_pci + 2048);
265 } else {
266 icom_port->statStg->rcv[index].leNext = 0;
267 icom_port->statStg->rcv[index].leBuffer = 0;
271 return 0;
274 static void stop_processor(struct icom_port *icom_port)
276 unsigned long temp;
277 unsigned long flags;
278 int port;
280 spin_lock_irqsave(&icom_lock, flags);
282 port = icom_port->port;
283 if (port >= ARRAY_SIZE(stop_proc)) {
284 dev_err(&icom_port->adapter->pci_dev->dev,
285 "Invalid port assignment\n");
286 goto unlock;
289 if (port == 0 || port == 1)
290 stop_proc[port].global_control_reg = &icom_port->global_reg->control;
291 else
292 stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
294 temp = readl(stop_proc[port].global_control_reg);
295 temp = (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
296 writel(temp, stop_proc[port].global_control_reg);
298 /* write flush */
299 readl(stop_proc[port].global_control_reg);
301 unlock:
302 spin_unlock_irqrestore(&icom_lock, flags);
305 static void start_processor(struct icom_port *icom_port)
307 unsigned long temp;
308 unsigned long flags;
309 int port;
311 spin_lock_irqsave(&icom_lock, flags);
313 port = icom_port->port;
314 if (port >= ARRAY_SIZE(start_proc)) {
315 dev_err(&icom_port->adapter->pci_dev->dev,
316 "Invalid port assignment\n");
317 goto unlock;
320 if (port == 0 || port == 1)
321 start_proc[port].global_control_reg = &icom_port->global_reg->control;
322 else
323 start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
325 temp = readl(start_proc[port].global_control_reg);
326 temp = (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
327 writel(temp, start_proc[port].global_control_reg);
329 /* write flush */
330 readl(start_proc[port].global_control_reg);
332 unlock:
333 spin_unlock_irqrestore(&icom_lock, flags);
336 static void load_code(struct icom_port *icom_port)
338 const struct firmware *fw;
339 char __iomem *iram_ptr;
340 int index;
341 int status = 0;
342 void __iomem *dram_ptr = icom_port->dram;
343 dma_addr_t temp_pci;
344 unsigned char *new_page = NULL;
345 unsigned char cable_id = NO_CABLE;
346 struct pci_dev *dev = icom_port->adapter->pci_dev;
348 /* Clear out any pending interrupts */
349 writew(0x3FFF, icom_port->int_reg);
351 trace(icom_port, "CLEAR_INTERRUPTS", 0);
353 /* Stop processor */
354 stop_processor(icom_port);
356 /* Zero out DRAM */
357 memset_io(dram_ptr, 0, 512);
359 /* Load Call Setup into Adapter */
360 if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
361 dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
362 status = -1;
363 goto load_code_exit;
366 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
367 dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
368 release_firmware(fw);
369 status = -1;
370 goto load_code_exit;
373 iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
374 for (index = 0; index < fw->size; index++)
375 writeb(fw->data[index], &iram_ptr[index]);
377 release_firmware(fw);
379 /* Load Resident DCE portion of Adapter */
380 if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
381 dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
382 status = -1;
383 goto load_code_exit;
386 if (fw->size > ICOM_IRAM_SIZE) {
387 dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
388 release_firmware(fw);
389 status = -1;
390 goto load_code_exit;
393 iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
394 for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
395 writeb(fw->data[index], &iram_ptr[index]);
397 release_firmware(fw);
399 /* Set Hardware level */
400 if (icom_port->adapter->version == ADAPTER_V2)
401 writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));
403 /* Start the processor in Adapter */
404 start_processor(icom_port);
406 writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
407 &(icom_port->dram->HDLCConfigReg));
408 writeb(0x04, &(icom_port->dram->FlagFillIdleTimer)); /* 0.5 seconds */
409 writeb(0x00, &(icom_port->dram->CmdReg));
410 writeb(0x10, &(icom_port->dram->async_config3));
411 writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
412 ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));
414 /*Set up data in icom DRAM to indicate where personality
415 *code is located and its length.
417 new_page = pci_alloc_consistent(dev, 4096, &temp_pci);
419 if (!new_page) {
420 dev_err(&dev->dev, "Can not allocate DMA buffer\n");
421 status = -1;
422 goto load_code_exit;
425 if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
426 dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
427 status = -1;
428 goto load_code_exit;
431 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
432 dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
433 release_firmware(fw);
434 status = -1;
435 goto load_code_exit;
438 for (index = 0; index < fw->size; index++)
439 new_page[index] = fw->data[index];
441 writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
442 writel(temp_pci, &icom_port->dram->mac_load_addr);
444 release_firmware(fw);
446 /*Setting the syncReg to 0x80 causes adapter to start downloading
447 the personality code into adapter instruction RAM.
448 Once code is loaded, it will begin executing and, based on
449 information provided above, will start DMAing data from
450 shared memory to adapter DRAM.
452 /* the wait loop below verifies this write operation has been done
453 and processed
455 writeb(START_DOWNLOAD, &icom_port->dram->sync);
457 /* Wait max 1 Sec for data download and processor to start */
458 for (index = 0; index < 10; index++) {
459 msleep(100);
460 if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
461 break;
464 if (index == 10)
465 status = -1;
468 * check Cable ID
470 cable_id = readb(&icom_port->dram->cable_id);
472 if (cable_id & ICOM_CABLE_ID_VALID) {
473 /* Get cable ID into the lower 4 bits (standard form) */
474 cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
475 icom_port->cable_id = cable_id;
476 } else {
477 dev_err(&dev->dev,"Invalid or no cable attached\n");
478 icom_port->cable_id = NO_CABLE;
481 load_code_exit:
483 if (status != 0) {
484 /* Clear out any pending interrupts */
485 writew(0x3FFF, icom_port->int_reg);
487 /* Turn off port */
488 writeb(ICOM_DISABLE, &(icom_port->dram->disable));
490 /* Stop processor */
491 stop_processor(icom_port);
493 dev_err(&icom_port->adapter->pci_dev->dev,"Port not operational\n");
496 if (new_page != NULL)
497 pci_free_consistent(dev, 4096, new_page, temp_pci);
500 static int startup(struct icom_port *icom_port)
502 unsigned long temp;
503 unsigned char cable_id, raw_cable_id;
504 unsigned long flags;
505 int port;
507 trace(icom_port, "STARTUP", 0);
509 if (!icom_port->dram) {
510 /* should NEVER be NULL */
511 dev_err(&icom_port->adapter->pci_dev->dev,
512 "Unusable Port, port configuration missing\n");
513 return -ENODEV;
517 * check Cable ID
519 raw_cable_id = readb(&icom_port->dram->cable_id);
520 trace(icom_port, "CABLE_ID", raw_cable_id);
522 /* Get cable ID into the lower 4 bits (standard form) */
523 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
525 /* Check for valid Cable ID */
526 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
527 (cable_id != icom_port->cable_id)) {
529 /* reload adapter code, pick up any potential changes in cable id */
530 load_code(icom_port);
532 /* still no sign of cable, error out */
533 raw_cable_id = readb(&icom_port->dram->cable_id);
534 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
535 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
536 (icom_port->cable_id == NO_CABLE))
537 return -EIO;
541 * Finally, clear and enable interrupts
543 spin_lock_irqsave(&icom_lock, flags);
544 port = icom_port->port;
545 if (port >= ARRAY_SIZE(int_mask_tbl)) {
546 dev_err(&icom_port->adapter->pci_dev->dev,
547 "Invalid port assignment\n");
548 goto unlock;
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);
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);
567 unlock:
568 spin_unlock_irqrestore(&icom_lock, flags);
569 return 0;
572 static void shutdown(struct icom_port *icom_port)
574 unsigned long temp;
575 unsigned char cmdReg;
576 unsigned long flags;
577 int port;
579 spin_lock_irqsave(&icom_lock, flags);
580 trace(icom_port, "SHUTDOWN", 0);
583 * disable all interrupts
585 port = icom_port->port;
586 if (port >= ARRAY_SIZE(int_mask_tbl)) {
587 dev_err(&icom_port->adapter->pci_dev->dev,
588 "Invalid port assignment\n");
589 goto unlock;
591 if (port == 0 || port == 1)
592 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
593 else
594 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
596 temp = readl(int_mask_tbl[port].global_int_mask);
597 writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
599 /* write flush */
600 readl(int_mask_tbl[port].global_int_mask);
602 unlock:
603 spin_unlock_irqrestore(&icom_lock, flags);
606 * disable break condition
608 cmdReg = readb(&icom_port->dram->CmdReg);
609 if (cmdReg & CMD_SND_BREAK) {
610 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
614 static int icom_write(struct uart_port *port)
616 unsigned long data_count;
617 unsigned char cmdReg;
618 unsigned long offset;
619 int temp_tail = port->state->xmit.tail;
621 trace(ICOM_PORT, "WRITE", 0);
623 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
624 SA_FLAGS_READY_TO_XMIT) {
625 trace(ICOM_PORT, "WRITE_FULL", 0);
626 return 0;
629 data_count = 0;
630 while ((port->state->xmit.head != temp_tail) &&
631 (data_count <= XMIT_BUFF_SZ)) {
633 ICOM_PORT->xmit_buf[data_count++] =
634 port->state->xmit.buf[temp_tail];
636 temp_tail++;
637 temp_tail &= (UART_XMIT_SIZE - 1);
640 if (data_count) {
641 ICOM_PORT->statStg->xmit[0].flags =
642 cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
643 ICOM_PORT->statStg->xmit[0].leLength =
644 cpu_to_le16(data_count);
645 offset =
646 (unsigned long) &ICOM_PORT->statStg->xmit[0] -
647 (unsigned long) ICOM_PORT->statStg;
648 *ICOM_PORT->xmitRestart =
649 cpu_to_le32(ICOM_PORT->statStg_pci + offset);
650 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
651 writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
652 &ICOM_PORT->dram->CmdReg);
653 writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
654 trace(ICOM_PORT, "WRITE_START", data_count);
655 /* write flush */
656 readb(&ICOM_PORT->dram->StartXmitCmd);
659 return data_count;
662 static inline void check_modem_status(struct icom_port *icom_port)
664 static char old_status = 0;
665 char delta_status;
666 unsigned char status;
668 spin_lock(&icom_port->uart_port.lock);
670 /*modem input register */
671 status = readb(&icom_port->dram->isr);
672 trace(icom_port, "CHECK_MODEM", status);
673 delta_status = status ^ old_status;
674 if (delta_status) {
675 if (delta_status & ICOM_RI)
676 icom_port->uart_port.icount.rng++;
677 if (delta_status & ICOM_DSR)
678 icom_port->uart_port.icount.dsr++;
679 if (delta_status & ICOM_DCD)
680 uart_handle_dcd_change(&icom_port->uart_port,
681 delta_status & ICOM_DCD);
682 if (delta_status & ICOM_CTS)
683 uart_handle_cts_change(&icom_port->uart_port,
684 delta_status & ICOM_CTS);
686 wake_up_interruptible(&icom_port->uart_port.state->
687 port.delta_msr_wait);
688 old_status = status;
690 spin_unlock(&icom_port->uart_port.lock);
693 static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
695 unsigned short int count;
696 int i;
698 if (port_int_reg & (INT_XMIT_COMPLETED)) {
699 trace(icom_port, "XMIT_COMPLETE", 0);
701 /* clear buffer in use bit */
702 icom_port->statStg->xmit[0].flags &=
703 cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
705 count = (unsigned short int)
706 cpu_to_le16(icom_port->statStg->xmit[0].leLength);
707 icom_port->uart_port.icount.tx += count;
709 for (i=0; i<count &&
710 !uart_circ_empty(&icom_port->uart_port.state->xmit); i++) {
712 icom_port->uart_port.state->xmit.tail++;
713 icom_port->uart_port.state->xmit.tail &=
714 (UART_XMIT_SIZE - 1);
717 if (!icom_write(&icom_port->uart_port))
718 /* activate write queue */
719 uart_write_wakeup(&icom_port->uart_port);
720 } else
721 trace(icom_port, "XMIT_DISABLED", 0);
724 static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
726 short int count, rcv_buff;
727 struct tty_port *port = &icom_port->uart_port.state->port;
728 unsigned short int status;
729 struct uart_icount *icount;
730 unsigned long offset;
731 unsigned char flag;
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) {
738 int first = -1;
740 trace(icom_port, "FID_STATUS", status);
741 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
743 trace(icom_port, "RCV_COUNT", count);
745 trace(icom_port, "REAL_COUNT", count);
747 offset =
748 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
749 icom_port->recv_buf_pci;
751 /* Block copy all but the last byte as this may have status */
752 if (count > 0) {
753 first = icom_port->recv_buf[offset];
754 tty_insert_flip_string(port, icom_port->recv_buf + offset, count - 1);
757 icount = &icom_port->uart_port.icount;
758 icount->rx += count;
760 /* Break detect logic */
761 if ((status & SA_FLAGS_FRAME_ERROR)
762 && first == 0) {
763 status &= ~SA_FLAGS_FRAME_ERROR;
764 status |= SA_FLAGS_BREAK_DET;
765 trace(icom_port, "BREAK_DET", 0);
768 flag = TTY_NORMAL;
770 if (status &
771 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
772 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
774 if (status & SA_FLAGS_BREAK_DET)
775 icount->brk++;
776 if (status & SA_FLAGS_PARITY_ERROR)
777 icount->parity++;
778 if (status & SA_FLAGS_FRAME_ERROR)
779 icount->frame++;
780 if (status & SA_FLAGS_OVERRUN)
781 icount->overrun++;
784 * Now check to see if character should be
785 * ignored, and mask off conditions which
786 * should be ignored.
788 if (status & icom_port->ignore_status_mask) {
789 trace(icom_port, "IGNORE_CHAR", 0);
790 goto ignore_char;
793 status &= icom_port->read_status_mask;
795 if (status & SA_FLAGS_BREAK_DET) {
796 flag = TTY_BREAK;
797 } else if (status & SA_FLAGS_PARITY_ERROR) {
798 trace(icom_port, "PARITY_ERROR", 0);
799 flag = TTY_PARITY;
800 } else if (status & SA_FLAGS_FRAME_ERROR)
801 flag = TTY_FRAME;
805 tty_insert_flip_char(port, *(icom_port->recv_buf + offset + count - 1), flag);
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 tty_insert_flip_char(port, 0, TTY_OVERRUN);
814 ignore_char:
815 icom_port->statStg->rcv[rcv_buff].flags = 0;
816 icom_port->statStg->rcv[rcv_buff].leLength = 0;
817 icom_port->statStg->rcv[rcv_buff].WorkingLength =
818 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
820 rcv_buff++;
821 if (rcv_buff == NUM_RBUFFS)
822 rcv_buff = 0;
824 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
826 icom_port->next_rcv = rcv_buff;
828 spin_unlock(&icom_port->uart_port.lock);
829 tty_flip_buffer_push(port);
830 spin_lock(&icom_port->uart_port.lock);
833 static void process_interrupt(u16 port_int_reg,
834 struct icom_port *icom_port)
837 spin_lock(&icom_port->uart_port.lock);
838 trace(icom_port, "INTERRUPT", port_int_reg);
840 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
841 xmit_interrupt(port_int_reg, icom_port);
843 if (port_int_reg & INT_RCV_COMPLETED)
844 recv_interrupt(port_int_reg, icom_port);
846 spin_unlock(&icom_port->uart_port.lock);
849 static irqreturn_t icom_interrupt(int irq, void *dev_id)
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) {
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_break(struct uart_port *port, int break_state)
1040 unsigned char cmdReg;
1041 unsigned long flags;
1043 spin_lock_irqsave(&port->lock, flags);
1044 trace(ICOM_PORT, "BREAK", 0);
1045 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1046 if (break_state == -1) {
1047 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1048 } else {
1049 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1051 spin_unlock_irqrestore(&port->lock, flags);
1054 static int icom_open(struct uart_port *port)
1056 int retval;
1058 kref_get(&ICOM_PORT->adapter->kref);
1059 retval = startup(ICOM_PORT);
1061 if (retval) {
1062 kref_put(&ICOM_PORT->adapter->kref, icom_kref_release);
1063 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1064 return retval;
1067 return 0;
1070 static void icom_close(struct uart_port *port)
1072 unsigned char cmdReg;
1074 trace(ICOM_PORT, "CLOSE", 0);
1076 /* stop receiver */
1077 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1078 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1080 shutdown(ICOM_PORT);
1082 kref_put(&ICOM_PORT->adapter->kref, icom_kref_release);
1085 static void icom_set_termios(struct uart_port *port,
1086 struct ktermios *termios,
1087 struct ktermios *old_termios)
1089 int baud;
1090 unsigned cflag, iflag;
1091 char new_config2;
1092 char new_config3 = 0;
1093 char tmp_byte;
1094 int index;
1095 int rcv_buff, xmit_buff;
1096 unsigned long offset;
1097 unsigned long flags;
1099 spin_lock_irqsave(&port->lock, flags);
1100 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1102 cflag = termios->c_cflag;
1103 iflag = termios->c_iflag;
1105 new_config2 = ICOM_ACFG_DRIVE1;
1107 /* byte size and parity */
1108 switch (cflag & CSIZE) {
1109 case CS5: /* 5 bits/char */
1110 new_config2 |= ICOM_ACFG_5BPC;
1111 break;
1112 case CS6: /* 6 bits/char */
1113 new_config2 |= ICOM_ACFG_6BPC;
1114 break;
1115 case CS7: /* 7 bits/char */
1116 new_config2 |= ICOM_ACFG_7BPC;
1117 break;
1118 case CS8: /* 8 bits/char */
1119 new_config2 |= ICOM_ACFG_8BPC;
1120 break;
1121 default:
1122 break;
1124 if (cflag & CSTOPB) {
1125 /* 2 stop bits */
1126 new_config2 |= ICOM_ACFG_2STOP_BIT;
1128 if (cflag & PARENB) {
1129 /* parity bit enabled */
1130 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1131 trace(ICOM_PORT, "PARENB", 0);
1133 if (cflag & PARODD) {
1134 /* odd parity */
1135 new_config2 |= ICOM_ACFG_PARITY_ODD;
1136 trace(ICOM_PORT, "PARODD", 0);
1139 /* Determine divisor based on baud rate */
1140 baud = uart_get_baud_rate(port, termios, old_termios,
1141 icom_acfg_baud[0],
1142 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1143 if (!baud)
1144 baud = 9600; /* B0 transition handled in rs_set_termios */
1146 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1147 if (icom_acfg_baud[index] == baud) {
1148 new_config3 = index;
1149 break;
1153 uart_update_timeout(port, cflag, baud);
1155 /* CTS flow control flag and modem status interrupts */
1156 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1157 if (cflag & CRTSCTS)
1158 tmp_byte |= HDLC_HDW_FLOW;
1159 else
1160 tmp_byte &= ~HDLC_HDW_FLOW;
1161 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1164 * Set up parity check flag
1166 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1167 if (iflag & INPCK)
1168 ICOM_PORT->read_status_mask |=
1169 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1171 if ((iflag & BRKINT) || (iflag & PARMRK))
1172 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1175 * Characters to ignore
1177 ICOM_PORT->ignore_status_mask = 0;
1178 if (iflag & IGNPAR)
1179 ICOM_PORT->ignore_status_mask |=
1180 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1181 if (iflag & IGNBRK) {
1182 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1184 * If we're ignore parity and break indicators, ignore
1185 * overruns too. (For real raw support).
1187 if (iflag & IGNPAR)
1188 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1192 * !!! ignore all characters if CREAD is not set
1194 if ((cflag & CREAD) == 0)
1195 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1197 /* Turn off Receiver to prepare for reset */
1198 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1200 for (index = 0; index < 10; index++) {
1201 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1202 break;
1206 /* clear all current buffers of data */
1207 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1208 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1209 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1210 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1211 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1214 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1215 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1218 /* activate changes and start xmit and receiver here */
1219 /* Enable the receiver */
1220 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1221 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1222 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1223 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1224 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1225 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer)); /* 0.5 seconds */
1226 writeb(0xFF, &(ICOM_PORT->dram->ier)); /* enable modem signal interrupts */
1228 /* reset processor */
1229 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1231 for (index = 0; index < 10; index++) {
1232 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1233 break;
1237 /* Enable Transmitter and Receiver */
1238 offset =
1239 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1240 (unsigned long) ICOM_PORT->statStg;
1241 writel(ICOM_PORT->statStg_pci + offset,
1242 &ICOM_PORT->dram->RcvStatusAddr);
1243 ICOM_PORT->next_rcv = 0;
1244 ICOM_PORT->put_length = 0;
1245 *ICOM_PORT->xmitRestart = 0;
1246 writel(ICOM_PORT->xmitRestart_pci,
1247 &ICOM_PORT->dram->XmitStatusAddr);
1248 trace(ICOM_PORT, "XR_ENAB", 0);
1249 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1251 spin_unlock_irqrestore(&port->lock, flags);
1254 static const char *icom_type(struct uart_port *port)
1256 return "icom";
1259 static void icom_release_port(struct uart_port *port)
1263 static int icom_request_port(struct uart_port *port)
1265 return 0;
1268 static void icom_config_port(struct uart_port *port, int flags)
1270 port->type = PORT_ICOM;
1273 static const struct uart_ops icom_ops = {
1274 .tx_empty = icom_tx_empty,
1275 .set_mctrl = icom_set_mctrl,
1276 .get_mctrl = icom_get_mctrl,
1277 .stop_tx = icom_stop_tx,
1278 .start_tx = icom_start_tx,
1279 .send_xchar = icom_send_xchar,
1280 .stop_rx = icom_stop_rx,
1281 .break_ctl = icom_break,
1282 .startup = icom_open,
1283 .shutdown = icom_close,
1284 .set_termios = icom_set_termios,
1285 .type = icom_type,
1286 .release_port = icom_release_port,
1287 .request_port = icom_request_port,
1288 .config_port = icom_config_port,
1291 #define ICOM_CONSOLE NULL
1293 static struct uart_driver icom_uart_driver = {
1294 .owner = THIS_MODULE,
1295 .driver_name = ICOM_DRIVER_NAME,
1296 .dev_name = "ttyA",
1297 .major = ICOM_MAJOR,
1298 .minor = ICOM_MINOR_START,
1299 .nr = NR_PORTS,
1300 .cons = ICOM_CONSOLE,
1303 static int icom_init_ports(struct icom_adapter *icom_adapter)
1305 u32 subsystem_id = icom_adapter->subsystem_id;
1306 int i;
1307 struct icom_port *icom_port;
1309 if (icom_adapter->version == ADAPTER_V1) {
1310 icom_adapter->numb_ports = 2;
1312 for (i = 0; i < 2; i++) {
1313 icom_port = &icom_adapter->port_info[i];
1314 icom_port->port = i;
1315 icom_port->status = ICOM_PORT_ACTIVE;
1316 icom_port->imbed_modem = ICOM_UNKNOWN;
1318 } else {
1319 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1320 icom_adapter->numb_ports = 4;
1322 for (i = 0; i < 4; i++) {
1323 icom_port = &icom_adapter->port_info[i];
1325 icom_port->port = i;
1326 icom_port->status = ICOM_PORT_ACTIVE;
1327 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1329 } else {
1330 icom_adapter->numb_ports = 4;
1332 icom_adapter->port_info[0].port = 0;
1333 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1335 if (subsystem_id ==
1336 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1337 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1338 } else {
1339 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1342 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1344 icom_adapter->port_info[2].port = 2;
1345 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1346 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1347 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1351 return 0;
1354 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1356 if (icom_adapter->version == ADAPTER_V1) {
1357 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1358 icom_port->int_reg = icom_adapter->base_addr +
1359 0x4004 + 2 - 2 * port_num;
1360 } else {
1361 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1362 if (icom_port->port < 2)
1363 icom_port->int_reg = icom_adapter->base_addr +
1364 0x8004 + 2 - 2 * icom_port->port;
1365 else
1366 icom_port->int_reg = icom_adapter->base_addr +
1367 0x8024 + 2 - 2 * (icom_port->port - 2);
1370 static int icom_load_ports(struct icom_adapter *icom_adapter)
1372 struct icom_port *icom_port;
1373 int port_num;
1375 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1377 icom_port = &icom_adapter->port_info[port_num];
1379 if (icom_port->status == ICOM_PORT_ACTIVE) {
1380 icom_port_active(icom_port, icom_adapter, port_num);
1381 icom_port->dram = icom_adapter->base_addr +
1382 0x2000 * icom_port->port;
1384 icom_port->adapter = icom_adapter;
1386 /* get port memory */
1387 if (get_port_memory(icom_port) != 0) {
1388 dev_err(&icom_port->adapter->pci_dev->dev,
1389 "Memory allocation for port FAILED\n");
1393 return 0;
1396 static int icom_alloc_adapter(struct icom_adapter
1397 **icom_adapter_ref)
1399 int adapter_count = 0;
1400 struct icom_adapter *icom_adapter;
1401 struct icom_adapter *cur_adapter_entry;
1402 struct list_head *tmp;
1404 icom_adapter = kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1406 if (!icom_adapter) {
1407 return -ENOMEM;
1410 list_for_each(tmp, &icom_adapter_head) {
1411 cur_adapter_entry =
1412 list_entry(tmp, struct icom_adapter,
1413 icom_adapter_entry);
1414 if (cur_adapter_entry->index != adapter_count) {
1415 break;
1417 adapter_count++;
1420 icom_adapter->index = adapter_count;
1421 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1423 *icom_adapter_ref = icom_adapter;
1424 return 0;
1427 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1429 list_del(&icom_adapter->icom_adapter_entry);
1430 kfree(icom_adapter);
1433 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1435 struct icom_port *icom_port;
1436 int index;
1438 for (index = 0; index < icom_adapter->numb_ports; index++) {
1439 icom_port = &icom_adapter->port_info[index];
1441 if (icom_port->status == ICOM_PORT_ACTIVE) {
1442 dev_info(&icom_adapter->pci_dev->dev,
1443 "Device removed\n");
1445 uart_remove_one_port(&icom_uart_driver,
1446 &icom_port->uart_port);
1448 /* be sure that DTR and RTS are dropped */
1449 writeb(0x00, &icom_port->dram->osr);
1451 /* Wait 0.1 Sec for simple Init to complete */
1452 msleep(100);
1454 /* Stop proccessor */
1455 stop_processor(icom_port);
1457 free_port_memory(icom_port);
1461 free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
1462 iounmap(icom_adapter->base_addr);
1463 pci_release_regions(icom_adapter->pci_dev);
1464 icom_free_adapter(icom_adapter);
1467 static void icom_kref_release(struct kref *kref)
1469 struct icom_adapter *icom_adapter;
1471 icom_adapter = to_icom_adapter(kref);
1472 icom_remove_adapter(icom_adapter);
1475 static int icom_probe(struct pci_dev *dev,
1476 const struct pci_device_id *ent)
1478 int index;
1479 unsigned int command_reg;
1480 int retval;
1481 struct icom_adapter *icom_adapter;
1482 struct icom_port *icom_port;
1484 retval = pci_enable_device(dev);
1485 if (retval) {
1486 dev_err(&dev->dev, "Device enable FAILED\n");
1487 return retval;
1490 retval = pci_request_regions(dev, "icom");
1491 if (retval) {
1492 dev_err(&dev->dev, "pci_request_regions FAILED\n");
1493 pci_disable_device(dev);
1494 return retval;
1497 pci_set_master(dev);
1499 retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg);
1500 if (retval) {
1501 dev_err(&dev->dev, "PCI Config read FAILED\n");
1502 return retval;
1505 pci_write_config_dword(dev, PCI_COMMAND,
1506 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1507 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1509 if (ent->driver_data == ADAPTER_V1) {
1510 pci_write_config_dword(dev, 0x44, 0x8300830A);
1511 } else {
1512 pci_write_config_dword(dev, 0x44, 0x42004200);
1513 pci_write_config_dword(dev, 0x48, 0x42004200);
1517 retval = icom_alloc_adapter(&icom_adapter);
1518 if (retval) {
1519 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1520 retval = -EIO;
1521 goto probe_exit0;
1524 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1525 icom_adapter->pci_dev = dev;
1526 icom_adapter->version = ent->driver_data;
1527 icom_adapter->subsystem_id = ent->subdevice;
1530 retval = icom_init_ports(icom_adapter);
1531 if (retval) {
1532 dev_err(&dev->dev, "Port configuration failed\n");
1533 goto probe_exit1;
1536 icom_adapter->base_addr = pci_ioremap_bar(dev, 0);
1538 if (!icom_adapter->base_addr) {
1539 retval = -ENOMEM;
1540 goto probe_exit1;
1543 /* save off irq and request irq line */
1544 retval = request_irq(dev->irq, icom_interrupt, IRQF_SHARED, ICOM_DRIVER_NAME, (void *)icom_adapter);
1545 if (retval) {
1546 goto probe_exit2;
1549 retval = icom_load_ports(icom_adapter);
1551 for (index = 0; index < icom_adapter->numb_ports; index++) {
1552 icom_port = &icom_adapter->port_info[index];
1554 if (icom_port->status == ICOM_PORT_ACTIVE) {
1555 icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
1556 icom_port->uart_port.type = PORT_ICOM;
1557 icom_port->uart_port.iotype = UPIO_MEM;
1558 icom_port->uart_port.membase =
1559 (unsigned char __iomem *)icom_adapter->base_addr_pci;
1560 icom_port->uart_port.fifosize = 16;
1561 icom_port->uart_port.ops = &icom_ops;
1562 icom_port->uart_port.line =
1563 icom_port->port + icom_adapter->index * 4;
1564 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1565 icom_port->status = ICOM_PORT_OFF;
1566 dev_err(&dev->dev, "Device add failed\n");
1567 } else
1568 dev_info(&dev->dev, "Device added\n");
1572 kref_init(&icom_adapter->kref);
1573 return 0;
1575 probe_exit2:
1576 iounmap(icom_adapter->base_addr);
1577 probe_exit1:
1578 icom_free_adapter(icom_adapter);
1580 probe_exit0:
1581 pci_release_regions(dev);
1582 pci_disable_device(dev);
1584 return retval;
1587 static void icom_remove(struct pci_dev *dev)
1589 struct icom_adapter *icom_adapter;
1590 struct list_head *tmp;
1592 list_for_each(tmp, &icom_adapter_head) {
1593 icom_adapter = list_entry(tmp, struct icom_adapter,
1594 icom_adapter_entry);
1595 if (icom_adapter->pci_dev == dev) {
1596 kref_put(&icom_adapter->kref, icom_kref_release);
1597 return;
1601 dev_err(&dev->dev, "Unable to find device to remove\n");
1604 static struct pci_driver icom_pci_driver = {
1605 .name = ICOM_DRIVER_NAME,
1606 .id_table = icom_pci_table,
1607 .probe = icom_probe,
1608 .remove = icom_remove,
1611 static int __init icom_init(void)
1613 int ret;
1615 spin_lock_init(&icom_lock);
1617 ret = uart_register_driver(&icom_uart_driver);
1618 if (ret)
1619 return ret;
1621 ret = pci_register_driver(&icom_pci_driver);
1623 if (ret < 0)
1624 uart_unregister_driver(&icom_uart_driver);
1626 return ret;
1629 static void __exit icom_exit(void)
1631 pci_unregister_driver(&icom_pci_driver);
1632 uart_unregister_driver(&icom_uart_driver);
1635 module_init(icom_init);
1636 module_exit(icom_exit);
1638 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1639 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1640 MODULE_SUPPORTED_DEVICE
1641 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1642 MODULE_LICENSE("GPL");
1643 MODULE_FIRMWARE("icom_call_setup.bin");
1644 MODULE_FIRMWARE("icom_res_dce.bin");
1645 MODULE_FIRMWARE("icom_asc.bin");