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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* mca_53c9x.c: Driver for the SCSI adapter found on NCR 35xx
  2.  *  (and maybe some other) Microchannel machines
  3.  *
  4.  * Code taken mostly from Cyberstorm SCSI drivers
  5.  *   Copyright (C) 1996 Jesper Skov (jskov@cygnus.co.uk)
  6.  *
  7.  * Hacked to work with the NCR MCA stuff by Tymm Twillman (tymm@computer.org)
  8.  *
  9.  * The CyberStorm SCSI driver (and this driver) is based on David S. Miller's
  10.  *   ESP driver  * for the Sparc computers. 
  11.  * 
  12.  * Special thanks to Ken Stewart at Symbios (LSI) for helping with info on
  13.  *  the 86C01.  I was on the brink of going ga-ga...
  14.  *
  15.  * Also thanks to Jesper Skov for helping me with info on how the Amiga
  16.  *  does things...
  17.  */
  18. /*
  19.  * This is currently only set up to use one 53c9x card at a time; it could be 
  20.  *  changed fairly easily to detect/use more than one, but I'm not too sure how
  21.  *  many cards that use the 53c9x on MCA systems there are (if, in fact, there
  22.  *  are cards that use them, other than the one built into some NCR systems)...
  23.  *  If anyone requests this, I'll throw it in, otherwise it's not worth the
  24.  *  effort.
  25.  */
  26. /*
  27.  * Info on the 86C01 MCA interface chip at the bottom, if you care enough to
  28.  *  look.
  29.  */
  30. #include <linux/kernel.h>
  31. #include <linux/delay.h>
  32. #include <linux/types.h>
  33. #include <linux/string.h>
  34. #include <linux/slab.h>
  35. #include <linux/blk.h>
  36. #include <linux/proc_fs.h>
  37. #include <linux/stat.h>
  38. #include "scsi.h"
  39. #include "hosts.h"
  40. #include "NCR53C9x.h"
  41. #include "mca_53c9x.h"
  42. #include <asm/dma.h>
  43. #include <linux/mca.h>
  44. #include <asm/irq.h>
  45. #include <asm/mca_dma.h>
  46. #include <asm/pgtable.h>
  47. static int  dma_bytes_sent(struct NCR_ESP *, int);
  48. static int  dma_can_transfer(struct NCR_ESP *, Scsi_Cmnd *);
  49. static void dma_dump_state(struct NCR_ESP *);
  50. static void dma_init_read(struct NCR_ESP *, __u32, int);
  51. static void dma_init_write(struct NCR_ESP *, __u32, int);
  52. static void dma_ints_off(struct NCR_ESP *);
  53. static void dma_ints_on(struct NCR_ESP *);
  54. static int  dma_irq_p(struct NCR_ESP *);
  55. static int  dma_ports_p(struct NCR_ESP *);
  56. static void dma_setup(struct NCR_ESP *, __u32, int, int);
  57. static void dma_led_on(struct NCR_ESP *);
  58. static void dma_led_off(struct NCR_ESP *);
  59. /* This is where all commands are put before they are trasfered to the 
  60.  *  53c9x via PIO.
  61.  */
  62. static volatile unsigned char cmd_buffer[16];
  63. /*
  64.  * We keep the structure that is used to access the registers on the 53c9x
  65.  *  here.
  66.  */
  67. static struct ESP_regs eregs;
  68. /***************************************************************** Detection */
  69. int mca_esp_detect(Scsi_Host_Template *tpnt)
  70. {
  71. struct NCR_ESP *esp;
  72. static int io_port_by_pos[] = MCA_53C9X_IO_PORTS;
  73. int mca_53c9x_ids[] = MCA_53C9X_IDS;
  74. int *id_to_check = mca_53c9x_ids;
  75. int slot;
  76. int pos[3];
  77. unsigned int tmp_io_addr;
  78. unsigned char tmp_byte;
  79. if (!MCA_bus)
  80. return 0;
  81. while (*id_to_check) { 
  82. if ((slot = mca_find_adapter(*id_to_check, 0)) !=
  83.   MCA_NOTFOUND) 
  84. {
  85. esp = esp_allocate(tpnt, (void *) NULL);
  86. pos[0] = mca_read_stored_pos(slot, 2);
  87. pos[1] = mca_read_stored_pos(slot, 3);
  88. pos[2] = mca_read_stored_pos(slot, 4);
  89. esp->eregs = &eregs;
  90. /*
  91.  * IO port base is given in the first (non-ID) pos
  92.  *  register, like so:
  93.  *
  94.  *  Bits 3  2  1       IO base
  95.  * ----------------------------
  96.  *       0  0  0       <disabled>
  97.  *       0  0  1       0x0240
  98.  *       0  1  0       0x0340
  99.  *       0  1  1       0x0400
  100.  *       1  0  0       0x0420
  101.  *       1  0  1       0x3240
  102.  *       1  1  0       0x8240
  103.  *       1  1  1       0xA240
  104.  */
  105. tmp_io_addr =
  106.   io_port_by_pos[(pos[0] & 0x0E) >> 1];
  107. esp->eregs->io_addr = tmp_io_addr + 0x10;
  108.        if (esp->eregs->io_addr == 0x0000) { 
  109.          printk("Adapter is disabled.n");
  110. break;
  111. }
  112. /*
  113.  * IRQ is specified in bits 4 and 5:
  114.  *
  115.  *  Bits  4  5        IRQ
  116.  * -----------------------
  117.  *        0  0         3
  118.  *        0  1         5
  119.  *        1  0         7
  120.  *        1  1         9
  121.  */
  122.        esp->irq = ((pos[0] & 0x30) >> 3) + 3;
  123. /*
  124.  * DMA channel is in the low 3 bits of the second
  125.  *  POS register
  126.  */
  127. esp->dma = pos[1] & 7;
  128. esp->slot = slot;
  129. if (request_irq(esp->irq, esp_intr, 0,
  130.  "NCR 53c9x SCSI", esp_intr))
  131. {
  132. printk("Unable to request IRQ %d.n", esp->irq);
  133. esp_deallocate(esp);
  134. scsi_unregister(esp->ehost);
  135. return 0;
  136. }
  137.   if (request_dma(esp->dma, "NCR 53c9x SCSI")) {
  138. printk("Unable to request DMA channel %d.n",
  139.  esp->dma);
  140. free_irq(esp->irq, esp_intr);
  141. esp_deallocate(esp);
  142. scsi_unregister(esp->ehost);
  143. return 0;
  144. }
  145. request_region(tmp_io_addr, 32, "NCR 53c9x SCSI");
  146. /*
  147.  * 86C01 handles DMA, IO mode, from address
  148.  *  (base + 0x0a)
  149.  */
  150. mca_disable_dma(esp->dma);
  151. mca_set_dma_io(esp->dma, tmp_io_addr + 0x0a);
  152. mca_enable_dma(esp->dma);
  153.  
  154. /* Tell the 86C01 to give us interrupts */
  155. tmp_byte = inb(tmp_io_addr + 0x02) | 0x40;
  156. outb(tmp_byte, tmp_io_addr + 0x02); 
  157. /*
  158.  * Scsi ID -- general purpose register, hi
  159.  *  2 bits; add 4 to this number to get the
  160.  *  ID
  161.  */
  162. esp->scsi_id = ((pos[2] & 0xC0) >> 6) + 4;
  163. /* Do command transfer with programmed I/O */
  164. esp->do_pio_cmds = 1;
  165. /* Required functions */
  166. esp->dma_bytes_sent = &dma_bytes_sent;
  167. esp->dma_can_transfer = &dma_can_transfer;
  168. esp->dma_dump_state = &dma_dump_state;
  169. esp->dma_init_read = &dma_init_read;
  170. esp->dma_init_write = &dma_init_write;
  171. esp->dma_ints_off = &dma_ints_off;
  172. esp->dma_ints_on = &dma_ints_on;
  173. esp->dma_irq_p = &dma_irq_p;
  174. esp->dma_ports_p = &dma_ports_p;
  175. esp->dma_setup = &dma_setup;
  176. /* Optional functions */
  177. esp->dma_barrier = 0;
  178. esp->dma_drain = 0;
  179. esp->dma_invalidate = 0;
  180. esp->dma_irq_entry = 0;
  181. esp->dma_irq_exit = 0;
  182. esp->dma_led_on = dma_led_on;
  183. esp->dma_led_off = dma_led_off;
  184. esp->dma_poll = 0;
  185. esp->dma_reset = 0;
  186. /* Set the command buffer */
  187. esp->esp_command = (volatile unsigned char*)
  188.   cmd_buffer;
  189.   esp->esp_command_dvma = virt_to_bus(cmd_buffer);
  190. /* SCSI chip speed */
  191. esp->cfreq = 25000000;
  192. /* Differential SCSI? I think not. */
  193. esp->diff = 0;
  194. esp_initialize(esp);
  195.        printk(" Adapter found in slot %2d: io port 0x%x "
  196.   "irq %d dma channel %dn", slot + 1, tmp_io_addr,
  197.    esp->irq, esp->dma);
  198. mca_set_adapter_name(slot, "NCR 53C9X SCSI Adapter");
  199. mca_mark_as_used(slot);
  200. break;
  201. }
  202.     
  203. id_to_check++;
  204. }
  205. return esps_in_use;
  206. }
  207. /******************************************************************* Release */
  208. int mca_esp_release(struct Scsi_Host *host)
  209. {
  210. struct NCR_ESP *esp = (struct NCR_ESP *)host->hostdata;
  211. unsigned char tmp_byte;
  212. esp_deallocate(esp);
  213. /*
  214.  * Tell the 86C01 to stop sending interrupts
  215.  */
  216. tmp_byte = inb(esp->eregs->io_addr - 0x0E);
  217. tmp_byte &= ~0x40;
  218. outb(tmp_byte, esp->eregs->io_addr - 0x0E);
  219. free_irq(esp->irq, esp_intr);
  220. free_dma(esp->dma);
  221. mca_mark_as_unused(esp->slot);
  222. return 0;
  223. }
  224. /************************************************************* DMA Functions */
  225. static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
  226. {
  227. /* Ask the 53c9x.  It knows. */
  228. return fifo_count;
  229. }
  230. static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp)
  231. {
  232. /* 
  233.  * The MCA dma channels can only do up to 128K bytes at a time.
  234.          *  (16 bit mode)
  235.  */
  236. unsigned long sz = sp->SCp.this_residual;
  237. if(sz > 0x20000)
  238. sz = 0x20000;
  239. return sz;
  240. }
  241. static void dma_dump_state(struct NCR_ESP *esp)
  242. {
  243. /*
  244.  * Doesn't quite match up to the other drivers, but we do what we
  245.  *  can.
  246.  */
  247. ESPLOG(("esp%d: dma channel <%d>n", esp->esp_id, esp->dma));
  248. ESPLOG(("bytes left to dma: %dn", mca_get_dma_residue(esp->dma)));
  249. }
  250. static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
  251. {
  252. unsigned long flags;
  253. save_flags(flags);
  254. cli();
  255. mca_disable_dma(esp->dma);
  256. mca_set_dma_mode(esp->dma, MCA_DMA_MODE_XFER | MCA_DMA_MODE_16 |
  257.   MCA_DMA_MODE_IO);
  258. mca_set_dma_addr(esp->dma, addr);
  259. mca_set_dma_count(esp->dma, length / 2); /* !!! */
  260. mca_enable_dma(esp->dma);
  261. restore_flags(flags);
  262. }
  263. static void dma_init_write(struct NCR_ESP *esp, __u32 addr, int length)
  264. {
  265. unsigned long flags;
  266. save_flags(flags);
  267. cli();
  268. mca_disable_dma(esp->dma);
  269. mca_set_dma_mode(esp->dma, MCA_DMA_MODE_XFER | MCA_DMA_MODE_WRITE |
  270.   MCA_DMA_MODE_16 | MCA_DMA_MODE_IO);
  271. mca_set_dma_addr(esp->dma, addr);
  272. mca_set_dma_count(esp->dma, length / 2); /* !!! */
  273. mca_enable_dma(esp->dma);
  274. restore_flags(flags);
  275. }
  276. static void dma_ints_off(struct NCR_ESP *esp)
  277. {
  278. /*
  279.  * Tell the 'C01 to shut up.  All interrupts are routed through it.
  280.  */
  281. outb(inb(esp->eregs->io_addr - 0x0E) & ~0x40,
  282.  esp->eregs->io_addr - 0x0E);
  283. }
  284. static void dma_ints_on(struct NCR_ESP *esp)
  285. {
  286. /*
  287.  * Ok.  You can speak again.
  288.  */
  289. outb(inb(esp->eregs->io_addr - 0x0E) | 0x40,
  290.  esp->eregs->io_addr - 0x0E);
  291. }
  292. static int dma_irq_p(struct NCR_ESP *esp)
  293. {
  294. /*
  295.  * DaveM says that this should return a "yes" if there is an interrupt
  296.  *  or a DMA error occurred.  I copied the Amiga driver's semantics,
  297.  *  though, because it seems to work and we can't really tell if
  298.  *  a DMA error happened.  This gives the "yes" if the scsi chip
  299.  *  is sending an interrupt and no DMA activity is taking place
  300.  */
  301. return (!(inb(esp->eregs->io_addr - 0x04) & 1) &&
  302.  !(inb(esp->eregs->io_addr - 0x04) & 2) ); 
  303. }
  304. static int dma_ports_p(struct NCR_ESP *esp)
  305. {
  306. /*
  307.  * Check to see if interrupts are enabled on the 'C01 (in case abort
  308.  *  is entered multiple times, so we only do the abort once)
  309.  */
  310. return (inb(esp->eregs->io_addr - 0x0E) & 0x40) ? 1:0;
  311. }
  312. static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
  313. {
  314. if(write){
  315. dma_init_write(esp, addr, count);
  316. } else {
  317. dma_init_read(esp, addr, count);
  318. }
  319. }
  320. /*
  321.  * These will not play nicely with other disk controllers that try to use the
  322.  *  disk active LED... but what can you do?  Don't answer that.
  323.  *
  324.  * Stolen shamelessly from ibmmca.c -- IBM Microchannel SCSI adapter driver
  325.  *
  326.  */
  327. static void dma_led_on(struct NCR_ESP *esp)
  328. {
  329. outb(inb(PS2_SYS_CTR) | 0xc0, PS2_SYS_CTR);
  330. }
  331. static void dma_led_off(struct NCR_ESP *esp)
  332. {
  333. outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR);
  334. }
  335. static Scsi_Host_Template driver_template = MCA_53C9X;
  336. #include "scsi_module.c"
  337. /*
  338.  * OK, here's the goods I promised.  The NCR 86C01 is an MCA interface chip 
  339.  *  that handles enabling/diabling IRQ, dma interfacing, IO port selection
  340.  *  and other fun stuff.  It takes up 16 addresses, and the chip it is
  341.  *  connnected to gets the following 16.  Registers are as follows:
  342.  *
  343.  * Offsets 0-1 : Card ID
  344.  *
  345.  * Offset    2 : Mode enable register --
  346.  *                Bit    7 : Data Word width (1 = 16, 0 = 8)
  347.  *   Bit    6 : IRQ enable (1 = enabled)
  348.  *                Bits 5,4 : IRQ select
  349.  *                              0  0 : IRQ 3
  350.  *         0  1 : IRQ 5
  351.  *  1  0 : IRQ 7
  352.  *   1  1 : IRQ 9
  353.  *                Bits 3-1 : Base Address
  354.  *                           0  0  0 : <disabled>
  355.  *       0  0  1 : 0x0240
  356.  *          0  1  0 : 0x0340
  357.  *           0  1  1 : 0x0400
  358.  *       1  0  0 : 0x0420
  359.  *       1  0  1 : 0x3240
  360.  *       1  1  0 : 0x8240
  361.  *       1  1  1 : 0xA240
  362.  *   Bit    0 : Card enable (1 = enabled)
  363.  *
  364.  * Offset    3 : DMA control register --
  365.  *                Bit    7 : DMA enable (1 = enabled)
  366.  *                Bits 6,5 : Preemt Count Select (transfers to complete after
  367.  *                            'C01 has been preempted on MCA bus)
  368.  *                              0  0 : 0
  369.  *                              0  1 : 1
  370.  *                              1  0 : 3
  371.  *                              1  1 : 7
  372.  *  (all these wacky numbers; I'm sure there's a reason somewhere)
  373.  *                Bit    4 : Fairness enable (1 = fair bus priority)
  374.  *                Bits 3-0 : Arbitration level (0-15 consecutive)
  375.  * 
  376.  * Offset    4 : General purpose register
  377.  *                Bits 7-3 : User definable (here, 7,6 are SCSI ID)
  378.  *                Bits 2-0 : reserved
  379.  *
  380.  * Offset   10 : DMA decode register (used for IO based DMA; also can do
  381.  *                PIO through this port)
  382.  *
  383.  * Offset   12 : Status
  384.  *                Bits 7-2 : reserved
  385.  *                Bit    1 : DMA pending (1 = pending)
  386.  *                Bit    0 : IRQ pending (0 = pending)
  387.  *
  388.  * Exciting, huh?  
  389.  *
  390.  */