1 /* 2 * Generic Generic NCR5380 driver 3 * 4 * Copyright 1993, Drew Eckhardt 5 * Visionary Computing 6 * (Unix and Linux consulting and custom programming) 7 * drew@colorado.edu 8 * +1 (303) 440-4894 9 * 10 * NCR53C400 extensions (c) 1994,1995,1996, Kevin Lentin 11 * K.Lentin@cs.monash.edu.au 12 * 13 * NCR53C400A extensions (c) 1996, Ingmar Baumgart 14 * ingmar@gonzo.schwaben.de 15 * 16 * DTC3181E extensions (c) 1997, Ronald van Cuijlenborg 17 * ronald.van.cuijlenborg@tip.nl or nutty@dds.nl 18 * 19 * Added ISAPNP support for DTC436 adapters, 20 * Thomas Sailer, sailer@ife.ee.ethz.ch 21 * 22 * See Documentation/scsi/g_NCR5380.txt for more info. 23 */ 24 25 #include <asm/io.h> 26 #include <linux/blkdev.h> 27 #include <linux/module.h> 28 #include <scsi/scsi_host.h> 29 #include "g_NCR5380.h" 30 #include "NCR5380.h" 31 #include <linux/init.h> 32 #include <linux/ioport.h> 33 #include <linux/isa.h> 34 #include <linux/pnp.h> 35 #include <linux/interrupt.h> 36 37 #define MAX_CARDS 8 38 39 /* old-style parameters for compatibility */ 40 static int ncr_irq = -1; 41 static int ncr_addr; 42 static int ncr_5380; 43 static int ncr_53c400; 44 static int ncr_53c400a; 45 static int dtc_3181e; 46 static int hp_c2502; 47 module_param(ncr_irq, int, 0); 48 module_param(ncr_addr, int, 0); 49 module_param(ncr_5380, int, 0); 50 module_param(ncr_53c400, int, 0); 51 module_param(ncr_53c400a, int, 0); 52 module_param(dtc_3181e, int, 0); 53 module_param(hp_c2502, int, 0); 54 55 static int irq[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; 56 module_param_array(irq, int, NULL, 0); 57 MODULE_PARM_DESC(irq, "IRQ number(s) (0=none, 254=auto [default])"); 58 59 static int base[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 60 module_param_array(base, int, NULL, 0); 61 MODULE_PARM_DESC(base, "base address(es)"); 62 63 static int card[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; 64 module_param_array(card, int, NULL, 0); 65 MODULE_PARM_DESC(card, "card type (0=NCR5380, 1=NCR53C400, 2=NCR53C400A, 3=DTC3181E, 4=HP C2502)"); 66 67 MODULE_ALIAS("g_NCR5380_mmio"); 68 MODULE_LICENSE("GPL"); 69 70 static void g_NCR5380_trigger_irq(struct Scsi_Host *instance) 71 { 72 struct NCR5380_hostdata *hostdata = shost_priv(instance); 73 74 /* 75 * An interrupt is triggered whenever BSY = false, SEL = true 76 * and a bit set in the SELECT_ENABLE_REG is asserted on the 77 * SCSI bus. 78 * 79 * Note that the bus is only driven when the phase control signals 80 * (I/O, C/D, and MSG) match those in the TCR. 81 */ 82 NCR5380_write(TARGET_COMMAND_REG, 83 PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK)); 84 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); 85 NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); 86 NCR5380_write(INITIATOR_COMMAND_REG, 87 ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); 88 89 msleep(1); 90 91 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); 92 NCR5380_write(SELECT_ENABLE_REG, 0); 93 NCR5380_write(TARGET_COMMAND_REG, 0); 94 } 95 96 /** 97 * g_NCR5380_probe_irq - find the IRQ of a NCR5380 or equivalent 98 * @instance: SCSI host instance 99 * 100 * Autoprobe for the IRQ line used by the card by triggering an IRQ 101 * and then looking to see what interrupt actually turned up. 102 */ 103 104 static int g_NCR5380_probe_irq(struct Scsi_Host *instance) 105 { 106 struct NCR5380_hostdata *hostdata = shost_priv(instance); 107 int irq_mask, irq; 108 109 NCR5380_read(RESET_PARITY_INTERRUPT_REG); 110 irq_mask = probe_irq_on(); 111 g_NCR5380_trigger_irq(instance); 112 irq = probe_irq_off(irq_mask); 113 NCR5380_read(RESET_PARITY_INTERRUPT_REG); 114 115 if (irq <= 0) 116 return NO_IRQ; 117 return irq; 118 } 119 120 /* 121 * Configure I/O address of 53C400A or DTC436 by writing magic numbers 122 * to ports 0x779 and 0x379. 123 */ 124 static void magic_configure(int idx, u8 irq, u8 magic[]) 125 { 126 u8 cfg = 0; 127 128 outb(magic[0], 0x779); 129 outb(magic[1], 0x379); 130 outb(magic[2], 0x379); 131 outb(magic[3], 0x379); 132 outb(magic[4], 0x379); 133 134 if (irq == 9) 135 irq = 2; 136 137 if (idx >= 0 && idx <= 7) 138 cfg = 0x80 | idx | (irq << 4); 139 outb(cfg, 0x379); 140 } 141 142 static irqreturn_t legacy_empty_irq_handler(int irq, void *dev_id) 143 { 144 return IRQ_HANDLED; 145 } 146 147 static int legacy_find_free_irq(int *irq_table) 148 { 149 while (*irq_table != -1) { 150 if (!request_irq(*irq_table, legacy_empty_irq_handler, 151 IRQF_PROBE_SHARED, "Test IRQ", 152 (void *)irq_table)) { 153 free_irq(*irq_table, (void *) irq_table); 154 return *irq_table; 155 } 156 irq_table++; 157 } 158 return -1; 159 } 160 161 static unsigned int ncr_53c400a_ports[] = { 162 0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0 163 }; 164 static unsigned int dtc_3181e_ports[] = { 165 0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0 166 }; 167 static u8 ncr_53c400a_magic[] = { /* 53C400A & DTC436 */ 168 0x59, 0xb9, 0xc5, 0xae, 0xa6 169 }; 170 static u8 hp_c2502_magic[] = { /* HP C2502 */ 171 0x0f, 0x22, 0xf0, 0x20, 0x80 172 }; 173 static int hp_c2502_irqs[] = { 174 9, 5, 7, 3, 4, -1 175 }; 176 177 static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, 178 struct device *pdev, int base, int irq, int board) 179 { 180 bool is_pmio = base <= 0xffff; 181 int ret; 182 int flags = 0; 183 unsigned int *ports = NULL; 184 u8 *magic = NULL; 185 int i; 186 int port_idx = -1; 187 unsigned long region_size; 188 struct Scsi_Host *instance; 189 struct NCR5380_hostdata *hostdata; 190 u8 __iomem *iomem; 191 192 switch (board) { 193 case BOARD_NCR5380: 194 flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP; 195 break; 196 case BOARD_NCR53C400A: 197 ports = ncr_53c400a_ports; 198 magic = ncr_53c400a_magic; 199 break; 200 case BOARD_HP_C2502: 201 ports = ncr_53c400a_ports; 202 magic = hp_c2502_magic; 203 break; 204 case BOARD_DTC3181E: 205 ports = dtc_3181e_ports; 206 magic = ncr_53c400a_magic; 207 break; 208 } 209 210 if (is_pmio && ports && magic) { 211 /* wakeup sequence for the NCR53C400A and DTC3181E */ 212 213 /* Disable the adapter and look for a free io port */ 214 magic_configure(-1, 0, magic); 215 216 region_size = 16; 217 if (base) 218 for (i = 0; ports[i]; i++) { 219 if (base == ports[i]) { /* index found */ 220 if (!request_region(ports[i], 221 region_size, 222 "ncr53c80")) 223 return -EBUSY; 224 break; 225 } 226 } 227 else 228 for (i = 0; ports[i]; i++) { 229 if (!request_region(ports[i], region_size, 230 "ncr53c80")) 231 continue; 232 if (inb(ports[i]) == 0xff) 233 break; 234 release_region(ports[i], region_size); 235 } 236 if (ports[i]) { 237 /* At this point we have our region reserved */ 238 magic_configure(i, 0, magic); /* no IRQ yet */ 239 base = ports[i]; 240 outb(0xc0, base + 9); 241 if (inb(base + 9) != 0x80) { 242 ret = -ENODEV; 243 goto out_release; 244 } 245 port_idx = i; 246 } else 247 return -EINVAL; 248 } else if (is_pmio) { 249 /* NCR5380 - no configuration, just grab */ 250 region_size = 8; 251 if (!base || !request_region(base, region_size, "ncr5380")) 252 return -EBUSY; 253 } else { /* MMIO */ 254 region_size = NCR53C400_region_size; 255 if (!request_mem_region(base, region_size, "ncr5380")) 256 return -EBUSY; 257 } 258 259 if (is_pmio) 260 iomem = ioport_map(base, region_size); 261 else 262 iomem = ioremap(base, region_size); 263 264 if (!iomem) { 265 ret = -ENOMEM; 266 goto out_release; 267 } 268 269 instance = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata)); 270 if (instance == NULL) { 271 ret = -ENOMEM; 272 goto out_unmap; 273 } 274 hostdata = shost_priv(instance); 275 276 hostdata->io = iomem; 277 hostdata->region_size = region_size; 278 279 if (is_pmio) { 280 hostdata->io_port = base; 281 hostdata->io_width = 1; /* 8-bit PDMA by default */ 282 hostdata->offset = 0; 283 284 /* 285 * On NCR53C400 boards, NCR5380 registers are mapped 8 past 286 * the base address. 287 */ 288 switch (board) { 289 case BOARD_NCR53C400: 290 hostdata->io_port += 8; 291 hostdata->c400_ctl_status = 0; 292 hostdata->c400_blk_cnt = 1; 293 hostdata->c400_host_buf = 4; 294 break; 295 case BOARD_DTC3181E: 296 hostdata->io_width = 2; /* 16-bit PDMA */ 297 /* fall through */ 298 case BOARD_NCR53C400A: 299 case BOARD_HP_C2502: 300 hostdata->c400_ctl_status = 9; 301 hostdata->c400_blk_cnt = 10; 302 hostdata->c400_host_buf = 8; 303 break; 304 } 305 } else { 306 hostdata->base = base; 307 hostdata->offset = NCR53C400_mem_base; 308 switch (board) { 309 case BOARD_NCR53C400: 310 hostdata->c400_ctl_status = 0x100; 311 hostdata->c400_blk_cnt = 0x101; 312 hostdata->c400_host_buf = 0x104; 313 break; 314 case BOARD_DTC3181E: 315 case BOARD_NCR53C400A: 316 case BOARD_HP_C2502: 317 pr_err(DRV_MODULE_NAME ": unknown register offsets\n"); 318 ret = -EINVAL; 319 goto out_unregister; 320 } 321 } 322 323 /* Check for vacant slot */ 324 NCR5380_write(MODE_REG, 0); 325 if (NCR5380_read(MODE_REG) != 0) { 326 ret = -ENODEV; 327 goto out_unregister; 328 } 329 330 ret = NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP); 331 if (ret) 332 goto out_unregister; 333 334 switch (board) { 335 case BOARD_NCR53C400: 336 case BOARD_DTC3181E: 337 case BOARD_NCR53C400A: 338 case BOARD_HP_C2502: 339 NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); 340 } 341 342 NCR5380_maybe_reset_bus(instance); 343 344 /* Compatibility with documented NCR5380 kernel parameters */ 345 if (irq == 255 || irq == 0) 346 irq = NO_IRQ; 347 else if (irq == -1) 348 irq = IRQ_AUTO; 349 350 if (board == BOARD_HP_C2502) { 351 int *irq_table = hp_c2502_irqs; 352 int board_irq = -1; 353 354 switch (irq) { 355 case NO_IRQ: 356 board_irq = 0; 357 break; 358 case IRQ_AUTO: 359 board_irq = legacy_find_free_irq(irq_table); 360 break; 361 default: 362 while (*irq_table != -1) 363 if (*irq_table++ == irq) 364 board_irq = irq; 365 } 366 367 if (board_irq <= 0) { 368 board_irq = 0; 369 irq = NO_IRQ; 370 } 371 372 magic_configure(port_idx, board_irq, magic); 373 } 374 375 if (irq == IRQ_AUTO) { 376 instance->irq = g_NCR5380_probe_irq(instance); 377 if (instance->irq == NO_IRQ) 378 shost_printk(KERN_INFO, instance, "no irq detected\n"); 379 } else { 380 instance->irq = irq; 381 if (instance->irq == NO_IRQ) 382 shost_printk(KERN_INFO, instance, "no irq provided\n"); 383 } 384 385 if (instance->irq != NO_IRQ) { 386 if (request_irq(instance->irq, generic_NCR5380_intr, 387 0, "NCR5380", instance)) { 388 instance->irq = NO_IRQ; 389 shost_printk(KERN_INFO, instance, 390 "irq %d denied\n", instance->irq); 391 } else { 392 shost_printk(KERN_INFO, instance, 393 "irq %d acquired\n", instance->irq); 394 } 395 } 396 397 ret = scsi_add_host(instance, pdev); 398 if (ret) 399 goto out_free_irq; 400 scsi_scan_host(instance); 401 dev_set_drvdata(pdev, instance); 402 return 0; 403 404 out_free_irq: 405 if (instance->irq != NO_IRQ) 406 free_irq(instance->irq, instance); 407 NCR5380_exit(instance); 408 out_unregister: 409 scsi_host_put(instance); 410 out_unmap: 411 iounmap(iomem); 412 out_release: 413 if (is_pmio) 414 release_region(base, region_size); 415 else 416 release_mem_region(base, region_size); 417 return ret; 418 } 419 420 static void generic_NCR5380_release_resources(struct Scsi_Host *instance) 421 { 422 struct NCR5380_hostdata *hostdata = shost_priv(instance); 423 void __iomem *iomem = hostdata->io; 424 unsigned long io_port = hostdata->io_port; 425 unsigned long base = hostdata->base; 426 unsigned long region_size = hostdata->region_size; 427 428 scsi_remove_host(instance); 429 if (instance->irq != NO_IRQ) 430 free_irq(instance->irq, instance); 431 NCR5380_exit(instance); 432 scsi_host_put(instance); 433 iounmap(iomem); 434 if (io_port) 435 release_region(io_port, region_size); 436 else 437 release_mem_region(base, region_size); 438 } 439 440 /** 441 * generic_NCR5380_pread - pseudo DMA read 442 * @hostdata: scsi host private data 443 * @dst: buffer to read into 444 * @len: buffer length 445 * 446 * Perform a pseudo DMA mode read from an NCR53C400 or equivalent 447 * controller 448 */ 449 450 static inline int generic_NCR5380_pread(struct NCR5380_hostdata *hostdata, 451 unsigned char *dst, int len) 452 { 453 int blocks = len / 128; 454 int start = 0; 455 456 NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR); 457 NCR5380_write(hostdata->c400_blk_cnt, blocks); 458 while (1) { 459 if (NCR5380_read(hostdata->c400_blk_cnt) == 0) 460 break; 461 if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) { 462 printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); 463 return -1; 464 } 465 while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) 466 ; /* FIXME - no timeout */ 467 468 if (hostdata->io_port && hostdata->io_width == 2) 469 insw(hostdata->io_port + hostdata->c400_host_buf, 470 dst + start, 64); 471 else if (hostdata->io_port) 472 insb(hostdata->io_port + hostdata->c400_host_buf, 473 dst + start, 128); 474 else 475 memcpy_fromio(dst + start, 476 hostdata->io + NCR53C400_host_buffer, 128); 477 478 start += 128; 479 blocks--; 480 } 481 482 if (blocks) { 483 while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) 484 ; /* FIXME - no timeout */ 485 486 if (hostdata->io_port && hostdata->io_width == 2) 487 insw(hostdata->io_port + hostdata->c400_host_buf, 488 dst + start, 64); 489 else if (hostdata->io_port) 490 insb(hostdata->io_port + hostdata->c400_host_buf, 491 dst + start, 128); 492 else 493 memcpy_fromio(dst + start, 494 hostdata->io + NCR53C400_host_buffer, 128); 495 496 start += 128; 497 blocks--; 498 } 499 500 if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) 501 printk("53C400r: no 53C80 gated irq after transfer"); 502 503 /* wait for 53C80 registers to be available */ 504 while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) 505 ; 506 507 if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) 508 printk(KERN_ERR "53C400r: no end dma signal\n"); 509 510 return 0; 511 } 512 513 /** 514 * generic_NCR5380_pwrite - pseudo DMA write 515 * @hostdata: scsi host private data 516 * @dst: buffer to read into 517 * @len: buffer length 518 * 519 * Perform a pseudo DMA mode read from an NCR53C400 or equivalent 520 * controller 521 */ 522 523 static inline int generic_NCR5380_pwrite(struct NCR5380_hostdata *hostdata, 524 unsigned char *src, int len) 525 { 526 int blocks = len / 128; 527 int start = 0; 528 529 NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); 530 NCR5380_write(hostdata->c400_blk_cnt, blocks); 531 while (1) { 532 if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) { 533 printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); 534 return -1; 535 } 536 537 if (NCR5380_read(hostdata->c400_blk_cnt) == 0) 538 break; 539 while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) 540 ; // FIXME - timeout 541 542 if (hostdata->io_port && hostdata->io_width == 2) 543 outsw(hostdata->io_port + hostdata->c400_host_buf, 544 src + start, 64); 545 else if (hostdata->io_port) 546 outsb(hostdata->io_port + hostdata->c400_host_buf, 547 src + start, 128); 548 else 549 memcpy_toio(hostdata->io + NCR53C400_host_buffer, 550 src + start, 128); 551 552 start += 128; 553 blocks--; 554 } 555 if (blocks) { 556 while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) 557 ; // FIXME - no timeout 558 559 if (hostdata->io_port && hostdata->io_width == 2) 560 outsw(hostdata->io_port + hostdata->c400_host_buf, 561 src + start, 64); 562 else if (hostdata->io_port) 563 outsb(hostdata->io_port + hostdata->c400_host_buf, 564 src + start, 128); 565 else 566 memcpy_toio(hostdata->io + NCR53C400_host_buffer, 567 src + start, 128); 568 569 start += 128; 570 blocks--; 571 } 572 573 /* wait for 53C80 registers to be available */ 574 while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) { 575 udelay(4); /* DTC436 chip hangs without this */ 576 /* FIXME - no timeout */ 577 } 578 579 if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) { 580 printk(KERN_ERR "53C400w: no end dma signal\n"); 581 } 582 583 while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT)) 584 ; // TIMEOUT 585 return 0; 586 } 587 588 static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata, 589 struct scsi_cmnd *cmd) 590 { 591 int transfersize = cmd->transfersize; 592 593 if (hostdata->flags & FLAG_NO_PSEUDO_DMA) 594 return 0; 595 596 /* Limit transfers to 32K, for xx400 & xx406 597 * pseudoDMA that transfers in 128 bytes blocks. 598 */ 599 if (transfersize > 32 * 1024 && cmd->SCp.this_residual && 600 !(cmd->SCp.this_residual % transfersize)) 601 transfersize = 32 * 1024; 602 603 /* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */ 604 if (transfersize % 128) 605 transfersize = 0; 606 607 return transfersize; 608 } 609 610 /* 611 * Include the NCR5380 core code that we build our driver around 612 */ 613 614 #include "NCR5380.c" 615 616 static struct scsi_host_template driver_template = { 617 .module = THIS_MODULE, 618 .proc_name = DRV_MODULE_NAME, 619 .name = "Generic NCR5380/NCR53C400 SCSI", 620 .info = generic_NCR5380_info, 621 .queuecommand = generic_NCR5380_queue_command, 622 .eh_abort_handler = generic_NCR5380_abort, 623 .eh_bus_reset_handler = generic_NCR5380_bus_reset, 624 .can_queue = 16, 625 .this_id = 7, 626 .sg_tablesize = SG_ALL, 627 .cmd_per_lun = 2, 628 .use_clustering = DISABLE_CLUSTERING, 629 .cmd_size = NCR5380_CMD_SIZE, 630 .max_sectors = 128, 631 }; 632 633 634 static int generic_NCR5380_isa_match(struct device *pdev, unsigned int ndev) 635 { 636 int ret = generic_NCR5380_init_one(&driver_template, pdev, base[ndev], 637 irq[ndev], card[ndev]); 638 if (ret) { 639 if (base[ndev]) 640 printk(KERN_WARNING "Card not found at address 0x%03x\n", 641 base[ndev]); 642 return 0; 643 } 644 645 return 1; 646 } 647 648 static int generic_NCR5380_isa_remove(struct device *pdev, 649 unsigned int ndev) 650 { 651 generic_NCR5380_release_resources(dev_get_drvdata(pdev)); 652 dev_set_drvdata(pdev, NULL); 653 return 0; 654 } 655 656 static struct isa_driver generic_NCR5380_isa_driver = { 657 .match = generic_NCR5380_isa_match, 658 .remove = generic_NCR5380_isa_remove, 659 .driver = { 660 .name = DRV_MODULE_NAME 661 }, 662 }; 663 664 #ifdef CONFIG_PNP 665 static struct pnp_device_id generic_NCR5380_pnp_ids[] = { 666 { .id = "DTC436e", .driver_data = BOARD_DTC3181E }, 667 { .id = "" } 668 }; 669 MODULE_DEVICE_TABLE(pnp, generic_NCR5380_pnp_ids); 670 671 static int generic_NCR5380_pnp_probe(struct pnp_dev *pdev, 672 const struct pnp_device_id *id) 673 { 674 int base, irq; 675 676 if (pnp_activate_dev(pdev) < 0) 677 return -EBUSY; 678 679 base = pnp_port_start(pdev, 0); 680 irq = pnp_irq(pdev, 0); 681 682 return generic_NCR5380_init_one(&driver_template, &pdev->dev, base, irq, 683 id->driver_data); 684 } 685 686 static void generic_NCR5380_pnp_remove(struct pnp_dev *pdev) 687 { 688 generic_NCR5380_release_resources(pnp_get_drvdata(pdev)); 689 pnp_set_drvdata(pdev, NULL); 690 } 691 692 static struct pnp_driver generic_NCR5380_pnp_driver = { 693 .name = DRV_MODULE_NAME, 694 .id_table = generic_NCR5380_pnp_ids, 695 .probe = generic_NCR5380_pnp_probe, 696 .remove = generic_NCR5380_pnp_remove, 697 }; 698 #endif /* defined(CONFIG_PNP) */ 699 700 static int pnp_registered, isa_registered; 701 702 static int __init generic_NCR5380_init(void) 703 { 704 int ret = 0; 705 706 /* compatibility with old-style parameters */ 707 if (irq[0] == -1 && base[0] == 0 && card[0] == -1) { 708 irq[0] = ncr_irq; 709 base[0] = ncr_addr; 710 if (ncr_5380) 711 card[0] = BOARD_NCR5380; 712 if (ncr_53c400) 713 card[0] = BOARD_NCR53C400; 714 if (ncr_53c400a) 715 card[0] = BOARD_NCR53C400A; 716 if (dtc_3181e) 717 card[0] = BOARD_DTC3181E; 718 if (hp_c2502) 719 card[0] = BOARD_HP_C2502; 720 } 721 722 #ifdef CONFIG_PNP 723 if (!pnp_register_driver(&generic_NCR5380_pnp_driver)) 724 pnp_registered = 1; 725 #endif 726 ret = isa_register_driver(&generic_NCR5380_isa_driver, MAX_CARDS); 727 if (!ret) 728 isa_registered = 1; 729 730 return (pnp_registered || isa_registered) ? 0 : ret; 731 } 732 733 static void __exit generic_NCR5380_exit(void) 734 { 735 #ifdef CONFIG_PNP 736 if (pnp_registered) 737 pnp_unregister_driver(&generic_NCR5380_pnp_driver); 738 #endif 739 if (isa_registered) 740 isa_unregister_driver(&generic_NCR5380_isa_driver); 741 } 742 743 module_init(generic_NCR5380_init); 744 module_exit(generic_NCR5380_exit); 745