Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 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

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_enable_ms(struct uart_port *port)
1056 {
1057         /* no-op */
1058 }
1059 
1060 static void icom_break(struct uart_port *port, int break_state)
1061 {
1062         unsigned char cmdReg;
1063         unsigned long flags;
1064 
1065         spin_lock_irqsave(&port->lock, flags);
1066         trace(ICOM_PORT, "BREAK", 0);
1067         cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1068         if (break_state == -1) {
1069                 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1070         } else {
1071                 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1072         }
1073         spin_unlock_irqrestore(&port->lock, flags);
1074 }
1075 
1076 static int icom_open(struct uart_port *port)
1077 {
1078         int retval;
1079 
1080         kref_get(&ICOM_PORT->adapter->kref);
1081         retval = startup(ICOM_PORT);
1082 
1083         if (retval) {
1084                 kref_put(&ICOM_PORT->adapter->kref, icom_kref_release);
1085                 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1086                 return retval;
1087         }
1088 
1089         return 0;
1090 }
1091 
1092 static void icom_close(struct uart_port *port)
1093 {
1094         unsigned char cmdReg;
1095 
1096         trace(ICOM_PORT, "CLOSE", 0);
1097 
1098         /* stop receiver */
1099         cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1100         writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1101 
1102         shutdown(ICOM_PORT);
1103 
1104         kref_put(&ICOM_PORT->adapter->kref, icom_kref_release);
1105 }
1106 
1107 static void icom_set_termios(struct uart_port *port,
1108                              struct ktermios *termios,
1109                              struct ktermios *old_termios)
1110 {
1111         int baud;
1112         unsigned cflag, iflag;
1113         char new_config2;
1114         char new_config3 = 0;
1115         char tmp_byte;
1116         int index;
1117         int rcv_buff, xmit_buff;
1118         unsigned long offset;
1119         unsigned long flags;
1120 
1121         spin_lock_irqsave(&port->lock, flags);
1122         trace(ICOM_PORT, "CHANGE_SPEED", 0);
1123 
1124         cflag = termios->c_cflag;
1125         iflag = termios->c_iflag;
1126 
1127         new_config2 = ICOM_ACFG_DRIVE1;
1128 
1129         /* byte size and parity */
1130         switch (cflag & CSIZE) {
1131         case CS5:               /* 5 bits/char */
1132                 new_config2 |= ICOM_ACFG_5BPC;
1133                 break;
1134         case CS6:               /* 6 bits/char */
1135                 new_config2 |= ICOM_ACFG_6BPC;
1136                 break;
1137         case CS7:               /* 7 bits/char */
1138                 new_config2 |= ICOM_ACFG_7BPC;
1139                 break;
1140         case CS8:               /* 8 bits/char */
1141                 new_config2 |= ICOM_ACFG_8BPC;
1142                 break;
1143         default:
1144                 break;
1145         }
1146         if (cflag & CSTOPB) {
1147                 /* 2 stop bits */
1148                 new_config2 |= ICOM_ACFG_2STOP_BIT;
1149         }
1150         if (cflag & PARENB) {
1151                 /* parity bit enabled */
1152                 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1153                 trace(ICOM_PORT, "PARENB", 0);
1154         }
1155         if (cflag & PARODD) {
1156                 /* odd parity */
1157                 new_config2 |= ICOM_ACFG_PARITY_ODD;
1158                 trace(ICOM_PORT, "PARODD", 0);
1159         }
1160 
1161         /* Determine divisor based on baud rate */
1162         baud = uart_get_baud_rate(port, termios, old_termios,
1163                                   icom_acfg_baud[0],
1164                                   icom_acfg_baud[BAUD_TABLE_LIMIT]);
1165         if (!baud)
1166                 baud = 9600;    /* B0 transition handled in rs_set_termios */
1167 
1168         for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1169                 if (icom_acfg_baud[index] == baud) {
1170                         new_config3 = index;
1171                         break;
1172                 }
1173         }
1174 
1175         uart_update_timeout(port, cflag, baud);
1176 
1177         /* CTS flow control flag and modem status interrupts */
1178         tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1179         if (cflag & CRTSCTS)
1180                 tmp_byte |= HDLC_HDW_FLOW;
1181         else
1182                 tmp_byte &= ~HDLC_HDW_FLOW;
1183         writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1184 
1185         /*
1186          * Set up parity check flag
1187          */
1188         ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1189         if (iflag & INPCK)
1190                 ICOM_PORT->read_status_mask |=
1191                     SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1192 
1193         if ((iflag & BRKINT) || (iflag & PARMRK))
1194                 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1195 
1196         /*
1197          * Characters to ignore
1198          */
1199         ICOM_PORT->ignore_status_mask = 0;
1200         if (iflag & IGNPAR)
1201                 ICOM_PORT->ignore_status_mask |=
1202                     SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1203         if (iflag & IGNBRK) {
1204                 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1205                 /*
1206                  * If we're ignore parity and break indicators, ignore
1207                  * overruns too.  (For real raw support).
1208                  */
1209                 if (iflag & IGNPAR)
1210                         ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1211         }
1212 
1213         /*
1214          * !!! ignore all characters if CREAD is not set
1215          */
1216         if ((cflag & CREAD) == 0)
1217                 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1218 
1219         /* Turn off Receiver to prepare for reset */
1220         writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1221 
1222         for (index = 0; index < 10; index++) {
1223                 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1224                         break;
1225                 }
1226         }
1227 
1228         /* clear all current buffers of data */
1229         for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1230                 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1231                 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1232                 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1233                     (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1234         }
1235 
1236         for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1237                 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1238         }
1239 
1240         /* activate changes and start xmit and receiver here */
1241         /* Enable the receiver */
1242         writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1243         writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1244         tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1245         tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1246         writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1247         writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer));    /* 0.5 seconds */
1248         writeb(0xFF, &(ICOM_PORT->dram->ier));  /* enable modem signal interrupts */
1249 
1250         /* reset processor */
1251         writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1252 
1253         for (index = 0; index < 10; index++) {
1254                 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1255                         break;
1256                 }
1257         }
1258 
1259         /* Enable Transmitter and Receiver */
1260         offset =
1261             (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1262             (unsigned long) ICOM_PORT->statStg;
1263         writel(ICOM_PORT->statStg_pci + offset,
1264                &ICOM_PORT->dram->RcvStatusAddr);
1265         ICOM_PORT->next_rcv = 0;
1266         ICOM_PORT->put_length = 0;
1267         *ICOM_PORT->xmitRestart = 0;
1268         writel(ICOM_PORT->xmitRestart_pci,
1269                &ICOM_PORT->dram->XmitStatusAddr);
1270         trace(ICOM_PORT, "XR_ENAB", 0);
1271         writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1272 
1273         spin_unlock_irqrestore(&port->lock, flags);
1274 }
1275 
1276 static const char *icom_type(struct uart_port *port)
1277 {
1278         return "icom";
1279 }
1280 
1281 static void icom_release_port(struct uart_port *port)
1282 {
1283 }
1284 
1285 static int icom_request_port(struct uart_port *port)
1286 {
1287         return 0;
1288 }
1289 
1290 static void icom_config_port(struct uart_port *port, int flags)
1291 {
1292         port->type = PORT_ICOM;
1293 }
1294 
1295 static struct uart_ops icom_ops = {
1296         .tx_empty = icom_tx_empty,
1297         .set_mctrl = icom_set_mctrl,
1298         .get_mctrl = icom_get_mctrl,
1299         .stop_tx = icom_stop_tx,
1300         .start_tx = icom_start_tx,
1301         .send_xchar = icom_send_xchar,
1302         .stop_rx = icom_stop_rx,
1303         .enable_ms = icom_enable_ms,
1304         .break_ctl = icom_break,
1305         .startup = icom_open,
1306         .shutdown = icom_close,
1307         .set_termios = icom_set_termios,
1308         .type = icom_type,
1309         .release_port = icom_release_port,
1310         .request_port = icom_request_port,
1311         .config_port = icom_config_port,
1312 };
1313 
1314 #define ICOM_CONSOLE NULL
1315 
1316 static struct uart_driver icom_uart_driver = {
1317         .owner = THIS_MODULE,
1318         .driver_name = ICOM_DRIVER_NAME,
1319         .dev_name = "ttyA",
1320         .major = ICOM_MAJOR,
1321         .minor = ICOM_MINOR_START,
1322         .nr = NR_PORTS,
1323         .cons = ICOM_CONSOLE,
1324 };
1325 
1326 static int icom_init_ports(struct icom_adapter *icom_adapter)
1327 {
1328         u32 subsystem_id = icom_adapter->subsystem_id;
1329         int i;
1330         struct icom_port *icom_port;
1331 
1332         if (icom_adapter->version == ADAPTER_V1) {
1333                 icom_adapter->numb_ports = 2;
1334 
1335                 for (i = 0; i < 2; i++) {
1336                         icom_port = &icom_adapter->port_info[i];
1337                         icom_port->port = i;
1338                         icom_port->status = ICOM_PORT_ACTIVE;
1339                         icom_port->imbed_modem = ICOM_UNKNOWN;
1340                 }
1341         } else {
1342                 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1343                         icom_adapter->numb_ports = 4;
1344 
1345                         for (i = 0; i < 4; i++) {
1346                                 icom_port = &icom_adapter->port_info[i];
1347 
1348                                 icom_port->port = i;
1349                                 icom_port->status = ICOM_PORT_ACTIVE;
1350                                 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1351                         }
1352                 } else {
1353                         icom_adapter->numb_ports = 4;
1354 
1355                         icom_adapter->port_info[0].port = 0;
1356                         icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1357 
1358                         if (subsystem_id ==
1359                             PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1360                                 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1361                         } else {
1362                                 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1363                         }
1364 
1365                         icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1366 
1367                         icom_adapter->port_info[2].port = 2;
1368                         icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1369                         icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1370                         icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1371                 }
1372         }
1373 
1374         return 0;
1375 }
1376 
1377 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1378 {
1379         if (icom_adapter->version == ADAPTER_V1) {
1380                 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1381                 icom_port->int_reg = icom_adapter->base_addr +
1382                     0x4004 + 2 - 2 * port_num;
1383         } else {
1384                 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1385                 if (icom_port->port < 2)
1386                         icom_port->int_reg = icom_adapter->base_addr +
1387                             0x8004 + 2 - 2 * icom_port->port;
1388                 else
1389                         icom_port->int_reg = icom_adapter->base_addr +
1390                             0x8024 + 2 - 2 * (icom_port->port - 2);
1391         }
1392 }
1393 static int icom_load_ports(struct icom_adapter *icom_adapter)
1394 {
1395         struct icom_port *icom_port;
1396         int port_num;
1397 
1398         for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1399 
1400                 icom_port = &icom_adapter->port_info[port_num];
1401 
1402                 if (icom_port->status == ICOM_PORT_ACTIVE) {
1403                         icom_port_active(icom_port, icom_adapter, port_num);
1404                         icom_port->dram = icom_adapter->base_addr +
1405                                         0x2000 * icom_port->port;
1406 
1407                         icom_port->adapter = icom_adapter;
1408 
1409                         /* get port memory */
1410                         if (get_port_memory(icom_port) != 0) {
1411                                 dev_err(&icom_port->adapter->pci_dev->dev,
1412                                         "Memory allocation for port FAILED\n");
1413                         }
1414                 }
1415         }
1416         return 0;
1417 }
1418 
1419 static int icom_alloc_adapter(struct icom_adapter
1420                                         **icom_adapter_ref)
1421 {
1422         int adapter_count = 0;
1423         struct icom_adapter *icom_adapter;
1424         struct icom_adapter *cur_adapter_entry;
1425         struct list_head *tmp;
1426 
1427         icom_adapter = kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1428 
1429         if (!icom_adapter) {
1430                 return -ENOMEM;
1431         }
1432 
1433         list_for_each(tmp, &icom_adapter_head) {
1434                 cur_adapter_entry =
1435                     list_entry(tmp, struct icom_adapter,
1436                                icom_adapter_entry);
1437                 if (cur_adapter_entry->index != adapter_count) {
1438                         break;
1439                 }
1440                 adapter_count++;
1441         }
1442 
1443         icom_adapter->index = adapter_count;
1444         list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1445 
1446         *icom_adapter_ref = icom_adapter;
1447         return 0;
1448 }
1449 
1450 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1451 {
1452         list_del(&icom_adapter->icom_adapter_entry);
1453         kfree(icom_adapter);
1454 }
1455 
1456 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1457 {
1458         struct icom_port *icom_port;
1459         int index;
1460 
1461         for (index = 0; index < icom_adapter->numb_ports; index++) {
1462                 icom_port = &icom_adapter->port_info[index];
1463 
1464                 if (icom_port->status == ICOM_PORT_ACTIVE) {
1465                         dev_info(&icom_adapter->pci_dev->dev,
1466                                  "Device removed\n");
1467 
1468                         uart_remove_one_port(&icom_uart_driver,
1469                                              &icom_port->uart_port);
1470 
1471                         /* be sure that DTR and RTS are dropped */
1472                         writeb(0x00, &icom_port->dram->osr);
1473 
1474                         /* Wait 0.1 Sec for simple Init to complete */
1475                         msleep(100);
1476 
1477                         /* Stop proccessor */
1478                         stop_processor(icom_port);
1479 
1480                         free_port_memory(icom_port);
1481                 }
1482         }
1483 
1484         free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
1485         iounmap(icom_adapter->base_addr);
1486         pci_release_regions(icom_adapter->pci_dev);
1487         icom_free_adapter(icom_adapter);
1488 }
1489 
1490 static void icom_kref_release(struct kref *kref)
1491 {
1492         struct icom_adapter *icom_adapter;
1493 
1494         icom_adapter = to_icom_adapter(kref);
1495         icom_remove_adapter(icom_adapter);
1496 }
1497 
1498 static int icom_probe(struct pci_dev *dev,
1499                                 const struct pci_device_id *ent)
1500 {
1501         int index;
1502         unsigned int command_reg;
1503         int retval;
1504         struct icom_adapter *icom_adapter;
1505         struct icom_port *icom_port;
1506 
1507         retval = pci_enable_device(dev);
1508         if (retval) {
1509                 dev_err(&dev->dev, "Device enable FAILED\n");
1510                 return retval;
1511         }
1512 
1513         if ( (retval = pci_request_regions(dev, "icom"))) {
1514                  dev_err(&dev->dev, "pci_request_regions FAILED\n");
1515                  pci_disable_device(dev);
1516                  return retval;
1517          }
1518 
1519         pci_set_master(dev);
1520 
1521         if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1522                 dev_err(&dev->dev, "PCI Config read FAILED\n");
1523                 return retval;
1524         }
1525 
1526         pci_write_config_dword(dev, PCI_COMMAND,
1527                 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1528                 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1529 
1530         if (ent->driver_data == ADAPTER_V1) {
1531                 pci_write_config_dword(dev, 0x44, 0x8300830A);
1532         } else {
1533                 pci_write_config_dword(dev, 0x44, 0x42004200);
1534                 pci_write_config_dword(dev, 0x48, 0x42004200);
1535         }
1536 
1537 
1538         retval = icom_alloc_adapter(&icom_adapter);
1539         if (retval) {
1540                  dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1541                  retval = -EIO;
1542                  goto probe_exit0;
1543         }
1544 
1545         icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1546         icom_adapter->pci_dev = dev;
1547         icom_adapter->version = ent->driver_data;
1548         icom_adapter->subsystem_id = ent->subdevice;
1549 
1550 
1551         retval = icom_init_ports(icom_adapter);
1552         if (retval) {
1553                 dev_err(&dev->dev, "Port configuration failed\n");
1554                 goto probe_exit1;
1555         }
1556 
1557         icom_adapter->base_addr = pci_ioremap_bar(dev, 0);
1558 
1559         if (!icom_adapter->base_addr)
1560                 goto probe_exit1;
1561 
1562          /* save off irq and request irq line */
1563          if ( (retval = request_irq(dev->irq, icom_interrupt,
1564                                    IRQF_SHARED, ICOM_DRIVER_NAME,
1565                                    (void *) icom_adapter))) {
1566                   goto probe_exit2;
1567          }
1568 
1569         retval = icom_load_ports(icom_adapter);
1570 
1571         for (index = 0; index < icom_adapter->numb_ports; index++) {
1572                 icom_port = &icom_adapter->port_info[index];
1573 
1574                 if (icom_port->status == ICOM_PORT_ACTIVE) {
1575                         icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
1576                         icom_port->uart_port.type = PORT_ICOM;
1577                         icom_port->uart_port.iotype = UPIO_MEM;
1578                         icom_port->uart_port.membase =
1579                                 (unsigned char __iomem *)icom_adapter->base_addr_pci;
1580                         icom_port->uart_port.fifosize = 16;
1581                         icom_port->uart_port.ops = &icom_ops;
1582                         icom_port->uart_port.line =
1583                         icom_port->port + icom_adapter->index * 4;
1584                         if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1585                                 icom_port->status = ICOM_PORT_OFF;
1586                                 dev_err(&dev->dev, "Device add failed\n");
1587                          } else
1588                                 dev_info(&dev->dev, "Device added\n");
1589                 }
1590         }
1591 
1592         kref_init(&icom_adapter->kref);
1593         return 0;
1594 
1595 probe_exit2:
1596         iounmap(icom_adapter->base_addr);
1597 probe_exit1:
1598         icom_free_adapter(icom_adapter);
1599 
1600 probe_exit0:
1601         pci_release_regions(dev);
1602         pci_disable_device(dev);
1603 
1604         return retval;
1605 }
1606 
1607 static void icom_remove(struct pci_dev *dev)
1608 {
1609         struct icom_adapter *icom_adapter;
1610         struct list_head *tmp;
1611 
1612         list_for_each(tmp, &icom_adapter_head) {
1613                 icom_adapter = list_entry(tmp, struct icom_adapter,
1614                                           icom_adapter_entry);
1615                 if (icom_adapter->pci_dev == dev) {
1616                         kref_put(&icom_adapter->kref, icom_kref_release);
1617                         return;
1618                 }
1619         }
1620 
1621         dev_err(&dev->dev, "Unable to find device to remove\n");
1622 }
1623 
1624 static struct pci_driver icom_pci_driver = {
1625         .name = ICOM_DRIVER_NAME,
1626         .id_table = icom_pci_table,
1627         .probe = icom_probe,
1628         .remove = icom_remove,
1629 };
1630 
1631 static int __init icom_init(void)
1632 {
1633         int ret;
1634 
1635         spin_lock_init(&icom_lock);
1636 
1637         ret = uart_register_driver(&icom_uart_driver);
1638         if (ret)
1639                 return ret;
1640 
1641         ret = pci_register_driver(&icom_pci_driver);
1642 
1643         if (ret < 0)
1644                 uart_unregister_driver(&icom_uart_driver);
1645 
1646         return ret;
1647 }
1648 
1649 static void __exit icom_exit(void)
1650 {
1651         pci_unregister_driver(&icom_pci_driver);
1652         uart_unregister_driver(&icom_uart_driver);
1653 }
1654 
1655 module_init(icom_init);
1656 module_exit(icom_exit);
1657 
1658 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1659 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1660 MODULE_SUPPORTED_DEVICE
1661     ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1662 MODULE_LICENSE("GPL");
1663 MODULE_FIRMWARE("icom_call_setup.bin");
1664 MODULE_FIRMWARE("icom_res_dce.bin");
1665 MODULE_FIRMWARE("icom_asc.bin");
1666 

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