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