aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mvme147.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mvme147.c')
-rw-r--r--drivers/scsi/mvme147.c169
1 files changed, 86 insertions, 83 deletions
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index d722235111a8..716d1785cda7 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -13,112 +13,116 @@
13#include "wd33c93.h" 13#include "wd33c93.h"
14#include "mvme147.h" 14#include "mvme147.h"
15 15
16#include<linux/stat.h> 16#include <linux/stat.h>
17 17
18#define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
19 18
20static struct Scsi_Host *mvme147_host = NULL; 19static struct Scsi_Host *mvme147_host = NULL;
21 20
22static irqreturn_t mvme147_intr (int irq, void *dummy) 21static irqreturn_t mvme147_intr(int irq, void *dummy)
23{ 22{
24 if (irq == MVME147_IRQ_SCSI_PORT) 23 if (irq == MVME147_IRQ_SCSI_PORT)
25 wd33c93_intr (mvme147_host); 24 wd33c93_intr(mvme147_host);
26 else 25 else
27 m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ 26 m147_pcc->dma_intr = 0x89; /* Ack and enable ints */
28 return IRQ_HANDLED; 27 return IRQ_HANDLED;
29} 28}
30 29
31static int dma_setup(struct scsi_cmnd *cmd, int dir_in) 30static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
32{ 31{
33 unsigned char flags = 0x01; 32 struct WD33C93_hostdata *hdata = shost_priv(mvme147_host);
34 unsigned long addr = virt_to_bus(cmd->SCp.ptr); 33 unsigned char flags = 0x01;
35 34 unsigned long addr = virt_to_bus(cmd->SCp.ptr);
36 /* setup dma direction */ 35
37 if (!dir_in) 36 /* setup dma direction */
38 flags |= 0x04; 37 if (!dir_in)
39 38 flags |= 0x04;
40 /* remember direction */ 39
41 HDATA(mvme147_host)->dma_dir = dir_in; 40 /* remember direction */
42 41 hdata->dma_dir = dir_in;
43 if (dir_in) 42
44 /* invalidate any cache */ 43 if (dir_in) {
45 cache_clear (addr, cmd->SCp.this_residual); 44 /* invalidate any cache */
46 else 45 cache_clear(addr, cmd->SCp.this_residual);
47 /* push any dirty cache */ 46 } else {
48 cache_push (addr, cmd->SCp.this_residual); 47 /* push any dirty cache */
49 48 cache_push(addr, cmd->SCp.this_residual);
50 /* start DMA */ 49 }
51 m147_pcc->dma_bcr = cmd->SCp.this_residual | (1<<24); 50
52 m147_pcc->dma_dadr = addr; 51 /* start DMA */
53 m147_pcc->dma_cntrl = flags; 52 m147_pcc->dma_bcr = cmd->SCp.this_residual | (1 << 24);
54 53 m147_pcc->dma_dadr = addr;
55 /* return success */ 54 m147_pcc->dma_cntrl = flags;
56 return 0; 55
56 /* return success */
57 return 0;
57} 58}
58 59
59static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, 60static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
60 int status) 61 int status)
61{ 62{
62 m147_pcc->dma_cntrl = 0; 63 m147_pcc->dma_cntrl = 0;
63} 64}
64 65
65int mvme147_detect(struct scsi_host_template *tpnt) 66int mvme147_detect(struct scsi_host_template *tpnt)
66{ 67{
67 static unsigned char called = 0; 68 static unsigned char called = 0;
68 wd33c93_regs regs; 69 wd33c93_regs regs;
69 70 struct WD33C93_hostdata *hdata;
70 if (!MACH_IS_MVME147 || called) 71
71 return 0; 72 if (!MACH_IS_MVME147 || called)
72 called++; 73 return 0;
73 74 called++;
74 tpnt->proc_name = "MVME147"; 75
75 tpnt->proc_info = &wd33c93_proc_info; 76 tpnt->proc_name = "MVME147";
76 77 tpnt->proc_info = &wd33c93_proc_info;
77 mvme147_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata)); 78
78 if (!mvme147_host) 79 mvme147_host = scsi_register(tpnt, sizeof(struct WD33C93_hostdata));
79 goto err_out; 80 if (!mvme147_host)
80 81 goto err_out;
81 mvme147_host->base = 0xfffe4000; 82
82 mvme147_host->irq = MVME147_IRQ_SCSI_PORT; 83 mvme147_host->base = 0xfffe4000;
83 regs.SASR = (volatile unsigned char *)0xfffe4000; 84 mvme147_host->irq = MVME147_IRQ_SCSI_PORT;
84 regs.SCMD = (volatile unsigned char *)0xfffe4001; 85 regs.SASR = (volatile unsigned char *)0xfffe4000;
85 HDATA(mvme147_host)->no_sync = 0xff; 86 regs.SCMD = (volatile unsigned char *)0xfffe4001;
86 HDATA(mvme147_host)->fast = 0; 87 hdata = shost_priv(mvme147_host);
87 HDATA(mvme147_host)->dma_mode = CTRL_DMA; 88 hdata->no_sync = 0xff;
88 wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10); 89 hdata->fast = 0;
89 90 hdata->dma_mode = CTRL_DMA;
90 if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr)) 91 wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
91 goto err_unregister; 92
92 if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0, "MVME147 SCSI DMA", mvme147_intr)) 93 if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0,
93 goto err_free_irq; 94 "MVME147 SCSI PORT", mvme147_intr))
95 goto err_unregister;
96 if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0,
97 "MVME147 SCSI DMA", mvme147_intr))
98 goto err_free_irq;
94#if 0 /* Disabled; causes problems booting */ 99#if 0 /* Disabled; causes problems booting */
95 m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */ 100 m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */
96 udelay(100); 101 udelay(100);
97 m147_pcc->scsi_interrupt = 0x00; /* Negate SCSI bus reset */ 102 m147_pcc->scsi_interrupt = 0x00; /* Negate SCSI bus reset */
98 udelay(2000); 103 udelay(2000);
99 m147_pcc->scsi_interrupt = 0x40; /* Clear bus reset interrupt */ 104 m147_pcc->scsi_interrupt = 0x40; /* Clear bus reset interrupt */
100#endif 105#endif
101 m147_pcc->scsi_interrupt = 0x09; /* Enable interrupt */ 106 m147_pcc->scsi_interrupt = 0x09; /* Enable interrupt */
102 107
103 m147_pcc->dma_cntrl = 0x00; /* ensure DMA is stopped */ 108 m147_pcc->dma_cntrl = 0x00; /* ensure DMA is stopped */
104 m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ 109 m147_pcc->dma_intr = 0x89; /* Ack and enable ints */
105 110
106 return 1; 111 return 1;
107 112
108 err_free_irq: 113err_free_irq:
109 free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); 114 free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr);
110 err_unregister: 115err_unregister:
111 wd33c93_release(); 116 scsi_unregister(mvme147_host);
112 scsi_unregister(mvme147_host); 117err_out:
113 err_out: 118 return 0;
114 return 0;
115} 119}
116 120
117static int mvme147_bus_reset(struct scsi_cmnd *cmd) 121static int mvme147_bus_reset(struct scsi_cmnd *cmd)
118{ 122{
119 /* FIXME perform bus-specific reset */ 123 /* FIXME perform bus-specific reset */
120 124
121 /* FIXME 2: kill this function, and let midlayer fallback to 125 /* FIXME 2: kill this function, and let midlayer fallback to
122 the same result, calling wd33c93_host_reset() */ 126 the same result, calling wd33c93_host_reset() */
123 127
124 spin_lock_irq(cmd->device->host->host_lock); 128 spin_lock_irq(cmd->device->host->host_lock);
@@ -154,10 +158,9 @@ static struct scsi_host_template driver_template = {
154int mvme147_release(struct Scsi_Host *instance) 158int mvme147_release(struct Scsi_Host *instance)
155{ 159{
156#ifdef MODULE 160#ifdef MODULE
157 /* XXX Make sure DMA is stopped! */ 161 /* XXX Make sure DMA is stopped! */
158 wd33c93_release(); 162 free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr);
159 free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); 163 free_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr);
160 free_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr);
161#endif 164#endif
162 return 1; 165 return 1;
163} 166}