1 /* 2 * 68k mac 53c9[46] scsi driver 3 * 4 * copyright (c) 1998, David Weis weisd3458@uni.edu 5 * 6 * debugging on Quadra 800 and 660AV Michael Schmitz, Dave Kilzer 7/98 7 * 8 * based loosely on cyber_esp.c 9 */ 10 11 /* these are unused for now */ 12 #define myreadl(addr) (*(volatile unsigned int *) (addr)) 13 #define mywritel(b, addr) ((*(volatile unsigned int *) (addr)) = (b)) 14 15 16 #include <linux/kernel.h> 17 #include <linux/delay.h> 18 #include <linux/types.h> 19 #include <linux/ctype.h> 20 #include <linux/string.h> 21 #include <linux/slab.h> 22 #include <linux/blkdev.h> 23 #include <linux/proc_fs.h> 24 #include <linux/stat.h> 25 #include <linux/init.h> 26 #include <linux/interrupt.h> 27 28 #include "scsi.h" 29 #include <scsi/scsi_host.h> 30 #include "NCR53C9x.h" 31 32 #include <asm/io.h> 33 34 #include <asm/setup.h> 35 #include <asm/irq.h> 36 #include <asm/macints.h> 37 #include <asm/machw.h> 38 #include <asm/mac_via.h> 39 40 #include <asm/pgtable.h> 41 42 #include <asm/macintosh.h> 43 44 /* #define DEBUG_MAC_ESP */ 45 46 #define mac_turnon_irq(x) mac_enable_irq(x) 47 #define mac_turnoff_irq(x) mac_disable_irq(x) 48 49 extern void esp_handle(struct NCR_ESP *esp); 50 extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs); 51 52 static int dma_bytes_sent(struct NCR_ESP * esp, int fifo_count); 53 static int dma_can_transfer(struct NCR_ESP * esp, Scsi_Cmnd *sp); 54 static void dma_dump_state(struct NCR_ESP * esp); 55 static void dma_init_read(struct NCR_ESP * esp, char * vaddress, int length); 56 static void dma_init_write(struct NCR_ESP * esp, char * vaddress, int length); 57 static void dma_ints_off(struct NCR_ESP * esp); 58 static void dma_ints_on(struct NCR_ESP * esp); 59 static int dma_irq_p(struct NCR_ESP * esp); 60 static int dma_irq_p_quick(struct NCR_ESP * esp); 61 static void dma_led_off(struct NCR_ESP * esp); 62 static void dma_led_on(struct NCR_ESP *esp); 63 static int dma_ports_p(struct NCR_ESP *esp); 64 static void dma_setup(struct NCR_ESP * esp, __u32 addr, int count, int write); 65 static void dma_setup_quick(struct NCR_ESP * esp, __u32 addr, int count, int write); 66 67 static int esp_dafb_dma_irq_p(struct NCR_ESP * espdev); 68 static int esp_iosb_dma_irq_p(struct NCR_ESP * espdev); 69 70 static volatile unsigned char cmd_buffer[16]; 71 /* This is where all commands are put 72 * before they are transferred to the ESP chip 73 * via PIO. 74 */ 75 76 static int esp_initialized = 0; 77 78 static int setup_num_esps = -1; 79 static int setup_disconnect = -1; 80 static int setup_nosync = -1; 81 static int setup_can_queue = -1; 82 static int setup_cmd_per_lun = -1; 83 static int setup_sg_tablesize = -1; 84 #ifdef SUPPORT_TAGS 85 static int setup_use_tagged_queuing = -1; 86 #endif 87 static int setup_hostid = -1; 88 89 /* 90 * Experimental ESP inthandler; check macints.c to make sure dev_id is 91 * set up properly! 92 */ 93 94 void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs) 95 { 96 struct NCR_ESP *esp = (struct NCR_ESP *) dev_id; 97 int irq_p = 0; 98 99 /* Handle the one ESP interrupt showing at this IRQ level. */ 100 if(((esp)->irq & 0xff) == irq) { 101 /* 102 * Debug .. 103 */ 104 irq_p = esp->dma_irq_p(esp); 105 printk("mac_esp: irq_p %x current %p disconnected %p\n", 106 irq_p, esp->current_SC, esp->disconnected_SC); 107 108 /* 109 * Mac: if we're here, it's an ESP interrupt for sure! 110 */ 111 if((esp->current_SC || esp->disconnected_SC)) { 112 esp->dma_ints_off(esp); 113 114 ESPIRQ(("I%d(", esp->esp_id)); 115 esp_handle(esp); 116 ESPIRQ((")")); 117 118 esp->dma_ints_on(esp); 119 } 120 } 121 } 122 123 /* 124 * Debug hooks; use for playing with the interrupt flag testing and interrupt 125 * acknowledge on the various machines 126 */ 127 128 void scsi_esp_polled(int irq, void *dev_id, struct pt_regs *pregs) 129 { 130 if (esp_initialized == 0) 131 return; 132 133 mac_esp_intr(irq, dev_id, pregs); 134 } 135 136 void fake_intr(int irq, void *dev_id, struct pt_regs *pregs) 137 { 138 #ifdef DEBUG_MAC_ESP 139 printk("mac_esp: got irq\n"); 140 #endif 141 142 mac_esp_intr(irq, dev_id, pregs); 143 } 144 145 irqreturn_t fake_drq(int irq, void *dev_id, struct pt_regs *pregs) 146 { 147 printk("mac_esp: got drq\n"); 148 return IRQ_HANDLED; 149 } 150 151 #define DRIVER_SETUP 152 153 /* 154 * Function : mac_esp_setup(char *str) 155 * 156 * Purpose : booter command line initialization of the overrides array, 157 * 158 * Inputs : str - parameters, separated by commas. 159 * 160 * Currently unused in the new driver; need to add settable parameters to the 161 * detect function. 162 * 163 */ 164 165 static int __init mac_esp_setup(char *str) { 166 #ifdef DRIVER_SETUP 167 /* Format of mac53c9x parameter is: 168 * mac53c9x=<num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags> 169 * Negative values mean don't change. 170 */ 171 172 char *this_opt; 173 long opt; 174 175 this_opt = strsep (&str, ","); 176 if(this_opt) { 177 opt = simple_strtol( this_opt, NULL, 0 ); 178 179 if (opt >= 0 && opt <= 2) 180 setup_num_esps = opt; 181 else if (opt > 2) 182 printk( "mac_esp_setup: invalid number of hosts %ld !\n", opt ); 183 184 this_opt = strsep (&str, ","); 185 } 186 if(this_opt) { 187 opt = simple_strtol( this_opt, NULL, 0 ); 188 189 if (opt > 0) 190 setup_disconnect = opt; 191 192 this_opt = strsep (&str, ","); 193 } 194 if(this_opt) { 195 opt = simple_strtol( this_opt, NULL, 0 ); 196 197 if (opt >= 0) 198 setup_nosync = opt; 199 200 this_opt = strsep (&str, ","); 201 } 202 if(this_opt) { 203 opt = simple_strtol( this_opt, NULL, 0 ); 204 205 if (opt > 0) 206 setup_can_queue = opt; 207 208 this_opt = strsep (&str, ","); 209 } 210 if(this_opt) { 211 opt = simple_strtol( this_opt, NULL, 0 ); 212 213 if (opt > 0) 214 setup_cmd_per_lun = opt; 215 216 this_opt = strsep (&str, ","); 217 } 218 if(this_opt) { 219 opt = simple_strtol( this_opt, NULL, 0 ); 220 221 if (opt >= 0) { 222 setup_sg_tablesize = opt; 223 /* Must be <= SG_ALL (255) */ 224 if (setup_sg_tablesize > SG_ALL) 225 setup_sg_tablesize = SG_ALL; 226 } 227 228 this_opt = strsep (&str, ","); 229 } 230 if(this_opt) { 231 opt = simple_strtol( this_opt, NULL, 0 ); 232 233 /* Must be between 0 and 7 */ 234 if (opt >= 0 && opt <= 7) 235 setup_hostid = opt; 236 else if (opt > 7) 237 printk( "mac_esp_setup: invalid host ID %ld !\n", opt); 238 239 this_opt = strsep (&str, ","); 240 } 241 #ifdef SUPPORT_TAGS 242 if(this_opt) { 243 opt = simple_strtol( this_opt, NULL, 0 ); 244 if (opt >= 0) 245 setup_use_tagged_queuing = !!opt; 246 } 247 #endif 248 #endif 249 return 1; 250 } 251 252 __setup("mac53c9x=", mac_esp_setup); 253 254 255 /* 256 * ESP address 'detection' 257 */ 258 259 unsigned long get_base(int chip_num) 260 { 261 /* 262 * using the chip_num and mac model, figure out where the 263 * chips are mapped 264 */ 265 266 unsigned long io_base = 0x50f00000; 267 unsigned int second_offset = 0x402; 268 unsigned long scsi_loc = 0; 269 270 switch (macintosh_config->scsi_type) { 271 272 /* 950, 900, 700 */ 273 case MAC_SCSI_QUADRA2: 274 scsi_loc = io_base + 0xf000 + ((chip_num == 0) ? 0 : second_offset); 275 break; 276 277 /* av's */ 278 case MAC_SCSI_QUADRA3: 279 scsi_loc = io_base + 0x18000 + ((chip_num == 0) ? 0 : second_offset); 280 break; 281 282 /* most quadra/centris models are like this */ 283 case MAC_SCSI_QUADRA: 284 scsi_loc = io_base + 0x10000; 285 break; 286 287 default: 288 printk("mac_esp: get_base: hit default!\n"); 289 scsi_loc = io_base + 0x10000; 290 break; 291 292 } /* switch */ 293 294 printk("mac_esp: io base at 0x%lx\n", scsi_loc); 295 296 return scsi_loc; 297 } 298 299 /* 300 * Model dependent ESP setup 301 */ 302 303 int mac_esp_detect(Scsi_Host_Template * tpnt) 304 { 305 int quick = 0; 306 int chipnum, chipspresent = 0; 307 #if 0 308 unsigned long timeout; 309 #endif 310 311 if (esp_initialized > 0) 312 return -ENODEV; 313 314 /* what do we have in this machine... */ 315 if (MACHW_PRESENT(MAC_SCSI_96)) { 316 chipspresent ++; 317 } 318 319 if (MACHW_PRESENT(MAC_SCSI_96_2)) { 320 chipspresent ++; 321 } 322 323 /* number of ESPs present ? */ 324 if (setup_num_esps >= 0) { 325 if (chipspresent >= setup_num_esps) 326 chipspresent = setup_num_esps; 327 else 328 printk("mac_esp_detect: num_hosts detected %d setup %d \n", 329 chipspresent, setup_num_esps); 330 } 331 332 /* TODO: add disconnect / nosync flags */ 333 334 /* setup variables */ 335 tpnt->can_queue = 336 (setup_can_queue > 0) ? setup_can_queue : 7; 337 tpnt->cmd_per_lun = 338 (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : 1; 339 tpnt->sg_tablesize = 340 (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_ALL; 341 342 if (setup_hostid >= 0) 343 tpnt->this_id = setup_hostid; 344 else { 345 /* use 7 as default */ 346 tpnt->this_id = 7; 347 } 348 349 #ifdef SUPPORT_TAGS 350 if (setup_use_tagged_queuing < 0) 351 setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING; 352 #endif 353 354 for (chipnum = 0; chipnum < chipspresent; chipnum ++) { 355 struct NCR_ESP * esp; 356 357 esp = esp_allocate(tpnt, (void *) NULL); 358 esp->eregs = (struct ESP_regs *) get_base(chipnum); 359 360 esp->dma_irq_p = &esp_dafb_dma_irq_p; 361 if (chipnum == 0) { 362 363 if (macintosh_config->scsi_type == MAC_SCSI_QUADRA) { 364 /* most machines except those below :-) */ 365 quick = 1; 366 esp->dma_irq_p = &esp_iosb_dma_irq_p; 367 } else if (macintosh_config->scsi_type == MAC_SCSI_QUADRA3) { 368 /* mostly av's */ 369 quick = 0; 370 } else { 371 /* q950, 900, 700 */ 372 quick = 1; 373 out_be32(0xf9800024, 0x1d1); 374 esp->dregs = (void *) 0xf9800024; 375 } 376 377 } else { /* chipnum */ 378 379 quick = 1; 380 out_be32(0xf9800028, 0x1d1); 381 esp->dregs = (void *) 0xf9800028; 382 383 } /* chipnum == 0 */ 384 385 /* use pio for command bytes; pio for message/data: TBI */ 386 esp->do_pio_cmds = 1; 387 388 /* Set the command buffer */ 389 esp->esp_command = (volatile unsigned char*) cmd_buffer; 390 esp->esp_command_dvma = (__u32) cmd_buffer; 391 392 /* various functions */ 393 esp->dma_bytes_sent = &dma_bytes_sent; 394 esp->dma_can_transfer = &dma_can_transfer; 395 esp->dma_dump_state = &dma_dump_state; 396 esp->dma_init_read = NULL; 397 esp->dma_init_write = NULL; 398 esp->dma_ints_off = &dma_ints_off; 399 esp->dma_ints_on = &dma_ints_on; 400 401 esp->dma_ports_p = &dma_ports_p; 402 403 404 /* Optional functions */ 405 esp->dma_barrier = NULL; 406 esp->dma_drain = NULL; 407 esp->dma_invalidate = NULL; 408 esp->dma_irq_entry = NULL; 409 esp->dma_irq_exit = NULL; 410 esp->dma_led_on = NULL; 411 esp->dma_led_off = NULL; 412 esp->dma_poll = NULL; 413 esp->dma_reset = NULL; 414 415 /* SCSI chip speed */ 416 /* below esp->cfreq = 40000000; */ 417 418 419 if (quick) { 420 /* 'quick' means there's handshake glue logic like in the 5380 case */ 421 esp->dma_setup = &dma_setup_quick; 422 } else { 423 esp->dma_setup = &dma_setup; 424 } 425 426 if (chipnum == 0) { 427 428 esp->irq = IRQ_MAC_SCSI; 429 430 request_irq(IRQ_MAC_SCSI, esp_intr, 0, "Mac ESP SCSI", esp->ehost); 431 #if 0 /* conflicts with IOP ADB */ 432 request_irq(IRQ_MAC_SCSIDRQ, fake_drq, 0, "Mac ESP DRQ", esp->ehost); 433 #endif 434 435 if (macintosh_config->scsi_type == MAC_SCSI_QUADRA) { 436 esp->cfreq = 16500000; 437 } else { 438 esp->cfreq = 25000000; 439 } 440 441 442 } else { /* chipnum == 1 */ 443 444 esp->irq = IRQ_MAC_SCSIDRQ; 445 #if 0 /* conflicts with IOP ADB */ 446 request_irq(IRQ_MAC_SCSIDRQ, esp_intr, 0, "Mac ESP SCSI 2", esp->ehost); 447 #endif 448 449 esp->cfreq = 25000000; 450 451 } 452 453 if (quick) { 454 printk("esp: using quick version\n"); 455 } 456 457 printk("esp: addr at 0x%p\n", esp->eregs); 458 459 esp->scsi_id = 7; 460 esp->diff = 0; 461 462 esp_initialize(esp); 463 464 } /* for chipnum */ 465 466 if (chipspresent) 467 printk("\nmac_esp: %d esp controllers found\n", chipspresent); 468 469 esp_initialized = chipspresent; 470 471 return chipspresent; 472 } 473 474 static int mac_esp_release(struct Scsi_Host *shost) 475 { 476 if (shost->irq) 477 free_irq(shost->irq, NULL); 478 if (shost->io_port && shost->n_io_port) 479 release_region(shost->io_port, shost->n_io_port); 480 scsi_unregister(shost); 481 return 0; 482 } 483 484 /* 485 * I've been wondering what this is supposed to do, for some time. Talking 486 * to Allen Briggs: These machines have an extra register someplace where the 487 * DRQ pin of the ESP can be monitored. That isn't useful for determining 488 * anything else (such as reselect interrupt or other magic) though. 489 * Maybe make the semantics should be changed like 490 * if (esp->current_SC) 491 * ... check DRQ flag ... 492 * else 493 * ... disconnected, check pending VIA interrupt ... 494 * 495 * There's a problem with using the dabf flag or mac_irq_pending() here: both 496 * seem to return 1 even though no interrupt is currently pending, resulting 497 * in esp_exec_cmd() holding off the next command, and possibly infinite loops 498 * in esp_intr(). 499 * Short term fix: just use esp_status & ESP_STAT_INTR here, as long as we 500 * use simple PIO. The DRQ status will be important when implementing pseudo 501 * DMA mode (set up ESP transfer count, return, do a batch of bytes in PIO or 502 * 'hardware handshake' mode upon DRQ). 503 * If you plan on changing this (i.e. to save the esp_status register access in 504 * favor of a VIA register access or a shadow register for the IFR), make sure 505 * to try a debug version of this first to monitor what registers would be a good 506 * indicator of the ESP interrupt. 507 */ 508 509 static int esp_dafb_dma_irq_p(struct NCR_ESP * esp) 510 { 511 unsigned int ret; 512 int sreg = esp_read(esp->eregs->esp_status); 513 514 #ifdef DEBUG_MAC_ESP 515 printk("mac_esp: esp_dafb_dma_irq_p dafb %d irq %d\n", 516 readl(esp->dregs), mac_irq_pending(IRQ_MAC_SCSI)); 517 #endif 518 519 sreg &= ESP_STAT_INTR; 520 521 /* 522 * maybe working; this is essentially what's used for iosb_dma_irq_p 523 */ 524 if (sreg) 525 return 1; 526 else 527 return 0; 528 529 /* 530 * didn't work ... 531 */ 532 #if 0 533 if (esp->current_SC) 534 ret = readl(esp->dregs) & 0x200; 535 else if (esp->disconnected_SC) 536 ret = 1; /* sreg ?? */ 537 else 538 ret = mac_irq_pending(IRQ_MAC_SCSI); 539 540 return(ret); 541 #endif 542 543 } 544 545 /* 546 * See above: testing mac_irq_pending always returned 8 (SCSI IRQ) regardless 547 * of the actual ESP status. 548 */ 549 550 static int esp_iosb_dma_irq_p(struct NCR_ESP * esp) 551 { 552 int ret = mac_irq_pending(IRQ_MAC_SCSI) || mac_irq_pending(IRQ_MAC_SCSIDRQ); 553 int sreg = esp_read(esp->eregs->esp_status); 554 555 #ifdef DEBUG_MAC_ESP 556 printk("mac_esp: dma_irq_p drq %d irq %d sreg %x curr %p disc %p\n", 557 mac_irq_pending(IRQ_MAC_SCSIDRQ), mac_irq_pending(IRQ_MAC_SCSI), 558 sreg, esp->current_SC, esp->disconnected_SC); 559 #endif 560 561 sreg &= ESP_STAT_INTR; 562 563 if (sreg) 564 return (sreg); 565 else 566 return 0; 567 } 568 569 /* 570 * This seems to be OK for PIO at least ... usually 0 after PIO. 571 */ 572 573 static int dma_bytes_sent(struct NCR_ESP * esp, int fifo_count) 574 { 575 576 #ifdef DEBUG_MAC_ESP 577 printk("mac_esp: dma bytes sent = %x\n", fifo_count); 578 #endif 579 580 return fifo_count; 581 } 582 583 /* 584 * dma_can_transfer is used to switch between DMA and PIO, if DMA (pseudo) 585 * is ever implemented. Returning 0 here will use PIO. 586 */ 587 588 static int dma_can_transfer(struct NCR_ESP * esp, Scsi_Cmnd * sp) 589 { 590 unsigned long sz = sp->SCp.this_residual; 591 #if 0 /* no DMA yet; make conditional */ 592 if (sz > 0x10000000) { 593 sz = 0x10000000; 594 } 595 printk("mac_esp: dma can transfer = 0lx%x\n", sz); 596 #else 597 598 #ifdef DEBUG_MAC_ESP 599 printk("mac_esp: pio to transfer = %ld\n", sz); 600 #endif 601 602 sz = 0; 603 #endif 604 return sz; 605 } 606 607 /* 608 * Not yet ... 609 */ 610 611 static void dma_dump_state(struct NCR_ESP * esp) 612 { 613 #ifdef DEBUG_MAC_ESP 614 printk("mac_esp: dma_dump_state: called\n"); 615 #endif 616 #if 0 617 ESPLOG(("esp%d: dma -- cond_reg<%02x>\n", 618 esp->esp_id, ((struct mac_dma_registers *) 619 (esp->dregs))->cond_reg)); 620 #endif 621 } 622 623 /* 624 * DMA setup: should be used to set up the ESP transfer count for pseudo 625 * DMA transfers; need a DRQ transfer function to do the actual transfer 626 */ 627 628 static void dma_init_read(struct NCR_ESP * esp, char * vaddress, int length) 629 { 630 printk("mac_esp: dma_init_read\n"); 631 } 632 633 634 static void dma_init_write(struct NCR_ESP * esp, char * vaddress, int length) 635 { 636 printk("mac_esp: dma_init_write\n"); 637 } 638 639 640 static void dma_ints_off(struct NCR_ESP * esp) 641 { 642 mac_turnoff_irq(esp->irq); 643 } 644 645 646 static void dma_ints_on(struct NCR_ESP * esp) 647 { 648 mac_turnon_irq(esp->irq); 649 } 650 651 /* 652 * generic dma_irq_p(), unused 653 */ 654 655 static int dma_irq_p(struct NCR_ESP * esp) 656 { 657 int i = esp_read(esp->eregs->esp_status); 658 659 #ifdef DEBUG_MAC_ESP 660 printk("mac_esp: dma_irq_p status %d\n", i); 661 #endif 662 663 return (i & ESP_STAT_INTR); 664 } 665 666 static int dma_irq_p_quick(struct NCR_ESP * esp) 667 { 668 /* 669 * Copied from iosb_dma_irq_p() 670 */ 671 int ret = mac_irq_pending(IRQ_MAC_SCSI) || mac_irq_pending(IRQ_MAC_SCSIDRQ); 672 int sreg = esp_read(esp->eregs->esp_status); 673 674 #ifdef DEBUG_MAC_ESP 675 printk("mac_esp: dma_irq_p drq %d irq %d sreg %x curr %p disc %p\n", 676 mac_irq_pending(IRQ_MAC_SCSIDRQ), mac_irq_pending(IRQ_MAC_SCSI), 677 sreg, esp->current_SC, esp->disconnected_SC); 678 #endif 679 680 sreg &= ESP_STAT_INTR; 681 682 if (sreg) 683 return (sreg); 684 else 685 return 0; 686 687 } 688 689 static void dma_led_off(struct NCR_ESP * esp) 690 { 691 #ifdef DEBUG_MAC_ESP 692 printk("mac_esp: dma_led_off: called\n"); 693 #endif 694 } 695 696 697 static void dma_led_on(struct NCR_ESP * esp) 698 { 699 #ifdef DEBUG_MAC_ESP 700 printk("mac_esp: dma_led_on: called\n"); 701 #endif 702 } 703 704 705 static int dma_ports_p(struct NCR_ESP * esp) 706 { 707 return 0; 708 } 709 710 711 static void dma_setup(struct NCR_ESP * esp, __u32 addr, int count, int write) 712 { 713 714 #ifdef DEBUG_MAC_ESP 715 printk("mac_esp: dma_setup\n"); 716 #endif 717 718 if (write) { 719 dma_init_read(esp, (char *) addr, count); 720 } else { 721 dma_init_write(esp, (char *) addr, count); 722 } 723 } 724 725 726 static void dma_setup_quick(struct NCR_ESP * esp, __u32 addr, int count, int write) 727 { 728 #ifdef DEBUG_MAC_ESP 729 printk("mac_esp: dma_setup_quick\n"); 730 #endif 731 } 732 733 static Scsi_Host_Template driver_template = { 734 .proc_name = "mac_esp", 735 .name = "Mac 53C9x SCSI", 736 .detect = mac_esp_detect, 737 .slave_alloc = esp_slave_alloc, 738 .slave_destroy = esp_slave_destroy, 739 .release = mac_esp_release, 740 .info = esp_info, 741 .queuecommand = esp_queue, 742 .eh_abort_handler = esp_abort, 743 .eh_bus_reset_handler = esp_reset, 744 .can_queue = 7, 745 .this_id = 7, 746 .sg_tablesize = SG_ALL, 747 .cmd_per_lun = 1, 748 .use_clustering = DISABLE_CLUSTERING 749 }; 750 751 752 #include "scsi_module.c" 753 754 MODULE_LICENSE("GPL"); 755