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 char new_config2;
1102 char new_config3 = 0;
1103 char tmp_byte;
1104 int index;
1105 int rcv_buff, xmit_buff;
1106 unsigned long offset;
1107 unsigned long flags;
1108
1109 spin_lock_irqsave(&port->lock, flags);
1110 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1111
1112 cflag = termios->c_cflag;
1113 iflag = termios->c_iflag;
1114
1115 new_config2 = ICOM_ACFG_DRIVE1;
1116
1117
1118 switch (cflag & CSIZE) {
1119 case CS5:
1120 new_config2 |= ICOM_ACFG_5BPC;
1121 break;
1122 case CS6:
1123 new_config2 |= ICOM_ACFG_6BPC;
1124 break;
1125 case CS7:
1126 new_config2 |= ICOM_ACFG_7BPC;
1127 break;
1128 case CS8:
1129 new_config2 |= ICOM_ACFG_8BPC;
1130 break;
1131 default:
1132 break;
1133 }
1134 if (cflag & CSTOPB) {
1135
1136 new_config2 |= ICOM_ACFG_2STOP_BIT;
1137 }
1138 if (cflag & PARENB) {
1139
1140 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1141 trace(ICOM_PORT, "PARENB", 0);
1142 }
1143 if (cflag & PARODD) {
1144
1145 new_config2 |= ICOM_ACFG_PARITY_ODD;
1146 trace(ICOM_PORT, "PARODD", 0);
1147 }
1148
1149
1150 baud = uart_get_baud_rate(port, termios, old_termios,
1151 icom_acfg_baud[0],
1152 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1153 if (!baud)
1154 baud = 9600;
1155
1156 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1157 if (icom_acfg_baud[index] == baud) {
1158 new_config3 = index;
1159 break;
1160 }
1161 }
1162
1163 uart_update_timeout(port, cflag, baud);
1164
1165
1166 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1167 if (cflag & CRTSCTS)
1168 tmp_byte |= HDLC_HDW_FLOW;
1169 else
1170 tmp_byte &= ~HDLC_HDW_FLOW;
1171 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1172
1173
1174
1175
1176 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1177 if (iflag & INPCK)
1178 ICOM_PORT->read_status_mask |=
1179 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1180
1181 if ((iflag & BRKINT) || (iflag & PARMRK))
1182 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1183
1184
1185
1186
1187 ICOM_PORT->ignore_status_mask = 0;
1188 if (iflag & IGNPAR)
1189 ICOM_PORT->ignore_status_mask |=
1190 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1191 if (iflag & IGNBRK) {
1192 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1193
1194
1195
1196
1197 if (iflag & IGNPAR)
1198 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1199 }
1200
1201
1202
1203
1204 if ((cflag & CREAD) == 0)
1205 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1206
1207
1208 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1209
1210 for (index = 0; index < 10; index++) {
1211 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1212 break;
1213 }
1214 }
1215
1216
1217 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1218 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1219 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1220 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1221 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1222 }
1223
1224 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1225 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1226 }
1227
1228
1229
1230 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1231 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1232 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1233 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1234 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1235 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer));
1236 writeb(0xFF, &(ICOM_PORT->dram->ier));
1237
1238
1239 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1240
1241 for (index = 0; index < 10; index++) {
1242 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1243 break;
1244 }
1245 }
1246
1247
1248 offset =
1249 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1250 (unsigned long) ICOM_PORT->statStg;
1251 writel(ICOM_PORT->statStg_pci + offset,
1252 &ICOM_PORT->dram->RcvStatusAddr);
1253 ICOM_PORT->next_rcv = 0;
1254 ICOM_PORT->put_length = 0;
1255 *ICOM_PORT->xmitRestart = 0;
1256 writel(ICOM_PORT->xmitRestart_pci,
1257 &ICOM_PORT->dram->XmitStatusAddr);
1258 trace(ICOM_PORT, "XR_ENAB", 0);
1259 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1260
1261 spin_unlock_irqrestore(&port->lock, flags);
1262}
1263
1264static const char *icom_type(struct uart_port *port)
1265{
1266 return "icom";
1267}
1268
1269static void icom_release_port(struct uart_port *port)
1270{
1271}
1272
1273static int icom_request_port(struct uart_port *port)
1274{
1275 return 0;
1276}
1277
1278static void icom_config_port(struct uart_port *port, int flags)
1279{
1280 port->type = PORT_ICOM;
1281}
1282
1283static struct uart_ops icom_ops = {
1284 .tx_empty = icom_tx_empty,
1285 .set_mctrl = icom_set_mctrl,
1286 .get_mctrl = icom_get_mctrl,
1287 .stop_tx = icom_stop_tx,
1288 .start_tx = icom_start_tx,
1289 .send_xchar = icom_send_xchar,
1290 .stop_rx = icom_stop_rx,
1291 .enable_ms = icom_enable_ms,
1292 .break_ctl = icom_break,
1293 .startup = icom_open,
1294 .shutdown = icom_close,
1295 .set_termios = icom_set_termios,
1296 .type = icom_type,
1297 .release_port = icom_release_port,
1298 .request_port = icom_request_port,
1299 .config_port = icom_config_port,
1300};
1301
1302#define ICOM_CONSOLE NULL
1303
1304static struct uart_driver icom_uart_driver = {
1305 .owner = THIS_MODULE,
1306 .driver_name = ICOM_DRIVER_NAME,
1307 .dev_name = "ttyA",
1308 .major = ICOM_MAJOR,
1309 .minor = ICOM_MINOR_START,
1310 .nr = NR_PORTS,
1311 .cons = ICOM_CONSOLE,
1312};
1313
1314static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1315{
1316 u32 subsystem_id = icom_adapter->subsystem_id;
1317 int i;
1318 struct icom_port *icom_port;
1319
1320 if (icom_adapter->version == ADAPTER_V1) {
1321 icom_adapter->numb_ports = 2;
1322
1323 for (i = 0; i < 2; i++) {
1324 icom_port = &icom_adapter->port_info[i];
1325 icom_port->port = i;
1326 icom_port->status = ICOM_PORT_ACTIVE;
1327 icom_port->imbed_modem = ICOM_UNKNOWN;
1328 }
1329 } else {
1330 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1331 icom_adapter->numb_ports = 4;
1332
1333 for (i = 0; i < 4; i++) {
1334 icom_port = &icom_adapter->port_info[i];
1335
1336 icom_port->port = i;
1337 icom_port->status = ICOM_PORT_ACTIVE;
1338 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1339 }
1340 } else {
1341 icom_adapter->numb_ports = 4;
1342
1343 icom_adapter->port_info[0].port = 0;
1344 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1345
1346 if (subsystem_id ==
1347 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1348 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1349 } else {
1350 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1351 }
1352
1353 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1354
1355 icom_adapter->port_info[2].port = 2;
1356 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1357 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1358 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1359 }
1360 }
1361
1362 return 0;
1363}
1364
1365static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1366{
1367 if (icom_adapter->version == ADAPTER_V1) {
1368 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1369 icom_port->int_reg = icom_adapter->base_addr +
1370 0x4004 + 2 - 2 * port_num;
1371 } else {
1372 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1373 if (icom_port->port < 2)
1374 icom_port->int_reg = icom_adapter->base_addr +
1375 0x8004 + 2 - 2 * icom_port->port;
1376 else
1377 icom_port->int_reg = icom_adapter->base_addr +
1378 0x8024 + 2 - 2 * (icom_port->port - 2);
1379 }
1380}
1381static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
1382{
1383 struct icom_port *icom_port;
1384 int port_num;
1385
1386 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1387
1388 icom_port = &icom_adapter->port_info[port_num];
1389
1390 if (icom_port->status == ICOM_PORT_ACTIVE) {
1391 icom_port_active(icom_port, icom_adapter, port_num);
1392 icom_port->dram = icom_adapter->base_addr +
1393 0x2000 * icom_port->port;
1394
1395 icom_port->adapter = icom_adapter;
1396
1397
1398 if (get_port_memory(icom_port) != 0) {
1399 dev_err(&icom_port->adapter->pci_dev->dev,
1400 "Memory allocation for port FAILED\n");
1401 }
1402 }
1403 }
1404 return 0;
1405}
1406
1407static int __devinit icom_alloc_adapter(struct icom_adapter
1408 **icom_adapter_ref)
1409{
1410 int adapter_count = 0;
1411 struct icom_adapter *icom_adapter;
1412 struct icom_adapter *cur_adapter_entry;
1413 struct list_head *tmp;
1414
1415 icom_adapter = (struct icom_adapter *)
1416 kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1417
1418 if (!icom_adapter) {
1419 return -ENOMEM;
1420 }
1421
1422 list_for_each(tmp, &icom_adapter_head) {
1423 cur_adapter_entry =
1424 list_entry(tmp, struct icom_adapter,
1425 icom_adapter_entry);
1426 if (cur_adapter_entry->index != adapter_count) {
1427 break;
1428 }
1429 adapter_count++;
1430 }
1431
1432 icom_adapter->index = adapter_count;
1433 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1434
1435 *icom_adapter_ref = icom_adapter;
1436 return 0;
1437}
1438
1439static void icom_free_adapter(struct icom_adapter *icom_adapter)
1440{
1441 list_del(&icom_adapter->icom_adapter_entry);
1442 kfree(icom_adapter);
1443}
1444
1445static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1446{
1447 struct icom_port *icom_port;
1448 int index;
1449
1450 for (index = 0; index < icom_adapter->numb_ports; index++) {
1451 icom_port = &icom_adapter->port_info[index];
1452
1453 if (icom_port->status == ICOM_PORT_ACTIVE) {
1454 dev_info(&icom_adapter->pci_dev->dev,
1455 "Device removed\n");
1456
1457 uart_remove_one_port(&icom_uart_driver,
1458 &icom_port->uart_port);
1459
1460
1461 writeb(0x00, &icom_port->dram->osr);
1462
1463
1464 msleep(100);
1465
1466
1467 stop_processor(icom_port);
1468
1469 free_port_memory(icom_port);
1470 }
1471 }
1472
1473 free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
1474 iounmap(icom_adapter->base_addr);
1475 pci_release_regions(icom_adapter->pci_dev);
1476 icom_free_adapter(icom_adapter);
1477}
1478
1479static void icom_kref_release(struct kref *kref)
1480{
1481 struct icom_adapter *icom_adapter;
1482
1483 icom_adapter = to_icom_adapter(kref);
1484 icom_remove_adapter(icom_adapter);
1485}
1486
1487static int __devinit icom_probe(struct pci_dev *dev,
1488 const struct pci_device_id *ent)
1489{
1490 int index;
1491 unsigned int command_reg;
1492 int retval;
1493 struct icom_adapter *icom_adapter;
1494 struct icom_port *icom_port;
1495
1496 retval = pci_enable_device(dev);
1497 if (retval) {
1498 dev_err(&dev->dev, "Device enable FAILED\n");
1499 return retval;
1500 }
1501
1502 if ( (retval = pci_request_regions(dev, "icom"))) {
1503 dev_err(&dev->dev, "pci_request_regions FAILED\n");
1504 pci_disable_device(dev);
1505 return retval;
1506 }
1507
1508 pci_set_master(dev);
1509
1510 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1511 dev_err(&dev->dev, "PCI Config read FAILED\n");
1512 return retval;
1513 }
1514
1515 pci_write_config_dword(dev, PCI_COMMAND,
1516 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1517 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1518
1519 if (ent->driver_data == ADAPTER_V1) {
1520 pci_write_config_dword(dev, 0x44, 0x8300830A);
1521 } else {
1522 pci_write_config_dword(dev, 0x44, 0x42004200);
1523 pci_write_config_dword(dev, 0x48, 0x42004200);
1524 }
1525
1526
1527 retval = icom_alloc_adapter(&icom_adapter);
1528 if (retval) {
1529 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1530 retval = -EIO;
1531 goto probe_exit0;
1532 }
1533
1534 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1535 icom_adapter->pci_dev = dev;
1536 icom_adapter->version = ent->driver_data;
1537 icom_adapter->subsystem_id = ent->subdevice;
1538
1539
1540 retval = icom_init_ports(icom_adapter);
1541 if (retval) {
1542 dev_err(&dev->dev, "Port configuration failed\n");
1543 goto probe_exit1;
1544 }
1545
1546 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1547 pci_resource_len(dev, 0));
1548
1549 if (!icom_adapter->base_addr)
1550 goto probe_exit1;
1551
1552
1553 if ( (retval = request_irq(dev->irq, icom_interrupt,
1554 IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
1555 (void *) icom_adapter))) {
1556 goto probe_exit2;
1557 }
1558
1559 retval = icom_load_ports(icom_adapter);
1560
1561 for (index = 0; index < icom_adapter->numb_ports; index++) {
1562 icom_port = &icom_adapter->port_info[index];
1563
1564 if (icom_port->status == ICOM_PORT_ACTIVE) {
1565 icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
1566 icom_port->uart_port.type = PORT_ICOM;
1567 icom_port->uart_port.iotype = UPIO_MEM;
1568 icom_port->uart_port.membase =
1569 (char *) icom_adapter->base_addr_pci;
1570 icom_port->uart_port.fifosize = 16;
1571 icom_port->uart_port.ops = &icom_ops;
1572 icom_port->uart_port.line =
1573 icom_port->port + icom_adapter->index * 4;
1574 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1575 icom_port->status = ICOM_PORT_OFF;
1576 dev_err(&dev->dev, "Device add failed\n");
1577 } else
1578 dev_info(&dev->dev, "Device added\n");
1579 }
1580 }
1581
1582 kref_init(&icom_adapter->kref);
1583 return 0;
1584
1585probe_exit2:
1586 iounmap(icom_adapter->base_addr);
1587probe_exit1:
1588 icom_free_adapter(icom_adapter);
1589
1590probe_exit0:
1591 pci_release_regions(dev);
1592 pci_disable_device(dev);
1593
1594 return retval;
1595
1596
1597}
1598
1599static void __devexit icom_remove(struct pci_dev *dev)
1600{
1601 struct icom_adapter *icom_adapter;
1602 struct list_head *tmp;
1603
1604 list_for_each(tmp, &icom_adapter_head) {
1605 icom_adapter = list_entry(tmp, struct icom_adapter,
1606 icom_adapter_entry);
1607 if (icom_adapter->pci_dev == dev) {
1608 kref_put(&icom_adapter->kref, icom_kref_release);
1609 return;
1610 }
1611 }
1612
1613 dev_err(&dev->dev, "Unable to find device to remove\n");
1614}
1615
1616static struct pci_driver icom_pci_driver = {
1617 .name = ICOM_DRIVER_NAME,
1618 .id_table = icom_pci_table,
1619 .probe = icom_probe,
1620 .remove = __devexit_p(icom_remove),
1621};
1622
1623static int __init icom_init(void)
1624{
1625 int ret;
1626
1627 spin_lock_init(&icom_lock);
1628
1629 ret = uart_register_driver(&icom_uart_driver);
1630 if (ret)
1631 return ret;
1632
1633 ret = pci_register_driver(&icom_pci_driver);
1634
1635 if (ret < 0)
1636 uart_unregister_driver(&icom_uart_driver);
1637
1638 return ret;
1639}
1640
1641static void __exit icom_exit(void)
1642{
1643 pci_unregister_driver(&icom_pci_driver);
1644 uart_unregister_driver(&icom_uart_driver);
1645}
1646
1647module_init(icom_init);
1648module_exit(icom_exit);
1649
1650#ifdef ICOM_TRACE
1651static inline void trace(struct icom_port *icom_port, char *trace_pt,
1652 unsigned long trace_data)
1653{
1654 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1655 icom_port->port, trace_pt, trace_data);
1656}
1657#endif
1658
1659MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1660MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1661MODULE_SUPPORTED_DEVICE
1662 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1663MODULE_LICENSE("GPL");
1664
1665