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