[PATCH] TTY layer buffering revamp
[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;
33f0f88f 732 unsigned char flag;
1da177e4
LT
733
734 trace(icom_port, "RCV_COMPLETE", 0);
735 rcv_buff = icom_port->next_rcv;
736
737 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
738 while (status & SA_FL_RCV_DONE) {
33f0f88f 739 int first = -1;
1da177e4
LT
740
741 trace(icom_port, "FID_STATUS", status);
742 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
743
33f0f88f 744 count = tty_buffer_request_room(tty, count);
1da177e4 745 trace(icom_port, "RCV_COUNT", count);
1da177e4
LT
746
747 trace(icom_port, "REAL_COUNT", count);
748
749 offset =
750 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
751 icom_port->recv_buf_pci;
752
33f0f88f 753 /* Block copy all but the last byte as this may have status */
1da177e4 754 if (count > 0) {
33f0f88f
AC
755 first = icom_port->recv_buf[offset];
756 tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1);
1da177e4
LT
757 }
758
759 icount = &icom_port->uart_port.icount;
760 icount->rx += count;
761
762 /* Break detect logic */
763 if ((status & SA_FLAGS_FRAME_ERROR)
33f0f88f 764 && first == 0) {
1da177e4
LT
765 status &= ~SA_FLAGS_FRAME_ERROR;
766 status |= SA_FLAGS_BREAK_DET;
767 trace(icom_port, "BREAK_DET", 0);
768 }
769
33f0f88f
AC
770 flag = TTY_NORMAL;
771
1da177e4
LT
772 if (status &
773 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
774 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
775
776 if (status & SA_FLAGS_BREAK_DET)
777 icount->brk++;
778 if (status & SA_FLAGS_PARITY_ERROR)
779 icount->parity++;
780 if (status & SA_FLAGS_FRAME_ERROR)
781 icount->frame++;
782 if (status & SA_FLAGS_OVERRUN)
783 icount->overrun++;
784
785 /*
786 * Now check to see if character should be
787 * ignored, and mask off conditions which
788 * should be ignored.
789 */
790 if (status & icom_port->ignore_status_mask) {
791 trace(icom_port, "IGNORE_CHAR", 0);
792 goto ignore_char;
793 }
794
795 status &= icom_port->read_status_mask;
796
797 if (status & SA_FLAGS_BREAK_DET) {
33f0f88f 798 flag = TTY_BREAK;
1da177e4
LT
799 } else if (status & SA_FLAGS_PARITY_ERROR) {
800 trace(icom_port, "PARITY_ERROR", 0);
33f0f88f 801 flag = TTY_PARITY;
1da177e4 802 } else if (status & SA_FLAGS_FRAME_ERROR)
33f0f88f
AC
803 flag = TTY_FRAME;
804
1da177e4
LT
805 }
806
33f0f88f
AC
807 tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag);
808
809 if (status & SA_FLAGS_OVERRUN)
810 /*
811 * Overrun is special, since it's
812 * reported immediately, and doesn't
813 * affect the current character
814 */
815 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
816ignore_char:
817 icom_port->statStg->rcv[rcv_buff].flags = 0;
1da177e4
LT
818 icom_port->statStg->rcv[rcv_buff].leLength = 0;
819 icom_port->statStg->rcv[rcv_buff].WorkingLength =
820 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
821
822 rcv_buff++;
823 if (rcv_buff == NUM_RBUFFS)
824 rcv_buff = 0;
825
826 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
827 }
828 icom_port->next_rcv = rcv_buff;
829 tty_flip_buffer_push(tty);
830}
831
832static void process_interrupt(u16 port_int_reg,
833 struct icom_port *icom_port)
834{
835
836 spin_lock(&icom_port->uart_port.lock);
837 trace(icom_port, "INTERRUPT", port_int_reg);
838
839 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
840 xmit_interrupt(port_int_reg, icom_port);
841
842 if (port_int_reg & INT_RCV_COMPLETED)
843 recv_interrupt(port_int_reg, icom_port);
844
845 spin_unlock(&icom_port->uart_port.lock);
846}
847
848static irqreturn_t icom_interrupt(int irq, void *dev_id,
849 struct pt_regs *regs)
850{
851 void __iomem * int_reg;
852 u32 adapter_interrupts;
853 u16 port_int_reg;
854 struct icom_adapter *icom_adapter;
855 struct icom_port *icom_port;
856
857 /* find icom_port for this interrupt */
858 icom_adapter = (struct icom_adapter *) dev_id;
859
860 if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
861 int_reg = icom_adapter->base_addr + 0x8024;
862
863 adapter_interrupts = readl(int_reg);
864
865 if (adapter_interrupts & 0x00003FFF) {
866 /* port 2 interrupt, NOTE: for all ADAPTER_V2, port 2 will be active */
867 icom_port = &icom_adapter->port_info[2];
868 port_int_reg = (u16) adapter_interrupts;
869 process_interrupt(port_int_reg, icom_port);
870 check_modem_status(icom_port);
871 }
872 if (adapter_interrupts & 0x3FFF0000) {
873 /* port 3 interrupt */
874 icom_port = &icom_adapter->port_info[3];
875 if (icom_port->status == ICOM_PORT_ACTIVE) {
876 port_int_reg =
877 (u16) (adapter_interrupts >> 16);
878 process_interrupt(port_int_reg, icom_port);
879 check_modem_status(icom_port);
880 }
881 }
882
883 /* Clear out any pending interrupts */
884 writel(adapter_interrupts, int_reg);
885
886 int_reg = icom_adapter->base_addr + 0x8004;
887 } else {
888 int_reg = icom_adapter->base_addr + 0x4004;
889 }
890
891 adapter_interrupts = readl(int_reg);
892
893 if (adapter_interrupts & 0x00003FFF) {
894 /* port 0 interrupt, NOTE: for all adapters, port 0 will be active */
895 icom_port = &icom_adapter->port_info[0];
896 port_int_reg = (u16) adapter_interrupts;
897 process_interrupt(port_int_reg, icom_port);
898 check_modem_status(icom_port);
899 }
900 if (adapter_interrupts & 0x3FFF0000) {
901 /* port 1 interrupt */
902 icom_port = &icom_adapter->port_info[1];
903 if (icom_port->status == ICOM_PORT_ACTIVE) {
904 port_int_reg = (u16) (adapter_interrupts >> 16);
905 process_interrupt(port_int_reg, icom_port);
906 check_modem_status(icom_port);
907 }
908 }
909
910 /* Clear out any pending interrupts */
911 writel(adapter_interrupts, int_reg);
912
913 /* flush the write */
914 adapter_interrupts = readl(int_reg);
915
916 return IRQ_HANDLED;
917}
918
919/*
920 * ------------------------------------------------------------------
921 * Begin serial-core API
922 * ------------------------------------------------------------------
923 */
924static unsigned int icom_tx_empty(struct uart_port *port)
925{
926 int ret;
927 unsigned long flags;
928
929 spin_lock_irqsave(&port->lock, flags);
930 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
931 SA_FLAGS_READY_TO_XMIT)
932 ret = TIOCSER_TEMT;
933 else
934 ret = 0;
935
936 spin_unlock_irqrestore(&port->lock, flags);
937 return ret;
938}
939
940static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
941{
942 unsigned char local_osr;
943
944 trace(ICOM_PORT, "SET_MODEM", 0);
945 local_osr = readb(&ICOM_PORT->dram->osr);
946
947 if (mctrl & TIOCM_RTS) {
948 trace(ICOM_PORT, "RAISE_RTS", 0);
949 local_osr |= ICOM_RTS;
950 } else {
951 trace(ICOM_PORT, "LOWER_RTS", 0);
952 local_osr &= ~ICOM_RTS;
953 }
954
955 if (mctrl & TIOCM_DTR) {
956 trace(ICOM_PORT, "RAISE_DTR", 0);
957 local_osr |= ICOM_DTR;
958 } else {
959 trace(ICOM_PORT, "LOWER_DTR", 0);
960 local_osr &= ~ICOM_DTR;
961 }
962
963 writeb(local_osr, &ICOM_PORT->dram->osr);
964}
965
966static unsigned int icom_get_mctrl(struct uart_port *port)
967{
968 unsigned char status;
969 unsigned int result;
970
971 trace(ICOM_PORT, "GET_MODEM", 0);
972
973 status = readb(&ICOM_PORT->dram->isr);
974
975 result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
976 | ((status & ICOM_RI) ? TIOCM_RNG : 0)
977 | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
978 | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
979 return result;
980}
981
b129a8cc 982static void icom_stop_tx(struct uart_port *port)
1da177e4
LT
983{
984 unsigned char cmdReg;
985
b129a8cc
RK
986 trace(ICOM_PORT, "STOP", 0);
987 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
988 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
1da177e4
LT
989}
990
b129a8cc 991static void icom_start_tx(struct uart_port *port)
1da177e4
LT
992{
993 unsigned char cmdReg;
994
995 trace(ICOM_PORT, "START", 0);
996 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
997 if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
998 writeb(cmdReg & ~CMD_HOLD_XMIT,
999 &ICOM_PORT->dram->CmdReg);
1000
1001 icom_write(port);
1002}
1003
1004static void icom_send_xchar(struct uart_port *port, char ch)
1005{
1006 unsigned char xdata;
1007 int index;
1008 unsigned long flags;
1009
1010 trace(ICOM_PORT, "SEND_XCHAR", ch);
1011
1012 /* wait .1 sec to send char */
1013 for (index = 0; index < 10; index++) {
1014 spin_lock_irqsave(&port->lock, flags);
1015 xdata = readb(&ICOM_PORT->dram->xchar);
1016 if (xdata == 0x00) {
1017 trace(ICOM_PORT, "QUICK_WRITE", 0);
1018 writeb(ch, &ICOM_PORT->dram->xchar);
1019
1020 /* flush write operation */
1021 xdata = readb(&ICOM_PORT->dram->xchar);
1022 spin_unlock_irqrestore(&port->lock, flags);
1023 break;
1024 }
1025 spin_unlock_irqrestore(&port->lock, flags);
1026 msleep(10);
1027 }
1028}
1029
1030static void icom_stop_rx(struct uart_port *port)
1031{
1032 unsigned char cmdReg;
1033
1034 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1035 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1036}
1037
1038static void icom_enable_ms(struct uart_port *port)
1039{
1040 /* no-op */
1041}
1042
1043static void icom_break(struct uart_port *port, int break_state)
1044{
1045 unsigned char cmdReg;
1046 unsigned long flags;
1047
1048 spin_lock_irqsave(&port->lock, flags);
1049 trace(ICOM_PORT, "BREAK", 0);
1050 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1051 if (break_state == -1) {
1052 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1053 } else {
1054 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1055 }
1056 spin_unlock_irqrestore(&port->lock, flags);
1057}
1058
1059static int icom_open(struct uart_port *port)
1060{
1061 int retval;
1062
1063 kobject_get(&ICOM_PORT->adapter->kobj);
1064 retval = startup(ICOM_PORT);
1065
1066 if (retval) {
1067 kobject_put(&ICOM_PORT->adapter->kobj);
1068 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1069 return retval;
1070 }
1071
1072 return 0;
1073}
1074
1075static void icom_close(struct uart_port *port)
1076{
1077 unsigned char cmdReg;
1078
1079 trace(ICOM_PORT, "CLOSE", 0);
1080
1081 /* stop receiver */
1082 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1083 writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1084 &ICOM_PORT->dram->CmdReg);
1085
1086 shutdown(ICOM_PORT);
1087
1088 kobject_put(&ICOM_PORT->adapter->kobj);
1089}
1090
1091static void icom_set_termios(struct uart_port *port,
1092 struct termios *termios,
1093 struct termios *old_termios)
1094{
1095 int baud;
1096 unsigned cflag, iflag;
1097 int bits;
1098 char new_config2;
1099 char new_config3 = 0;
1100 char tmp_byte;
1101 int index;
1102 int rcv_buff, xmit_buff;
1103 unsigned long offset;
1104 unsigned long flags;
1105
1106 spin_lock_irqsave(&port->lock, flags);
1107 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1108
1109 cflag = termios->c_cflag;
1110 iflag = termios->c_iflag;
1111
1112 new_config2 = ICOM_ACFG_DRIVE1;
1113
1114 /* byte size and parity */
1115 switch (cflag & CSIZE) {
1116 case CS5: /* 5 bits/char */
1117 new_config2 |= ICOM_ACFG_5BPC;
1118 bits = 7;
1119 break;
1120 case CS6: /* 6 bits/char */
1121 new_config2 |= ICOM_ACFG_6BPC;
1122 bits = 8;
1123 break;
1124 case CS7: /* 7 bits/char */
1125 new_config2 |= ICOM_ACFG_7BPC;
1126 bits = 9;
1127 break;
1128 case CS8: /* 8 bits/char */
1129 new_config2 |= ICOM_ACFG_8BPC;
1130 bits = 10;
1131 break;
1132 default:
1133 bits = 10;
1134 break;
1135 }
1136 if (cflag & CSTOPB) {
1137 /* 2 stop bits */
1138 new_config2 |= ICOM_ACFG_2STOP_BIT;
1139 bits++;
1140 }
1141 if (cflag & PARENB) {
1142 /* parity bit enabled */
1143 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1144 trace(ICOM_PORT, "PARENB", 0);
1145 bits++;
1146 }
1147 if (cflag & PARODD) {
1148 /* odd parity */
1149 new_config2 |= ICOM_ACFG_PARITY_ODD;
1150 trace(ICOM_PORT, "PARODD", 0);
1151 }
1152
1153 /* Determine divisor based on baud rate */
1154 baud = uart_get_baud_rate(port, termios, old_termios,
1155 icom_acfg_baud[0],
1156 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1157 if (!baud)
1158 baud = 9600; /* B0 transition handled in rs_set_termios */
1159
1160 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1161 if (icom_acfg_baud[index] == baud) {
1162 new_config3 = index;
1163 break;
1164 }
1165 }
1166
1167 uart_update_timeout(port, cflag, baud);
1168
1169 /* CTS flow control flag and modem status interrupts */
1170 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1171 if (cflag & CRTSCTS)
1172 tmp_byte |= HDLC_HDW_FLOW;
1173 else
1174 tmp_byte &= ~HDLC_HDW_FLOW;
1175 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1176
1177 /*
1178 * Set up parity check flag
1179 */
1180 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1181 if (iflag & INPCK)
1182 ICOM_PORT->read_status_mask |=
1183 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1184
1185 if ((iflag & BRKINT) || (iflag & PARMRK))
1186 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1187
1188 /*
1189 * Characters to ignore
1190 */
1191 ICOM_PORT->ignore_status_mask = 0;
1192 if (iflag & IGNPAR)
1193 ICOM_PORT->ignore_status_mask |=
1194 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1195 if (iflag & IGNBRK) {
1196 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1197 /*
1198 * If we're ignore parity and break indicators, ignore
1199 * overruns too. (For real raw support).
1200 */
1201 if (iflag & IGNPAR)
1202 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1203 }
1204
1205 /*
1206 * !!! ignore all characters if CREAD is not set
1207 */
1208 if ((cflag & CREAD) == 0)
1209 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1210
1211 /* Turn off Receiver to prepare for reset */
1212 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1213
1214 for (index = 0; index < 10; index++) {
1215 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1216 break;
1217 }
1218 }
1219
1220 /* clear all current buffers of data */
1221 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1222 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1223 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1224 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1225 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1226 }
1227
1228 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1229 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1230 }
1231
1232 /* activate changes and start xmit and receiver here */
1233 /* Enable the receiver */
1234 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1235 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1236 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1237 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1238 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1239 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer)); /* 0.5 seconds */
1240 writeb(0xFF, &(ICOM_PORT->dram->ier)); /* enable modem signal interrupts */
1241
1242 /* reset processor */
1243 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1244
1245 for (index = 0; index < 10; index++) {
1246 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1247 break;
1248 }
1249 }
1250
1251 /* Enable Transmitter and Reciever */
1252 offset =
1253 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1254 (unsigned long) ICOM_PORT->statStg;
1255 writel(ICOM_PORT->statStg_pci + offset,
1256 &ICOM_PORT->dram->RcvStatusAddr);
1257 ICOM_PORT->next_rcv = 0;
1258 ICOM_PORT->put_length = 0;
1259 *ICOM_PORT->xmitRestart = 0;
1260 writel(ICOM_PORT->xmitRestart_pci,
1261 &ICOM_PORT->dram->XmitStatusAddr);
1262 trace(ICOM_PORT, "XR_ENAB", 0);
1263 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1264
1265 spin_unlock_irqrestore(&port->lock, flags);
1266}
1267
1268static const char *icom_type(struct uart_port *port)
1269{
1270 return "icom";
1271}
1272
1273static void icom_release_port(struct uart_port *port)
1274{
1275}
1276
1277static int icom_request_port(struct uart_port *port)
1278{
1279 return 0;
1280}
1281
1282static void icom_config_port(struct uart_port *port, int flags)
1283{
1284 port->type = PORT_ICOM;
1285}
1286
1287static struct uart_ops icom_ops = {
1288 .tx_empty = icom_tx_empty,
1289 .set_mctrl = icom_set_mctrl,
1290 .get_mctrl = icom_get_mctrl,
1291 .stop_tx = icom_stop_tx,
1292 .start_tx = icom_start_tx,
1293 .send_xchar = icom_send_xchar,
1294 .stop_rx = icom_stop_rx,
1295 .enable_ms = icom_enable_ms,
1296 .break_ctl = icom_break,
1297 .startup = icom_open,
1298 .shutdown = icom_close,
1299 .set_termios = icom_set_termios,
1300 .type = icom_type,
1301 .release_port = icom_release_port,
1302 .request_port = icom_request_port,
1303 .config_port = icom_config_port,
1304};
1305
1306#define ICOM_CONSOLE NULL
1307
1308static struct uart_driver icom_uart_driver = {
1309 .owner = THIS_MODULE,
1310 .driver_name = ICOM_DRIVER_NAME,
1311 .dev_name = "ttyA",
1312 .major = ICOM_MAJOR,
1313 .minor = ICOM_MINOR_START,
1314 .nr = NR_PORTS,
1315 .cons = ICOM_CONSOLE,
1316};
1317
1318static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1319{
1320 u32 subsystem_id = icom_adapter->subsystem_id;
1321 int retval = 0;
1322 int i;
1323 struct icom_port *icom_port;
1324
1325 if (icom_adapter->version == ADAPTER_V1) {
1326 icom_adapter->numb_ports = 2;
1327
1328 for (i = 0; i < 2; i++) {
1329 icom_port = &icom_adapter->port_info[i];
1330 icom_port->port = i;
1331 icom_port->status = ICOM_PORT_ACTIVE;
1332 icom_port->imbed_modem = ICOM_UNKNOWN;
1333 }
1334 } else {
1335 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1336 icom_adapter->numb_ports = 4;
1337
1338 for (i = 0; i < 4; i++) {
1339 icom_port = &icom_adapter->port_info[i];
1340
1341 icom_port->port = i;
1342 icom_port->status = ICOM_PORT_ACTIVE;
1343 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1344 }
1345 } else {
1346 icom_adapter->numb_ports = 4;
1347
1348 icom_adapter->port_info[0].port = 0;
1349 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1350
1351 if (subsystem_id ==
1352 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1353 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1354 } else {
1355 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1356 }
1357
1358 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1359
1360 icom_adapter->port_info[2].port = 2;
1361 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1362 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1363 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1364 }
1365 }
1366
1367 return retval;
1368}
1369
1370static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1371{
1372 if (icom_adapter->version == ADAPTER_V1) {
1373 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1374 icom_port->int_reg = icom_adapter->base_addr +
1375 0x4004 + 2 - 2 * port_num;
1376 } else {
1377 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1378 if (icom_port->port < 2)
1379 icom_port->int_reg = icom_adapter->base_addr +
1380 0x8004 + 2 - 2 * icom_port->port;
1381 else
1382 icom_port->int_reg = icom_adapter->base_addr +
1383 0x8024 + 2 - 2 * (icom_port->port - 2);
1384 }
1385}
1386static int __init icom_load_ports(struct icom_adapter *icom_adapter)
1387{
1388 struct icom_port *icom_port;
1389 int port_num;
1390 int retval;
1391
1392 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1393
1394 icom_port = &icom_adapter->port_info[port_num];
1395
1396 if (icom_port->status == ICOM_PORT_ACTIVE) {
1397 icom_port_active(icom_port, icom_adapter, port_num);
1398 icom_port->dram = icom_adapter->base_addr +
1399 0x2000 * icom_port->port;
1400
1401 icom_port->adapter = icom_adapter;
1402
1403 /* get port memory */
1404 if ((retval = get_port_memory(icom_port)) != 0) {
1405 dev_err(&icom_port->adapter->pci_dev->dev,
1406 "Memory allocation for port FAILED\n");
1407 }
1408 }
1409 }
1410 return 0;
1411}
1412
1413static int __devinit icom_alloc_adapter(struct icom_adapter
1414 **icom_adapter_ref)
1415{
1416 int adapter_count = 0;
1417 struct icom_adapter *icom_adapter;
1418 struct icom_adapter *cur_adapter_entry;
1419 struct list_head *tmp;
1420
1421 icom_adapter = (struct icom_adapter *)
1422 kmalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1423
1424 if (!icom_adapter) {
1425 return -ENOMEM;
1426 }
1427
1428 memset(icom_adapter, 0, sizeof(struct icom_adapter));
1429
1430 list_for_each(tmp, &icom_adapter_head) {
1431 cur_adapter_entry =
1432 list_entry(tmp, struct icom_adapter,
1433 icom_adapter_entry);
1434 if (cur_adapter_entry->index != adapter_count) {
1435 break;
1436 }
1437 adapter_count++;
1438 }
1439
1440 icom_adapter->index = adapter_count;
1441 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1442
1443 *icom_adapter_ref = icom_adapter;
1444 return 0;
1445}
1446
1447static void icom_free_adapter(struct icom_adapter *icom_adapter)
1448{
1449 list_del(&icom_adapter->icom_adapter_entry);
1450 kfree(icom_adapter);
1451}
1452
1453static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1454{
1455 struct icom_port *icom_port;
1456 int index;
1457
1458 for (index = 0; index < icom_adapter->numb_ports; index++) {
1459 icom_port = &icom_adapter->port_info[index];
1460
1461 if (icom_port->status == ICOM_PORT_ACTIVE) {
1462 dev_info(&icom_adapter->pci_dev->dev,
1463 "Device removed\n");
1464
1465 uart_remove_one_port(&icom_uart_driver,
1466 &icom_port->uart_port);
1467
1468 /* be sure that DTR and RTS are dropped */
1469 writeb(0x00, &icom_port->dram->osr);
1470
1471 /* Wait 0.1 Sec for simple Init to complete */
1472 msleep(100);
1473
1474 /* Stop proccessor */
1475 stop_processor(icom_port);
1476
1477 free_port_memory(icom_port);
1478 }
1479 }
1480
1481 free_irq(icom_adapter->irq_number, (void *) icom_adapter);
1482 iounmap(icom_adapter->base_addr);
1483 icom_free_adapter(icom_adapter);
1484 pci_release_regions(icom_adapter->pci_dev);
1485}
1486
1487static void icom_kobj_release(struct kobject *kobj)
1488{
1489 struct icom_adapter *icom_adapter;
1490
1491 icom_adapter = to_icom_adapter(kobj);
1492 icom_remove_adapter(icom_adapter);
1493}
1494
1495static struct kobj_type icom_kobj_type = {
1496 .release = icom_kobj_release,
1497};
1498
1499static int __devinit icom_probe(struct pci_dev *dev,
1500 const struct pci_device_id *ent)
1501{
1502 int index;
1503 unsigned int command_reg;
1504 int retval;
1505 struct icom_adapter *icom_adapter;
1506 struct icom_port *icom_port;
1507
1508 retval = pci_enable_device(dev);
1509 if (retval) {
1510 dev_err(&dev->dev, "Device enable FAILED\n");
1511 return retval;
1512 }
1513
1514 if ( (retval = pci_request_regions(dev, "icom"))) {
1515 dev_err(&dev->dev, "pci_request_region FAILED\n");
1516 pci_disable_device(dev);
1517 return retval;
1518 }
1519
1520 pci_set_master(dev);
1521
1522 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1523 dev_err(&dev->dev, "PCI Config read FAILED\n");
1524 return retval;
1525 }
1526
1527 pci_write_config_dword(dev, PCI_COMMAND,
1528 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1529 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1530
1531 if (ent->driver_data == ADAPTER_V1) {
1532 pci_write_config_dword(dev, 0x44, 0x8300830A);
1533 } else {
1534 pci_write_config_dword(dev, 0x44, 0x42004200);
1535 pci_write_config_dword(dev, 0x48, 0x42004200);
1536 }
1537
1538
1539 retval = icom_alloc_adapter(&icom_adapter);
1540 if (retval) {
1541 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1542 retval = -EIO;
1543 goto probe_exit0;
1544 }
1545
1546 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1547 icom_adapter->irq_number = dev->irq;
1548 icom_adapter->pci_dev = dev;
1549 icom_adapter->version = ent->driver_data;
1550 icom_adapter->subsystem_id = ent->subdevice;
1551
1552
1553 retval = icom_init_ports(icom_adapter);
1554 if (retval) {
1555 dev_err(&dev->dev, "Port configuration failed\n");
1556 goto probe_exit1;
1557 }
1558
1559 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1560 pci_resource_len(dev, 0));
1561
1562 if (!icom_adapter->base_addr)
1563 goto probe_exit1;
1564
1565 /* save off irq and request irq line */
1566 if ( (retval = request_irq(dev->irq, icom_interrupt,
1567 SA_INTERRUPT | SA_SHIRQ, ICOM_DRIVER_NAME,
1568 (void *) icom_adapter))) {
1569 goto probe_exit2;
1570 }
1571
1572 retval = icom_load_ports(icom_adapter);
1573
1574 for (index = 0; index < icom_adapter->numb_ports; index++) {
1575 icom_port = &icom_adapter->port_info[index];
1576
1577 if (icom_port->status == ICOM_PORT_ACTIVE) {
1578 icom_port->uart_port.irq = icom_port->adapter->irq_number;
1579 icom_port->uart_port.type = PORT_ICOM;
1580 icom_port->uart_port.iotype = UPIO_MEM;
1581 icom_port->uart_port.membase =
1582 (char *) icom_adapter->base_addr_pci;
1583 icom_port->uart_port.fifosize = 16;
1584 icom_port->uart_port.ops = &icom_ops;
1585 icom_port->uart_port.line =
1586 icom_port->port + icom_adapter->index * 4;
1587 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1588 icom_port->status = ICOM_PORT_OFF;
1589 dev_err(&dev->dev, "Device add failed\n");
1590 } else
1591 dev_info(&dev->dev, "Device added\n");
1592 }
1593 }
1594
1595 kobject_init(&icom_adapter->kobj);
1596 icom_adapter->kobj.ktype = &icom_kobj_type;
1597 return 0;
1598
1599probe_exit2:
1600 iounmap(icom_adapter->base_addr);
1601probe_exit1:
1602 icom_free_adapter(icom_adapter);
1603
1604probe_exit0:
1605 pci_release_regions(dev);
1606 pci_disable_device(dev);
1607
1608 return retval;
1609
1610
1611}
1612
1613static void __devexit icom_remove(struct pci_dev *dev)
1614{
1615 struct icom_adapter *icom_adapter;
1616 struct list_head *tmp;
1617
1618 list_for_each(tmp, &icom_adapter_head) {
1619 icom_adapter = list_entry(tmp, struct icom_adapter,
1620 icom_adapter_entry);
1621 if (icom_adapter->pci_dev == dev) {
1622 kobject_put(&icom_adapter->kobj);
1623 return;
1624 }
1625 }
1626
1627 dev_err(&dev->dev, "Unable to find device to remove\n");
1628}
1629
1630static struct pci_driver icom_pci_driver = {
1631 .name = ICOM_DRIVER_NAME,
1632 .id_table = icom_pci_table,
1633 .probe = icom_probe,
1634 .remove = __devexit_p(icom_remove),
1635};
1636
1637static int __init icom_init(void)
1638{
1639 int ret;
1640
1641 spin_lock_init(&icom_lock);
1642
1643 ret = uart_register_driver(&icom_uart_driver);
1644 if (ret)
1645 return ret;
1646
1647 ret = pci_register_driver(&icom_pci_driver);
1648
1649 if (ret < 0)
1650 uart_unregister_driver(&icom_uart_driver);
1651
1652 return ret;
1653}
1654
1655static void __exit icom_exit(void)
1656{
1657 pci_unregister_driver(&icom_pci_driver);
1658 uart_unregister_driver(&icom_uart_driver);
1659}
1660
1661module_init(icom_init);
1662module_exit(icom_exit);
1663
1664#ifdef ICOM_TRACE
1665static inline void trace(struct icom_port *icom_port, char *trace_pt,
1666 unsigned long trace_data)
1667{
1668 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1669 icom_port->port, trace_pt, trace_data);
1670}
1671#endif
1672
1673MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1674MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1675MODULE_SUPPORTED_DEVICE
1676 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1677MODULE_LICENSE("GPL");
1678
This page took 0.181348 seconds and 5 git commands to generate.