ecoscsi.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:7k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #define AUTOSENSE
  2. /* #define PSEUDO_DMA */
  3. /*
  4.  * EcoSCSI Generic NCR5380 driver
  5.  *
  6.  * Copyright 1995, Russell King
  7.  *
  8.  * ALPHA RELEASE 1.
  9.  *
  10.  * For more information, please consult
  11.  *
  12.  * NCR 5380 Family
  13.  * SCSI Protocol Controller
  14.  * Databook
  15.  *
  16.  * NCR Microelectronics
  17.  * 1635 Aeroplaza Drive
  18.  * Colorado Springs, CO 80916
  19.  * 1+ (719) 578-3400
  20.  * 1+ (800) 334-5454
  21.  */
  22. /*
  23.  * Options :
  24.  *
  25.  * PARITY - enable parity checking.  Not supported.
  26.  *
  27.  * SCSI2 - enable support for SCSI-II tagged queueing.  Untested.
  28.  *
  29.  * USLEEP - enable support for devices that don't disconnect.  Untested.
  30.  */
  31. /*
  32.  * $Log: ecoscsi.c,v $
  33.  * Revision 1.2  1998/03/08 05:49:47  davem
  34.  * Merge to 2.1.89
  35.  *
  36.  * Revision 1.1  1998/02/23 02:45:24  davem
  37.  * Merge to 2.1.88
  38.  *
  39.  */
  40. #include <linux/module.h>
  41. #include <linux/signal.h>
  42. #include <linux/sched.h>
  43. #include <linux/ioport.h>
  44. #include <linux/init.h>
  45. #include <linux/blk.h>
  46. #include <asm/io.h>
  47. #include <asm/system.h>
  48. #include "../../scsi/scsi.h"
  49. #include "../../scsi/hosts.h"
  50. #include "../../scsi/NCR5380.h"
  51. #include "../../scsi/constants.h"
  52. #define ECOSCSI_PUBLIC_RELEASE 1
  53. static char ecoscsi_read(struct Scsi_Host *instance, int reg)
  54. {
  55.   int iobase = instance->io_port;
  56.   outb(reg | 8, iobase);
  57.   return inb(iobase + 1);
  58. }
  59. static void ecoscsi_write(struct Scsi_Host *instance, int reg, int value)
  60. {
  61.   int iobase = instance->io_port;
  62.   outb(reg | 8, iobase);
  63.   outb(value, iobase + 1);
  64. }
  65. /*
  66.  * Function : ecoscsi_setup(char *str, int *ints)
  67.  *
  68.  * Purpose : LILO command line initialization of the overrides array,
  69.  *
  70.  * Inputs : str - unused, ints - array of integer parameters with ints[0]
  71.  * equal to the number of ints.
  72.  *
  73.  */
  74. void ecoscsi_setup(char *str, int *ints) {
  75. }
  76. /*
  77.  * Function : int ecoscsi_detect(Scsi_Host_Template * tpnt)
  78.  *
  79.  * Purpose : initializes ecoscsi NCR5380 driver based on the
  80.  * command line / compile time port and irq definitions.
  81.  *
  82.  * Inputs : tpnt - template for this SCSI adapter.
  83.  *
  84.  * Returns : 1 if a host adapter was found, 0 if not.
  85.  *
  86.  */
  87. int ecoscsi_detect(Scsi_Host_Template * tpnt)
  88. {
  89.     struct Scsi_Host *instance;
  90.     tpnt->proc_name = "ecoscsi";
  91.     instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
  92.     instance->io_port = 0x80ce8000;
  93.     instance->n_io_port = 144;
  94.     instance->irq = IRQ_NONE;
  95.     if (check_region (instance->io_port, instance->n_io_port)) {
  96. scsi_unregister (instance);
  97. return 0;
  98.     }
  99.     ecoscsi_write (instance, MODE_REG, 0x20); /* Is it really SCSI? */
  100.     if (ecoscsi_read (instance, MODE_REG) != 0x20) { /* Write to a reg.    */
  101.         scsi_unregister(instance);
  102.         return 0; /* and try to read    */
  103.     }
  104.     ecoscsi_write( instance, MODE_REG, 0x00 ); /* it back.       */
  105.     if (ecoscsi_read (instance, MODE_REG) != 0x00) {
  106.         scsi_unregister(instance);
  107.         return 0;
  108.     }
  109.     NCR5380_init(instance, 0);
  110.     if (request_region (instance->io_port, instance->n_io_port, "ecoscsi") == NULL) {
  111. scsi_unregister(instance);
  112. return 0;
  113.     }
  114.     if (instance->irq != IRQ_NONE)
  115. if (request_irq(instance->irq, do_ecoscsi_intr, SA_INTERRUPT, "ecoscsi", NULL)) {
  116.     printk("scsi%d: IRQ%d not free, interrupts disabledn",
  117.     instance->host_no, instance->irq);
  118.     instance->irq = IRQ_NONE;
  119. }
  120.     if (instance->irq != IRQ_NONE) {
  121.    printk("scsi%d: eek! Interrupts enabled, but I don't thinkn", instance->host_no);
  122. printk("scsi%d: that the board had an interrupt!n", instance->host_no);
  123.     }
  124.     printk("scsi%d: at port %X irq", instance->host_no, instance->io_port);
  125.     if (instance->irq == IRQ_NONE)
  126. printk ("s disabled");
  127.     else
  128.         printk (" %d", instance->irq);
  129.     printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
  130.         CAN_QUEUE, CMD_PER_LUN, ECOSCSI_PUBLIC_RELEASE);
  131.     printk("nscsi%d:", instance->host_no);
  132.     NCR5380_print_options(instance);
  133.     printk("n");
  134.     return 1;
  135. }
  136. int ecoscsi_release (struct Scsi_Host *shpnt)
  137. {
  138. if (shpnt->irq != IRQ_NONE)
  139. free_irq (shpnt->irq, NULL);
  140. if (shpnt->io_port)
  141. release_region (shpnt->io_port, shpnt->n_io_port);
  142. return 0;
  143. }
  144. const char * ecoscsi_info (struct Scsi_Host *spnt) {
  145.     return "";
  146. }
  147. #if 0
  148. #define STAT(p) inw(p + 144)
  149. static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
  150.               int len)
  151. {
  152.   int iobase = instance->io_port;
  153. printk("writing %p len %dn",addr, len);
  154.   if(!len) return -1;
  155.   while(1)
  156.   {
  157.     int status;
  158.     while(((status = STAT(iobase)) & 0x100)==0);
  159.   }
  160. }
  161. static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr,
  162.               int len)
  163. {
  164.   int iobase = instance->io_port;
  165.   int iobase2= instance->io_port + 0x100;
  166.   unsigned char *start = addr;
  167.   int s;
  168. printk("reading %p len %dn",addr, len);
  169.   outb(inb(iobase + 128), iobase + 135);
  170.   while(len > 0)
  171.   {
  172.     int status,b,i, timeout;
  173.     timeout = 0x07FFFFFF;
  174.     while(((status = STAT(iobase)) & 0x100)==0)
  175.     {
  176.       timeout--;
  177.       if(status & 0x200 || !timeout)
  178.       {
  179.         printk("status = %pn",status);
  180.         outb(0, iobase + 135);
  181.         return 1;
  182.       }
  183.     }
  184.     if(len >= 128)
  185.     {
  186.       for(i=0; i<64; i++)
  187.       {
  188.         b = inw(iobase + 136);
  189.         *addr++ = b;
  190.         *addr++ = b>>8;
  191.       }
  192.       len -= 128;
  193.     }
  194.     else
  195.     {
  196.       b = inw(iobase + 136);
  197.       *addr ++ = b;
  198.       len -= 1;
  199.       if(len)
  200.         *addr ++ = b>>8;
  201.       len -= 1;
  202.     }
  203.   }
  204.   outb(0, iobase + 135);
  205.   printk("first bytes = %02X %02X %02X %20X %02X %02X %02Xn",*start, start[1], start[2], start[3], start[4], start[5], start[6]);
  206.   return 1;
  207. }
  208. #endif
  209. #undef STAT
  210. #define NCR5380_implementation_fields 
  211.     int port, ctrl
  212. #define NCR5380_local_declare() 
  213.         struct Scsi_Host *_instance
  214. #define NCR5380_setup(instance) 
  215.         _instance = instance
  216. #define NCR5380_read(reg) ecoscsi_read(_instance, reg)
  217. #define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value)
  218. #define do_NCR5380_intr do_ecoscsi_intr
  219. #define NCR5380_queue_command ecoscsi_queue_command
  220. #define NCR5380_abort ecoscsi_abort
  221. #define NCR5380_reset ecoscsi_reset
  222. #define NCR5380_proc_info ecoscsi_proc_info
  223. int NCR5380_proc_info(char *buffer, char **start, off_t offset,
  224.       int length, int hostno, int inout);
  225. #define BOARD_NORMAL 0
  226. #define BOARD_NCR53C400 1
  227. #include "../../scsi/NCR5380.c"
  228. static Scsi_Host_Template ecoscsi_template =  {
  229. module: THIS_MODULE,
  230. name: "Serial Port EcoSCSI NCR5380",
  231. detect: ecoscsi_detect,
  232. release: ecoscsi_release,
  233. info: ecoscsi_info,
  234. queuecommand: ecoscsi_queue_command,
  235. abort: ecoscsi_abort,
  236. reset: ecoscsi_reset,
  237. can_queue: 16,
  238. this_id: 7,
  239. sg_tablesize: SG_ALL,
  240. cmd_per_lun: 2,
  241. use_clustering: DISABLE_CLUSTERING
  242. };
  243. static int __init ecoscsi_init(void)
  244. {
  245. scsi_register_module(MODULE_SCSI_HA, &ecoscsi_template);
  246. if (ecoscsi_template.present)
  247. return 0;
  248. scsi_unregister_module(MODULE_SCSI_HA, &ecoscsi_template);
  249. return -ENODEV;
  250. }
  251. static void __exit ecoscsi_exit(void)
  252. {
  253. scsi_unregister_module(MODULE_SCSI_HA, &ecoscsi_template);
  254. }
  255. module_init(ecoscsi_init);
  256. module_exit(ecoscsi_exit);
  257. MODULE_AUTHOR("Russell King");
  258. MODULE_DESCRIPTION("Econet-SCSI driver for Acorn machines");
  259. MODULE_LICENSE("GPL");
  260. EXPORT_NO_SYMBOLS;