This source file includes following definitions.
- gvp11_intr
- gvp11_setup
- dma_setup
- dma_stop
- gvp11_detect
1 #include <linux/types.h>
2 #include <linux/mm.h>
3 #include <linux/blk.h>
4 #include <linux/version.h>
5
6 #include <asm/page.h>
7 #include <asm/pgtable.h>
8 #include <asm/bootinfo.h>
9 #include <asm/amigaints.h>
10 #include <asm/amigahw.h>
11 #include <asm/zorro.h>
12 #include <asm/irq.h>
13
14 #include "scsi.h"
15 #include "hosts.h"
16 #include "wd33c93.h"
17 #include "gvp11.h"
18
19 #include<linux/stat.h>
20
21 struct proc_dir_entry proc_scsi_gvp11 = {
22 PROC_SCSI_GVP11, 5, "GVP11",
23 S_IFDIR | S_IRUGO | S_IXUGO, 2
24 };
25
26 #define DMA(ptr) ((gvp11_scsiregs *)((ptr)->base))
27 #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
28
29 static struct Scsi_Host *first_instance = NULL;
30 static Scsi_Host_Template *gvp11_template;
31
32 static void gvp11_intr (int irq, struct pt_regs *fp, void *dummy)
33 {
34 unsigned int status;
35 struct Scsi_Host *instance;
36
37 for (instance = first_instance; instance &&
38 instance->hostt == gvp11_template; instance = instance->next)
39 {
40 status = DMA(instance)->CNTR;
41 if (!(status & GVP11_DMAC_INT_PENDING))
42 continue;
43
44
45 custom.intena = IF_PORTS;
46 wd33c93_intr (instance);
47
48 custom.intena = IF_SETCLR | IF_PORTS;
49 }
50 }
51
52
53
54
55
56
57
58
59
60 static int gvp11_xfer_mask = GVP11_XFER_MASK;
61
62 void gvp11_setup (char *str, int *ints)
63 {
64 gvp11_xfer_mask = ints[1];
65 }
66
67 static int dma_setup (Scsi_Cmnd *cmd, int dir_in)
68 {
69 unsigned short cntr = GVP11_DMAC_INT_ENABLE;
70 unsigned long addr = VTOP(cmd->SCp.ptr);
71
72
73 if (addr & gvp11_xfer_mask ||
74 (!dir_in && mm_end_of_chunk (addr, cmd->SCp.this_residual)))
75 {
76 HDATA(cmd->host)->dma_bounce_len = (cmd->SCp.this_residual + 511)
77 & ~0x1ff;
78 HDATA(cmd->host)->dma_bounce_buffer =
79 scsi_malloc (HDATA(cmd->host)->dma_bounce_len);
80
81
82 if (!HDATA(cmd->host)->dma_bounce_buffer) {
83 HDATA(cmd->host)->dma_bounce_len = 0;
84 return 1;
85 }
86
87
88 addr = VTOP(HDATA(cmd->host)->dma_bounce_buffer);
89
90 if (addr & gvp11_xfer_mask) {
91 scsi_free (HDATA(cmd->host)->dma_bounce_buffer,
92 HDATA(cmd->host)->dma_bounce_len);
93 HDATA(cmd->host)->dma_bounce_buffer = NULL;
94 HDATA(cmd->host)->dma_bounce_len = 0;
95 return 1;
96 }
97
98 if (!dir_in) {
99
100 if (cmd->use_sg)
101 #if 0
102 panic ("scsi%ddma: incomplete s/g support",
103 cmd->host->host_no);
104 #else
105 memcpy (HDATA(cmd->host)->dma_bounce_buffer,
106 cmd->SCp.ptr, cmd->SCp.this_residual);
107 #endif
108 else
109 memcpy (HDATA(cmd->host)->dma_bounce_buffer,
110 cmd->request_buffer, cmd->request_bufflen);
111 }
112 }
113
114
115 if (!dir_in)
116 cntr |= GVP11_DMAC_DIR_WRITE;
117
118 HDATA(cmd->host)->dma_dir = dir_in;
119 DMA(cmd->host)->CNTR = cntr;
120
121
122 DMA(cmd->host)->ACR = addr;
123
124 if (dir_in)
125
126 cache_clear (addr, cmd->SCp.this_residual);
127 else
128
129 cache_push (addr, cmd->SCp.this_residual);
130
131
132 DMA(cmd->host)->ST_DMA = 1;
133
134
135 return 0;
136 }
137
138 static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
139 int status)
140 {
141
142 DMA(instance)->SP_DMA = 1;
143
144 DMA(instance)->CNTR = GVP11_DMAC_INT_ENABLE;
145
146
147 if (status && HDATA(instance)->dma_bounce_buffer) {
148 if (SCpnt && SCpnt->use_sg) {
149 #if 0
150 panic ("scsi%d: incomplete s/g support",
151 instance->host_no);
152 #else
153 if( HDATA(instance)->dma_dir )
154 memcpy (SCpnt->SCp.ptr,
155 HDATA(instance)->dma_bounce_buffer,
156 SCpnt->SCp.this_residual);
157 scsi_free (HDATA(instance)->dma_bounce_buffer,
158 HDATA(instance)->dma_bounce_len);
159 HDATA(instance)->dma_bounce_buffer = NULL;
160 HDATA(instance)->dma_bounce_len = 0;
161
162 #endif
163 } else {
164 if (HDATA(instance)->dma_dir && SCpnt)
165 memcpy (SCpnt->request_buffer,
166 HDATA(instance)->dma_bounce_buffer,
167 SCpnt->request_bufflen);
168
169 scsi_free (HDATA(instance)->dma_bounce_buffer,
170 HDATA(instance)->dma_bounce_len);
171 HDATA(instance)->dma_bounce_buffer = NULL;
172 HDATA(instance)->dma_bounce_len = 0;
173 }
174 }
175 }
176
177 int gvp11_detect(Scsi_Host_Template *tpnt)
178 {
179 static unsigned char called = 0;
180 struct Scsi_Host *instance;
181 int i, manuf, product, num_gvp11 = 0;
182 caddr_t address;
183 enum GVP_ident epc;
184
185 if (!MACH_IS_AMIGA || called)
186 return 0;
187 called = 1;
188
189 tpnt->proc_dir = &proc_scsi_gvp11;
190
191 for (i = 0; i < boot_info.bi_amiga.num_autocon; i++)
192 {
193 manuf = boot_info.bi_amiga.autocon[i].cd_Rom.er_Manufacturer;
194 product = boot_info.bi_amiga.autocon[i].cd_Rom.er_Product;
195 #if 0
196
197 if (manuf == MANUF_GVP &&
198 ((product == PROD_GVPIISCSI) || (product == PROD_GVPIISCSI_2))) {
199 #else
200 if (manuf == MANUF_GVP && product == PROD_GVPIISCSI) {
201 #endif
202
203 address = boot_info.bi_amiga.autocon[i].cd_BoardAddr;
204 epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000);
205
206 epc = epc & GVP_EPCMASK;
207
208
209
210
211
212
213 if (!((epc == GVP_A1291_SCSI) ||
214 (epc == GVP_GFORCE_040_SCSI) ||
215 (epc == GVP_GFORCE_030_SCSI) ||
216 (epc == GVP_A530_SCSI) ||
217 (epc == GVP_COMBO_R4_SCSI) ||
218 (epc == GVP_COMBO_R3_SCSI) ||
219 (epc == GVP_SERIESII)))
220 continue;
221
222 instance = scsi_register (tpnt,
223 sizeof (struct WD33C93_hostdata));
224 instance->base = (unsigned char *)ZTWO_VADDR(address);
225 DMA(instance)->secret2 = 1;
226 DMA(instance)->secret1 = 0;
227 DMA(instance)->secret3 = 15;
228 while (DMA(instance)->CNTR & GVP11_DMAC_BUSY) ;
229 DMA(instance)->CNTR = 0;
230 wd33c93_init(instance, (wd33c93_regs *)&(DMA(instance)->SASR),
231 dma_setup, dma_stop, WD33C93_FS_8_10);
232 if (num_gvp11++ == 0) {
233 first_instance = instance;
234 gvp11_template = instance->hostt;
235 add_isr(IRQ_AMIGA_PORTS, gvp11_intr, 0, NULL, "GVP11 SCSI");
236 }
237 DMA(instance)->CNTR = GVP11_DMAC_INT_ENABLE;
238
239 #if 0
240 boot_info.bi_amiga.autocon_configured |= 1<<i;
241 #endif
242
243 }
244 }
245
246 return num_gvp11;
247 }