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

scsi/NCR5380: merge sun3_scsi_vme.c into sun3_scsi.c

The sun3 drivers suffer from a whole bunch of duplicated code. Fix this
by following the g_NCR5380_mmio example. (Notionally, sun3_scsi relates to
sun3_scsi_vme in the same way that g_NCR5380 relates to g_NCR5380_mmio.)

Dead code is also removed: we now have working debug macros so
SUN3_SCSI_DEBUG is undesirable. Dead code within #ifdef OLD_DMA is also
dropped, consistent with sun3_scsi_vme.c.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Acked-by: Sam Creasey <sammy@sammy.net>
Signed-off-by: Christoph Hellwig <hch@lst.de>

authored by

Finn Thain and committed by
Christoph Hellwig
757f5bad 9f6620a3

+172 -634
+171 -52
drivers/scsi/sun3_scsi.c
··· 3 3 * 4 4 * Sun3 DMA routines added by Sam Creasey (sammy@sammy.net) 5 5 * 6 + * VME support added by Sam Creasey 7 + * 8 + * TODO: modify this driver to support multiple Sun3 SCSI VME boards 9 + * 6 10 * Adapted from mac_scsinew.c: 7 11 */ 8 12 /* ··· 77 73 #include "sun3_scsi.h" 78 74 #include "NCR5380.h" 79 75 80 - /* #define OLDDMA */ 76 + extern int sun3_map_test(unsigned long, char *); 81 77 82 78 #define USE_WRAPPER 83 79 /*#define RESET_BOOT */ ··· 93 89 94 90 /* #define SUPPORT_TAGS */ 95 91 92 + #ifdef SUN3_SCSI_VME 93 + #define ENABLE_IRQ() 94 + #else 96 95 #define ENABLE_IRQ() enable_irq( IRQ_SUN3_SCSI ); 96 + #endif 97 97 98 98 99 99 static irqreturn_t scsi_sun3_intr(int irq, void *dummy); ··· 134 126 135 127 static volatile unsigned char *sun3_scsi_regp; 136 128 static volatile struct sun3_dma_regs *dregs; 137 - #ifdef OLDDMA 138 - static unsigned char *dmabuf = NULL; /* dma memory buffer */ 139 - #endif 129 + #ifndef SUN3_SCSI_VME 140 130 static struct sun3_udc_regs *udc_regs = NULL; 131 + #endif 141 132 static unsigned char *sun3_dma_orig_addr = NULL; 142 133 static unsigned long sun3_dma_orig_count = 0; 143 134 static int sun3_dma_active = 0; ··· 156 149 sun3_scsi_regp[reg] = value; 157 150 } 158 151 152 + #ifndef SUN3_SCSI_VME 159 153 /* dma controller register access functions */ 160 154 161 155 static inline unsigned short sun3_udc_read(unsigned char reg) ··· 178 170 dregs->udc_data = val; 179 171 udelay(SUN3_DMA_DELAY); 180 172 } 173 + #endif 181 174 182 175 /* 183 176 * XXX: status debug ··· 197 188 * 198 189 */ 199 190 200 - int __init sun3scsi_detect(struct scsi_host_template * tpnt) 191 + static int __init sun3scsi_detect(struct scsi_host_template *tpnt) 201 192 { 202 - unsigned long ioaddr; 193 + unsigned long ioaddr, irq; 203 194 static int called = 0; 204 195 struct Scsi_Host *instance; 196 + #ifdef SUN3_SCSI_VME 197 + int i; 198 + unsigned long addrs[3] = { IOBASE_SUN3_VMESCSI, 199 + IOBASE_SUN3_VMESCSI + 0x4000, 200 + 0 }; 201 + unsigned long vecs[3] = { SUN3_VEC_VMESCSI0, 202 + SUN3_VEC_VMESCSI1, 203 + 0 }; 204 + #endif 205 205 206 206 /* check that this machine has an onboard 5380 */ 207 207 switch(idprom->id_machtype) { 208 + #ifdef SUN3_SCSI_VME 209 + case SM_SUN3|SM_3_160: 210 + case SM_SUN3|SM_3_260: 211 + break; 212 + #else 208 213 case SM_SUN3|SM_3_50: 209 214 case SM_SUN3|SM_3_60: 210 215 break; 216 + #endif 211 217 212 218 default: 213 219 return 0; ··· 231 207 if(called) 232 208 return 0; 233 209 210 + #ifdef SUN3_SCSI_VME 211 + tpnt->proc_name = "Sun3 5380 VME SCSI"; 212 + #else 234 213 tpnt->proc_name = "Sun3 5380 SCSI"; 214 + #endif 235 215 236 216 /* setup variables */ 237 217 tpnt->can_queue = ··· 252 224 tpnt->this_id = 7; 253 225 } 254 226 227 + #ifdef SUN3_SCSI_VME 228 + ioaddr = 0; 229 + for (i = 0; addrs[i] != 0; i++) { 230 + unsigned char x; 231 + 232 + ioaddr = (unsigned long)sun3_ioremap(addrs[i], PAGE_SIZE, 233 + SUN3_PAGE_TYPE_VME16); 234 + irq = vecs[i]; 235 + sun3_scsi_regp = (unsigned char *)ioaddr; 236 + 237 + dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8); 238 + 239 + if (sun3_map_test((unsigned long)dregs, &x)) { 240 + unsigned short oldcsr; 241 + 242 + oldcsr = dregs->csr; 243 + dregs->csr = 0; 244 + udelay(SUN3_DMA_DELAY); 245 + if (dregs->csr == 0x1400) 246 + break; 247 + 248 + dregs->csr = oldcsr; 249 + } 250 + 251 + iounmap((void *)ioaddr); 252 + ioaddr = 0; 253 + } 254 + 255 + if (!ioaddr) 256 + return 0; 257 + #else 258 + irq = IRQ_SUN3_SCSI; 255 259 ioaddr = (unsigned long)ioremap(IOBASE_SUN3_SCSI, PAGE_SIZE); 256 260 sun3_scsi_regp = (unsigned char *)ioaddr; 257 261 ··· 291 231 292 232 if((udc_regs = dvma_malloc(sizeof(struct sun3_udc_regs))) 293 233 == NULL) { 294 - printk("SUN3 Scsi couldn't allocate DVMA memory!\n"); 295 - return 0; 296 - } 297 - #ifdef OLDDMA 298 - if((dmabuf = dvma_malloc_align(SUN3_DVMA_BUFSIZE, 0x10000)) == NULL) { 299 234 printk("SUN3 Scsi couldn't allocate DVMA memory!\n"); 300 235 return 0; 301 236 } ··· 307 252 default_instance = instance; 308 253 309 254 instance->io_port = (unsigned long) ioaddr; 310 - instance->irq = IRQ_SUN3_SCSI; 255 + instance->irq = irq; 311 256 312 257 NCR5380_init(instance, 0); 313 258 ··· 328 273 #endif 329 274 } 330 275 331 - printk("scsi%d: Sun3 5380 at port %lX irq", instance->host_no, instance->io_port); 276 + pr_info("scsi%d: %s at port %lX irq", instance->host_no, 277 + tpnt->proc_name, instance->io_port); 332 278 if (instance->irq == SCSI_IRQ_NONE) 333 279 printk ("s disabled"); 334 280 else ··· 346 290 dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR; 347 291 udelay(SUN3_DMA_DELAY); 348 292 dregs->fifo_count = 0; 293 + #ifdef SUN3_SCSI_VME 294 + dregs->fifo_count_hi = 0; 295 + dregs->dma_addr_hi = 0; 296 + dregs->dma_addr_lo = 0; 297 + dregs->dma_count_hi = 0; 298 + dregs->dma_count_lo = 0; 299 + 300 + dregs->ivect = VME_DATA24 | (instance->irq & 0xff); 301 + #endif 349 302 350 303 called = 1; 351 304 ··· 422 357 } 423 358 #endif 424 359 425 - const char * sun3scsi_info (struct Scsi_Host *spnt) { 360 + static const char *sun3scsi_info(struct Scsi_Host *spnt) 361 + { 426 362 return ""; 427 363 } 428 364 ··· 434 368 { 435 369 unsigned short csr = dregs->csr; 436 370 int handled = 0; 371 + 372 + #ifdef SUN3_SCSI_VME 373 + dregs->csr &= ~CSR_DMA_ENABLE; 374 + #endif 437 375 438 376 if(csr & ~CSR_GOOD) { 439 377 if(csr & CSR_DMA_BUSERR) { ··· 482 412 /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */ 483 413 static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag) 484 414 { 485 - #ifdef OLDDMA 486 - if(write_flag) 487 - memcpy(dmabuf, data, count); 488 - else { 489 - sun3_dma_orig_addr = data; 490 - sun3_dma_orig_count = count; 491 - } 492 - #else 493 415 void *addr; 494 416 495 417 if(sun3_dma_orig_addr != NULL) 496 418 dvma_unmap(sun3_dma_orig_addr); 497 419 498 - // addr = sun3_dvma_page((unsigned long)data, (unsigned long)dmabuf); 420 + #ifdef SUN3_SCSI_VME 421 + addr = (void *)dvma_map_vme((unsigned long) data, count); 422 + #else 499 423 addr = (void *)dvma_map((unsigned long) data, count); 424 + #endif 500 425 501 426 sun3_dma_orig_addr = addr; 502 427 sun3_dma_orig_count = count; 503 - #endif 428 + 429 + #ifndef SUN3_SCSI_VME 504 430 dregs->fifo_count = 0; 505 431 sun3_udc_write(UDC_RESET, UDC_CSR); 506 432 507 433 /* reset fifo */ 508 434 dregs->csr &= ~CSR_FIFO; 509 435 dregs->csr |= CSR_FIFO; 436 + #endif 510 437 511 438 /* set direction */ 512 439 if(write_flag) ··· 511 444 else 512 445 dregs->csr &= ~CSR_SEND; 513 446 447 + #ifdef SUN3_SCSI_VME 448 + dregs->csr |= CSR_PACK_ENABLE; 449 + 450 + dregs->dma_addr_hi = ((unsigned long)addr >> 16); 451 + dregs->dma_addr_lo = ((unsigned long)addr & 0xffff); 452 + 453 + dregs->dma_count_hi = 0; 454 + dregs->dma_count_lo = 0; 455 + dregs->fifo_count_hi = 0; 456 + dregs->fifo_count = 0; 457 + #else 514 458 /* byte count for fifo */ 515 459 dregs->fifo_count = count; 516 460 ··· 539 461 } 540 462 541 463 /* setup udc */ 542 - #ifdef OLDDMA 543 - udc_regs->addr_hi = ((dvma_vtob(dmabuf) & 0xff0000) >> 8); 544 - udc_regs->addr_lo = (dvma_vtob(dmabuf) & 0xffff); 545 - #else 546 464 udc_regs->addr_hi = (((unsigned long)(addr) & 0xff0000) >> 8); 547 465 udc_regs->addr_lo = ((unsigned long)(addr) & 0xffff); 548 - #endif 549 466 udc_regs->count = count/2; /* count in words */ 550 467 udc_regs->mode_hi = UDC_MODE_HIWORD; 551 468 if(write_flag) { ··· 564 491 565 492 /* interrupt enable */ 566 493 sun3_udc_write(UDC_INT_ENABLE, UDC_CSR); 494 + #endif 567 495 568 496 return count; 569 497 570 498 } 571 499 500 + #ifndef SUN3_SCSI_VME 572 501 static inline unsigned long sun3scsi_dma_count(struct Scsi_Host *instance) 573 502 { 574 503 unsigned short resid; ··· 583 508 584 509 return (unsigned long) resid; 585 510 } 511 + #endif 586 512 587 513 static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) 588 514 { ··· 602 526 603 527 static inline int sun3scsi_dma_start(unsigned long count, unsigned char *data) 604 528 { 529 + #ifdef SUN3_SCSI_VME 530 + unsigned short csr; 605 531 532 + csr = dregs->csr; 533 + 534 + dregs->dma_count_hi = (sun3_dma_orig_count >> 16); 535 + dregs->dma_count_lo = (sun3_dma_orig_count & 0xffff); 536 + 537 + dregs->fifo_count_hi = (sun3_dma_orig_count >> 16); 538 + dregs->fifo_count = (sun3_dma_orig_count & 0xffff); 539 + 540 + /* if(!(csr & CSR_DMA_ENABLE)) 541 + * dregs->csr |= CSR_DMA_ENABLE; 542 + */ 543 + #else 606 544 sun3_udc_write(UDC_CHN_START, UDC_CSR); 545 + #endif 607 546 608 547 return 0; 609 548 } ··· 626 535 /* clean up after our dma is done */ 627 536 static int sun3scsi_dma_finish(int write_flag) 628 537 { 629 - unsigned short count; 538 + unsigned short __maybe_unused count; 630 539 unsigned short fifo; 631 540 int ret = 0; 632 541 633 542 sun3_dma_active = 0; 634 - #if 1 543 + 544 + #ifdef SUN3_SCSI_VME 545 + dregs->csr &= ~CSR_DMA_ENABLE; 546 + 547 + fifo = dregs->fifo_count; 548 + if (write_flag) { 549 + if ((fifo > 0) && (fifo < sun3_dma_orig_count)) 550 + fifo++; 551 + } 552 + 553 + last_residual = fifo; 554 + /* empty bytes from the fifo which didn't make it */ 555 + if ((!write_flag) && (dregs->csr & CSR_LEFT)) { 556 + unsigned char *vaddr; 557 + 558 + vaddr = (unsigned char *)dvma_vmetov(sun3_dma_orig_addr); 559 + 560 + vaddr += (sun3_dma_orig_count - fifo); 561 + vaddr--; 562 + 563 + switch (dregs->csr & CSR_LEFT) { 564 + case CSR_LEFT_3: 565 + *vaddr = (dregs->bpack_lo & 0xff00) >> 8; 566 + vaddr--; 567 + 568 + case CSR_LEFT_2: 569 + *vaddr = (dregs->bpack_hi & 0x00ff); 570 + vaddr--; 571 + 572 + case CSR_LEFT_1: 573 + *vaddr = (dregs->bpack_hi & 0xff00) >> 8; 574 + break; 575 + } 576 + } 577 + #else 635 578 // check to empty the fifo on a read 636 579 if(!write_flag) { 637 580 int tmo = 20000; /* .2 sec */ ··· 681 556 udelay(10); 682 557 } 683 558 } 684 - 685 - #endif 686 559 687 560 count = sun3scsi_dma_count(default_instance); 688 - #ifdef OLDDMA 689 - 690 - /* if we've finished a read, copy out the data we read */ 691 - if(sun3_dma_orig_addr) { 692 - /* check for residual bytes after dma end */ 693 - if(count && (NCR5380_read(BUS_AND_STATUS_REG) & 694 - (BASR_PHASE_MATCH | BASR_ACK))) { 695 - printk("scsi%d: sun3_scsi_finish: read overrun baby... ", default_instance->host_no); 696 - printk("basr now %02x\n", NCR5380_read(BUS_AND_STATUS_REG)); 697 - ret = count; 698 - } 699 - 700 - /* copy in what we dma'd no matter what */ 701 - memcpy(sun3_dma_orig_addr, dmabuf, sun3_dma_orig_count); 702 - sun3_dma_orig_addr = NULL; 703 - 704 - } 705 - #else 706 561 707 562 fifo = dregs->fifo_count; 708 563 last_residual = fifo; ··· 700 595 vaddr[-2] = (data & 0xff00) >> 8; 701 596 vaddr[-1] = (data & 0xff); 702 597 } 598 + #endif 703 599 704 600 dvma_unmap(sun3_dma_orig_addr); 705 601 sun3_dma_orig_addr = NULL; 706 - #endif 602 + 603 + #ifdef SUN3_SCSI_VME 604 + dregs->dma_addr_hi = 0; 605 + dregs->dma_addr_lo = 0; 606 + dregs->dma_count_hi = 0; 607 + dregs->dma_count_lo = 0; 608 + 609 + dregs->fifo_count = 0; 610 + dregs->fifo_count_hi = 0; 611 + 612 + dregs->csr &= ~CSR_SEND; 613 + /* dregs->csr |= CSR_DMA_ENABLE; */ 614 + #else 707 615 sun3_udc_write(UDC_RESET, UDC_CSR); 708 616 dregs->fifo_count = 0; 709 617 dregs->csr &= ~CSR_SEND; ··· 724 606 /* reset fifo */ 725 607 dregs->csr &= ~CSR_FIFO; 726 608 dregs->csr |= CSR_FIFO; 609 + #endif 727 610 728 611 sun3_dma_setup_done = NULL; 729 612
+1 -582
drivers/scsi/sun3_scsi_vme.c
··· 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 - * Adapted from sun3_scsi.c -- see there for other headers 9 - * 10 - * TODO: modify this driver to support multiple Sun3 SCSI VME boards 11 - * 12 - */ 13 - 14 - #define AUTOSENSE 15 - 16 - #include <linux/types.h> 17 - #include <linux/stddef.h> 18 - #include <linux/ctype.h> 19 - #include <linux/delay.h> 20 - 21 - #include <linux/module.h> 22 - #include <linux/signal.h> 23 - #include <linux/ioport.h> 24 - #include <linux/init.h> 25 - #include <linux/blkdev.h> 26 - 27 - #include <asm/io.h> 28 - 29 - #include <asm/sun3ints.h> 30 - #include <asm/dvma.h> 31 - #include <asm/idprom.h> 32 - #include <asm/machines.h> 33 - 34 1 #define SUN3_SCSI_VME 35 2 36 - #undef SUN3_SCSI_DEBUG 37 - 38 - /* dma on! */ 39 - #define REAL_DMA 40 - 41 - #include "scsi.h" 42 - #include "initio.h" 43 - #include <scsi/scsi_host.h> 44 - #include "sun3_scsi.h" 45 - #include "NCR5380.h" 46 - 47 - extern int sun3_map_test(unsigned long, char *); 48 - 49 - #define USE_WRAPPER 50 - /*#define RESET_BOOT */ 51 - #define DRIVER_SETUP 52 - 53 - /* 54 - * BUG can be used to trigger a strange code-size related hang on 2.1 kernels 55 - */ 56 - #ifdef BUG 57 - #undef RESET_BOOT 58 - #undef DRIVER_SETUP 59 - #endif 60 - 61 - /* #define SUPPORT_TAGS */ 62 - 63 - //#define ENABLE_IRQ() enable_irq( SUN3_VEC_VMESCSI0 ); 64 - #define ENABLE_IRQ() 65 - 66 - 67 - static irqreturn_t scsi_sun3_intr(int irq, void *dummy); 68 - static inline unsigned char sun3scsi_read(int reg); 69 - static inline void sun3scsi_write(int reg, int value); 70 - 71 - static int setup_can_queue = -1; 72 - module_param(setup_can_queue, int, 0); 73 - static int setup_cmd_per_lun = -1; 74 - module_param(setup_cmd_per_lun, int, 0); 75 - static int setup_sg_tablesize = -1; 76 - module_param(setup_sg_tablesize, int, 0); 77 - #ifdef SUPPORT_TAGS 78 - static int setup_use_tagged_queuing = -1; 79 - module_param(setup_use_tagged_queuing, int, 0); 80 - #endif 81 - static int setup_hostid = -1; 82 - module_param(setup_hostid, int, 0); 83 - 84 - static struct scsi_cmnd *sun3_dma_setup_done = NULL; 85 - 86 - #define AFTER_RESET_DELAY (HZ/2) 87 - 88 - /* ms to wait after hitting dma regs */ 89 - #define SUN3_DMA_DELAY 10 90 - 91 - /* dvma buffer to allocate -- 32k should hopefully be more than sufficient */ 92 - #define SUN3_DVMA_BUFSIZE 0xe000 93 - 94 - /* minimum number of bytes to do dma on */ 95 - #define SUN3_DMA_MINSIZE 128 96 - 97 - static volatile unsigned char *sun3_scsi_regp; 98 - static volatile struct sun3_dma_regs *dregs; 99 - #ifdef OLDDMA 100 - static unsigned char *dmabuf = NULL; /* dma memory buffer */ 101 - #endif 102 - static unsigned char *sun3_dma_orig_addr = NULL; 103 - static unsigned long sun3_dma_orig_count = 0; 104 - static int sun3_dma_active = 0; 105 - static unsigned long last_residual = 0; 106 - 107 - /* 108 - * NCR 5380 register access functions 109 - */ 110 - 111 - static inline unsigned char sun3scsi_read(int reg) 112 - { 113 - return( sun3_scsi_regp[reg] ); 114 - } 115 - 116 - static inline void sun3scsi_write(int reg, int value) 117 - { 118 - sun3_scsi_regp[reg] = value; 119 - } 120 - 121 - /* 122 - * XXX: status debug 123 - */ 124 - static struct Scsi_Host *default_instance; 125 - 126 - /* 127 - * Function : int sun3scsi_detect(struct scsi_host_template * tpnt) 128 - * 129 - * Purpose : initializes mac NCR5380 driver based on the 130 - * command line / compile time port and irq definitions. 131 - * 132 - * Inputs : tpnt - template for this SCSI adapter. 133 - * 134 - * Returns : 1 if a host adapter was found, 0 if not. 135 - * 136 - */ 137 - 138 - static int __init sun3scsi_detect(struct scsi_host_template * tpnt) 139 - { 140 - unsigned long ioaddr, irq = 0; 141 - static int called = 0; 142 - struct Scsi_Host *instance; 143 - int i; 144 - unsigned long addrs[3] = { IOBASE_SUN3_VMESCSI, 145 - IOBASE_SUN3_VMESCSI + 0x4000, 146 - 0 }; 147 - unsigned long vecs[3] = { SUN3_VEC_VMESCSI0, 148 - SUN3_VEC_VMESCSI1, 149 - 0 }; 150 - /* check that this machine has an onboard 5380 */ 151 - switch(idprom->id_machtype) { 152 - case SM_SUN3|SM_3_160: 153 - case SM_SUN3|SM_3_260: 154 - break; 155 - 156 - default: 157 - return 0; 158 - } 159 - 160 - if(called) 161 - return 0; 162 - 163 - tpnt->proc_name = "Sun3 5380 VME SCSI"; 164 - 165 - /* setup variables */ 166 - tpnt->can_queue = 167 - (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE; 168 - tpnt->cmd_per_lun = 169 - (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN; 170 - tpnt->sg_tablesize = 171 - (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE; 172 - 173 - if (setup_hostid >= 0) 174 - tpnt->this_id = setup_hostid; 175 - else { 176 - /* use 7 as default */ 177 - tpnt->this_id = 7; 178 - } 179 - 180 - ioaddr = 0; 181 - for(i = 0; addrs[i] != 0; i++) { 182 - unsigned char x; 183 - 184 - ioaddr = (unsigned long)sun3_ioremap(addrs[i], PAGE_SIZE, 185 - SUN3_PAGE_TYPE_VME16); 186 - irq = vecs[i]; 187 - sun3_scsi_regp = (unsigned char *)ioaddr; 188 - 189 - dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8); 190 - 191 - if(sun3_map_test((unsigned long)dregs, &x)) { 192 - unsigned short oldcsr; 193 - 194 - oldcsr = dregs->csr; 195 - dregs->csr = 0; 196 - udelay(SUN3_DMA_DELAY); 197 - if(dregs->csr == 0x1400) 198 - break; 199 - 200 - dregs->csr = oldcsr; 201 - } 202 - 203 - iounmap((void *)ioaddr); 204 - ioaddr = 0; 205 - } 206 - 207 - if(!ioaddr) 208 - return 0; 209 - 210 - #ifdef SUPPORT_TAGS 211 - if (setup_use_tagged_queuing < 0) 212 - setup_use_tagged_queuing = USE_TAGGED_QUEUING; 213 - #endif 214 - 215 - instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); 216 - if(instance == NULL) 217 - return 0; 218 - 219 - default_instance = instance; 220 - 221 - instance->io_port = (unsigned long) ioaddr; 222 - instance->irq = irq; 223 - 224 - NCR5380_init(instance, 0); 225 - 226 - instance->n_io_port = 32; 227 - 228 - ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; 229 - 230 - if (request_irq(instance->irq, scsi_sun3_intr, 231 - 0, "Sun3SCSI-5380VME", instance)) { 232 - #ifndef REAL_DMA 233 - printk("scsi%d: IRQ%d not free, interrupts disabled\n", 234 - instance->host_no, instance->irq); 235 - instance->irq = SCSI_IRQ_NONE; 236 - #else 237 - printk("scsi%d: IRQ%d not free, bailing out\n", 238 - instance->host_no, instance->irq); 239 - return 0; 240 - #endif 241 - } 242 - 243 - printk("scsi%d: Sun3 5380 VME at port %lX irq", instance->host_no, instance->io_port); 244 - if (instance->irq == SCSI_IRQ_NONE) 245 - printk ("s disabled"); 246 - else 247 - printk (" %d", instance->irq); 248 - printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", 249 - instance->can_queue, instance->cmd_per_lun, 250 - SUN3SCSI_PUBLIC_RELEASE); 251 - printk("\nscsi%d:", instance->host_no); 252 - NCR5380_print_options(instance); 253 - printk("\n"); 254 - 255 - dregs->csr = 0; 256 - udelay(SUN3_DMA_DELAY); 257 - dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR; 258 - udelay(SUN3_DMA_DELAY); 259 - dregs->fifo_count = 0; 260 - dregs->fifo_count_hi = 0; 261 - dregs->dma_addr_hi = 0; 262 - dregs->dma_addr_lo = 0; 263 - dregs->dma_count_hi = 0; 264 - dregs->dma_count_lo = 0; 265 - 266 - dregs->ivect = VME_DATA24 | (instance->irq & 0xff); 267 - 268 - called = 1; 269 - 270 - #ifdef RESET_BOOT 271 - sun3_scsi_reset_boot(instance); 272 - #endif 273 - 274 - return 1; 275 - } 276 - 277 - int sun3scsi_release (struct Scsi_Host *shpnt) 278 - { 279 - if (shpnt->irq != SCSI_IRQ_NONE) 280 - free_irq(shpnt->irq, shpnt); 281 - 282 - iounmap((void *)sun3_scsi_regp); 283 - 284 - NCR5380_exit(shpnt); 285 - return 0; 286 - } 287 - 288 - #ifdef RESET_BOOT 289 - /* 290 - * Our 'bus reset on boot' function 291 - */ 292 - 293 - static void sun3_scsi_reset_boot(struct Scsi_Host *instance) 294 - { 295 - unsigned long end; 296 - 297 - NCR5380_local_declare(); 298 - NCR5380_setup(instance); 299 - 300 - /* 301 - * Do a SCSI reset to clean up the bus during initialization. No 302 - * messing with the queues, interrupts, or locks necessary here. 303 - */ 304 - 305 - printk( "Sun3 SCSI: resetting the SCSI bus..." ); 306 - 307 - /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */ 308 - // sun3_disable_irq( IRQ_SUN3_SCSI ); 309 - 310 - /* get in phase */ 311 - NCR5380_write( TARGET_COMMAND_REG, 312 - PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); 313 - 314 - /* assert RST */ 315 - NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); 316 - 317 - /* The min. reset hold time is 25us, so 40us should be enough */ 318 - udelay( 50 ); 319 - 320 - /* reset RST and interrupt */ 321 - NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); 322 - NCR5380_read( RESET_PARITY_INTERRUPT_REG ); 323 - 324 - for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) 325 - barrier(); 326 - 327 - /* switch on SCSI IRQ again */ 328 - // sun3_enable_irq( IRQ_SUN3_SCSI ); 329 - 330 - printk( " done\n" ); 331 - } 332 - #endif 333 - 334 - static const char * sun3scsi_info (struct Scsi_Host *spnt) { 335 - return ""; 336 - } 337 - 338 - // safe bits for the CSR 339 - #define CSR_GOOD 0x060f 340 - 341 - static irqreturn_t scsi_sun3_intr(int irq, void *dummy) 342 - { 343 - unsigned short csr = dregs->csr; 344 - int handled = 0; 345 - 346 - dregs->csr &= ~CSR_DMA_ENABLE; 347 - 348 - 349 - #ifdef SUN3_SCSI_DEBUG 350 - printk("scsi_intr csr %x\n", csr); 351 - #endif 352 - 353 - if(csr & ~CSR_GOOD) { 354 - if(csr & CSR_DMA_BUSERR) { 355 - printk("scsi%d: bus error in dma\n", default_instance->host_no); 356 - #ifdef SUN3_SCSI_DEBUG 357 - printk("scsi: residual %x count %x addr %p dmaaddr %x\n", 358 - dregs->fifo_count, 359 - dregs->dma_count_lo | (dregs->dma_count_hi << 16), 360 - sun3_dma_orig_addr, 361 - dregs->dma_addr_lo | (dregs->dma_addr_hi << 16)); 362 - #endif 363 - } 364 - 365 - if(csr & CSR_DMA_CONFLICT) { 366 - printk("scsi%d: dma conflict\n", default_instance->host_no); 367 - } 368 - handled = 1; 369 - } 370 - 371 - if(csr & (CSR_SDB_INT | CSR_DMA_INT)) { 372 - NCR5380_intr(irq, dummy); 373 - handled = 1; 374 - } 375 - 376 - return IRQ_RETVAL(handled); 377 - } 378 - 379 - /* 380 - * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; 381 - * reentering NCR5380_print_status seems to have ugly side effects 382 - */ 383 - 384 - /* this doesn't seem to get used at all -- sam */ 385 - #if 0 386 - void sun3_sun3_debug (void) 387 - { 388 - unsigned long flags; 389 - NCR5380_local_declare(); 390 - 391 - if (default_instance) { 392 - local_irq_save(flags); 393 - NCR5380_print_status(default_instance); 394 - local_irq_restore(flags); 395 - } 396 - } 397 - #endif 398 - 399 - 400 - /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */ 401 - static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag) 402 - { 403 - void *addr; 404 - 405 - if(sun3_dma_orig_addr != NULL) 406 - dvma_unmap(sun3_dma_orig_addr); 407 - 408 - // addr = sun3_dvma_page((unsigned long)data, (unsigned long)dmabuf); 409 - addr = (void *)dvma_map_vme((unsigned long) data, count); 410 - 411 - sun3_dma_orig_addr = addr; 412 - sun3_dma_orig_count = count; 413 - 414 - #ifdef SUN3_SCSI_DEBUG 415 - printk("scsi: dma_setup addr %p count %x\n", addr, count); 416 - #endif 417 - 418 - // dregs->fifo_count = 0; 419 - #if 0 420 - /* reset fifo */ 421 - dregs->csr &= ~CSR_FIFO; 422 - dregs->csr |= CSR_FIFO; 423 - #endif 424 - /* set direction */ 425 - if(write_flag) 426 - dregs->csr |= CSR_SEND; 427 - else 428 - dregs->csr &= ~CSR_SEND; 429 - 430 - /* reset fifo */ 431 - // dregs->csr &= ~CSR_FIFO; 432 - // dregs->csr |= CSR_FIFO; 433 - 434 - dregs->csr |= CSR_PACK_ENABLE; 435 - 436 - dregs->dma_addr_hi = ((unsigned long)addr >> 16); 437 - dregs->dma_addr_lo = ((unsigned long)addr & 0xffff); 438 - 439 - dregs->dma_count_hi = 0; 440 - dregs->dma_count_lo = 0; 441 - dregs->fifo_count_hi = 0; 442 - dregs->fifo_count = 0; 443 - 444 - #ifdef SUN3_SCSI_DEBUG 445 - printk("scsi: dma_setup done csr %x\n", dregs->csr); 446 - #endif 447 - return count; 448 - 449 - } 450 - 451 - static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) 452 - { 453 - return last_residual; 454 - } 455 - 456 - static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, 457 - struct scsi_cmnd *cmd, 458 - int write_flag) 459 - { 460 - if (cmd->request->cmd_type == REQ_TYPE_FS) 461 - return wanted; 462 - else 463 - return 0; 464 - } 465 - 466 - static int sun3scsi_dma_start(unsigned long count, char *data) 467 - { 468 - 469 - unsigned short csr; 470 - 471 - csr = dregs->csr; 472 - #ifdef SUN3_SCSI_DEBUG 473 - printk("scsi: dma_start data %p count %x csr %x fifo %x\n", data, count, csr, dregs->fifo_count); 474 - #endif 475 - 476 - dregs->dma_count_hi = (sun3_dma_orig_count >> 16); 477 - dregs->dma_count_lo = (sun3_dma_orig_count & 0xffff); 478 - 479 - dregs->fifo_count_hi = (sun3_dma_orig_count >> 16); 480 - dregs->fifo_count = (sun3_dma_orig_count & 0xffff); 481 - 482 - // if(!(csr & CSR_DMA_ENABLE)) 483 - // dregs->csr |= CSR_DMA_ENABLE; 484 - 485 - return 0; 486 - } 487 - 488 - /* clean up after our dma is done */ 489 - static int sun3scsi_dma_finish(int write_flag) 490 - { 491 - unsigned short fifo; 492 - int ret = 0; 493 - 494 - sun3_dma_active = 0; 495 - 496 - dregs->csr &= ~CSR_DMA_ENABLE; 497 - 498 - fifo = dregs->fifo_count; 499 - if(write_flag) { 500 - if((fifo > 0) && (fifo < sun3_dma_orig_count)) 501 - fifo++; 502 - } 503 - 504 - last_residual = fifo; 505 - #ifdef SUN3_SCSI_DEBUG 506 - printk("scsi: residual %x total %x\n", fifo, sun3_dma_orig_count); 507 - #endif 508 - /* empty bytes from the fifo which didn't make it */ 509 - if((!write_flag) && (dregs->csr & CSR_LEFT)) { 510 - unsigned char *vaddr; 511 - 512 - #ifdef SUN3_SCSI_DEBUG 513 - printk("scsi: got left over bytes\n"); 514 - #endif 515 - 516 - vaddr = (unsigned char *)dvma_vmetov(sun3_dma_orig_addr); 517 - 518 - vaddr += (sun3_dma_orig_count - fifo); 519 - vaddr--; 520 - 521 - switch(dregs->csr & CSR_LEFT) { 522 - case CSR_LEFT_3: 523 - *vaddr = (dregs->bpack_lo & 0xff00) >> 8; 524 - vaddr--; 525 - 526 - case CSR_LEFT_2: 527 - *vaddr = (dregs->bpack_hi & 0x00ff); 528 - vaddr--; 529 - 530 - case CSR_LEFT_1: 531 - *vaddr = (dregs->bpack_hi & 0xff00) >> 8; 532 - break; 533 - } 534 - 535 - 536 - } 537 - 538 - dvma_unmap(sun3_dma_orig_addr); 539 - sun3_dma_orig_addr = NULL; 540 - 541 - dregs->dma_addr_hi = 0; 542 - dregs->dma_addr_lo = 0; 543 - dregs->dma_count_hi = 0; 544 - dregs->dma_count_lo = 0; 545 - 546 - dregs->fifo_count = 0; 547 - dregs->fifo_count_hi = 0; 548 - 549 - dregs->csr &= ~CSR_SEND; 550 - 551 - // dregs->csr |= CSR_DMA_ENABLE; 552 - 553 - #if 0 554 - /* reset fifo */ 555 - dregs->csr &= ~CSR_FIFO; 556 - dregs->csr |= CSR_FIFO; 557 - #endif 558 - sun3_dma_setup_done = NULL; 559 - 560 - return ret; 561 - 562 - } 563 - 564 - #include "sun3_NCR5380.c" 565 - 566 - static struct scsi_host_template driver_template = { 567 - .name = SUN3_SCSI_NAME, 568 - .detect = sun3scsi_detect, 569 - .release = sun3scsi_release, 570 - .info = sun3scsi_info, 571 - .queuecommand = sun3scsi_queue_command, 572 - .eh_abort_handler = sun3scsi_abort, 573 - .eh_bus_reset_handler = sun3scsi_bus_reset, 574 - .can_queue = CAN_QUEUE, 575 - .this_id = 7, 576 - .sg_tablesize = SG_TABLESIZE, 577 - .cmd_per_lun = CMD_PER_LUN, 578 - .use_clustering = DISABLE_CLUSTERING 579 - }; 580 - 581 - 582 - #include "scsi_module.c" 583 - 584 - MODULE_LICENSE("GPL"); 3 + #include "sun3_scsi.c"