aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/icom.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/serial/icom.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/serial/icom.c')
-rw-r--r--drivers/serial/icom.c1691
1 files changed, 1691 insertions, 0 deletions
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
new file mode 100644
index 000000000000..546a0bc77e1e
--- /dev/null
+++ b/drivers/serial/icom.c
@@ -0,0 +1,1691 @@
1/*
2 * icom.c
3 *
4 * Copyright (C) 2001 IBM Corporation. All rights reserved.
5 *
6 * Serial device driver.
7 *
8 * Based on code from serial.c
9 *
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.
14 *
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.
19 *
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
23 *
24 */
25#define SERIAL_DO_RESTART
26#include <linux/module.h>
27#include <linux/config.h>
28#include <linux/version.h>
29#include <linux/kernel.h>
30#include <linux/errno.h>
31#include <linux/signal.h>
32#include <linux/sched.h>
33#include <linux/timer.h>
34#include <linux/interrupt.h>
35#include <linux/tty.h>
36#include <linux/termios.h>
37#include <linux/fs.h>
38#include <linux/tty_flip.h>
39#include <linux/serial.h>
40#include <linux/serial_reg.h>
41#include <linux/major.h>
42#include <linux/string.h>
43#include <linux/fcntl.h>
44#include <linux/ptrace.h>
45#include <linux/ioport.h>
46#include <linux/mm.h>
47#include <linux/slab.h>
48#include <linux/init.h>
49#include <linux/delay.h>
50#include <linux/pci.h>
51#include <linux/vmalloc.h>
52#include <linux/smp.h>
53#include <linux/smp_lock.h>
54#include <linux/spinlock.h>
55#include <linux/kobject.h>
56#include <linux/firmware.h>
57#include <linux/bitops.h>
58
59#include <asm/system.h>
60#include <asm/segment.h>
61#include <asm/io.h>
62#include <asm/irq.h>
63#include <asm/uaccess.h>
64
65#include "icom.h"
66
67/*#define ICOM_TRACE enable port trace capabilities */
68
69#define ICOM_DRIVER_NAME "icom"
70#define ICOM_VERSION_STR "1.3.1"
71#define NR_PORTS 128
72#define ICOM_PORT ((struct icom_port *)port)
73#define to_icom_adapter(d) container_of(d, struct icom_adapter, kobj)
74
75static const struct pci_device_id icom_pci_table[] = {
76 {
77 .vendor = PCI_VENDOR_ID_IBM,
78 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
79 .subvendor = PCI_ANY_ID,
80 .subdevice = PCI_ANY_ID,
81 .driver_data = ADAPTER_V1,
82 },
83 {
84 .vendor = PCI_VENDOR_ID_IBM,
85 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
86 .subvendor = PCI_VENDOR_ID_IBM,
87 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
88 .driver_data = ADAPTER_V2,
89 },
90 {
91 .vendor = PCI_VENDOR_ID_IBM,
92 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
93 .subvendor = PCI_VENDOR_ID_IBM,
94 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
95 .driver_data = ADAPTER_V2,
96 },
97 {
98 .vendor = PCI_VENDOR_ID_IBM,
99 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
100 .subvendor = PCI_VENDOR_ID_IBM,
101 .subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
102 .driver_data = ADAPTER_V2,
103 },
104 {}
105};
106
107struct lookup_proc_table start_proc[4] = {
108 {NULL, ICOM_CONTROL_START_A},
109 {NULL, ICOM_CONTROL_START_B},
110 {NULL, ICOM_CONTROL_START_C},
111 {NULL, ICOM_CONTROL_START_D}
112};
113
114
115struct lookup_proc_table stop_proc[4] = {
116 {NULL, ICOM_CONTROL_STOP_A},
117 {NULL, ICOM_CONTROL_STOP_B},
118 {NULL, ICOM_CONTROL_STOP_C},
119 {NULL, ICOM_CONTROL_STOP_D}
120};
121
122struct lookup_int_table int_mask_tbl[4] = {
123 {NULL, ICOM_INT_MASK_PRC_A},
124 {NULL, ICOM_INT_MASK_PRC_B},
125 {NULL, ICOM_INT_MASK_PRC_C},
126 {NULL, ICOM_INT_MASK_PRC_D},
127};
128
129
130MODULE_DEVICE_TABLE(pci, icom_pci_table);
131
132static LIST_HEAD(icom_adapter_head);
133
134/* spinlock for adapter initialization and changing adapter operations */
135static spinlock_t icom_lock;
136
137#ifdef ICOM_TRACE
138static inline void trace(struct icom_port *, char *, unsigned long) {};
139#else
140static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
141#endif
142
143static void free_port_memory(struct icom_port *icom_port)
144{
145 struct pci_dev *dev = icom_port->adapter->pci_dev;
146
147 trace(icom_port, "RET_PORT_MEM", 0);
148 if (icom_port->recv_buf) {
149 pci_free_consistent(dev, 4096, icom_port->recv_buf,
150 icom_port->recv_buf_pci);
151 icom_port->recv_buf = NULL;
152 }
153 if (icom_port->xmit_buf) {
154 pci_free_consistent(dev, 4096, icom_port->xmit_buf,
155 icom_port->xmit_buf_pci);
156 icom_port->xmit_buf = NULL;
157 }
158 if (icom_port->statStg) {
159 pci_free_consistent(dev, 4096, icom_port->statStg,
160 icom_port->statStg_pci);
161 icom_port->statStg = NULL;
162 }
163
164 if (icom_port->xmitRestart) {
165 pci_free_consistent(dev, 4096, icom_port->xmitRestart,
166 icom_port->xmitRestart_pci);
167 icom_port->xmitRestart = NULL;
168 }
169}
170
171static int __init get_port_memory(struct icom_port *icom_port)
172{
173 int index;
174 unsigned long stgAddr;
175 unsigned long startStgAddr;
176 unsigned long offset;
177 struct pci_dev *dev = icom_port->adapter->pci_dev;
178
179 icom_port->xmit_buf =
180 pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
181 if (!icom_port->xmit_buf) {
182 dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
183 return -ENOMEM;
184 }
185
186 trace(icom_port, "GET_PORT_MEM",
187 (unsigned long) icom_port->xmit_buf);
188
189 icom_port->recv_buf =
190 pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
191 if (!icom_port->recv_buf) {
192 dev_err(&dev->dev, "Can not allocate Receive buffer\n");
193 free_port_memory(icom_port);
194 return -ENOMEM;
195 }
196 trace(icom_port, "GET_PORT_MEM",
197 (unsigned long) icom_port->recv_buf);
198
199 icom_port->statStg =
200 pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
201 if (!icom_port->statStg) {
202 dev_err(&dev->dev, "Can not allocate Status buffer\n");
203 free_port_memory(icom_port);
204 return -ENOMEM;
205 }
206 trace(icom_port, "GET_PORT_MEM",
207 (unsigned long) icom_port->statStg);
208
209 icom_port->xmitRestart =
210 pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
211 if (!icom_port->xmitRestart) {
212 dev_err(&dev->dev,
213 "Can not allocate xmit Restart buffer\n");
214 free_port_memory(icom_port);
215 return -ENOMEM;
216 }
217
218 memset(icom_port->statStg, 0, 4096);
219
220 /* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
221 indicates that frames are to be transmitted
222 */
223
224 stgAddr = (unsigned long) icom_port->statStg;
225 for (index = 0; index < NUM_XBUFFS; index++) {
226 trace(icom_port, "FOD_ADDR", stgAddr);
227 stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
228 if (index < (NUM_XBUFFS - 1)) {
229 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
230 icom_port->statStg->xmit[index].leLengthASD =
231 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
232 trace(icom_port, "FOD_ADDR", stgAddr);
233 trace(icom_port, "FOD_XBUFF",
234 (unsigned long) icom_port->xmit_buf);
235 icom_port->statStg->xmit[index].leBuffer =
236 cpu_to_le32(icom_port->xmit_buf_pci);
237 } else if (index == (NUM_XBUFFS - 1)) {
238 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
239 icom_port->statStg->xmit[index].leLengthASD =
240 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
241 trace(icom_port, "FOD_XBUFF",
242 (unsigned long) icom_port->xmit_buf);
243 icom_port->statStg->xmit[index].leBuffer =
244 cpu_to_le32(icom_port->xmit_buf_pci);
245 } else {
246 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
247 }
248 }
249 /* FIDs */
250 startStgAddr = stgAddr;
251
252 /* fill in every entry, even if no buffer */
253 for (index = 0; index < NUM_RBUFFS; index++) {
254 trace(icom_port, "FID_ADDR", stgAddr);
255 stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
256 icom_port->statStg->rcv[index].leLength = 0;
257 icom_port->statStg->rcv[index].WorkingLength =
258 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
259 if (index < (NUM_RBUFFS - 1) ) {
260 offset = stgAddr - (unsigned long) icom_port->statStg;
261 icom_port->statStg->rcv[index].leNext =
262 cpu_to_le32(icom_port-> statStg_pci + offset);
263 trace(icom_port, "FID_RBUFF",
264 (unsigned long) icom_port->recv_buf);
265 icom_port->statStg->rcv[index].leBuffer =
266 cpu_to_le32(icom_port->recv_buf_pci);
267 } else if (index == (NUM_RBUFFS -1) ) {
268 offset = startStgAddr - (unsigned long) icom_port->statStg;
269 icom_port->statStg->rcv[index].leNext =
270 cpu_to_le32(icom_port-> statStg_pci + offset);
271 trace(icom_port, "FID_RBUFF",
272 (unsigned long) icom_port->recv_buf + 2048);
273 icom_port->statStg->rcv[index].leBuffer =
274 cpu_to_le32(icom_port->recv_buf_pci + 2048);
275 } else {
276 icom_port->statStg->rcv[index].leNext = 0;
277 icom_port->statStg->rcv[index].leBuffer = 0;
278 }
279 }
280
281 return 0;
282}
283
284static void stop_processor(struct icom_port *icom_port)
285{
286 unsigned long temp;
287 unsigned long flags;
288 int port;
289
290 spin_lock_irqsave(&icom_lock, flags);
291
292 port = icom_port->port;
293 if (port == 0 || port == 1)
294 stop_proc[port].global_control_reg = &icom_port->global_reg->control;
295 else
296 stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
297
298
299 if (port < 4) {
300 temp = readl(stop_proc[port].global_control_reg);
301 temp =
302 (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
303 writel(temp, stop_proc[port].global_control_reg);
304
305 /* write flush */
306 readl(stop_proc[port].global_control_reg);
307 } else {
308 dev_err(&icom_port->adapter->pci_dev->dev,
309 "Invalid port assignment\n");
310 }
311
312 spin_unlock_irqrestore(&icom_lock, flags);
313}
314
315static void start_processor(struct icom_port *icom_port)
316{
317 unsigned long temp;
318 unsigned long flags;
319 int port;
320
321 spin_lock_irqsave(&icom_lock, flags);
322
323 port = icom_port->port;
324 if (port == 0 || port == 1)
325 start_proc[port].global_control_reg = &icom_port->global_reg->control;
326 else
327 start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
328 if (port < 4) {
329 temp = readl(start_proc[port].global_control_reg);
330 temp =
331 (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
332 writel(temp, start_proc[port].global_control_reg);
333
334 /* write flush */
335 readl(start_proc[port].global_control_reg);
336 } else {
337 dev_err(&icom_port->adapter->pci_dev->dev,
338 "Invalid port assignment\n");
339 }
340
341 spin_unlock_irqrestore(&icom_lock, flags);
342}
343
344static void load_code(struct icom_port *icom_port)
345{
346 const struct firmware *fw;
347 char __iomem *iram_ptr;
348 int index;
349 int status = 0;
350 void __iomem *dram_ptr = icom_port->dram;
351 dma_addr_t temp_pci;
352 unsigned char *new_page = NULL;
353 unsigned char cable_id = NO_CABLE;
354 struct pci_dev *dev = icom_port->adapter->pci_dev;
355
356 /* Clear out any pending interrupts */
357 writew(0x3FFF, icom_port->int_reg);
358
359 trace(icom_port, "CLEAR_INTERRUPTS", 0);
360
361 /* Stop processor */
362 stop_processor(icom_port);
363
364 /* Zero out DRAM */
365 memset_io(dram_ptr, 0, 512);
366
367 /* Load Call Setup into Adapter */
368 if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
369 dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
370 status = -1;
371 goto load_code_exit;
372 }
373
374 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
375 dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
376 release_firmware(fw);
377 status = -1;
378 goto load_code_exit;
379 }
380
381 iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
382 for (index = 0; index < fw->size; index++)
383 writeb(fw->data[index], &iram_ptr[index]);
384
385 release_firmware(fw);
386
387 /* Load Resident DCE portion of Adapter */
388 if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
389 dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
390 status = -1;
391 goto load_code_exit;
392 }
393
394 if (fw->size > ICOM_IRAM_SIZE) {
395 dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
396 release_firmware(fw);
397 status = -1;
398 goto load_code_exit;
399 }
400
401 iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
402 for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
403 writeb(fw->data[index], &iram_ptr[index]);
404
405 release_firmware(fw);
406
407 /* Set Hardware level */
408 if ((icom_port->adapter->version | ADAPTER_V2) == ADAPTER_V2)
409 writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));
410
411 /* Start the processor in Adapter */
412 start_processor(icom_port);
413
414 writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
415 &(icom_port->dram->HDLCConfigReg));
416 writeb(0x04, &(icom_port->dram->FlagFillIdleTimer)); /* 0.5 seconds */
417 writeb(0x00, &(icom_port->dram->CmdReg));
418 writeb(0x10, &(icom_port->dram->async_config3));
419 writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
420 ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));
421
422 /*Set up data in icom DRAM to indicate where personality
423 *code is located and its length.
424 */
425 new_page = pci_alloc_consistent(dev, 4096, &temp_pci);
426
427 if (!new_page) {
428 dev_err(&dev->dev, "Can not allocate DMA buffer\n");
429 status = -1;
430 goto load_code_exit;
431 }
432
433 if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
434 dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
435 status = -1;
436 goto load_code_exit;
437 }
438
439 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
440 dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
441 release_firmware(fw);
442 status = -1;
443 goto load_code_exit;
444 }
445
446 for (index = 0; index < fw->size; index++)
447 new_page[index] = fw->data[index];
448
449 release_firmware(fw);
450
451 writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
452 writel(temp_pci, &icom_port->dram->mac_load_addr);
453
454 /*Setting the syncReg to 0x80 causes adapter to start downloading
455 the personality code into adapter instruction RAM.
456 Once code is loaded, it will begin executing and, based on
457 information provided above, will start DMAing data from
458 shared memory to adapter DRAM.
459 */
460 /* the wait loop below verifies this write operation has been done
461 and processed
462 */
463 writeb(START_DOWNLOAD, &icom_port->dram->sync);
464
465 /* Wait max 1 Sec for data download and processor to start */
466 for (index = 0; index < 10; index++) {
467 msleep(100);
468 if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
469 break;
470 }
471
472 if (index == 10)
473 status = -1;
474
475 /*
476 * check Cable ID
477 */
478 cable_id = readb(&icom_port->dram->cable_id);
479
480 if (cable_id & ICOM_CABLE_ID_VALID) {
481 /* Get cable ID into the lower 4 bits (standard form) */
482 cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
483 icom_port->cable_id = cable_id;
484 } else {
485 dev_err(&dev->dev,"Invalid or no cable attached\n");
486 icom_port->cable_id = NO_CABLE;
487 }
488
489 load_code_exit:
490
491 if (status != 0) {
492 /* Clear out any pending interrupts */
493 writew(0x3FFF, icom_port->int_reg);
494
495 /* Turn off port */
496 writeb(ICOM_DISABLE, &(icom_port->dram->disable));
497
498 /* Stop processor */
499 stop_processor(icom_port);
500
501 dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
502 }
503
504 if (new_page != NULL)
505 pci_free_consistent(dev, 4096, new_page, temp_pci);
506}
507
508static int startup(struct icom_port *icom_port)
509{
510 unsigned long temp;
511 unsigned char cable_id, raw_cable_id;
512 unsigned long flags;
513 int port;
514
515 trace(icom_port, "STARTUP", 0);
516
517 if (!icom_port->dram) {
518 /* should NEVER be NULL */
519 dev_err(&icom_port->adapter->pci_dev->dev,
520 "Unusable Port, port configuration missing\n");
521 return -ENODEV;
522 }
523
524 /*
525 * check Cable ID
526 */
527 raw_cable_id = readb(&icom_port->dram->cable_id);
528 trace(icom_port, "CABLE_ID", raw_cable_id);
529
530 /* Get cable ID into the lower 4 bits (standard form) */
531 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
532
533 /* Check for valid Cable ID */
534 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
535 (cable_id != icom_port->cable_id)) {
536
537 /* reload adapter code, pick up any potential changes in cable id */
538 load_code(icom_port);
539
540 /* still no sign of cable, error out */
541 raw_cable_id = readb(&icom_port->dram->cable_id);
542 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
543 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
544 (icom_port->cable_id == NO_CABLE))
545 return -EIO;
546 }
547
548 /*
549 * Finally, clear and enable interrupts
550 */
551 spin_lock_irqsave(&icom_lock, flags);
552 port = icom_port->port;
553 if (port == 0 || port == 1)
554 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
555 else
556 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
557
558 if (port == 0 || port == 2)
559 writew(0x00FF, icom_port->int_reg);
560 else
561 writew(0x3F00, icom_port->int_reg);
562 if (port < 4) {
563 temp = readl(int_mask_tbl[port].global_int_mask);
564 writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
565
566 /* write flush */
567 readl(int_mask_tbl[port].global_int_mask);
568 } else {
569 dev_err(&icom_port->adapter->pci_dev->dev,
570 "Invalid port assignment\n");
571 }
572
573 spin_unlock_irqrestore(&icom_lock, flags);
574 return 0;
575}
576
577static void shutdown(struct icom_port *icom_port)
578{
579 unsigned long temp;
580 unsigned char cmdReg;
581 unsigned long flags;
582 int port;
583
584 spin_lock_irqsave(&icom_lock, flags);
585 trace(icom_port, "SHUTDOWN", 0);
586
587 /*
588 * disable all interrupts
589 */
590 port = icom_port->port;
591 if (port == 0 || port == 1)
592 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
593 else
594 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
595
596 if (port < 4) {
597 temp = readl(int_mask_tbl[port].global_int_mask);
598 writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
599
600 /* write flush */
601 readl(int_mask_tbl[port].global_int_mask);
602 } else {
603 dev_err(&icom_port->adapter->pci_dev->dev,
604 "Invalid port assignment\n");
605 }
606 spin_unlock_irqrestore(&icom_lock, flags);
607
608 /*
609 * disable break condition
610 */
611 cmdReg = readb(&icom_port->dram->CmdReg);
612 if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) {
613 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
614 }
615}
616
617static int icom_write(struct uart_port *port)
618{
619 unsigned long data_count;
620 unsigned char cmdReg;
621 unsigned long offset;
622 int temp_tail = port->info->xmit.tail;
623
624 trace(ICOM_PORT, "WRITE", 0);
625
626 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
627 SA_FLAGS_READY_TO_XMIT) {
628 trace(ICOM_PORT, "WRITE_FULL", 0);
629 return 0;
630 }
631
632 data_count = 0;
633 while ((port->info->xmit.head != temp_tail) &&
634 (data_count <= XMIT_BUFF_SZ)) {
635
636 ICOM_PORT->xmit_buf[data_count++] =
637 port->info->xmit.buf[temp_tail];
638
639 temp_tail++;
640 temp_tail &= (UART_XMIT_SIZE - 1);
641 }
642
643 if (data_count) {
644 ICOM_PORT->statStg->xmit[0].flags =
645 cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
646 ICOM_PORT->statStg->xmit[0].leLength =
647 cpu_to_le16(data_count);
648 offset =
649 (unsigned long) &ICOM_PORT->statStg->xmit[0] -
650 (unsigned long) ICOM_PORT->statStg;
651 *ICOM_PORT->xmitRestart =
652 cpu_to_le32(ICOM_PORT->statStg_pci + offset);
653 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
654 writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
655 &ICOM_PORT->dram->CmdReg);
656 writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
657 trace(ICOM_PORT, "WRITE_START", data_count);
658 /* write flush */
659 readb(&ICOM_PORT->dram->StartXmitCmd);
660 }
661
662 return data_count;
663}
664
665static inline void check_modem_status(struct icom_port *icom_port)
666{
667 static char old_status = 0;
668 char delta_status;
669 unsigned char status;
670
671 spin_lock(&icom_port->uart_port.lock);
672
673 /*modem input register */
674 status = readb(&icom_port->dram->isr);
675 trace(icom_port, "CHECK_MODEM", status);
676 delta_status = status ^ old_status;
677 if (delta_status) {
678 if (delta_status & ICOM_RI)
679 icom_port->uart_port.icount.rng++;
680 if (delta_status & ICOM_DSR)
681 icom_port->uart_port.icount.dsr++;
682 if (delta_status & ICOM_DCD)
683 uart_handle_dcd_change(&icom_port->uart_port,
684 delta_status & ICOM_DCD);
685 if (delta_status & ICOM_CTS)
686 uart_handle_cts_change(&icom_port->uart_port,
687 delta_status & ICOM_CTS);
688
689 wake_up_interruptible(&icom_port->uart_port.info->
690 delta_msr_wait);
691 old_status = status;
692 }
693 spin_unlock(&icom_port->uart_port.lock);
694}
695
696static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
697{
698 unsigned short int count;
699 int i;
700
701 if (port_int_reg & (INT_XMIT_COMPLETED)) {
702 trace(icom_port, "XMIT_COMPLETE", 0);
703
704 /* clear buffer in use bit */
705 icom_port->statStg->xmit[0].flags &=
706 cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
707
708 count = (unsigned short int)
709 cpu_to_le16(icom_port->statStg->xmit[0].leLength);
710 icom_port->uart_port.icount.tx += count;
711
712 for (i=0; i<count &&
713 !uart_circ_empty(&icom_port->uart_port.info->xmit); i++) {
714
715 icom_port->uart_port.info->xmit.tail++;
716 icom_port->uart_port.info->xmit.tail &=
717 (UART_XMIT_SIZE - 1);
718 }
719
720 if (!icom_write(&icom_port->uart_port))
721 /* activate write queue */
722 uart_write_wakeup(&icom_port->uart_port);
723 } else
724 trace(icom_port, "XMIT_DISABLED", 0);
725}
726
727static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
728{
729 short int count, rcv_buff;
730 struct tty_struct *tty = icom_port->uart_port.info->tty;
731 unsigned short int status;
732 struct uart_icount *icount;
733 unsigned long offset;
734
735 trace(icom_port, "RCV_COMPLETE", 0);
736 rcv_buff = icom_port->next_rcv;
737
738 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
739 while (status & SA_FL_RCV_DONE) {
740
741 trace(icom_port, "FID_STATUS", status);
742 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
743
744 trace(icom_port, "RCV_COUNT", count);
745 if (count > (TTY_FLIPBUF_SIZE - tty->flip.count))
746 count = TTY_FLIPBUF_SIZE - tty->flip.count;
747
748 trace(icom_port, "REAL_COUNT", count);
749
750 offset =
751 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
752 icom_port->recv_buf_pci;
753
754 memcpy(tty->flip.char_buf_ptr,(unsigned char *)
755 ((unsigned long)icom_port->recv_buf + offset), count);
756
757 if (count > 0) {
758 tty->flip.count += count - 1;
759 tty->flip.char_buf_ptr += count - 1;
760
761 memset(tty->flip.flag_buf_ptr, 0, count);
762 tty->flip.flag_buf_ptr += count - 1;
763 }
764
765 icount = &icom_port->uart_port.icount;
766 icount->rx += count;
767
768 /* Break detect logic */
769 if ((status & SA_FLAGS_FRAME_ERROR)
770 && (tty->flip.char_buf_ptr[0] == 0x00)) {
771 status &= ~SA_FLAGS_FRAME_ERROR;
772 status |= SA_FLAGS_BREAK_DET;
773 trace(icom_port, "BREAK_DET", 0);
774 }
775
776 if (status &
777 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
778 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
779
780 if (status & SA_FLAGS_BREAK_DET)
781 icount->brk++;
782 if (status & SA_FLAGS_PARITY_ERROR)
783 icount->parity++;
784 if (status & SA_FLAGS_FRAME_ERROR)
785 icount->frame++;
786 if (status & SA_FLAGS_OVERRUN)
787 icount->overrun++;
788
789 /*
790 * Now check to see if character should be
791 * ignored, and mask off conditions which
792 * should be ignored.
793 */
794 if (status & icom_port->ignore_status_mask) {
795 trace(icom_port, "IGNORE_CHAR", 0);
796 goto ignore_char;
797 }
798
799 status &= icom_port->read_status_mask;
800
801 if (status & SA_FLAGS_BREAK_DET) {
802 *tty->flip.flag_buf_ptr = TTY_BREAK;
803 } else if (status & SA_FLAGS_PARITY_ERROR) {
804 trace(icom_port, "PARITY_ERROR", 0);
805 *tty->flip.flag_buf_ptr = TTY_PARITY;
806 } else if (status & SA_FLAGS_FRAME_ERROR)
807 *tty->flip.flag_buf_ptr = TTY_FRAME;
808
809 if (status & SA_FLAGS_OVERRUN) {
810 /*
811 * Overrun is special, since it's
812 * reported immediately, and doesn't
813 * affect the current character
814 */
815 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
816 tty->flip.count++;
817 tty->flip.flag_buf_ptr++;
818 tty->flip.char_buf_ptr++;
819 *tty->flip.flag_buf_ptr = TTY_OVERRUN;
820 }
821 }
822 }
823
824 tty->flip.flag_buf_ptr++;
825 tty->flip.char_buf_ptr++;
826 tty->flip.count++;
827 ignore_char:
828 icom_port->statStg->rcv[rcv_buff].flags = 0;
829 icom_port->statStg->rcv[rcv_buff].leLength = 0;
830 icom_port->statStg->rcv[rcv_buff].WorkingLength =
831 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
832
833 rcv_buff++;
834 if (rcv_buff == NUM_RBUFFS)
835 rcv_buff = 0;
836
837 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
838 }
839 icom_port->next_rcv = rcv_buff;
840 tty_flip_buffer_push(tty);
841}
842
843static void process_interrupt(u16 port_int_reg,
844 struct icom_port *icom_port)
845{
846
847 spin_lock(&icom_port->uart_port.lock);
848 trace(icom_port, "INTERRUPT", port_int_reg);
849
850 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
851 xmit_interrupt(port_int_reg, icom_port);
852
853 if (port_int_reg & INT_RCV_COMPLETED)
854 recv_interrupt(port_int_reg, icom_port);
855
856 spin_unlock(&icom_port->uart_port.lock);
857}
858
859static irqreturn_t icom_interrupt(int irq, void *dev_id,
860 struct pt_regs *regs)
861{
862 void __iomem * int_reg;
863 u32 adapter_interrupts;
864 u16 port_int_reg;
865 struct icom_adapter *icom_adapter;
866 struct icom_port *icom_port;
867
868 /* find icom_port for this interrupt */
869 icom_adapter = (struct icom_adapter *) dev_id;
870
871 if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
872 int_reg = icom_adapter->base_addr + 0x8024;
873
874 adapter_interrupts = readl(int_reg);
875
876 if (adapter_interrupts & 0x00003FFF) {
877 /* port 2 interrupt, NOTE: for all ADAPTER_V2, port 2 will be active */
878 icom_port = &icom_adapter->port_info[2];
879 port_int_reg = (u16) adapter_interrupts;
880 process_interrupt(port_int_reg, icom_port);
881 check_modem_status(icom_port);
882 }
883 if (adapter_interrupts & 0x3FFF0000) {
884 /* port 3 interrupt */
885 icom_port = &icom_adapter->port_info[3];
886 if (icom_port->status == ICOM_PORT_ACTIVE) {
887 port_int_reg =
888 (u16) (adapter_interrupts >> 16);
889 process_interrupt(port_int_reg, icom_port);
890 check_modem_status(icom_port);
891 }
892 }
893
894 /* Clear out any pending interrupts */
895 writel(adapter_interrupts, int_reg);
896
897 int_reg = icom_adapter->base_addr + 0x8004;
898 } else {
899 int_reg = icom_adapter->base_addr + 0x4004;
900 }
901
902 adapter_interrupts = readl(int_reg);
903
904 if (adapter_interrupts & 0x00003FFF) {
905 /* port 0 interrupt, NOTE: for all adapters, port 0 will be active */
906 icom_port = &icom_adapter->port_info[0];
907 port_int_reg = (u16) adapter_interrupts;
908 process_interrupt(port_int_reg, icom_port);
909 check_modem_status(icom_port);
910 }
911 if (adapter_interrupts & 0x3FFF0000) {
912 /* port 1 interrupt */
913 icom_port = &icom_adapter->port_info[1];
914 if (icom_port->status == ICOM_PORT_ACTIVE) {
915 port_int_reg = (u16) (adapter_interrupts >> 16);
916 process_interrupt(port_int_reg, icom_port);
917 check_modem_status(icom_port);
918 }
919 }
920
921 /* Clear out any pending interrupts */
922 writel(adapter_interrupts, int_reg);
923
924 /* flush the write */
925 adapter_interrupts = readl(int_reg);
926
927 return IRQ_HANDLED;
928}
929
930/*
931 * ------------------------------------------------------------------
932 * Begin serial-core API
933 * ------------------------------------------------------------------
934 */
935static unsigned int icom_tx_empty(struct uart_port *port)
936{
937 int ret;
938 unsigned long flags;
939
940 spin_lock_irqsave(&port->lock, flags);
941 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
942 SA_FLAGS_READY_TO_XMIT)
943 ret = TIOCSER_TEMT;
944 else
945 ret = 0;
946
947 spin_unlock_irqrestore(&port->lock, flags);
948 return ret;
949}
950
951static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
952{
953 unsigned char local_osr;
954
955 trace(ICOM_PORT, "SET_MODEM", 0);
956 local_osr = readb(&ICOM_PORT->dram->osr);
957
958 if (mctrl & TIOCM_RTS) {
959 trace(ICOM_PORT, "RAISE_RTS", 0);
960 local_osr |= ICOM_RTS;
961 } else {
962 trace(ICOM_PORT, "LOWER_RTS", 0);
963 local_osr &= ~ICOM_RTS;
964 }
965
966 if (mctrl & TIOCM_DTR) {
967 trace(ICOM_PORT, "RAISE_DTR", 0);
968 local_osr |= ICOM_DTR;
969 } else {
970 trace(ICOM_PORT, "LOWER_DTR", 0);
971 local_osr &= ~ICOM_DTR;
972 }
973
974 writeb(local_osr, &ICOM_PORT->dram->osr);
975}
976
977static unsigned int icom_get_mctrl(struct uart_port *port)
978{
979 unsigned char status;
980 unsigned int result;
981
982 trace(ICOM_PORT, "GET_MODEM", 0);
983
984 status = readb(&ICOM_PORT->dram->isr);
985
986 result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
987 | ((status & ICOM_RI) ? TIOCM_RNG : 0)
988 | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
989 | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
990 return result;
991}
992
993static void icom_stop_tx(struct uart_port *port, unsigned int tty_stop)
994{
995 unsigned char cmdReg;
996
997 if (tty_stop) {
998 trace(ICOM_PORT, "STOP", 0);
999 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1000 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
1001 }
1002}
1003
1004static void icom_start_tx(struct uart_port *port, unsigned int tty_start)
1005{
1006 unsigned char cmdReg;
1007
1008 trace(ICOM_PORT, "START", 0);
1009 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1010 if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
1011 writeb(cmdReg & ~CMD_HOLD_XMIT,
1012 &ICOM_PORT->dram->CmdReg);
1013
1014 icom_write(port);
1015}
1016
1017static void icom_send_xchar(struct uart_port *port, char ch)
1018{
1019 unsigned char xdata;
1020 int index;
1021 unsigned long flags;
1022
1023 trace(ICOM_PORT, "SEND_XCHAR", ch);
1024
1025 /* wait .1 sec to send char */
1026 for (index = 0; index < 10; index++) {
1027 spin_lock_irqsave(&port->lock, flags);
1028 xdata = readb(&ICOM_PORT->dram->xchar);
1029 if (xdata == 0x00) {
1030 trace(ICOM_PORT, "QUICK_WRITE", 0);
1031 writeb(ch, &ICOM_PORT->dram->xchar);
1032
1033 /* flush write operation */
1034 xdata = readb(&ICOM_PORT->dram->xchar);
1035 spin_unlock_irqrestore(&port->lock, flags);
1036 break;
1037 }
1038 spin_unlock_irqrestore(&port->lock, flags);
1039 msleep(10);
1040 }
1041}
1042
1043static void icom_stop_rx(struct uart_port *port)
1044{
1045 unsigned char cmdReg;
1046
1047 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1048 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1049}
1050
1051static void icom_enable_ms(struct uart_port *port)
1052{
1053 /* no-op */
1054}
1055
1056static void icom_break(struct uart_port *port, int break_state)
1057{
1058 unsigned char cmdReg;
1059 unsigned long flags;
1060
1061 spin_lock_irqsave(&port->lock, flags);
1062 trace(ICOM_PORT, "BREAK", 0);
1063 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1064 if (break_state == -1) {
1065 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1066 } else {
1067 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1068 }
1069 spin_unlock_irqrestore(&port->lock, flags);
1070}
1071
1072static int icom_open(struct uart_port *port)
1073{
1074 int retval;
1075
1076 kobject_get(&ICOM_PORT->adapter->kobj);
1077 retval = startup(ICOM_PORT);
1078
1079 if (retval) {
1080 kobject_put(&ICOM_PORT->adapter->kobj);
1081 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1082 return retval;
1083 }
1084
1085 return 0;
1086}
1087
1088static void icom_close(struct uart_port *port)
1089{
1090 unsigned char cmdReg;
1091
1092 trace(ICOM_PORT, "CLOSE", 0);
1093
1094 /* stop receiver */
1095 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1096 writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1097 &ICOM_PORT->dram->CmdReg);
1098
1099 shutdown(ICOM_PORT);
1100
1101 kobject_put(&ICOM_PORT->adapter->kobj);
1102}
1103
1104static void icom_set_termios(struct uart_port *port,
1105 struct termios *termios,
1106 struct termios *old_termios)
1107{
1108 int baud;
1109 unsigned cflag, iflag;
1110 int bits;
1111 char new_config2;
1112 char new_config3 = 0;
1113 char tmp_byte;
1114 int index;
1115 int rcv_buff, xmit_buff;
1116 unsigned long offset;
1117 unsigned long flags;
1118
1119 spin_lock_irqsave(&port->lock, flags);
1120 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1121
1122 cflag = termios->c_cflag;
1123 iflag = termios->c_iflag;
1124
1125 new_config2 = ICOM_ACFG_DRIVE1;
1126
1127 /* byte size and parity */
1128 switch (cflag & CSIZE) {
1129 case CS5: /* 5 bits/char */
1130 new_config2 |= ICOM_ACFG_5BPC;
1131 bits = 7;
1132 break;
1133 case CS6: /* 6 bits/char */
1134 new_config2 |= ICOM_ACFG_6BPC;
1135 bits = 8;
1136 break;
1137 case CS7: /* 7 bits/char */
1138 new_config2 |= ICOM_ACFG_7BPC;
1139 bits = 9;
1140 break;
1141 case CS8: /* 8 bits/char */
1142 new_config2 |= ICOM_ACFG_8BPC;
1143 bits = 10;
1144 break;
1145 default:
1146 bits = 10;
1147 break;
1148 }
1149 if (cflag & CSTOPB) {
1150 /* 2 stop bits */
1151 new_config2 |= ICOM_ACFG_2STOP_BIT;
1152 bits++;
1153 }
1154 if (cflag & PARENB) {
1155 /* parity bit enabled */
1156 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1157 trace(ICOM_PORT, "PARENB", 0);
1158 bits++;
1159 }
1160 if (cflag & PARODD) {
1161 /* odd parity */
1162 new_config2 |= ICOM_ACFG_PARITY_ODD;
1163 trace(ICOM_PORT, "PARODD", 0);
1164 }
1165
1166 /* Determine divisor based on baud rate */
1167 baud = uart_get_baud_rate(port, termios, old_termios,
1168 icom_acfg_baud[0],
1169 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1170 if (!baud)
1171 baud = 9600; /* B0 transition handled in rs_set_termios */
1172
1173 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1174 if (icom_acfg_baud[index] == baud) {
1175 new_config3 = index;
1176 break;
1177 }
1178 }
1179
1180 uart_update_timeout(port, cflag, baud);
1181
1182 /* CTS flow control flag and modem status interrupts */
1183 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1184 if (cflag & CRTSCTS)
1185 tmp_byte |= HDLC_HDW_FLOW;
1186 else
1187 tmp_byte &= ~HDLC_HDW_FLOW;
1188 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1189
1190 /*
1191 * Set up parity check flag
1192 */
1193 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1194 if (iflag & INPCK)
1195 ICOM_PORT->read_status_mask |=
1196 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1197
1198 if ((iflag & BRKINT) || (iflag & PARMRK))
1199 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1200
1201 /*
1202 * Characters to ignore
1203 */
1204 ICOM_PORT->ignore_status_mask = 0;
1205 if (iflag & IGNPAR)
1206 ICOM_PORT->ignore_status_mask |=
1207 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1208 if (iflag & IGNBRK) {
1209 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1210 /*
1211 * If we're ignore parity and break indicators, ignore
1212 * overruns too. (For real raw support).
1213 */
1214 if (iflag & IGNPAR)
1215 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1216 }
1217
1218 /*
1219 * !!! ignore all characters if CREAD is not set
1220 */
1221 if ((cflag & CREAD) == 0)
1222 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1223
1224 /* Turn off Receiver to prepare for reset */
1225 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1226
1227 for (index = 0; index < 10; index++) {
1228 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1229 break;
1230 }
1231 }
1232
1233 /* clear all current buffers of data */
1234 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1235 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1236 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1237 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1238 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1239 }
1240
1241 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1242 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1243 }
1244
1245 /* activate changes and start xmit and receiver here */
1246 /* Enable the receiver */
1247 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1248 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1249 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1250 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1251 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1252 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer)); /* 0.5 seconds */
1253 writeb(0xFF, &(ICOM_PORT->dram->ier)); /* enable modem signal interrupts */
1254
1255 /* reset processor */
1256 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1257
1258 for (index = 0; index < 10; index++) {
1259 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1260 break;
1261 }
1262 }
1263
1264 /* Enable Transmitter and Reciever */
1265 offset =
1266 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1267 (unsigned long) ICOM_PORT->statStg;
1268 writel(ICOM_PORT->statStg_pci + offset,
1269 &ICOM_PORT->dram->RcvStatusAddr);
1270 ICOM_PORT->next_rcv = 0;
1271 ICOM_PORT->put_length = 0;
1272 *ICOM_PORT->xmitRestart = 0;
1273 writel(ICOM_PORT->xmitRestart_pci,
1274 &ICOM_PORT->dram->XmitStatusAddr);
1275 trace(ICOM_PORT, "XR_ENAB", 0);
1276 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1277
1278 spin_unlock_irqrestore(&port->lock, flags);
1279}
1280
1281static const char *icom_type(struct uart_port *port)
1282{
1283 return "icom";
1284}
1285
1286static void icom_release_port(struct uart_port *port)
1287{
1288}
1289
1290static int icom_request_port(struct uart_port *port)
1291{
1292 return 0;
1293}
1294
1295static void icom_config_port(struct uart_port *port, int flags)
1296{
1297 port->type = PORT_ICOM;
1298}
1299
1300static struct uart_ops icom_ops = {
1301 .tx_empty = icom_tx_empty,
1302 .set_mctrl = icom_set_mctrl,
1303 .get_mctrl = icom_get_mctrl,
1304 .stop_tx = icom_stop_tx,
1305 .start_tx = icom_start_tx,
1306 .send_xchar = icom_send_xchar,
1307 .stop_rx = icom_stop_rx,
1308 .enable_ms = icom_enable_ms,
1309 .break_ctl = icom_break,
1310 .startup = icom_open,
1311 .shutdown = icom_close,
1312 .set_termios = icom_set_termios,
1313 .type = icom_type,
1314 .release_port = icom_release_port,
1315 .request_port = icom_request_port,
1316 .config_port = icom_config_port,
1317};
1318
1319#define ICOM_CONSOLE NULL
1320
1321static struct uart_driver icom_uart_driver = {
1322 .owner = THIS_MODULE,
1323 .driver_name = ICOM_DRIVER_NAME,
1324 .dev_name = "ttyA",
1325 .major = ICOM_MAJOR,
1326 .minor = ICOM_MINOR_START,
1327 .nr = NR_PORTS,
1328 .cons = ICOM_CONSOLE,
1329};
1330
1331static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1332{
1333 u32 subsystem_id = icom_adapter->subsystem_id;
1334 int retval = 0;
1335 int i;
1336 struct icom_port *icom_port;
1337
1338 if (icom_adapter->version == ADAPTER_V1) {
1339 icom_adapter->numb_ports = 2;
1340
1341 for (i = 0; i < 2; i++) {
1342 icom_port = &icom_adapter->port_info[i];
1343 icom_port->port = i;
1344 icom_port->status = ICOM_PORT_ACTIVE;
1345 icom_port->imbed_modem = ICOM_UNKNOWN;
1346 }
1347 } else {
1348 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1349 icom_adapter->numb_ports = 4;
1350
1351 for (i = 0; i < 4; i++) {
1352 icom_port = &icom_adapter->port_info[i];
1353
1354 icom_port->port = i;
1355 icom_port->status = ICOM_PORT_ACTIVE;
1356 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1357 }
1358 } else {
1359 icom_adapter->numb_ports = 4;
1360
1361 icom_adapter->port_info[0].port = 0;
1362 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1363
1364 if (subsystem_id ==
1365 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1366 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1367 } else {
1368 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1369 }
1370
1371 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1372
1373 icom_adapter->port_info[2].port = 2;
1374 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1375 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1376 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1377 }
1378 }
1379
1380 return retval;
1381}
1382
1383static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1384{
1385 if (icom_adapter->version == ADAPTER_V1) {
1386 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1387 icom_port->int_reg = icom_adapter->base_addr +
1388 0x4004 + 2 - 2 * port_num;
1389 } else {
1390 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1391 if (icom_port->port < 2)
1392 icom_port->int_reg = icom_adapter->base_addr +
1393 0x8004 + 2 - 2 * icom_port->port;
1394 else
1395 icom_port->int_reg = icom_adapter->base_addr +
1396 0x8024 + 2 - 2 * (icom_port->port - 2);
1397 }
1398}
1399static int __init icom_load_ports(struct icom_adapter *icom_adapter)
1400{
1401 struct icom_port *icom_port;
1402 int port_num;
1403 int retval;
1404
1405 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1406
1407 icom_port = &icom_adapter->port_info[port_num];
1408
1409 if (icom_port->status == ICOM_PORT_ACTIVE) {
1410 icom_port_active(icom_port, icom_adapter, port_num);
1411 icom_port->dram = icom_adapter->base_addr +
1412 0x2000 * icom_port->port;
1413
1414 icom_port->adapter = icom_adapter;
1415
1416 /* get port memory */
1417 if ((retval = get_port_memory(icom_port)) != 0) {
1418 dev_err(&icom_port->adapter->pci_dev->dev,
1419 "Memory allocation for port FAILED\n");
1420 }
1421 }
1422 }
1423 return 0;
1424}
1425
1426static int __devinit icom_alloc_adapter(struct icom_adapter
1427 **icom_adapter_ref)
1428{
1429 int adapter_count = 0;
1430 struct icom_adapter *icom_adapter;
1431 struct icom_adapter *cur_adapter_entry;
1432 struct list_head *tmp;
1433
1434 icom_adapter = (struct icom_adapter *)
1435 kmalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1436
1437 if (!icom_adapter) {
1438 return -ENOMEM;
1439 }
1440
1441 memset(icom_adapter, 0, sizeof(struct icom_adapter));
1442
1443 list_for_each(tmp, &icom_adapter_head) {
1444 cur_adapter_entry =
1445 list_entry(tmp, struct icom_adapter,
1446 icom_adapter_entry);
1447 if (cur_adapter_entry->index != adapter_count) {
1448 break;
1449 }
1450 adapter_count++;
1451 }
1452
1453 icom_adapter->index = adapter_count;
1454 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1455
1456 *icom_adapter_ref = icom_adapter;
1457 return 0;
1458}
1459
1460static void icom_free_adapter(struct icom_adapter *icom_adapter)
1461{
1462 list_del(&icom_adapter->icom_adapter_entry);
1463 kfree(icom_adapter);
1464}
1465
1466static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1467{
1468 struct icom_port *icom_port;
1469 int index;
1470
1471 for (index = 0; index < icom_adapter->numb_ports; index++) {
1472 icom_port = &icom_adapter->port_info[index];
1473
1474 if (icom_port->status == ICOM_PORT_ACTIVE) {
1475 dev_info(&icom_adapter->pci_dev->dev,
1476 "Device removed\n");
1477
1478 uart_remove_one_port(&icom_uart_driver,
1479 &icom_port->uart_port);
1480
1481 /* be sure that DTR and RTS are dropped */
1482 writeb(0x00, &icom_port->dram->osr);
1483
1484 /* Wait 0.1 Sec for simple Init to complete */
1485 msleep(100);
1486
1487 /* Stop proccessor */
1488 stop_processor(icom_port);
1489
1490 free_port_memory(icom_port);
1491 }
1492 }
1493
1494 free_irq(icom_adapter->irq_number, (void *) icom_adapter);
1495 iounmap(icom_adapter->base_addr);
1496 icom_free_adapter(icom_adapter);
1497 pci_release_regions(icom_adapter->pci_dev);
1498}
1499
1500static void icom_kobj_release(struct kobject *kobj)
1501{
1502 struct icom_adapter *icom_adapter;
1503
1504 icom_adapter = to_icom_adapter(kobj);
1505 icom_remove_adapter(icom_adapter);
1506}
1507
1508static struct kobj_type icom_kobj_type = {
1509 .release = icom_kobj_release,
1510};
1511
1512static int __devinit icom_probe(struct pci_dev *dev,
1513 const struct pci_device_id *ent)
1514{
1515 int index;
1516 unsigned int command_reg;
1517 int retval;
1518 struct icom_adapter *icom_adapter;
1519 struct icom_port *icom_port;
1520
1521 retval = pci_enable_device(dev);
1522 if (retval) {
1523 dev_err(&dev->dev, "Device enable FAILED\n");
1524 return retval;
1525 }
1526
1527 if ( (retval = pci_request_regions(dev, "icom"))) {
1528 dev_err(&dev->dev, "pci_request_region FAILED\n");
1529 pci_disable_device(dev);
1530 return retval;
1531 }
1532
1533 pci_set_master(dev);
1534
1535 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1536 dev_err(&dev->dev, "PCI Config read FAILED\n");
1537 return retval;
1538 }
1539
1540 pci_write_config_dword(dev, PCI_COMMAND,
1541 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1542 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1543
1544 if (ent->driver_data == ADAPTER_V1) {
1545 pci_write_config_dword(dev, 0x44, 0x8300830A);
1546 } else {
1547 pci_write_config_dword(dev, 0x44, 0x42004200);
1548 pci_write_config_dword(dev, 0x48, 0x42004200);
1549 }
1550
1551
1552 retval = icom_alloc_adapter(&icom_adapter);
1553 if (retval) {
1554 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1555 retval = -EIO;
1556 goto probe_exit0;
1557 }
1558
1559 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1560 icom_adapter->irq_number = dev->irq;
1561 icom_adapter->pci_dev = dev;
1562 icom_adapter->version = ent->driver_data;
1563 icom_adapter->subsystem_id = ent->subdevice;
1564
1565
1566 retval = icom_init_ports(icom_adapter);
1567 if (retval) {
1568 dev_err(&dev->dev, "Port configuration failed\n");
1569 goto probe_exit1;
1570 }
1571
1572 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1573 pci_resource_len(dev, 0));
1574
1575 if (!icom_adapter->base_addr)
1576 goto probe_exit1;
1577
1578 /* save off irq and request irq line */
1579 if ( (retval = request_irq(dev->irq, icom_interrupt,
1580 SA_INTERRUPT | SA_SHIRQ, ICOM_DRIVER_NAME,
1581 (void *) icom_adapter))) {
1582 goto probe_exit2;
1583 }
1584
1585 retval = icom_load_ports(icom_adapter);
1586
1587 for (index = 0; index < icom_adapter->numb_ports; index++) {
1588 icom_port = &icom_adapter->port_info[index];
1589
1590 if (icom_port->status == ICOM_PORT_ACTIVE) {
1591 icom_port->uart_port.irq = icom_port->adapter->irq_number;
1592 icom_port->uart_port.type = PORT_ICOM;
1593 icom_port->uart_port.iotype = UPIO_MEM;
1594 icom_port->uart_port.membase =
1595 (char *) icom_adapter->base_addr_pci;
1596 icom_port->uart_port.fifosize = 16;
1597 icom_port->uart_port.ops = &icom_ops;
1598 icom_port->uart_port.line =
1599 icom_port->port + icom_adapter->index * 4;
1600 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1601 icom_port->status = ICOM_PORT_OFF;
1602 dev_err(&dev->dev, "Device add failed\n");
1603 } else
1604 dev_info(&dev->dev, "Device added\n");
1605 }
1606 }
1607
1608 kobject_init(&icom_adapter->kobj);
1609 icom_adapter->kobj.ktype = &icom_kobj_type;
1610 return 0;
1611
1612probe_exit2:
1613 iounmap(icom_adapter->base_addr);
1614probe_exit1:
1615 icom_free_adapter(icom_adapter);
1616
1617probe_exit0:
1618 pci_release_regions(dev);
1619 pci_disable_device(dev);
1620
1621 return retval;
1622
1623
1624}
1625
1626static void __devexit icom_remove(struct pci_dev *dev)
1627{
1628 struct icom_adapter *icom_adapter;
1629 struct list_head *tmp;
1630
1631 list_for_each(tmp, &icom_adapter_head) {
1632 icom_adapter = list_entry(tmp, struct icom_adapter,
1633 icom_adapter_entry);
1634 if (icom_adapter->pci_dev == dev) {
1635 kobject_put(&icom_adapter->kobj);
1636 return;
1637 }
1638 }
1639
1640 dev_err(&dev->dev, "Unable to find device to remove\n");
1641}
1642
1643static struct pci_driver icom_pci_driver = {
1644 .name = ICOM_DRIVER_NAME,
1645 .id_table = icom_pci_table,
1646 .probe = icom_probe,
1647 .remove = __devexit_p(icom_remove),
1648};
1649
1650static int __init icom_init(void)
1651{
1652 int ret;
1653
1654 spin_lock_init(&icom_lock);
1655
1656 ret = uart_register_driver(&icom_uart_driver);
1657 if (ret)
1658 return ret;
1659
1660 ret = pci_register_driver(&icom_pci_driver);
1661
1662 if (ret < 0)
1663 uart_unregister_driver(&icom_uart_driver);
1664
1665 return ret;
1666}
1667
1668static void __exit icom_exit(void)
1669{
1670 pci_unregister_driver(&icom_pci_driver);
1671 uart_unregister_driver(&icom_uart_driver);
1672}
1673
1674module_init(icom_init);
1675module_exit(icom_exit);
1676
1677#ifdef ICOM_TRACE
1678static inline void trace(struct icom_port *icom_port, char *trace_pt,
1679 unsigned long trace_data)
1680{
1681 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1682 icom_port->port, trace_pt, trace_data);
1683}
1684#endif
1685
1686MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1687MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1688MODULE_SUPPORTED_DEVICE
1689 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1690MODULE_LICENSE("GPL");
1691