1 /* 2 * Sun3 SCSI stuff by Erik Verbruggen (erik@bigmama.xtdnet.nl) 3 * 4 * Sun3 DMA routines added by Sam Creasey (sammy@sammy.net) 5 * 6 * VME support added by Sam Creasey 7 * 8 * TODO: modify this driver to support multiple Sun3 SCSI VME boards 9 * 10 * Adapted from mac_scsinew.c: 11 */ 12 /* 13 * Generic Macintosh NCR5380 driver 14 * 15 * Copyright 1998, Michael Schmitz <mschmitz@lbl.gov> 16 * 17 * derived in part from: 18 */ 19 /* 20 * Generic Generic NCR5380 driver 21 * 22 * Copyright 1995, Russell King 23 */ 24 25 #include <linux/types.h> 26 #include <linux/delay.h> 27 #include <linux/module.h> 28 #include <linux/ioport.h> 29 #include <linux/init.h> 30 #include <linux/blkdev.h> 31 #include <linux/platform_device.h> 32 33 #include <asm/io.h> 34 #include <asm/dvma.h> 35 36 #include <scsi/scsi_host.h> 37 #include "sun3_scsi.h" 38 39 /* Definitions for the core NCR5380 driver. */ 40 41 #define REAL_DMA 42 /* #define SUPPORT_TAGS */ 43 /* minimum number of bytes to do dma on */ 44 #define DMA_MIN_SIZE 129 45 46 /* #define MAX_TAGS 32 */ 47 48 #define NCR5380_implementation_fields /* none */ 49 50 #define NCR5380_read(reg) sun3scsi_read(reg) 51 #define NCR5380_write(reg, value) sun3scsi_write(reg, value) 52 53 #define NCR5380_queue_command sun3scsi_queue_command 54 #define NCR5380_bus_reset sun3scsi_bus_reset 55 #define NCR5380_abort sun3scsi_abort 56 #define NCR5380_show_info sun3scsi_show_info 57 #define NCR5380_info sun3scsi_info 58 59 #define NCR5380_dma_read_setup(instance, data, count) \ 60 sun3scsi_dma_setup(data, count, 0) 61 #define NCR5380_dma_write_setup(instance, data, count) \ 62 sun3scsi_dma_setup(data, count, 1) 63 #define NCR5380_dma_residual(instance) \ 64 sun3scsi_dma_residual(instance) 65 #define NCR5380_dma_xfer_len(instance, cmd, phase) \ 66 sun3scsi_dma_xfer_len(cmd->SCp.this_residual, cmd, !((phase) & SR_IO)) 67 68 #define NCR5380_acquire_dma_irq(instance) (1) 69 #define NCR5380_release_dma_irq(instance) 70 71 #include "NCR5380.h" 72 73 74 extern int sun3_map_test(unsigned long, char *); 75 76 static int setup_can_queue = -1; 77 module_param(setup_can_queue, int, 0); 78 static int setup_cmd_per_lun = -1; 79 module_param(setup_cmd_per_lun, int, 0); 80 static int setup_sg_tablesize = -1; 81 module_param(setup_sg_tablesize, int, 0); 82 #ifdef SUPPORT_TAGS 83 static int setup_use_tagged_queuing = -1; 84 module_param(setup_use_tagged_queuing, int, 0); 85 #endif 86 static int setup_hostid = -1; 87 module_param(setup_hostid, int, 0); 88 89 /* #define RESET_BOOT */ 90 91 #define AFTER_RESET_DELAY (HZ/2) 92 93 /* ms to wait after hitting dma regs */ 94 #define SUN3_DMA_DELAY 10 95 96 /* dvma buffer to allocate -- 32k should hopefully be more than sufficient */ 97 #define SUN3_DVMA_BUFSIZE 0xe000 98 99 static struct scsi_cmnd *sun3_dma_setup_done; 100 static unsigned char *sun3_scsi_regp; 101 static volatile struct sun3_dma_regs *dregs; 102 static struct sun3_udc_regs *udc_regs; 103 static unsigned char *sun3_dma_orig_addr = NULL; 104 static unsigned long sun3_dma_orig_count = 0; 105 static int sun3_dma_active = 0; 106 static unsigned long last_residual = 0; 107 static struct Scsi_Host *default_instance; 108 109 /* 110 * NCR 5380 register access functions 111 */ 112 113 static inline unsigned char sun3scsi_read(int reg) 114 { 115 return in_8(sun3_scsi_regp + reg); 116 } 117 118 static inline void sun3scsi_write(int reg, int value) 119 { 120 out_8(sun3_scsi_regp + reg, value); 121 } 122 123 #ifndef SUN3_SCSI_VME 124 /* dma controller register access functions */ 125 126 static inline unsigned short sun3_udc_read(unsigned char reg) 127 { 128 unsigned short ret; 129 130 dregs->udc_addr = UDC_CSR; 131 udelay(SUN3_DMA_DELAY); 132 ret = dregs->udc_data; 133 udelay(SUN3_DMA_DELAY); 134 135 return ret; 136 } 137 138 static inline void sun3_udc_write(unsigned short val, unsigned char reg) 139 { 140 dregs->udc_addr = reg; 141 udelay(SUN3_DMA_DELAY); 142 dregs->udc_data = val; 143 udelay(SUN3_DMA_DELAY); 144 } 145 #endif 146 147 #ifdef RESET_BOOT 148 static void sun3_scsi_reset_boot(struct Scsi_Host *instance) 149 { 150 unsigned long end; 151 152 /* 153 * Do a SCSI reset to clean up the bus during initialization. No 154 * messing with the queues, interrupts, or locks necessary here. 155 */ 156 157 printk( "Sun3 SCSI: resetting the SCSI bus..." ); 158 159 /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */ 160 // sun3_disable_irq( IRQ_SUN3_SCSI ); 161 162 /* get in phase */ 163 NCR5380_write( TARGET_COMMAND_REG, 164 PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); 165 166 /* assert RST */ 167 NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); 168 169 /* The min. reset hold time is 25us, so 40us should be enough */ 170 udelay( 50 ); 171 172 /* reset RST and interrupt */ 173 NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); 174 NCR5380_read( RESET_PARITY_INTERRUPT_REG ); 175 176 for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) 177 barrier(); 178 179 /* switch on SCSI IRQ again */ 180 // sun3_enable_irq( IRQ_SUN3_SCSI ); 181 182 printk( " done\n" ); 183 } 184 #endif 185 186 // safe bits for the CSR 187 #define CSR_GOOD 0x060f 188 189 static irqreturn_t scsi_sun3_intr(int irq, void *dummy) 190 { 191 unsigned short csr = dregs->csr; 192 int handled = 0; 193 194 #ifdef SUN3_SCSI_VME 195 dregs->csr &= ~CSR_DMA_ENABLE; 196 #endif 197 198 if(csr & ~CSR_GOOD) { 199 if(csr & CSR_DMA_BUSERR) { 200 printk("scsi%d: bus error in dma\n", default_instance->host_no); 201 } 202 203 if(csr & CSR_DMA_CONFLICT) { 204 printk("scsi%d: dma conflict\n", default_instance->host_no); 205 } 206 handled = 1; 207 } 208 209 if(csr & (CSR_SDB_INT | CSR_DMA_INT)) { 210 NCR5380_intr(irq, dummy); 211 handled = 1; 212 } 213 214 return IRQ_RETVAL(handled); 215 } 216 217 /* 218 * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; 219 * reentering NCR5380_print_status seems to have ugly side effects 220 */ 221 222 /* this doesn't seem to get used at all -- sam */ 223 #if 0 224 void sun3_sun3_debug (void) 225 { 226 unsigned long flags; 227 228 if (default_instance) { 229 local_irq_save(flags); 230 NCR5380_print_status(default_instance); 231 local_irq_restore(flags); 232 } 233 } 234 #endif 235 236 237 /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */ 238 static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag) 239 { 240 void *addr; 241 242 if(sun3_dma_orig_addr != NULL) 243 dvma_unmap(sun3_dma_orig_addr); 244 245 #ifdef SUN3_SCSI_VME 246 addr = (void *)dvma_map_vme((unsigned long) data, count); 247 #else 248 addr = (void *)dvma_map((unsigned long) data, count); 249 #endif 250 251 sun3_dma_orig_addr = addr; 252 sun3_dma_orig_count = count; 253 254 #ifndef SUN3_SCSI_VME 255 dregs->fifo_count = 0; 256 sun3_udc_write(UDC_RESET, UDC_CSR); 257 258 /* reset fifo */ 259 dregs->csr &= ~CSR_FIFO; 260 dregs->csr |= CSR_FIFO; 261 #endif 262 263 /* set direction */ 264 if(write_flag) 265 dregs->csr |= CSR_SEND; 266 else 267 dregs->csr &= ~CSR_SEND; 268 269 #ifdef SUN3_SCSI_VME 270 dregs->csr |= CSR_PACK_ENABLE; 271 272 dregs->dma_addr_hi = ((unsigned long)addr >> 16); 273 dregs->dma_addr_lo = ((unsigned long)addr & 0xffff); 274 275 dregs->dma_count_hi = 0; 276 dregs->dma_count_lo = 0; 277 dregs->fifo_count_hi = 0; 278 dregs->fifo_count = 0; 279 #else 280 /* byte count for fifo */ 281 dregs->fifo_count = count; 282 283 sun3_udc_write(UDC_RESET, UDC_CSR); 284 285 /* reset fifo */ 286 dregs->csr &= ~CSR_FIFO; 287 dregs->csr |= CSR_FIFO; 288 289 if(dregs->fifo_count != count) { 290 printk("scsi%d: fifo_mismatch %04x not %04x\n", 291 default_instance->host_no, dregs->fifo_count, 292 (unsigned int) count); 293 NCR5380_dprint(NDEBUG_DMA, default_instance); 294 } 295 296 /* setup udc */ 297 udc_regs->addr_hi = (((unsigned long)(addr) & 0xff0000) >> 8); 298 udc_regs->addr_lo = ((unsigned long)(addr) & 0xffff); 299 udc_regs->count = count/2; /* count in words */ 300 udc_regs->mode_hi = UDC_MODE_HIWORD; 301 if(write_flag) { 302 if(count & 1) 303 udc_regs->count++; 304 udc_regs->mode_lo = UDC_MODE_LSEND; 305 udc_regs->rsel = UDC_RSEL_SEND; 306 } else { 307 udc_regs->mode_lo = UDC_MODE_LRECV; 308 udc_regs->rsel = UDC_RSEL_RECV; 309 } 310 311 /* announce location of regs block */ 312 sun3_udc_write(((dvma_vtob(udc_regs) & 0xff0000) >> 8), 313 UDC_CHN_HI); 314 315 sun3_udc_write((dvma_vtob(udc_regs) & 0xffff), UDC_CHN_LO); 316 317 /* set dma master on */ 318 sun3_udc_write(0xd, UDC_MODE); 319 320 /* interrupt enable */ 321 sun3_udc_write(UDC_INT_ENABLE, UDC_CSR); 322 #endif 323 324 return count; 325 326 } 327 328 #ifndef SUN3_SCSI_VME 329 static inline unsigned long sun3scsi_dma_count(struct Scsi_Host *instance) 330 { 331 unsigned short resid; 332 333 dregs->udc_addr = 0x32; 334 udelay(SUN3_DMA_DELAY); 335 resid = dregs->udc_data; 336 udelay(SUN3_DMA_DELAY); 337 resid *= 2; 338 339 return (unsigned long) resid; 340 } 341 #endif 342 343 static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) 344 { 345 return last_residual; 346 } 347 348 static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, 349 struct scsi_cmnd *cmd, 350 int write_flag) 351 { 352 if (cmd->request->cmd_type == REQ_TYPE_FS) 353 return wanted; 354 else 355 return 0; 356 } 357 358 static inline int sun3scsi_dma_start(unsigned long count, unsigned char *data) 359 { 360 #ifdef SUN3_SCSI_VME 361 unsigned short csr; 362 363 csr = dregs->csr; 364 365 dregs->dma_count_hi = (sun3_dma_orig_count >> 16); 366 dregs->dma_count_lo = (sun3_dma_orig_count & 0xffff); 367 368 dregs->fifo_count_hi = (sun3_dma_orig_count >> 16); 369 dregs->fifo_count = (sun3_dma_orig_count & 0xffff); 370 371 /* if(!(csr & CSR_DMA_ENABLE)) 372 * dregs->csr |= CSR_DMA_ENABLE; 373 */ 374 #else 375 sun3_udc_write(UDC_CHN_START, UDC_CSR); 376 #endif 377 378 return 0; 379 } 380 381 /* clean up after our dma is done */ 382 static int sun3scsi_dma_finish(int write_flag) 383 { 384 unsigned short __maybe_unused count; 385 unsigned short fifo; 386 int ret = 0; 387 388 sun3_dma_active = 0; 389 390 #ifdef SUN3_SCSI_VME 391 dregs->csr &= ~CSR_DMA_ENABLE; 392 393 fifo = dregs->fifo_count; 394 if (write_flag) { 395 if ((fifo > 0) && (fifo < sun3_dma_orig_count)) 396 fifo++; 397 } 398 399 last_residual = fifo; 400 /* empty bytes from the fifo which didn't make it */ 401 if ((!write_flag) && (dregs->csr & CSR_LEFT)) { 402 unsigned char *vaddr; 403 404 vaddr = (unsigned char *)dvma_vmetov(sun3_dma_orig_addr); 405 406 vaddr += (sun3_dma_orig_count - fifo); 407 vaddr--; 408 409 switch (dregs->csr & CSR_LEFT) { 410 case CSR_LEFT_3: 411 *vaddr = (dregs->bpack_lo & 0xff00) >> 8; 412 vaddr--; 413 414 case CSR_LEFT_2: 415 *vaddr = (dregs->bpack_hi & 0x00ff); 416 vaddr--; 417 418 case CSR_LEFT_1: 419 *vaddr = (dregs->bpack_hi & 0xff00) >> 8; 420 break; 421 } 422 } 423 #else 424 // check to empty the fifo on a read 425 if(!write_flag) { 426 int tmo = 20000; /* .2 sec */ 427 428 while(1) { 429 if(dregs->csr & CSR_FIFO_EMPTY) 430 break; 431 432 if(--tmo <= 0) { 433 printk("sun3scsi: fifo failed to empty!\n"); 434 return 1; 435 } 436 udelay(10); 437 } 438 } 439 440 count = sun3scsi_dma_count(default_instance); 441 442 fifo = dregs->fifo_count; 443 last_residual = fifo; 444 445 /* empty bytes from the fifo which didn't make it */ 446 if((!write_flag) && (count - fifo) == 2) { 447 unsigned short data; 448 unsigned char *vaddr; 449 450 data = dregs->fifo_data; 451 vaddr = (unsigned char *)dvma_btov(sun3_dma_orig_addr); 452 453 vaddr += (sun3_dma_orig_count - fifo); 454 455 vaddr[-2] = (data & 0xff00) >> 8; 456 vaddr[-1] = (data & 0xff); 457 } 458 #endif 459 460 dvma_unmap(sun3_dma_orig_addr); 461 sun3_dma_orig_addr = NULL; 462 463 #ifdef SUN3_SCSI_VME 464 dregs->dma_addr_hi = 0; 465 dregs->dma_addr_lo = 0; 466 dregs->dma_count_hi = 0; 467 dregs->dma_count_lo = 0; 468 469 dregs->fifo_count = 0; 470 dregs->fifo_count_hi = 0; 471 472 dregs->csr &= ~CSR_SEND; 473 /* dregs->csr |= CSR_DMA_ENABLE; */ 474 #else 475 sun3_udc_write(UDC_RESET, UDC_CSR); 476 dregs->fifo_count = 0; 477 dregs->csr &= ~CSR_SEND; 478 479 /* reset fifo */ 480 dregs->csr &= ~CSR_FIFO; 481 dregs->csr |= CSR_FIFO; 482 #endif 483 484 sun3_dma_setup_done = NULL; 485 486 return ret; 487 488 } 489 490 #include "atari_NCR5380.c" 491 492 #ifdef SUN3_SCSI_VME 493 #define SUN3_SCSI_NAME "Sun3 NCR5380 VME SCSI" 494 #define DRV_MODULE_NAME "sun3_scsi_vme" 495 #else 496 #define SUN3_SCSI_NAME "Sun3 NCR5380 SCSI" 497 #define DRV_MODULE_NAME "sun3_scsi" 498 #endif 499 500 #define PFX DRV_MODULE_NAME ": " 501 502 static struct scsi_host_template sun3_scsi_template = { 503 .module = THIS_MODULE, 504 .proc_name = DRV_MODULE_NAME, 505 .show_info = sun3scsi_show_info, 506 .name = SUN3_SCSI_NAME, 507 .info = sun3scsi_info, 508 .queuecommand = sun3scsi_queue_command, 509 .eh_abort_handler = sun3scsi_abort, 510 .eh_bus_reset_handler = sun3scsi_bus_reset, 511 .can_queue = 16, 512 .this_id = 7, 513 .sg_tablesize = SG_NONE, 514 .cmd_per_lun = 2, 515 .use_clustering = DISABLE_CLUSTERING 516 }; 517 518 static int __init sun3_scsi_probe(struct platform_device *pdev) 519 { 520 struct Scsi_Host *instance; 521 int error; 522 struct resource *irq, *mem; 523 unsigned char *ioaddr; 524 int host_flags = 0; 525 #ifdef SUN3_SCSI_VME 526 int i; 527 #endif 528 529 if (setup_can_queue > 0) 530 sun3_scsi_template.can_queue = setup_can_queue; 531 if (setup_cmd_per_lun > 0) 532 sun3_scsi_template.cmd_per_lun = setup_cmd_per_lun; 533 if (setup_sg_tablesize >= 0) 534 sun3_scsi_template.sg_tablesize = setup_sg_tablesize; 535 if (setup_hostid >= 0) 536 sun3_scsi_template.this_id = setup_hostid & 7; 537 538 #ifdef SUN3_SCSI_VME 539 ioaddr = NULL; 540 for (i = 0; i < 2; i++) { 541 unsigned char x; 542 543 irq = platform_get_resource(pdev, IORESOURCE_IRQ, i); 544 mem = platform_get_resource(pdev, IORESOURCE_MEM, i); 545 if (!irq || !mem) 546 break; 547 548 ioaddr = sun3_ioremap(mem->start, resource_size(mem), 549 SUN3_PAGE_TYPE_VME16); 550 dregs = (struct sun3_dma_regs *)(ioaddr + 8); 551 552 if (sun3_map_test((unsigned long)dregs, &x)) { 553 unsigned short oldcsr; 554 555 oldcsr = dregs->csr; 556 dregs->csr = 0; 557 udelay(SUN3_DMA_DELAY); 558 if (dregs->csr == 0x1400) 559 break; 560 561 dregs->csr = oldcsr; 562 } 563 564 iounmap(ioaddr); 565 ioaddr = NULL; 566 } 567 if (!ioaddr) 568 return -ENODEV; 569 #else 570 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 571 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 572 if (!irq || !mem) 573 return -ENODEV; 574 575 ioaddr = ioremap(mem->start, resource_size(mem)); 576 dregs = (struct sun3_dma_regs *)(ioaddr + 8); 577 578 udc_regs = dvma_malloc(sizeof(struct sun3_udc_regs)); 579 if (!udc_regs) { 580 pr_err(PFX "couldn't allocate DVMA memory!\n"); 581 iounmap(ioaddr); 582 return -ENOMEM; 583 } 584 #endif 585 586 sun3_scsi_regp = ioaddr; 587 588 instance = scsi_host_alloc(&sun3_scsi_template, 589 sizeof(struct NCR5380_hostdata)); 590 if (!instance) { 591 error = -ENOMEM; 592 goto fail_alloc; 593 } 594 default_instance = instance; 595 596 instance->io_port = (unsigned long)ioaddr; 597 instance->irq = irq->start; 598 599 #ifdef SUPPORT_TAGS 600 host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; 601 #endif 602 603 NCR5380_init(instance, host_flags); 604 605 error = request_irq(instance->irq, scsi_sun3_intr, 0, 606 "NCR5380", instance); 607 if (error) { 608 #ifdef REAL_DMA 609 pr_err(PFX "scsi%d: IRQ %d not free, bailing out\n", 610 instance->host_no, instance->irq); 611 goto fail_irq; 612 #else 613 pr_warn(PFX "scsi%d: IRQ %d not free, interrupts disabled\n", 614 instance->host_no, instance->irq); 615 instance->irq = NO_IRQ; 616 #endif 617 } 618 619 dregs->csr = 0; 620 udelay(SUN3_DMA_DELAY); 621 dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR; 622 udelay(SUN3_DMA_DELAY); 623 dregs->fifo_count = 0; 624 #ifdef SUN3_SCSI_VME 625 dregs->fifo_count_hi = 0; 626 dregs->dma_addr_hi = 0; 627 dregs->dma_addr_lo = 0; 628 dregs->dma_count_hi = 0; 629 dregs->dma_count_lo = 0; 630 631 dregs->ivect = VME_DATA24 | (instance->irq & 0xff); 632 #endif 633 634 #ifdef RESET_BOOT 635 sun3_scsi_reset_boot(instance); 636 #endif 637 638 error = scsi_add_host(instance, NULL); 639 if (error) 640 goto fail_host; 641 642 platform_set_drvdata(pdev, instance); 643 644 scsi_scan_host(instance); 645 return 0; 646 647 fail_host: 648 if (instance->irq != NO_IRQ) 649 free_irq(instance->irq, instance); 650 fail_irq: 651 NCR5380_exit(instance); 652 scsi_host_put(instance); 653 fail_alloc: 654 if (udc_regs) 655 dvma_free(udc_regs); 656 iounmap(sun3_scsi_regp); 657 return error; 658 } 659 660 static int __exit sun3_scsi_remove(struct platform_device *pdev) 661 { 662 struct Scsi_Host *instance = platform_get_drvdata(pdev); 663 664 scsi_remove_host(instance); 665 if (instance->irq != NO_IRQ) 666 free_irq(instance->irq, instance); 667 NCR5380_exit(instance); 668 scsi_host_put(instance); 669 if (udc_regs) 670 dvma_free(udc_regs); 671 iounmap(sun3_scsi_regp); 672 return 0; 673 } 674 675 static struct platform_driver sun3_scsi_driver = { 676 .remove = __exit_p(sun3_scsi_remove), 677 .driver = { 678 .name = DRV_MODULE_NAME, 679 .owner = THIS_MODULE, 680 }, 681 }; 682 683 module_platform_driver_probe(sun3_scsi_driver, sun3_scsi_probe); 684 685 MODULE_ALIAS("platform:" DRV_MODULE_NAME); 686 MODULE_LICENSE("GPL"); 687