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