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