Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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