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 23 /* 24 * TODO : flesh out DMA support, find some one actually using this (I have 25 * a memory mapped Trantor board that works fine) 26 */ 27 28 /* 29 * The card is detected and initialized in one of several ways : 30 * 1. With command line overrides - NCR5380=port,irq may be 31 * used on the LILO command line to override the defaults. 32 * 33 * 2. With the GENERIC_NCR5380_OVERRIDE compile time define. This is 34 * specified as an array of address, irq, dma, board tuples. Ie, for 35 * one board at 0x350, IRQ5, no dma, I could say 36 * -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NCR5380}} 37 * 38 * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an 39 * IRQ line if overridden on the command line. 40 * 41 * 3. When included as a module, with arguments passed on the command line: 42 * ncr_irq=xx the interrupt 43 * ncr_addr=xx the port or base address (for port or memory 44 * mapped, resp.) 45 * ncr_dma=xx the DMA 46 * ncr_5380=1 to set up for a NCR5380 board 47 * ncr_53c400=1 to set up for a NCR53C400 board 48 * e.g. 49 * modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1 50 * for a port mapped NCR5380 board or 51 * modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1 52 * for a memory mapped NCR53C400 board with interrupts disabled. 53 * 54 * 255 should be specified for no or DMA interrupt, 254 to autoprobe for an 55 * IRQ line if overridden on the command line. 56 * 57 */ 58 59 /* settings for DTC3181E card with only Mustek scanner attached */ 60 #define USLEEP_POLL msecs_to_jiffies(10) 61 #define USLEEP_SLEEP msecs_to_jiffies(200) 62 #define USLEEP_WAITLONG msecs_to_jiffies(5000) 63 64 #define AUTOPROBE_IRQ 65 66 #ifdef CONFIG_SCSI_GENERIC_NCR53C400 67 #define NCR53C400_PSEUDO_DMA 1 68 #define PSEUDO_DMA 69 #define NCR53C400 70 #endif 71 72 #include <asm/io.h> 73 #include <linux/signal.h> 74 #include <linux/blkdev.h> 75 #include <scsi/scsi_host.h> 76 #include "g_NCR5380.h" 77 #include "NCR5380.h" 78 #include <linux/stat.h> 79 #include <linux/init.h> 80 #include <linux/ioport.h> 81 #include <linux/isapnp.h> 82 #include <linux/delay.h> 83 #include <linux/interrupt.h> 84 85 #define NCR_NOT_SET 0 86 static int ncr_irq = NCR_NOT_SET; 87 static int ncr_dma = NCR_NOT_SET; 88 static int ncr_addr = NCR_NOT_SET; 89 static int ncr_5380 = NCR_NOT_SET; 90 static int ncr_53c400 = NCR_NOT_SET; 91 static int ncr_53c400a = NCR_NOT_SET; 92 static int dtc_3181e = NCR_NOT_SET; 93 94 static struct override { 95 NCR5380_map_type NCR5380_map_name; 96 int irq; 97 int dma; 98 int board; /* Use NCR53c400, Ricoh, etc. extensions ? */ 99 } overrides 100 #ifdef GENERIC_NCR5380_OVERRIDE 101 [] __initdata = GENERIC_NCR5380_OVERRIDE; 102 #else 103 [1] __initdata = { { 0,},}; 104 #endif 105 106 #define NO_OVERRIDES ARRAY_SIZE(overrides) 107 108 #ifndef MODULE 109 110 /** 111 * internal_setup - handle lilo command string override 112 * @board: BOARD_* identifier for the board 113 * @str: unused 114 * @ints: numeric parameters 115 * 116 * Do LILO command line initialization of the overrides array. Display 117 * errors when needed 118 * 119 * Locks: none 120 */ 121 122 static void __init internal_setup(int board, char *str, int *ints) 123 { 124 static int commandline_current = 0; 125 switch (board) { 126 case BOARD_NCR5380: 127 if (ints[0] != 2 && ints[0] != 3) { 128 printk(KERN_ERR "generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n"); 129 return; 130 } 131 break; 132 case BOARD_NCR53C400: 133 if (ints[0] != 2) { 134 printk(KERN_ERR "generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n"); 135 return; 136 } 137 break; 138 case BOARD_NCR53C400A: 139 if (ints[0] != 2) { 140 printk(KERN_ERR "generic_NCR53C400A_setup : usage ncr53c400a=" STRVAL(NCR5380_map_name) ",irq\n"); 141 return; 142 } 143 break; 144 case BOARD_DTC3181E: 145 if (ints[0] != 2) { 146 printk("generic_DTC3181E_setup : usage dtc3181e=" STRVAL(NCR5380_map_name) ",irq\n"); 147 return; 148 } 149 break; 150 } 151 152 if (commandline_current < NO_OVERRIDES) { 153 overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type) ints[1]; 154 overrides[commandline_current].irq = ints[2]; 155 if (ints[0] == 3) 156 overrides[commandline_current].dma = ints[3]; 157 else 158 overrides[commandline_current].dma = DMA_NONE; 159 overrides[commandline_current].board = board; 160 ++commandline_current; 161 } 162 } 163 164 165 /** 166 * do_NCR53C80_setup - set up entry point 167 * @str: unused 168 * 169 * Setup function invoked at boot to parse the ncr5380= command 170 * line. 171 */ 172 173 static int __init do_NCR5380_setup(char *str) 174 { 175 int ints[10]; 176 177 get_options(str, ARRAY_SIZE(ints), ints); 178 internal_setup(BOARD_NCR5380, str, ints); 179 return 1; 180 } 181 182 /** 183 * do_NCR53C400_setup - set up entry point 184 * @str: unused 185 * @ints: integer parameters from kernel setup code 186 * 187 * Setup function invoked at boot to parse the ncr53c400= command 188 * line. 189 */ 190 191 static int __init do_NCR53C400_setup(char *str) 192 { 193 int ints[10]; 194 195 get_options(str, ARRAY_SIZE(ints), ints); 196 internal_setup(BOARD_NCR53C400, str, ints); 197 return 1; 198 } 199 200 /** 201 * do_NCR53C400A_setup - set up entry point 202 * @str: unused 203 * @ints: integer parameters from kernel setup code 204 * 205 * Setup function invoked at boot to parse the ncr53c400a= command 206 * line. 207 */ 208 209 static int __init do_NCR53C400A_setup(char *str) 210 { 211 int ints[10]; 212 213 get_options(str, ARRAY_SIZE(ints), ints); 214 internal_setup(BOARD_NCR53C400A, str, ints); 215 return 1; 216 } 217 218 /** 219 * do_DTC3181E_setup - set up entry point 220 * @str: unused 221 * @ints: integer parameters from kernel setup code 222 * 223 * Setup function invoked at boot to parse the dtc3181e= command 224 * line. 225 */ 226 227 static int __init do_DTC3181E_setup(char *str) 228 { 229 int ints[10]; 230 231 get_options(str, ARRAY_SIZE(ints), ints); 232 internal_setup(BOARD_DTC3181E, str, ints); 233 return 1; 234 } 235 236 #endif 237 238 /** 239 * generic_NCR5380_detect - look for NCR5380 controllers 240 * @tpnt: the scsi template 241 * 242 * Scan for the present of NCR5380, NCR53C400, NCR53C400A, DTC3181E 243 * and DTC436(ISAPnP) controllers. If overrides have been set we use 244 * them. 245 * 246 * The caller supplied NCR5380_init function is invoked from here, before 247 * the interrupt line is taken. 248 * 249 * Locks: none 250 */ 251 252 static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) 253 { 254 static int current_override = 0; 255 int count; 256 unsigned int *ports; 257 #ifndef SCSI_G_NCR5380_MEM 258 int i; 259 unsigned long region_size = 16; 260 #endif 261 static unsigned int __initdata ncr_53c400a_ports[] = { 262 0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0 263 }; 264 static unsigned int __initdata dtc_3181e_ports[] = { 265 0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0 266 }; 267 int flags = 0; 268 struct Scsi_Host *instance; 269 #ifdef SCSI_G_NCR5380_MEM 270 unsigned long base; 271 void __iomem *iomem; 272 #endif 273 274 if (ncr_irq != NCR_NOT_SET) 275 overrides[0].irq = ncr_irq; 276 if (ncr_dma != NCR_NOT_SET) 277 overrides[0].dma = ncr_dma; 278 if (ncr_addr != NCR_NOT_SET) 279 overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr; 280 if (ncr_5380 != NCR_NOT_SET) 281 overrides[0].board = BOARD_NCR5380; 282 else if (ncr_53c400 != NCR_NOT_SET) 283 overrides[0].board = BOARD_NCR53C400; 284 else if (ncr_53c400a != NCR_NOT_SET) 285 overrides[0].board = BOARD_NCR53C400A; 286 else if (dtc_3181e != NCR_NOT_SET) 287 overrides[0].board = BOARD_DTC3181E; 288 #ifndef SCSI_G_NCR5380_MEM 289 if (!current_override && isapnp_present()) { 290 struct pnp_dev *dev = NULL; 291 count = 0; 292 while ((dev = pnp_find_dev(NULL, ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e), dev))) { 293 if (count >= NO_OVERRIDES) 294 break; 295 if (pnp_device_attach(dev) < 0) 296 continue; 297 if (pnp_activate_dev(dev) < 0) { 298 printk(KERN_ERR "dtc436e probe: activate failed\n"); 299 pnp_device_detach(dev); 300 continue; 301 } 302 if (!pnp_port_valid(dev, 0)) { 303 printk(KERN_ERR "dtc436e probe: no valid port\n"); 304 pnp_device_detach(dev); 305 continue; 306 } 307 if (pnp_irq_valid(dev, 0)) 308 overrides[count].irq = pnp_irq(dev, 0); 309 else 310 overrides[count].irq = NO_IRQ; 311 if (pnp_dma_valid(dev, 0)) 312 overrides[count].dma = pnp_dma(dev, 0); 313 else 314 overrides[count].dma = DMA_NONE; 315 overrides[count].NCR5380_map_name = (NCR5380_map_type) pnp_port_start(dev, 0); 316 overrides[count].board = BOARD_DTC3181E; 317 count++; 318 } 319 } 320 #endif 321 tpnt->proc_name = "g_NCR5380"; 322 323 for (count = 0; current_override < NO_OVERRIDES; ++current_override) { 324 if (!(overrides[current_override].NCR5380_map_name)) 325 continue; 326 327 ports = NULL; 328 switch (overrides[current_override].board) { 329 case BOARD_NCR5380: 330 flags = FLAG_NO_PSEUDO_DMA; 331 break; 332 case BOARD_NCR53C400: 333 flags = FLAG_NCR53C400; 334 break; 335 case BOARD_NCR53C400A: 336 flags = FLAG_NO_PSEUDO_DMA; 337 ports = ncr_53c400a_ports; 338 break; 339 case BOARD_DTC3181E: 340 flags = FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E; 341 ports = dtc_3181e_ports; 342 break; 343 } 344 345 #ifndef SCSI_G_NCR5380_MEM 346 if (ports) { 347 /* wakeup sequence for the NCR53C400A and DTC3181E */ 348 349 /* Disable the adapter and look for a free io port */ 350 outb(0x59, 0x779); 351 outb(0xb9, 0x379); 352 outb(0xc5, 0x379); 353 outb(0xae, 0x379); 354 outb(0xa6, 0x379); 355 outb(0x00, 0x379); 356 357 if (overrides[current_override].NCR5380_map_name != PORT_AUTO) 358 for (i = 0; ports[i]; i++) { 359 if (!request_region(ports[i], 16, "ncr53c80")) 360 continue; 361 if (overrides[current_override].NCR5380_map_name == ports[i]) 362 break; 363 release_region(ports[i], 16); 364 } else 365 for (i = 0; ports[i]; i++) { 366 if (!request_region(ports[i], 16, "ncr53c80")) 367 continue; 368 if (inb(ports[i]) == 0xff) 369 break; 370 release_region(ports[i], 16); 371 } 372 if (ports[i]) { 373 /* At this point we have our region reserved */ 374 outb(0x59, 0x779); 375 outb(0xb9, 0x379); 376 outb(0xc5, 0x379); 377 outb(0xae, 0x379); 378 outb(0xa6, 0x379); 379 outb(0x80 | i, 0x379); /* set io port to be used */ 380 outb(0xc0, ports[i] + 9); 381 if (inb(ports[i] + 9) != 0x80) 382 continue; 383 else 384 overrides[current_override].NCR5380_map_name = ports[i]; 385 } else 386 continue; 387 } 388 else 389 { 390 /* Not a 53C400A style setup - just grab */ 391 if(!(request_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size, "ncr5380"))) 392 continue; 393 region_size = NCR5380_region_size; 394 } 395 #else 396 base = overrides[current_override].NCR5380_map_name; 397 if (!request_mem_region(base, NCR5380_region_size, "ncr5380")) 398 continue; 399 iomem = ioremap(base, NCR5380_region_size); 400 if (!iomem) { 401 release_mem_region(base, NCR5380_region_size); 402 continue; 403 } 404 #endif 405 instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata)); 406 if (instance == NULL) { 407 #ifndef SCSI_G_NCR5380_MEM 408 release_region(overrides[current_override].NCR5380_map_name, region_size); 409 #else 410 iounmap(iomem); 411 release_mem_region(base, NCR5380_region_size); 412 #endif 413 continue; 414 } 415 416 instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name; 417 #ifndef SCSI_G_NCR5380_MEM 418 instance->n_io_port = region_size; 419 #else 420 ((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem; 421 #endif 422 423 NCR5380_init(instance, flags); 424 425 if (overrides[current_override].irq != IRQ_AUTO) 426 instance->irq = overrides[current_override].irq; 427 else 428 instance->irq = NCR5380_probe_irq(instance, 0xffff); 429 430 /* Compatibility with documented NCR5380 kernel parameters */ 431 if (instance->irq == 255) 432 instance->irq = NO_IRQ; 433 434 if (instance->irq != NO_IRQ) 435 if (request_irq(instance->irq, generic_NCR5380_intr, 436 0, "NCR5380", instance)) { 437 printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); 438 instance->irq = NO_IRQ; 439 } 440 441 if (instance->irq == NO_IRQ) { 442 printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); 443 printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); 444 } 445 446 ++current_override; 447 ++count; 448 } 449 return count; 450 } 451 452 /** 453 * generic_NCR5380_release_resources - free resources 454 * @instance: host adapter to clean up 455 * 456 * Free the generic interface resources from this adapter. 457 * 458 * Locks: none 459 */ 460 461 static int generic_NCR5380_release_resources(struct Scsi_Host *instance) 462 { 463 NCR5380_local_declare(); 464 NCR5380_setup(instance); 465 466 if (instance->irq != NO_IRQ) 467 free_irq(instance->irq, instance); 468 NCR5380_exit(instance); 469 470 #ifndef SCSI_G_NCR5380_MEM 471 release_region(instance->NCR5380_instance_name, instance->n_io_port); 472 #else 473 iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem); 474 release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size); 475 #endif 476 477 478 return 0; 479 } 480 481 #ifdef BIOSPARAM 482 /** 483 * generic_NCR5380_biosparam 484 * @disk: disk to compute geometry for 485 * @dev: device identifier for this disk 486 * @ip: sizes to fill in 487 * 488 * Generates a BIOS / DOS compatible H-C-S mapping for the specified 489 * device / size. 490 * 491 * XXX Most SCSI boards use this mapping, I could be incorrect. Someone 492 * using hard disks on a trantor should verify that this mapping 493 * corresponds to that used by the BIOS / ASPI driver by running the linux 494 * fdisk program and matching the H_C_S coordinates to what DOS uses. 495 * 496 * Locks: none 497 */ 498 499 static int 500 generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev, 501 sector_t capacity, int *ip) 502 { 503 ip[0] = 64; 504 ip[1] = 32; 505 ip[2] = capacity >> 11; 506 return 0; 507 } 508 #endif 509 510 #ifdef NCR53C400_PSEUDO_DMA 511 512 /** 513 * NCR5380_pread - pseudo DMA read 514 * @instance: adapter to read from 515 * @dst: buffer to read into 516 * @len: buffer length 517 * 518 * Perform a pseudo DMA mode read from an NCR53C400 or equivalent 519 * controller 520 */ 521 522 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len) 523 { 524 int blocks = len / 128; 525 int start = 0; 526 int bl; 527 528 NCR5380_local_declare(); 529 NCR5380_setup(instance); 530 531 NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR); 532 NCR5380_write(C400_BLOCK_COUNTER_REG, blocks); 533 while (1) { 534 if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) { 535 break; 536 } 537 if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) { 538 printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); 539 return -1; 540 } 541 while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY); 542 543 #ifndef SCSI_G_NCR5380_MEM 544 { 545 int i; 546 for (i = 0; i < 128; i++) 547 dst[start + i] = NCR5380_read(C400_HOST_BUFFER); 548 } 549 #else 550 /* implies SCSI_G_NCR5380_MEM */ 551 memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128); 552 #endif 553 start += 128; 554 blocks--; 555 } 556 557 if (blocks) { 558 while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY) 559 { 560 // FIXME - no timeout 561 } 562 563 #ifndef SCSI_G_NCR5380_MEM 564 { 565 int i; 566 for (i = 0; i < 128; i++) 567 dst[start + i] = NCR5380_read(C400_HOST_BUFFER); 568 } 569 #else 570 /* implies SCSI_G_NCR5380_MEM */ 571 memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128); 572 #endif 573 start += 128; 574 blocks--; 575 } 576 577 if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ)) 578 printk("53C400r: no 53C80 gated irq after transfer"); 579 580 #if 0 581 /* 582 * DON'T DO THIS - THEY NEVER ARRIVE! 583 */ 584 printk("53C400r: Waiting for 53C80 registers\n"); 585 while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG) 586 ; 587 #endif 588 if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) 589 printk(KERN_ERR "53C400r: no end dma signal\n"); 590 591 NCR5380_write(MODE_REG, MR_BASE); 592 NCR5380_read(RESET_PARITY_INTERRUPT_REG); 593 return 0; 594 } 595 596 /** 597 * NCR5380_write - pseudo DMA write 598 * @instance: adapter to read from 599 * @dst: buffer to read into 600 * @len: buffer length 601 * 602 * Perform a pseudo DMA mode read from an NCR53C400 or equivalent 603 * controller 604 */ 605 606 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len) 607 { 608 int blocks = len / 128; 609 int start = 0; 610 int bl; 611 int i; 612 613 NCR5380_local_declare(); 614 NCR5380_setup(instance); 615 616 NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE); 617 NCR5380_write(C400_BLOCK_COUNTER_REG, blocks); 618 while (1) { 619 if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) { 620 printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); 621 return -1; 622 } 623 624 if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) { 625 break; 626 } 627 while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY) 628 ; // FIXME - timeout 629 #ifndef SCSI_G_NCR5380_MEM 630 { 631 for (i = 0; i < 128; i++) 632 NCR5380_write(C400_HOST_BUFFER, src[start + i]); 633 } 634 #else 635 /* implies SCSI_G_NCR5380_MEM */ 636 memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128); 637 #endif 638 start += 128; 639 blocks--; 640 } 641 if (blocks) { 642 while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY) 643 ; // FIXME - no timeout 644 645 #ifndef SCSI_G_NCR5380_MEM 646 { 647 for (i = 0; i < 128; i++) 648 NCR5380_write(C400_HOST_BUFFER, src[start + i]); 649 } 650 #else 651 /* implies SCSI_G_NCR5380_MEM */ 652 memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128); 653 #endif 654 start += 128; 655 blocks--; 656 } 657 658 #if 0 659 printk("53C400w: waiting for registers to be available\n"); 660 THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG); 661 printk("53C400w: Got em\n"); 662 #endif 663 664 /* Let's wait for this instead - could be ugly */ 665 /* All documentation says to check for this. Maybe my hardware is too 666 * fast. Waiting for it seems to work fine! KLL 667 */ 668 while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ)) 669 ; // FIXME - no timeout 670 671 /* 672 * I know. i is certainly != 0 here but the loop is new. See previous 673 * comment. 674 */ 675 if (i) { 676 if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER)) 677 printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i); 678 } else 679 printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer (last block)\n"); 680 681 #if 0 682 if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) { 683 printk(KERN_ERR "53C400w: no end dma signal\n"); 684 } 685 #endif 686 while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT)) 687 ; // TIMEOUT 688 return 0; 689 } 690 #endif /* PSEUDO_DMA */ 691 692 /* 693 * Include the NCR5380 core code that we build our driver around 694 */ 695 696 #include "NCR5380.c" 697 698 static struct scsi_host_template driver_template = { 699 .show_info = generic_NCR5380_show_info, 700 .name = "Generic NCR5380/NCR53C400 SCSI", 701 .detect = generic_NCR5380_detect, 702 .release = generic_NCR5380_release_resources, 703 .info = generic_NCR5380_info, 704 .queuecommand = generic_NCR5380_queue_command, 705 .eh_abort_handler = generic_NCR5380_abort, 706 .eh_bus_reset_handler = generic_NCR5380_bus_reset, 707 .bios_param = NCR5380_BIOSPARAM, 708 .can_queue = CAN_QUEUE, 709 .this_id = 7, 710 .sg_tablesize = SG_ALL, 711 .cmd_per_lun = CMD_PER_LUN, 712 .use_clustering = DISABLE_CLUSTERING, 713 }; 714 #include <linux/module.h> 715 #include "scsi_module.c" 716 717 module_param(ncr_irq, int, 0); 718 module_param(ncr_dma, int, 0); 719 module_param(ncr_addr, int, 0); 720 module_param(ncr_5380, int, 0); 721 module_param(ncr_53c400, int, 0); 722 module_param(ncr_53c400a, int, 0); 723 module_param(dtc_3181e, int, 0); 724 MODULE_LICENSE("GPL"); 725 726 #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE) 727 static struct isapnp_device_id id_table[] = { 728 { 729 ISAPNP_ANY_ID, ISAPNP_ANY_ID, 730 ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e), 731 0}, 732 {0} 733 }; 734 735 MODULE_DEVICE_TABLE(isapnp, id_table); 736 #endif 737 738 __setup("ncr5380=", do_NCR5380_setup); 739 __setup("ncr53c400=", do_NCR53C400_setup); 740 __setup("ncr53c400a=", do_NCR53C400A_setup); 741 __setup("dtc3181e=", do_DTC3181E_setup); 742