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