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#define SERIAL_DO_RESTART
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/errno.h>
29#include <linux/signal.h>
30#include <linux/timer.h>
31#include <linux/interrupt.h>
32#include <linux/tty.h>
33#include <linux/termios.h>
34#include <linux/fs.h>
35#include <linux/tty_flip.h>
36#include <linux/serial.h>
37#include <linux/serial_reg.h>
38#include <linux/major.h>
39#include <linux/string.h>
40#include <linux/fcntl.h>
41#include <linux/ptrace.h>
42#include <linux/ioport.h>
43#include <linux/mm.h>
44#include <linux/slab.h>
45#include <linux/init.h>
46#include <linux/delay.h>
47#include <linux/pci.h>
48#include <linux/vmalloc.h>
49#include <linux/smp.h>
50#include <linux/spinlock.h>
51#include <linux/kref.h>
52#include <linux/firmware.h>
53#include <linux/bitops.h>
54
55#include <asm/system.h>
56#include <asm/io.h>
57#include <asm/irq.h>
58#include <asm/uaccess.h>
59
60#include "icom.h"
61
62
63
64#define ICOM_DRIVER_NAME "icom"
65#define ICOM_VERSION_STR "1.3.1"
66#define NR_PORTS 128
67#define ICOM_PORT ((struct icom_port *)port)
68#define to_icom_adapter(d) container_of(d, struct icom_adapter, kref)
69
70static const struct pci_device_id icom_pci_table[] = {
71 {
72 .vendor = PCI_VENDOR_ID_IBM,
73 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
74 .subvendor = PCI_ANY_ID,
75 .subdevice = PCI_ANY_ID,
76 .driver_data = ADAPTER_V1,
77 },
78 {
79 .vendor = PCI_VENDOR_ID_IBM,
80 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
81 .subvendor = PCI_VENDOR_ID_IBM,
82 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
83 .driver_data = ADAPTER_V2,
84 },
85 {
86 .vendor = PCI_VENDOR_ID_IBM,
87 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
88 .subvendor = PCI_VENDOR_ID_IBM,
89 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
90 .driver_data = ADAPTER_V2,
91 },
92 {
93 .vendor = PCI_VENDOR_ID_IBM,
94 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
95 .subvendor = PCI_VENDOR_ID_IBM,
96 .subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
97 .driver_data = ADAPTER_V2,
98 },
99 {
100 .vendor = PCI_VENDOR_ID_IBM,
101 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
102 .subvendor = PCI_VENDOR_ID_IBM,
103 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE,
104 .driver_data = ADAPTER_V2,
105 },
106 {}
107};
108
109struct lookup_proc_table start_proc[4] = {
110 {NULL, ICOM_CONTROL_START_A},
111 {NULL, ICOM_CONTROL_START_B},
112 {NULL, ICOM_CONTROL_START_C},
113 {NULL, ICOM_CONTROL_START_D}
114};
115
116
117struct lookup_proc_table stop_proc[4] = {
118 {NULL, ICOM_CONTROL_STOP_A},
119 {NULL, ICOM_CONTROL_STOP_B},
120 {NULL, ICOM_CONTROL_STOP_C},
121 {NULL, ICOM_CONTROL_STOP_D}
122};
123
124struct lookup_int_table int_mask_tbl[4] = {
125 {NULL, ICOM_INT_MASK_PRC_A},
126 {NULL, ICOM_INT_MASK_PRC_B},
127 {NULL, ICOM_INT_MASK_PRC_C},
128 {NULL, ICOM_INT_MASK_PRC_D},
129};
130
131
132MODULE_DEVICE_TABLE(pci, icom_pci_table);
133
134static LIST_HEAD(icom_adapter_head);
135
136
137static spinlock_t icom_lock;
138
139#ifdef ICOM_TRACE
140static inline void trace(struct icom_port *icom_port, char *trace_pt,
141 unsigned long trace_data)
142{
143 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
144 icom_port->port, trace_pt, trace_data);
145}
146#else
147static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
148#endif
149static void icom_kref_release(struct kref *kref);
150
151static void free_port_memory(struct icom_port *icom_port)
152{
153 struct pci_dev *dev = icom_port->adapter->pci_dev;
154
155 trace(icom_port, "RET_PORT_MEM", 0);
156 if (icom_port->recv_buf) {
157 pci_free_consistent(dev, 4096, icom_port->recv_buf,
158 icom_port->recv_buf_pci);
159 icom_port->recv_buf = NULL;
160 }
161 if (icom_port->xmit_buf) {
162 pci_free_consistent(dev, 4096, icom_port->xmit_buf,
163 icom_port->xmit_buf_pci);
164 icom_port->xmit_buf = NULL;
165 }
166 if (icom_port->statStg) {
167 pci_free_consistent(dev, 4096, icom_port->statStg,
168 icom_port->statStg_pci);
169 icom_port->statStg = NULL;
170 }
171
172 if (icom_port->xmitRestart) {
173 pci_free_consistent(dev, 4096, icom_port->xmitRestart,
174 icom_port->xmitRestart_pci);
175 icom_port->xmitRestart = NULL;
176 }
177}
178
179static int __devinit get_port_memory(struct icom_port *icom_port)
180{
181 int index;
182 unsigned long stgAddr;
183 unsigned long startStgAddr;
184 unsigned long offset;
185 struct pci_dev *dev = icom_port->adapter->pci_dev;
186
187 icom_port->xmit_buf =
188 pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
189 if (!icom_port->xmit_buf) {
190 dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
191 return -ENOMEM;
192 }
193
194 trace(icom_port, "GET_PORT_MEM",
195 (unsigned long) icom_port->xmit_buf);
196
197 icom_port->recv_buf =
198 pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
199 if (!icom_port->recv_buf) {
200 dev_err(&dev->dev, "Can not allocate Receive buffer\n");
201 free_port_memory(icom_port);
202 return -ENOMEM;
203 }
204 trace(icom_port, "GET_PORT_MEM",
205 (unsigned long) icom_port->recv_buf);
206
207 icom_port->statStg =
208 pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
209 if (!icom_port->statStg) {
210 dev_err(&dev->dev, "Can not allocate Status buffer\n");
211 free_port_memory(icom_port);
212 return -ENOMEM;
213 }
214 trace(icom_port, "GET_PORT_MEM",
215 (unsigned long) icom_port->statStg);
216
217 icom_port->xmitRestart =
218 pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
219 if (!icom_port->xmitRestart) {
220 dev_err(&dev->dev,
221 "Can not allocate xmit Restart buffer\n");
222 free_port_memory(icom_port);
223 return -ENOMEM;
224 }
225
226 memset(icom_port->statStg, 0, 4096);
227
228
229
230
231
232 stgAddr = (unsigned long) icom_port->statStg;
233 for (index = 0; index < NUM_XBUFFS; index++) {
234 trace(icom_port, "FOD_ADDR", stgAddr);
235 stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
236 if (index < (NUM_XBUFFS - 1)) {
237 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
238 icom_port->statStg->xmit[index].leLengthASD =
239 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
240 trace(icom_port, "FOD_ADDR", stgAddr);
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 if (index == (NUM_XBUFFS - 1)) {
246 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
247 icom_port->statStg->xmit[index].leLengthASD =
248 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
249 trace(icom_port, "FOD_XBUFF",
250 (unsigned long) icom_port->xmit_buf);
251 icom_port->statStg->xmit[index].leBuffer =
252 cpu_to_le32(icom_port->xmit_buf_pci);
253 } else {
254 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
255 }
256 }
257
258 startStgAddr = stgAddr;
259
260
261 for (index = 0; index < NUM_RBUFFS; index++) {
262 trace(icom_port, "FID_ADDR", stgAddr);
263 stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
264 icom_port->statStg->rcv[index].leLength = 0;
265 icom_port->statStg->rcv[index].WorkingLength =
266 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
267 if (index < (NUM_RBUFFS - 1) ) {
268 offset = stgAddr - (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);
273 icom_port->statStg->rcv[index].leBuffer =
274 cpu_to_le32(icom_port->recv_buf_pci);
275 } else if (index == (NUM_RBUFFS -1) ) {
276 offset = startStgAddr - (unsigned long) icom_port->statStg;
277 icom_port->statStg->rcv[index].leNext =
278 cpu_to_le32(icom_port-> statStg_pci + offset);
279 trace(icom_port, "FID_RBUFF",
280 (unsigned long) icom_port->recv_buf + 2048);
281 icom_port->statStg->rcv[index].leBuffer =
282 cpu_to_le32(icom_port->recv_buf_pci + 2048);
283 } else {
284 icom_port->statStg->rcv[index].leNext = 0;
285 icom_port->statStg->rcv[index].leBuffer = 0;
286 }
287 }
288
289 return 0;
290}
291
292static void stop_processor(struct icom_port *icom_port)
293{
294 unsigned long temp;
295 unsigned long flags;
296 int port;
297
298 spin_lock_irqsave(&icom_lock, flags);
299
300 port = icom_port->port;
301 if (port == 0 || port == 1)
302 stop_proc[port].global_control_reg = &icom_port->global_reg->control;
303 else
304 stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
305
306
307 if (port < 4) {
308 temp = readl(stop_proc[port].global_control_reg);
309 temp =
310 (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
311 writel(temp, stop_proc[port].global_control_reg);
312
313
314 readl(stop_proc[port].global_control_reg);
315 } else {
316 dev_err(&icom_port->adapter->pci_dev->dev,
317 "Invalid port assignment\n");
318 }
319
320 spin_unlock_irqrestore(&icom_lock, flags);
321}
322
323static void start_processor(struct icom_port *icom_port)
324{
325 unsigned long temp;
326 unsigned long flags;
327 int port;
328
329 spin_lock_irqsave(&icom_lock, flags);
330
331 port = icom_port->port;
332 if (port == 0 || port == 1)
333 start_proc[port].global_control_reg = &icom_port->global_reg->control;
334 else
335 start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
336 if (port < 4) {
337 temp = readl(start_proc[port].global_control_reg);
338 temp =
339 (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
340 writel(temp, start_proc[port].global_control_reg);
341
342
343 readl(start_proc[port].global_control_reg);
344 } else {
345 dev_err(&icom_port->adapter->pci_dev->dev,
346 "Invalid port assignment\n");
347 }
348
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 release_firmware(fw);
458
459 writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
460 writel(temp_pci, &icom_port->dram->mac_load_addr);
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 opertional\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 == 0 || port == 1)
562 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
563 else
564 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
565
566 if (port == 0 || port == 2)
567 writew(0x00FF, icom_port->int_reg);
568 else
569 writew(0x3F00, icom_port->int_reg);
570 if (port < 4) {
571 temp = readl(int_mask_tbl[port].global_int_mask);
572 writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
573
574
575 readl(int_mask_tbl[port].global_int_mask);
576 } else {
577 dev_err(&icom_port->adapter->pci_dev->dev,
578 "Invalid port assignment\n");
579 }
580
581 spin_unlock_irqrestore(&icom_lock, flags);
582 return 0;
583}
584
585static void shutdown(struct icom_port *icom_port)
586{
587 unsigned long temp;
588 unsigned char cmdReg;
589 unsigned long flags;
590 int port;
591
592 spin_lock_irqsave(&icom_lock, flags);
593 trace(icom_port, "SHUTDOWN", 0);
594
595
596
597
598 port = icom_port->port;
599 if (port == 0 || port == 1)
600 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
601 else
602 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
603
604 if (port < 4) {
605 temp = readl(int_mask_tbl[port].global_int_mask);
606 writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
607
608
609 readl(int_mask_tbl[port].global_int_mask);
610 } else {
611 dev_err(&icom_port->adapter->pci_dev->dev,
612 "Invalid port assignment\n");
613 }
614 spin_unlock_irqrestore(&icom_lock, flags);
615
616
617
618
619 cmdReg = readb(&icom_port->dram->CmdReg);
620 if (cmdReg & CMD_SND_BREAK) {
621 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
622 }
623}
624
625static int icom_write(struct uart_port *port)
626{
627 unsigned long data_count;
628 unsigned char cmdReg;
629 unsigned long offset;
630 int temp_tail = port->state->xmit.tail;
631
632 trace(ICOM_PORT, "WRITE", 0);
633
634 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
635 SA_FLAGS_READY_TO_XMIT) {
636 trace(ICOM_PORT, "WRITE_FULL", 0);
637 return 0;
638 }
639
640 data_count = 0;
641 while ((port->state->xmit.head != temp_tail) &&
642 (data_count <= XMIT_BUFF_SZ)) {
643
644 ICOM_PORT->xmit_buf[data_count++] =
645 port->state->xmit.buf[temp_tail];
646
647 temp_tail++;
648 temp_tail &= (UART_XMIT_SIZE - 1);
649 }
650
651 if (data_count) {
652 ICOM_PORT->statStg->xmit[0].flags =
653 cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
654 ICOM_PORT->statStg->xmit[0].leLength =
655 cpu_to_le16(data_count);
656 offset =
657 (unsigned long) &ICOM_PORT->statStg->xmit[0] -
658 (unsigned long) ICOM_PORT->statStg;
659 *ICOM_PORT->xmitRestart =
660 cpu_to_le32(ICOM_PORT->statStg_pci + offset);
661 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
662 writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
663 &ICOM_PORT->dram->CmdReg);
664 writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
665 trace(ICOM_PORT, "WRITE_START", data_count);
666
667 readb(&ICOM_PORT->dram->StartXmitCmd);
668 }
669
670 return data_count;
671}
672
673static inline void check_modem_status(struct icom_port *icom_port)
674{
675 static char old_status = 0;
676 char delta_status;
677 unsigned char status;
678
679 spin_lock(&icom_port->uart_port.lock);
680
681
682 status = readb(&icom_port->dram->isr);
683 trace(icom_port, "CHECK_MODEM", status);
684 delta_status = status ^ old_status;
685 if (delta_status) {
686 if (delta_status & ICOM_RI)
687 icom_port->uart_port.icount.rng++;
688 if (delta_status & ICOM_DSR)
689 icom_port->uart_port.icount.dsr++;
690 if (delta_status & ICOM_DCD)
691 uart_handle_dcd_change(&icom_port->uart_port,
692 delta_status & ICOM_DCD);
693 if (delta_status & ICOM_CTS)
694 uart_handle_cts_change(&icom_port->uart_port,
695 delta_status & ICOM_CTS);
696
697 wake_up_interruptible(&icom_port->uart_port.state->
698 port.delta_msr_wait);
699 old_status = status;
700 }
701 spin_unlock(&icom_port->uart_port.lock);
702}
703
704static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
705{
706 unsigned short int count;
707 int i;
708
709 if (port_int_reg & (INT_XMIT_COMPLETED)) {
710 trace(icom_port, "XMIT_COMPLETE", 0);
711
712
713 icom_port->statStg->xmit[0].flags &=
714 cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
715
716 count = (unsigned short int)
717 cpu_to_le16(icom_port->statStg->xmit[0].leLength);
718 icom_port->uart_port.icount.tx += count;
719
720 for (i=0; i<count &&
721 !uart_circ_empty(&icom_port->uart_port.state->xmit); i++) {
722
723 icom_port->uart_port.state->xmit.tail++;
724 icom_port->uart_port.state->xmit.tail &=
725 (UART_XMIT_SIZE - 1);
726 }
727
728 if (!icom_write(&icom_port->uart_port))
729
730 uart_write_wakeup(&icom_port->uart_port);
731 } else
732 trace(icom_port, "XMIT_DISABLED", 0);
733}
734
735static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
736{
737 short int count, rcv_buff;
738 struct tty_struct *tty = icom_port->uart_port.state->port.tty;
739 unsigned short int status;
740 struct uart_icount *icount;
741 unsigned long offset;
742 unsigned char flag;
743
744 trace(icom_port, "RCV_COMPLETE", 0);
745 rcv_buff = icom_port->next_rcv;
746
747 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
748 while (status & SA_FL_RCV_DONE) {
749 int first = -1;
750
751 trace(icom_port, "FID_STATUS", status);
752 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
753
754 count = tty_buffer_request_room(tty, count);
755 trace(icom_port, "RCV_COUNT", count);
756
757 trace(icom_port, "REAL_COUNT", count);
758
759 offset =
760 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
761 icom_port->recv_buf_pci;
762
763
764 if (count > 0) {
765 first = icom_port->recv_buf[offset];
766 tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1);
767 }
768
769 icount = &icom_port->uart_port.icount;
770 icount->rx += count;
771
772
773 if ((status & SA_FLAGS_FRAME_ERROR)
774 && first == 0) {
775 status &= ~SA_FLAGS_FRAME_ERROR;
776 status |= SA_FLAGS_BREAK_DET;
777 trace(icom_port, "BREAK_DET", 0);
778 }
779
780 flag = TTY_NORMAL;
781
782 if (status &
783 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
784 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
785
786 if (status & SA_FLAGS_BREAK_DET)
787 icount->brk++;
788 if (status & SA_FLAGS_PARITY_ERROR)
789 icount->parity++;
790 if (status & SA_FLAGS_FRAME_ERROR)
791 icount->frame++;
792 if (status & SA_FLAGS_OVERRUN)
793 icount->overrun++;
794
795
796
797
798
799
800 if (status & icom_port->ignore_status_mask) {
801 trace(icom_port, "IGNORE_CHAR", 0);
802 goto ignore_char;
803 }
804
805 status &= icom_port->read_status_mask;
806
807 if (status & SA_FLAGS_BREAK_DET) {
808 flag = TTY_BREAK;
809 } else if (status & SA_FLAGS_PARITY_ERROR) {
810 trace(icom_port, "PARITY_ERROR", 0);
811 flag = TTY_PARITY;
812 } else if (status & SA_FLAGS_FRAME_ERROR)
813 flag = TTY_FRAME;
814
815 }
816
817 tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag);
818
819 if (status & SA_FLAGS_OVERRUN)
820
821
822
823
824
825 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
826ignore_char:
827 icom_port->statStg->rcv[rcv_buff].flags = 0;
828 icom_port->statStg->rcv[rcv_buff].leLength = 0;
829 icom_port->statStg->rcv[rcv_buff].WorkingLength =
830 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
831
832 rcv_buff++;
833 if (rcv_buff == NUM_RBUFFS)
834 rcv_buff = 0;
835
836 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
837 }
838 icom_port->next_rcv = rcv_buff;
839 tty_flip_buffer_push(tty);
840}
841
842static void process_interrupt(u16 port_int_reg,
843 struct icom_port *icom_port)
844{
845
846 spin_lock(&icom_port->uart_port.lock);
847 trace(icom_port, "INTERRUPT", port_int_reg);
848
849 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
850 xmit_interrupt(port_int_reg, icom_port);
851
852 if (port_int_reg & INT_RCV_COMPLETED)
853 recv_interrupt(port_int_reg, icom_port);
854
855 spin_unlock(&icom_port->uart_port.lock);
856}
857
858static irqreturn_t icom_interrupt(int irq, void *dev_id)
859{
860 void __iomem * int_reg;
861 u32 adapter_interrupts;
862 u16 port_int_reg;
863 struct icom_adapter *icom_adapter;
864 struct icom_port *icom_port;
865
866
867 icom_adapter = (struct icom_adapter *) dev_id;
868
869 if (icom_adapter->version == ADAPTER_V2) {
870 int_reg = icom_adapter->base_addr + 0x8024;
871
872 adapter_interrupts = readl(int_reg);
873
874 if (adapter_interrupts & 0x00003FFF) {
875
876 icom_port = &icom_adapter->port_info[2];
877 port_int_reg = (u16) adapter_interrupts;
878 process_interrupt(port_int_reg, icom_port);
879 check_modem_status(icom_port);
880 }
881 if (adapter_interrupts & 0x3FFF0000) {
882
883 icom_port = &icom_adapter->port_info[3];
884 if (icom_port->status == ICOM_PORT_ACTIVE) {
885 port_int_reg =
886 (u16) (adapter_interrupts >> 16);
887 process_interrupt(port_int_reg, icom_port);
888 check_modem_status(icom_port);
889 }
890 }
891
892
893 writel(adapter_interrupts, int_reg);
894
895 int_reg = icom_adapter->base_addr + 0x8004;
896 } else {
897 int_reg = icom_adapter->base_addr + 0x4004;
898 }
899
900 adapter_interrupts = readl(int_reg);
901
902 if (adapter_interrupts & 0x00003FFF) {
903
904 icom_port = &icom_adapter->port_info[0];
905 port_int_reg = (u16) adapter_interrupts;
906 process_interrupt(port_int_reg, icom_port);
907 check_modem_status(icom_port);
908 }
909 if (adapter_interrupts & 0x3FFF0000) {
910
911 icom_port = &icom_adapter->port_info[1];
912 if (icom_port->status == ICOM_PORT_ACTIVE) {
913 port_int_reg = (u16) (adapter_interrupts >> 16);
914 process_interrupt(port_int_reg, icom_port);
915 check_modem_status(icom_port);
916 }
917 }
918
919
920 writel(adapter_interrupts, int_reg);
921
922
923 adapter_interrupts = readl(int_reg);
924
925 return IRQ_HANDLED;
926}
927
928
929
930
931
932
933static unsigned int icom_tx_empty(struct uart_port *port)
934{
935 int ret;
936 unsigned long flags;
937
938 spin_lock_irqsave(&port->lock, flags);
939 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
940 SA_FLAGS_READY_TO_XMIT)
941 ret = TIOCSER_TEMT;
942 else
943 ret = 0;
944
945 spin_unlock_irqrestore(&port->lock, flags);
946 return ret;
947}
948
949static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
950{
951 unsigned char local_osr;
952
953 trace(ICOM_PORT, "SET_MODEM", 0);
954 local_osr = readb(&ICOM_PORT->dram->osr);
955
956 if (mctrl & TIOCM_RTS) {
957 trace(ICOM_PORT, "RAISE_RTS", 0);
958 local_osr |= ICOM_RTS;
959 } else {
960 trace(ICOM_PORT, "LOWER_RTS", 0);
961 local_osr &= ~ICOM_RTS;
962 }
963
964 if (mctrl & TIOCM_DTR) {
965 trace(ICOM_PORT, "RAISE_DTR", 0);
966 local_osr |= ICOM_DTR;
967 } else {
968 trace(ICOM_PORT, "LOWER_DTR", 0);
969 local_osr &= ~ICOM_DTR;
970 }
971
972 writeb(local_osr, &ICOM_PORT->dram->osr);
973}
974
975static unsigned int icom_get_mctrl(struct uart_port *port)
976{
977 unsigned char status;
978 unsigned int result;
979
980 trace(ICOM_PORT, "GET_MODEM", 0);
981
982 status = readb(&ICOM_PORT->dram->isr);
983
984 result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
985 | ((status & ICOM_RI) ? TIOCM_RNG : 0)
986 | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
987 | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
988 return result;
989}
990
991static void icom_stop_tx(struct uart_port *port)
992{
993 unsigned char cmdReg;
994
995 trace(ICOM_PORT, "STOP", 0);
996 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
997 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
998}
999
1000static void icom_start_tx(struct uart_port *port)
1001{
1002 unsigned char cmdReg;
1003
1004 trace(ICOM_PORT, "START", 0);
1005 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1006 if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
1007 writeb(cmdReg & ~CMD_HOLD_XMIT,
1008 &ICOM_PORT->dram->CmdReg);
1009
1010 icom_write(port);
1011}
1012
1013static void icom_send_xchar(struct uart_port *port, char ch)
1014{
1015 unsigned char xdata;
1016 int index;
1017 unsigned long flags;
1018
1019 trace(ICOM_PORT, "SEND_XCHAR", ch);
1020
1021
1022 for (index = 0; index < 10; index++) {
1023 spin_lock_irqsave(&port->lock, flags);
1024 xdata = readb(&ICOM_PORT->dram->xchar);
1025 if (xdata == 0x00) {
1026 trace(ICOM_PORT, "QUICK_WRITE", 0);
1027 writeb(ch, &ICOM_PORT->dram->xchar);
1028
1029
1030 xdata = readb(&ICOM_PORT->dram->xchar);
1031 spin_unlock_irqrestore(&port->lock, flags);
1032 break;
1033 }
1034 spin_unlock_irqrestore(&port->lock, flags);
1035 msleep(10);
1036 }
1037}
1038
1039static void icom_stop_rx(struct uart_port *port)
1040{
1041 unsigned char cmdReg;
1042
1043 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1044 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1045}
1046
1047static void icom_enable_ms(struct uart_port *port)
1048{
1049
1050}
1051
1052static void icom_break(struct uart_port *port, int break_state)
1053{
1054 unsigned char cmdReg;
1055 unsigned long flags;
1056
1057 spin_lock_irqsave(&port->lock, flags);
1058 trace(ICOM_PORT, "BREAK", 0);
1059 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1060 if (break_state == -1) {
1061 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1062 } else {
1063 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1064 }
1065 spin_unlock_irqrestore(&port->lock, flags);
1066}
1067
1068static int icom_open(struct uart_port *port)
1069{
1070 int retval;
1071
1072 kref_get(&ICOM_PORT->adapter->kref);
1073 retval = startup(ICOM_PORT);
1074
1075 if (retval) {
1076 kref_put(&ICOM_PORT->adapter->kref, icom_kref_release);
1077 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1078 return retval;
1079 }
1080
1081 return 0;
1082}
1083
1084static void icom_close(struct uart_port *port)
1085{
1086 unsigned char cmdReg;
1087
1088 trace(ICOM_PORT, "CLOSE", 0);
1089
1090
1091 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1092 writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1093 &ICOM_PORT->dram->CmdReg);
1094
1095 shutdown(ICOM_PORT);
1096
1097 kref_put(&ICOM_PORT->adapter->kref, icom_kref_release);
1098}
1099
1100static void icom_set_termios(struct uart_port *port,
1101 struct ktermios *termios,
1102 struct ktermios *old_termios)
1103{
1104 int baud;
1105 unsigned cflag, iflag;
1106 char new_config2;
1107 char new_config3 = 0;
1108 char tmp_byte;
1109 int index;
1110 int rcv_buff, xmit_buff;
1111 unsigned long offset;
1112 unsigned long flags;
1113
1114 spin_lock_irqsave(&port->lock, flags);
1115 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1116
1117 cflag = termios->c_cflag;
1118 iflag = termios->c_iflag;
1119
1120 new_config2 = ICOM_ACFG_DRIVE1;
1121
1122
1123 switch (cflag & CSIZE) {
1124 case CS5:
1125 new_config2 |= ICOM_ACFG_5BPC;
1126 break;
1127 case CS6:
1128 new_config2 |= ICOM_ACFG_6BPC;
1129 break;
1130 case CS7:
1131 new_config2 |= ICOM_ACFG_7BPC;
1132 break;
1133 case CS8:
1134 new_config2 |= ICOM_ACFG_8BPC;
1135 break;
1136 default:
1137 break;
1138 }
1139 if (cflag & CSTOPB) {
1140
1141 new_config2 |= ICOM_ACFG_2STOP_BIT;
1142 }
1143 if (cflag & PARENB) {
1144
1145 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1146 trace(ICOM_PORT, "PARENB", 0);
1147 }
1148 if (cflag & PARODD) {
1149
1150 new_config2 |= ICOM_ACFG_PARITY_ODD;
1151 trace(ICOM_PORT, "PARODD", 0);
1152 }
1153
1154
1155 baud = uart_get_baud_rate(port, termios, old_termios,
1156 icom_acfg_baud[0],
1157 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1158 if (!baud)
1159 baud = 9600;
1160
1161 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1162 if (icom_acfg_baud[index] == baud) {
1163 new_config3 = index;
1164 break;
1165 }
1166 }
1167
1168 uart_update_timeout(port, cflag, baud);
1169
1170
1171 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1172 if (cflag & CRTSCTS)
1173 tmp_byte |= HDLC_HDW_FLOW;
1174 else
1175 tmp_byte &= ~HDLC_HDW_FLOW;
1176 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1177
1178
1179
1180
1181 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1182 if (iflag & INPCK)
1183 ICOM_PORT->read_status_mask |=
1184 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1185
1186 if ((iflag & BRKINT) || (iflag & PARMRK))
1187 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1188
1189
1190
1191
1192 ICOM_PORT->ignore_status_mask = 0;
1193 if (iflag & IGNPAR)
1194 ICOM_PORT->ignore_status_mask |=
1195 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1196 if (iflag & IGNBRK) {
1197 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1198
1199
1200
1201
1202 if (iflag & IGNPAR)
1203 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1204 }
1205
1206
1207
1208
1209 if ((cflag & CREAD) == 0)
1210 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1211
1212
1213 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1214
1215 for (index = 0; index < 10; index++) {
1216 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1217 break;
1218 }
1219 }
1220
1221
1222 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1223 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1224 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1225 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1226 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1227 }
1228
1229 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1230 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1231 }
1232
1233
1234
1235 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1236 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1237 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1238 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1239 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1240 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer));
1241 writeb(0xFF, &(ICOM_PORT->dram->ier));
1242
1243
1244 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1245
1246 for (index = 0; index < 10; index++) {
1247 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1248 break;
1249 }
1250 }
1251
1252
1253 offset =
1254 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1255 (unsigned long) ICOM_PORT->statStg;
1256 writel(ICOM_PORT->statStg_pci + offset,
1257 &ICOM_PORT->dram->RcvStatusAddr);
1258 ICOM_PORT->next_rcv = 0;
1259 ICOM_PORT->put_length = 0;
1260 *ICOM_PORT->xmitRestart = 0;
1261 writel(ICOM_PORT->xmitRestart_pci,
1262 &ICOM_PORT->dram->XmitStatusAddr);
1263 trace(ICOM_PORT, "XR_ENAB", 0);
1264 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1265
1266 spin_unlock_irqrestore(&port->lock, flags);
1267}
1268
1269static const char *icom_type(struct uart_port *port)
1270{
1271 return "icom";
1272}
1273
1274static void icom_release_port(struct uart_port *port)
1275{
1276}
1277
1278static int icom_request_port(struct uart_port *port)
1279{
1280 return 0;
1281}
1282
1283static void icom_config_port(struct uart_port *port, int flags)
1284{
1285 port->type = PORT_ICOM;
1286}
1287
1288static struct uart_ops icom_ops = {
1289 .tx_empty = icom_tx_empty,
1290 .set_mctrl = icom_set_mctrl,
1291 .get_mctrl = icom_get_mctrl,
1292 .stop_tx = icom_stop_tx,
1293 .start_tx = icom_start_tx,
1294 .send_xchar = icom_send_xchar,
1295 .stop_rx = icom_stop_rx,
1296 .enable_ms = icom_enable_ms,
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 __devinit 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 __devinit 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 __devinit 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 = (struct icom_adapter *)
1421 kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1422
1423 if (!icom_adapter) {
1424 return -ENOMEM;
1425 }
1426
1427 list_for_each(tmp, &icom_adapter_head) {
1428 cur_adapter_entry =
1429 list_entry(tmp, struct icom_adapter,
1430 icom_adapter_entry);
1431 if (cur_adapter_entry->index != adapter_count) {
1432 break;
1433 }
1434 adapter_count++;
1435 }
1436
1437 icom_adapter->index = adapter_count;
1438 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1439
1440 *icom_adapter_ref = icom_adapter;
1441 return 0;
1442}
1443
1444static void icom_free_adapter(struct icom_adapter *icom_adapter)
1445{
1446 list_del(&icom_adapter->icom_adapter_entry);
1447 kfree(icom_adapter);
1448}
1449
1450static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1451{
1452 struct icom_port *icom_port;
1453 int index;
1454
1455 for (index = 0; index < icom_adapter->numb_ports; index++) {
1456 icom_port = &icom_adapter->port_info[index];
1457
1458 if (icom_port->status == ICOM_PORT_ACTIVE) {
1459 dev_info(&icom_adapter->pci_dev->dev,
1460 "Device removed\n");
1461
1462 uart_remove_one_port(&icom_uart_driver,
1463 &icom_port->uart_port);
1464
1465
1466 writeb(0x00, &icom_port->dram->osr);
1467
1468
1469 msleep(100);
1470
1471
1472 stop_processor(icom_port);
1473
1474 free_port_memory(icom_port);
1475 }
1476 }
1477
1478 free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
1479 iounmap(icom_adapter->base_addr);
1480 pci_release_regions(icom_adapter->pci_dev);
1481 icom_free_adapter(icom_adapter);
1482}
1483
1484static void icom_kref_release(struct kref *kref)
1485{
1486 struct icom_adapter *icom_adapter;
1487
1488 icom_adapter = to_icom_adapter(kref);
1489 icom_remove_adapter(icom_adapter);
1490}
1491
1492static int __devinit icom_probe(struct pci_dev *dev,
1493 const struct pci_device_id *ent)
1494{
1495 int index;
1496 unsigned int command_reg;
1497 int retval;
1498 struct icom_adapter *icom_adapter;
1499 struct icom_port *icom_port;
1500
1501 retval = pci_enable_device(dev);
1502 if (retval) {
1503 dev_err(&dev->dev, "Device enable FAILED\n");
1504 return retval;
1505 }
1506
1507 if ( (retval = pci_request_regions(dev, "icom"))) {
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 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1516 dev_err(&dev->dev, "PCI Config read FAILED\n");
1517 return retval;
1518 }
1519
1520 pci_write_config_dword(dev, PCI_COMMAND,
1521 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1522 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1523
1524 if (ent->driver_data == ADAPTER_V1) {
1525 pci_write_config_dword(dev, 0x44, 0x8300830A);
1526 } else {
1527 pci_write_config_dword(dev, 0x44, 0x42004200);
1528 pci_write_config_dword(dev, 0x48, 0x42004200);
1529 }
1530
1531
1532 retval = icom_alloc_adapter(&icom_adapter);
1533 if (retval) {
1534 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1535 retval = -EIO;
1536 goto probe_exit0;
1537 }
1538
1539 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1540 icom_adapter->pci_dev = dev;
1541 icom_adapter->version = ent->driver_data;
1542 icom_adapter->subsystem_id = ent->subdevice;
1543
1544
1545 retval = icom_init_ports(icom_adapter);
1546 if (retval) {
1547 dev_err(&dev->dev, "Port configuration failed\n");
1548 goto probe_exit1;
1549 }
1550
1551 icom_adapter->base_addr = pci_ioremap_bar(dev, 0);
1552
1553 if (!icom_adapter->base_addr)
1554 goto probe_exit1;
1555
1556
1557 if ( (retval = request_irq(dev->irq, icom_interrupt,
1558 IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
1559 (void *) icom_adapter))) {
1560 goto probe_exit2;
1561 }
1562
1563 retval = icom_load_ports(icom_adapter);
1564
1565 for (index = 0; index < icom_adapter->numb_ports; index++) {
1566 icom_port = &icom_adapter->port_info[index];
1567
1568 if (icom_port->status == ICOM_PORT_ACTIVE) {
1569 icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
1570 icom_port->uart_port.type = PORT_ICOM;
1571 icom_port->uart_port.iotype = UPIO_MEM;
1572 icom_port->uart_port.membase =
1573 (char *) icom_adapter->base_addr_pci;
1574 icom_port->uart_port.fifosize = 16;
1575 icom_port->uart_port.ops = &icom_ops;
1576 icom_port->uart_port.line =
1577 icom_port->port + icom_adapter->index * 4;
1578 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1579 icom_port->status = ICOM_PORT_OFF;
1580 dev_err(&dev->dev, "Device add failed\n");
1581 } else
1582 dev_info(&dev->dev, "Device added\n");
1583 }
1584 }
1585
1586 kref_init(&icom_adapter->kref);
1587 return 0;
1588
1589probe_exit2:
1590 iounmap(icom_adapter->base_addr);
1591probe_exit1:
1592 icom_free_adapter(icom_adapter);
1593
1594probe_exit0:
1595 pci_release_regions(dev);
1596 pci_disable_device(dev);
1597
1598 return retval;
1599}
1600
1601static void __devexit icom_remove(struct pci_dev *dev)
1602{
1603 struct icom_adapter *icom_adapter;
1604 struct list_head *tmp;
1605
1606 list_for_each(tmp, &icom_adapter_head) {
1607 icom_adapter = list_entry(tmp, struct icom_adapter,
1608 icom_adapter_entry);
1609 if (icom_adapter->pci_dev == dev) {
1610 kref_put(&icom_adapter->kref, icom_kref_release);
1611 return;
1612 }
1613 }
1614
1615 dev_err(&dev->dev, "Unable to find device to remove\n");
1616}
1617
1618static struct pci_driver icom_pci_driver = {
1619 .name = ICOM_DRIVER_NAME,
1620 .id_table = icom_pci_table,
1621 .probe = icom_probe,
1622 .remove = __devexit_p(icom_remove),
1623};
1624
1625static int __init icom_init(void)
1626{
1627 int ret;
1628
1629 spin_lock_init(&icom_lock);
1630
1631 ret = uart_register_driver(&icom_uart_driver);
1632 if (ret)
1633 return ret;
1634
1635 ret = pci_register_driver(&icom_pci_driver);
1636
1637 if (ret < 0)
1638 uart_unregister_driver(&icom_uart_driver);
1639
1640 return ret;
1641}
1642
1643static void __exit icom_exit(void)
1644{
1645 pci_unregister_driver(&icom_pci_driver);
1646 uart_unregister_driver(&icom_uart_driver);
1647}
1648
1649module_init(icom_init);
1650module_exit(icom_exit);
1651
1652MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1653MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1654MODULE_SUPPORTED_DEVICE
1655 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1656MODULE_LICENSE("GPL");
1657
1658