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