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 #define AUTOPROBE_IRQ 60 61 #ifdef CONFIG_SCSI_GENERIC_NCR53C400 62 #define PSEUDO_DMA 63 #endif 64 65 #include <asm/io.h> 66 #include <linux/blkdev.h> 67 #include <linux/module.h> 68 #include <scsi/scsi_host.h> 69 #include "g_NCR5380.h" 70 #include "NCR5380.h" 71 #include <linux/init.h> 72 #include <linux/ioport.h> 73 #include <linux/isapnp.h> 74 #include <linux/interrupt.h> 75 76 static int ncr_irq; 77 static int ncr_dma; 78 static int ncr_addr; 79 static int ncr_5380; 80 static int ncr_53c400; 81 static int ncr_53c400a; 82 static int dtc_3181e; 83 static int hp_c2502; 84 85 static struct override { 86 NCR5380_map_type NCR5380_map_name; 87 int irq; 88 int dma; 89 int board; /* Use NCR53c400, Ricoh, etc. extensions ? */ 90 } overrides 91 #ifdef GENERIC_NCR5380_OVERRIDE 92 [] __initdata = GENERIC_NCR5380_OVERRIDE; 93 #else 94 [1] __initdata = { { 0,},}; 95 #endif 96 97 #define NO_OVERRIDES ARRAY_SIZE(overrides) 98 99 #ifndef MODULE 100 101 /** 102 * internal_setup - handle lilo command string override 103 * @board: BOARD_* identifier for the board 104 * @str: unused 105 * @ints: numeric parameters 106 * 107 * Do LILO command line initialization of the overrides array. Display 108 * errors when needed 109 * 110 * Locks: none 111 */ 112 113 static void __init internal_setup(int board, char *str, int *ints) 114 { 115 static int commandline_current; 116 switch (board) { 117 case BOARD_NCR5380: 118 if (ints[0] != 2 && ints[0] != 3) { 119 printk(KERN_ERR "generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n"); 120 return; 121 } 122 break; 123 case BOARD_NCR53C400: 124 if (ints[0] != 2) { 125 printk(KERN_ERR "generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n"); 126 return; 127 } 128 break; 129 case BOARD_NCR53C400A: 130 if (ints[0] != 2) { 131 printk(KERN_ERR "generic_NCR53C400A_setup : usage ncr53c400a=" STRVAL(NCR5380_map_name) ",irq\n"); 132 return; 133 } 134 break; 135 case BOARD_DTC3181E: 136 if (ints[0] != 2) { 137 printk("generic_DTC3181E_setup : usage dtc3181e=" STRVAL(NCR5380_map_name) ",irq\n"); 138 return; 139 } 140 break; 141 } 142 143 if (commandline_current < NO_OVERRIDES) { 144 overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type) ints[1]; 145 overrides[commandline_current].irq = ints[2]; 146 if (ints[0] == 3) 147 overrides[commandline_current].dma = ints[3]; 148 else 149 overrides[commandline_current].dma = DMA_NONE; 150 overrides[commandline_current].board = board; 151 ++commandline_current; 152 } 153 } 154 155 156 /** 157 * do_NCR53C80_setup - set up entry point 158 * @str: unused 159 * 160 * Setup function invoked at boot to parse the ncr5380= command 161 * line. 162 */ 163 164 static int __init do_NCR5380_setup(char *str) 165 { 166 int ints[10]; 167 168 get_options(str, ARRAY_SIZE(ints), ints); 169 internal_setup(BOARD_NCR5380, str, ints); 170 return 1; 171 } 172 173 /** 174 * do_NCR53C400_setup - set up entry point 175 * @str: unused 176 * @ints: integer parameters from kernel setup code 177 * 178 * Setup function invoked at boot to parse the ncr53c400= command 179 * line. 180 */ 181 182 static int __init do_NCR53C400_setup(char *str) 183 { 184 int ints[10]; 185 186 get_options(str, ARRAY_SIZE(ints), ints); 187 internal_setup(BOARD_NCR53C400, str, ints); 188 return 1; 189 } 190 191 /** 192 * do_NCR53C400A_setup - set up entry point 193 * @str: unused 194 * @ints: integer parameters from kernel setup code 195 * 196 * Setup function invoked at boot to parse the ncr53c400a= command 197 * line. 198 */ 199 200 static int __init do_NCR53C400A_setup(char *str) 201 { 202 int ints[10]; 203 204 get_options(str, ARRAY_SIZE(ints), ints); 205 internal_setup(BOARD_NCR53C400A, str, ints); 206 return 1; 207 } 208 209 /** 210 * do_DTC3181E_setup - set up entry point 211 * @str: unused 212 * @ints: integer parameters from kernel setup code 213 * 214 * Setup function invoked at boot to parse the dtc3181e= command 215 * line. 216 */ 217 218 static int __init do_DTC3181E_setup(char *str) 219 { 220 int ints[10]; 221 222 get_options(str, ARRAY_SIZE(ints), ints); 223 internal_setup(BOARD_DTC3181E, str, ints); 224 return 1; 225 } 226 227 #endif 228 229 #ifndef SCSI_G_NCR5380_MEM 230 /* 231 * Configure I/O address of 53C400A or DTC436 by writing magic numbers 232 * to ports 0x779 and 0x379. 233 */ 234 static void magic_configure(int idx, u8 irq, u8 magic[]) 235 { 236 u8 cfg = 0; 237 238 outb(magic[0], 0x779); 239 outb(magic[1], 0x379); 240 outb(magic[2], 0x379); 241 outb(magic[3], 0x379); 242 outb(magic[4], 0x379); 243 244 /* allowed IRQs for HP C2502 */ 245 if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7) 246 irq = 0; 247 if (idx >= 0 && idx <= 7) 248 cfg = 0x80 | idx | (irq << 4); 249 outb(cfg, 0x379); 250 } 251 #endif 252 253 /** 254 * generic_NCR5380_detect - look for NCR5380 controllers 255 * @tpnt: the scsi template 256 * 257 * Scan for the present of NCR5380, NCR53C400, NCR53C400A, DTC3181E 258 * and DTC436(ISAPnP) controllers. If overrides have been set we use 259 * them. 260 * 261 * Locks: none 262 */ 263 264 static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) 265 { 266 static int current_override; 267 int count; 268 unsigned int *ports; 269 u8 *magic = NULL; 270 #ifndef SCSI_G_NCR5380_MEM 271 int i; 272 int port_idx = -1; 273 unsigned long region_size = 16; 274 #endif 275 static unsigned int __initdata ncr_53c400a_ports[] = { 276 0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0 277 }; 278 static unsigned int __initdata dtc_3181e_ports[] = { 279 0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0 280 }; 281 static u8 ncr_53c400a_magic[] __initdata = { /* 53C400A & DTC436 */ 282 0x59, 0xb9, 0xc5, 0xae, 0xa6 283 }; 284 static u8 hp_c2502_magic[] __initdata = { /* HP C2502 */ 285 0x0f, 0x22, 0xf0, 0x20, 0x80 286 }; 287 int flags; 288 struct Scsi_Host *instance; 289 struct NCR5380_hostdata *hostdata; 290 #ifdef SCSI_G_NCR5380_MEM 291 unsigned long base; 292 void __iomem *iomem; 293 #endif 294 295 if (ncr_irq) 296 overrides[0].irq = ncr_irq; 297 if (ncr_dma) 298 overrides[0].dma = ncr_dma; 299 if (ncr_addr) 300 overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr; 301 if (ncr_5380) 302 overrides[0].board = BOARD_NCR5380; 303 else if (ncr_53c400) 304 overrides[0].board = BOARD_NCR53C400; 305 else if (ncr_53c400a) 306 overrides[0].board = BOARD_NCR53C400A; 307 else if (dtc_3181e) 308 overrides[0].board = BOARD_DTC3181E; 309 else if (hp_c2502) 310 overrides[0].board = BOARD_HP_C2502; 311 #ifndef SCSI_G_NCR5380_MEM 312 if (!current_override && isapnp_present()) { 313 struct pnp_dev *dev = NULL; 314 count = 0; 315 while ((dev = pnp_find_dev(NULL, ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e), dev))) { 316 if (count >= NO_OVERRIDES) 317 break; 318 if (pnp_device_attach(dev) < 0) 319 continue; 320 if (pnp_activate_dev(dev) < 0) { 321 printk(KERN_ERR "dtc436e probe: activate failed\n"); 322 pnp_device_detach(dev); 323 continue; 324 } 325 if (!pnp_port_valid(dev, 0)) { 326 printk(KERN_ERR "dtc436e probe: no valid port\n"); 327 pnp_device_detach(dev); 328 continue; 329 } 330 if (pnp_irq_valid(dev, 0)) 331 overrides[count].irq = pnp_irq(dev, 0); 332 else 333 overrides[count].irq = NO_IRQ; 334 if (pnp_dma_valid(dev, 0)) 335 overrides[count].dma = pnp_dma(dev, 0); 336 else 337 overrides[count].dma = DMA_NONE; 338 overrides[count].NCR5380_map_name = (NCR5380_map_type) pnp_port_start(dev, 0); 339 overrides[count].board = BOARD_DTC3181E; 340 count++; 341 } 342 } 343 #endif 344 345 for (count = 0; current_override < NO_OVERRIDES; ++current_override) { 346 if (!(overrides[current_override].NCR5380_map_name)) 347 continue; 348 349 ports = NULL; 350 flags = 0; 351 switch (overrides[current_override].board) { 352 case BOARD_NCR5380: 353 flags = FLAG_NO_PSEUDO_DMA; 354 break; 355 case BOARD_NCR53C400: 356 #ifdef PSEUDO_DMA 357 flags = FLAG_NO_DMA_FIXUP; 358 #endif 359 break; 360 case BOARD_NCR53C400A: 361 flags = FLAG_NO_DMA_FIXUP; 362 ports = ncr_53c400a_ports; 363 magic = ncr_53c400a_magic; 364 break; 365 case BOARD_HP_C2502: 366 flags = FLAG_NO_DMA_FIXUP; 367 ports = ncr_53c400a_ports; 368 magic = hp_c2502_magic; 369 break; 370 case BOARD_DTC3181E: 371 flags = FLAG_NO_DMA_FIXUP; 372 ports = dtc_3181e_ports; 373 magic = ncr_53c400a_magic; 374 break; 375 } 376 377 #ifndef SCSI_G_NCR5380_MEM 378 if (ports && magic) { 379 /* wakeup sequence for the NCR53C400A and DTC3181E */ 380 381 /* Disable the adapter and look for a free io port */ 382 magic_configure(-1, 0, magic); 383 384 if (overrides[current_override].NCR5380_map_name != PORT_AUTO) 385 for (i = 0; ports[i]; i++) { 386 if (!request_region(ports[i], 16, "ncr53c80")) 387 continue; 388 if (overrides[current_override].NCR5380_map_name == ports[i]) 389 break; 390 release_region(ports[i], 16); 391 } else 392 for (i = 0; ports[i]; i++) { 393 if (!request_region(ports[i], 16, "ncr53c80")) 394 continue; 395 if (inb(ports[i]) == 0xff) 396 break; 397 release_region(ports[i], 16); 398 } 399 if (ports[i]) { 400 /* At this point we have our region reserved */ 401 magic_configure(i, 0, magic); /* no IRQ yet */ 402 outb(0xc0, ports[i] + 9); 403 if (inb(ports[i] + 9) != 0x80) 404 continue; 405 overrides[current_override].NCR5380_map_name = ports[i]; 406 port_idx = i; 407 } else 408 continue; 409 } 410 else 411 { 412 /* Not a 53C400A style setup - just grab */ 413 if(!(request_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size, "ncr5380"))) 414 continue; 415 region_size = NCR5380_region_size; 416 } 417 #else 418 base = overrides[current_override].NCR5380_map_name; 419 if (!request_mem_region(base, NCR5380_region_size, "ncr5380")) 420 continue; 421 iomem = ioremap(base, NCR5380_region_size); 422 if (!iomem) { 423 release_mem_region(base, NCR5380_region_size); 424 continue; 425 } 426 #endif 427 instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata)); 428 if (instance == NULL) 429 goto out_release; 430 hostdata = shost_priv(instance); 431 432 #ifndef SCSI_G_NCR5380_MEM 433 instance->io_port = overrides[current_override].NCR5380_map_name; 434 instance->n_io_port = region_size; 435 hostdata->io_width = 1; /* 8-bit PDMA by default */ 436 437 /* 438 * On NCR53C400 boards, NCR5380 registers are mapped 8 past 439 * the base address. 440 */ 441 switch (overrides[current_override].board) { 442 case BOARD_NCR53C400: 443 instance->io_port += 8; 444 hostdata->c400_ctl_status = 0; 445 hostdata->c400_blk_cnt = 1; 446 hostdata->c400_host_buf = 4; 447 break; 448 case BOARD_DTC3181E: 449 hostdata->io_width = 2; /* 16-bit PDMA */ 450 /* fall through */ 451 case BOARD_NCR53C400A: 452 case BOARD_HP_C2502: 453 hostdata->c400_ctl_status = 9; 454 hostdata->c400_blk_cnt = 10; 455 hostdata->c400_host_buf = 8; 456 break; 457 } 458 #else 459 instance->base = overrides[current_override].NCR5380_map_name; 460 hostdata->iomem = iomem; 461 switch (overrides[current_override].board) { 462 case BOARD_NCR53C400: 463 hostdata->c400_ctl_status = 0x100; 464 hostdata->c400_blk_cnt = 0x101; 465 hostdata->c400_host_buf = 0x104; 466 break; 467 case BOARD_DTC3181E: 468 case BOARD_NCR53C400A: 469 case BOARD_HP_C2502: 470 pr_err(DRV_MODULE_NAME ": unknown register offsets\n"); 471 goto out_unregister; 472 } 473 #endif 474 475 if (NCR5380_init(instance, flags)) 476 goto out_unregister; 477 478 switch (overrides[current_override].board) { 479 case BOARD_NCR53C400: 480 case BOARD_DTC3181E: 481 case BOARD_NCR53C400A: 482 case BOARD_HP_C2502: 483 NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); 484 } 485 486 NCR5380_maybe_reset_bus(instance); 487 488 if (overrides[current_override].irq != IRQ_AUTO) 489 instance->irq = overrides[current_override].irq; 490 else 491 instance->irq = NCR5380_probe_irq(instance, 0xffff); 492 493 /* Compatibility with documented NCR5380 kernel parameters */ 494 if (instance->irq == 255) 495 instance->irq = NO_IRQ; 496 497 if (instance->irq != NO_IRQ) { 498 #ifndef SCSI_G_NCR5380_MEM 499 /* set IRQ for HP C2502 */ 500 if (overrides[current_override].board == BOARD_HP_C2502) 501 magic_configure(port_idx, instance->irq, magic); 502 #endif 503 if (request_irq(instance->irq, generic_NCR5380_intr, 504 0, "NCR5380", instance)) { 505 printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); 506 instance->irq = NO_IRQ; 507 } 508 } 509 510 if (instance->irq == NO_IRQ) { 511 printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); 512 printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); 513 } 514 515 ++current_override; 516 ++count; 517 } 518 return count; 519 520 out_unregister: 521 scsi_unregister(instance); 522 out_release: 523 #ifndef SCSI_G_NCR5380_MEM 524 release_region(overrides[current_override].NCR5380_map_name, region_size); 525 #else 526 iounmap(iomem); 527 release_mem_region(base, NCR5380_region_size); 528 #endif 529 return count; 530 } 531 532 /** 533 * generic_NCR5380_release_resources - free resources 534 * @instance: host adapter to clean up 535 * 536 * Free the generic interface resources from this adapter. 537 * 538 * Locks: none 539 */ 540 541 static int generic_NCR5380_release_resources(struct Scsi_Host *instance) 542 { 543 if (instance->irq != NO_IRQ) 544 free_irq(instance->irq, instance); 545 NCR5380_exit(instance); 546 #ifndef SCSI_G_NCR5380_MEM 547 release_region(instance->io_port, instance->n_io_port); 548 #else 549 iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem); 550 release_mem_region(instance->base, NCR5380_region_size); 551 #endif 552 return 0; 553 } 554 555 #ifdef BIOSPARAM 556 /** 557 * generic_NCR5380_biosparam 558 * @disk: disk to compute geometry for 559 * @dev: device identifier for this disk 560 * @ip: sizes to fill in 561 * 562 * Generates a BIOS / DOS compatible H-C-S mapping for the specified 563 * device / size. 564 * 565 * XXX Most SCSI boards use this mapping, I could be incorrect. Someone 566 * using hard disks on a trantor should verify that this mapping 567 * corresponds to that used by the BIOS / ASPI driver by running the linux 568 * fdisk program and matching the H_C_S coordinates to what DOS uses. 569 * 570 * Locks: none 571 */ 572 573 static int 574 generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev, 575 sector_t capacity, int *ip) 576 { 577 ip[0] = 64; 578 ip[1] = 32; 579 ip[2] = capacity >> 11; 580 return 0; 581 } 582 #endif 583 584 #ifdef PSEUDO_DMA 585 586 /** 587 * NCR5380_pread - pseudo DMA read 588 * @instance: adapter to read from 589 * @dst: buffer to read into 590 * @len: buffer length 591 * 592 * Perform a pseudo DMA mode read from an NCR53C400 or equivalent 593 * controller 594 */ 595 596 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len) 597 { 598 struct NCR5380_hostdata *hostdata = shost_priv(instance); 599 int blocks = len / 128; 600 int start = 0; 601 602 NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR); 603 NCR5380_write(hostdata->c400_blk_cnt, blocks); 604 while (1) { 605 if (NCR5380_read(hostdata->c400_blk_cnt) == 0) 606 break; 607 if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) { 608 printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); 609 return -1; 610 } 611 while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) 612 ; /* FIXME - no timeout */ 613 614 #ifndef SCSI_G_NCR5380_MEM 615 if (hostdata->io_width == 2) 616 insw(instance->io_port + hostdata->c400_host_buf, 617 dst + start, 64); 618 else 619 insb(instance->io_port + hostdata->c400_host_buf, 620 dst + start, 128); 621 #else 622 /* implies SCSI_G_NCR5380_MEM */ 623 memcpy_fromio(dst + start, 624 hostdata->iomem + NCR53C400_host_buffer, 128); 625 #endif 626 start += 128; 627 blocks--; 628 } 629 630 if (blocks) { 631 while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) 632 ; /* FIXME - no timeout */ 633 634 #ifndef SCSI_G_NCR5380_MEM 635 if (hostdata->io_width == 2) 636 insw(instance->io_port + hostdata->c400_host_buf, 637 dst + start, 64); 638 else 639 insb(instance->io_port + hostdata->c400_host_buf, 640 dst + start, 128); 641 #else 642 /* implies SCSI_G_NCR5380_MEM */ 643 memcpy_fromio(dst + start, 644 hostdata->iomem + NCR53C400_host_buffer, 128); 645 #endif 646 start += 128; 647 blocks--; 648 } 649 650 if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) 651 printk("53C400r: no 53C80 gated irq after transfer"); 652 653 /* wait for 53C80 registers to be available */ 654 while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) 655 ; 656 657 if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) 658 printk(KERN_ERR "53C400r: no end dma signal\n"); 659 660 return 0; 661 } 662 663 /** 664 * NCR5380_write - pseudo DMA write 665 * @instance: adapter to read from 666 * @dst: buffer to read into 667 * @len: buffer length 668 * 669 * Perform a pseudo DMA mode read from an NCR53C400 or equivalent 670 * controller 671 */ 672 673 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len) 674 { 675 struct NCR5380_hostdata *hostdata = shost_priv(instance); 676 int blocks = len / 128; 677 int start = 0; 678 679 NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); 680 NCR5380_write(hostdata->c400_blk_cnt, blocks); 681 while (1) { 682 if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) { 683 printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); 684 return -1; 685 } 686 687 if (NCR5380_read(hostdata->c400_blk_cnt) == 0) 688 break; 689 while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) 690 ; // FIXME - timeout 691 #ifndef SCSI_G_NCR5380_MEM 692 if (hostdata->io_width == 2) 693 outsw(instance->io_port + hostdata->c400_host_buf, 694 src + start, 64); 695 else 696 outsb(instance->io_port + hostdata->c400_host_buf, 697 src + start, 128); 698 #else 699 /* implies SCSI_G_NCR5380_MEM */ 700 memcpy_toio(hostdata->iomem + NCR53C400_host_buffer, 701 src + start, 128); 702 #endif 703 start += 128; 704 blocks--; 705 } 706 if (blocks) { 707 while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) 708 ; // FIXME - no timeout 709 710 #ifndef SCSI_G_NCR5380_MEM 711 if (hostdata->io_width == 2) 712 outsw(instance->io_port + hostdata->c400_host_buf, 713 src + start, 64); 714 else 715 outsb(instance->io_port + hostdata->c400_host_buf, 716 src + start, 128); 717 #else 718 /* implies SCSI_G_NCR5380_MEM */ 719 memcpy_toio(hostdata->iomem + NCR53C400_host_buffer, 720 src + start, 128); 721 #endif 722 start += 128; 723 blocks--; 724 } 725 726 /* wait for 53C80 registers to be available */ 727 while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) { 728 udelay(4); /* DTC436 chip hangs without this */ 729 /* FIXME - no timeout */ 730 } 731 732 if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) { 733 printk(KERN_ERR "53C400w: no end dma signal\n"); 734 } 735 736 while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT)) 737 ; // TIMEOUT 738 return 0; 739 } 740 741 static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd) 742 { 743 int transfersize = cmd->transfersize; 744 745 /* Limit transfers to 32K, for xx400 & xx406 746 * pseudoDMA that transfers in 128 bytes blocks. 747 */ 748 if (transfersize > 32 * 1024 && cmd->SCp.this_residual && 749 !(cmd->SCp.this_residual % transfersize)) 750 transfersize = 32 * 1024; 751 752 /* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */ 753 if (transfersize % 128) 754 transfersize = 0; 755 756 return transfersize; 757 } 758 759 #endif /* PSEUDO_DMA */ 760 761 /* 762 * Include the NCR5380 core code that we build our driver around 763 */ 764 765 #include "NCR5380.c" 766 767 static struct scsi_host_template driver_template = { 768 .proc_name = DRV_MODULE_NAME, 769 .name = "Generic NCR5380/NCR53C400 SCSI", 770 .detect = generic_NCR5380_detect, 771 .release = generic_NCR5380_release_resources, 772 .info = generic_NCR5380_info, 773 .queuecommand = generic_NCR5380_queue_command, 774 .eh_abort_handler = generic_NCR5380_abort, 775 .eh_bus_reset_handler = generic_NCR5380_bus_reset, 776 .bios_param = NCR5380_BIOSPARAM, 777 .can_queue = 16, 778 .this_id = 7, 779 .sg_tablesize = SG_ALL, 780 .cmd_per_lun = 2, 781 .use_clustering = DISABLE_CLUSTERING, 782 .cmd_size = NCR5380_CMD_SIZE, 783 .max_sectors = 128, 784 }; 785 786 #include "scsi_module.c" 787 788 module_param(ncr_irq, int, 0); 789 module_param(ncr_dma, int, 0); 790 module_param(ncr_addr, int, 0); 791 module_param(ncr_5380, int, 0); 792 module_param(ncr_53c400, int, 0); 793 module_param(ncr_53c400a, int, 0); 794 module_param(dtc_3181e, int, 0); 795 module_param(hp_c2502, int, 0); 796 MODULE_LICENSE("GPL"); 797 798 #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE) 799 static struct isapnp_device_id id_table[] = { 800 { 801 ISAPNP_ANY_ID, ISAPNP_ANY_ID, 802 ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e), 803 0}, 804 {0} 805 }; 806 807 MODULE_DEVICE_TABLE(isapnp, id_table); 808 #endif 809 810 __setup("ncr5380=", do_NCR5380_setup); 811 __setup("ncr53c400=", do_NCR53C400_setup); 812 __setup("ncr53c400a=", do_NCR53C400A_setup); 813 __setup("dtc3181e=", do_DTC3181E_setup); 814