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