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 <linux/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 DEFINE_SPINLOCK(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 tty_flip_buffer_push(port);
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 ret = uart_register_driver(&icom_uart_driver);
1618 if (ret)
1619 return ret;
1620
1621 ret = pci_register_driver(&icom_pci_driver);
1622
1623 if (ret < 0)
1624 uart_unregister_driver(&icom_uart_driver);
1625
1626 return ret;
1627}
1628
1629static void __exit icom_exit(void)
1630{
1631 pci_unregister_driver(&icom_pci_driver);
1632 uart_unregister_driver(&icom_uart_driver);
1633}
1634
1635module_init(icom_init);
1636module_exit(icom_exit);
1637
1638MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1639MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1640MODULE_LICENSE("GPL");
1641MODULE_FIRMWARE("icom_call_setup.bin");
1642MODULE_FIRMWARE("icom_res_dce.bin");
1643MODULE_FIRMWARE("icom_asc.bin");
1644