Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/drivers/tty/serial/icom.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us