Blame view

drivers/scsi/gvp11.c 10.5 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  #include <linux/types.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
  #include <linux/init.h>
  #include <linux/interrupt.h>
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
4
5
6
7
  #include <linux/mm.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/zorro.h>
acf3368ff   Paul Gortmaker   scsi: Fix up file...
8
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
13
  #include <asm/page.h>
  #include <asm/pgtable.h>
  #include <asm/amigaints.h>
  #include <asm/amigahw.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
  
  #include "scsi.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
  #include "wd33c93.h"
  #include "gvp11.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18

11ca46eaf   Geert Uytterhoeven   m68k/scsi: gvp11 ...
19
  #define CHECK_WD33C93
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
20
21
22
23
  struct gvp11_hostdata {
  	struct WD33C93_hostdata wh;
  	struct gvp11_scsiregs *regs;
  };
6869b15ef   Geert Uytterhoeven   m68k/scsi: gvp11 ...
24
  static irqreturn_t gvp11_intr(int irq, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
  {
6869b15ef   Geert Uytterhoeven   m68k/scsi: gvp11 ...
26
  	struct Scsi_Host *instance = data;
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
27
28
  	struct gvp11_hostdata *hdata = shost_priv(instance);
  	unsigned int status = hdata->regs->CNTR;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
29
  	unsigned long flags;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
30

bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
31
32
33
34
35
36
37
  	if (!(status & GVP11_DMAC_INT_PENDING))
  		return IRQ_NONE;
  
  	spin_lock_irqsave(instance->host_lock, flags);
  	wd33c93_intr(instance);
  	spin_unlock_irqrestore(instance->host_lock, flags);
  	return IRQ_HANDLED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
40
  }
  
  static int gvp11_xfer_mask = 0;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
41
  void gvp11_setup(char *str, int *ints)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
  {
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
43
  	gvp11_xfer_mask = ints[1];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
  }
65396410a   Henrik Kretzschmar   [SCSI] wd33c93: S...
45
  static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  {
52c3d8a65   Geert Uytterhoeven   [SCSI] gvp11: Use...
47
  	struct Scsi_Host *instance = cmd->device->host;
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
48
49
50
  	struct gvp11_hostdata *hdata = shost_priv(instance);
  	struct WD33C93_hostdata *wh = &hdata->wh;
  	struct gvp11_scsiregs *regs = hdata->regs;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
51
52
53
54
  	unsigned short cntr = GVP11_DMAC_INT_ENABLE;
  	unsigned long addr = virt_to_bus(cmd->SCp.ptr);
  	int bank_mask;
  	static int scsi_alloc_out_of_range = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55

bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
56
  	/* use bounce buffer if the physical address is bad */
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
57
58
  	if (addr & wh->dma_xfer_mask) {
  		wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
59
60
  
  		if (!scsi_alloc_out_of_range) {
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
61
62
63
  			wh->dma_bounce_buffer =
  				kmalloc(wh->dma_bounce_len, GFP_KERNEL);
  			wh->dma_buffer_pool = BUF_SCSI_ALLOCED;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
64
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65

bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
66
  		if (scsi_alloc_out_of_range ||
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
67
68
69
  		    !wh->dma_bounce_buffer) {
  			wh->dma_bounce_buffer =
  				amiga_chip_alloc(wh->dma_bounce_len,
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
70
  						 "GVP II SCSI Bounce Buffer");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71

cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
72
73
  			if (!wh->dma_bounce_buffer) {
  				wh->dma_bounce_len = 0;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
74
75
  				return 1;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76

cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
77
  			wh->dma_buffer_pool = BUF_CHIP_ALLOCED;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
78
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79

bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
80
  		/* check if the address of the bounce buffer is OK */
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
81
  		addr = virt_to_bus(wh->dma_bounce_buffer);
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
82

cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
83
  		if (addr & wh->dma_xfer_mask) {
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
84
  			/* fall back to Chip RAM if address out of range */
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
85
86
  			if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED) {
  				kfree(wh->dma_bounce_buffer);
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
87
88
  				scsi_alloc_out_of_range = 1;
  			} else {
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
89
  				amiga_chip_free(wh->dma_bounce_buffer);
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
90
  			}
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
91
92
  			wh->dma_bounce_buffer =
  				amiga_chip_alloc(wh->dma_bounce_len,
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
93
  						 "GVP II SCSI Bounce Buffer");
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
94
95
  			if (!wh->dma_bounce_buffer) {
  				wh->dma_bounce_len = 0;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
96
97
  				return 1;
  			}
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
98
99
  			addr = virt_to_bus(wh->dma_bounce_buffer);
  			wh->dma_buffer_pool = BUF_CHIP_ALLOCED;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
100
101
102
103
  		}
  
  		if (!dir_in) {
  			/* copy to bounce buffer for a write */
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
104
  			memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr,
52c3d8a65   Geert Uytterhoeven   [SCSI] gvp11: Use...
105
  			       cmd->SCp.this_residual);
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
106
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108

bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
109
110
111
  	/* setup dma direction */
  	if (!dir_in)
  		cntr |= GVP11_DMAC_DIR_WRITE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112

cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
113
  	wh->dma_dir = dir_in;
6869b15ef   Geert Uytterhoeven   m68k/scsi: gvp11 ...
114
  	regs->CNTR = cntr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115

bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
116
  	/* setup DMA *physical* address */
6869b15ef   Geert Uytterhoeven   m68k/scsi: gvp11 ...
117
  	regs->ACR = addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118

bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
119
120
121
122
123
124
125
  	if (dir_in) {
  		/* invalidate any cache */
  		cache_clear(addr, cmd->SCp.this_residual);
  	} else {
  		/* push any dirty cache */
  		cache_push(addr, cmd->SCp.this_residual);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126

cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
127
  	bank_mask = (~wh->dma_xfer_mask >> 18) & 0x01c0;
52c3d8a65   Geert Uytterhoeven   [SCSI] gvp11: Use...
128
  	if (bank_mask)
6869b15ef   Geert Uytterhoeven   m68k/scsi: gvp11 ...
129
  		regs->BANK = bank_mask & (addr >> 18);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130

bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
131
  	/* start DMA */
6869b15ef   Geert Uytterhoeven   m68k/scsi: gvp11 ...
132
  	regs->ST_DMA = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133

bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
134
135
  	/* return success */
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
  }
65396410a   Henrik Kretzschmar   [SCSI] wd33c93: S...
137
138
  static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
  		     int status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
  {
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
140
141
142
  	struct gvp11_hostdata *hdata = shost_priv(instance);
  	struct WD33C93_hostdata *wh = &hdata->wh;
  	struct gvp11_scsiregs *regs = hdata->regs;
52c3d8a65   Geert Uytterhoeven   [SCSI] gvp11: Use...
143

bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
144
  	/* stop DMA */
6869b15ef   Geert Uytterhoeven   m68k/scsi: gvp11 ...
145
  	regs->SP_DMA = 1;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
146
  	/* remove write bit from CONTROL bits */
6869b15ef   Geert Uytterhoeven   m68k/scsi: gvp11 ...
147
  	regs->CNTR = GVP11_DMAC_INT_ENABLE;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
148
149
  
  	/* copy from a bounce buffer, if necessary */
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
150
151
152
  	if (status && wh->dma_bounce_buffer) {
  		if (wh->dma_dir && SCpnt)
  			memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer,
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
153
  			       SCpnt->SCp.this_residual);
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
154
155
  		if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED)
  			kfree(wh->dma_bounce_buffer);
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
156
  		else
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
157
  			amiga_chip_free(wh->dma_bounce_buffer);
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
158

cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
159
160
  		wh->dma_bounce_buffer = NULL;
  		wh->dma_bounce_len = 0;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
161
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
  }
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  static int gvp11_bus_reset(struct scsi_cmnd *cmd)
  {
  	struct Scsi_Host *instance = cmd->device->host;
  
  	/* FIXME perform bus-specific reset */
  
  	/* FIXME 2: shouldn't we no-op this function (return
  	   FAILED), and fall back to host reset function,
  	   wd33c93_host_reset ? */
  
  	spin_lock_irq(instance->host_lock);
  	wd33c93_host_reset(cmd);
  	spin_unlock_irq(instance->host_lock);
  
  	return SUCCESS;
  }
  
  static struct scsi_host_template gvp11_scsi_template = {
  	.module			= THIS_MODULE,
  	.name			= "GVP Series II SCSI",
408bb25ba   Al Viro   switch wd33c93 to...
183
184
  	.show_info		= wd33c93_show_info,
  	.write_info		= wd33c93_write_info,
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
185
186
187
188
189
190
191
192
193
194
195
  	.proc_name		= "GVP11",
  	.queuecommand		= wd33c93_queuecommand,
  	.eh_abort_handler	= wd33c93_abort,
  	.eh_bus_reset_handler	= gvp11_bus_reset,
  	.eh_host_reset_handler	= wd33c93_host_reset,
  	.can_queue		= CAN_QUEUE,
  	.this_id		= 7,
  	.sg_tablesize		= SG_ALL,
  	.cmd_per_lun		= CMD_PER_LUN,
  	.use_clustering		= DISABLE_CLUSTERING
  };
6f0397905   Greg Kroah-Hartman   Drivers: scsi: re...
196
  static int check_wd33c93(struct gvp11_scsiregs *regs)
11ca46eaf   Geert Uytterhoeven   m68k/scsi: gvp11 ...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
  {
  #ifdef CHECK_WD33C93
  	volatile unsigned char *sasr_3393, *scmd_3393;
  	unsigned char save_sasr;
  	unsigned char q, qq;
  
  	/*
  	 * These darn GVP boards are a problem - it can be tough to tell
  	 * whether or not they include a SCSI controller. This is the
  	 * ultimate Yet-Another-GVP-Detection-Hack in that it actually
  	 * probes for a WD33c93 chip: If we find one, it's extremely
  	 * likely that this card supports SCSI, regardless of Product_
  	 * Code, Board_Size, etc.
  	 */
  
  	/* Get pointers to the presumed register locations and save contents */
  
  	sasr_3393 = &regs->SASR;
  	scmd_3393 = &regs->SCMD;
  	save_sasr = *sasr_3393;
  
  	/* First test the AuxStatus Reg */
  
  	q = *sasr_3393;	/* read it */
  	if (q & 0x08)	/* bit 3 should always be clear */
  		return -ENODEV;
  	*sasr_3393 = WD_AUXILIARY_STATUS;	/* setup indirect address */
  	if (*sasr_3393 == WD_AUXILIARY_STATUS) {	/* shouldn't retain the write */
  		*sasr_3393 = save_sasr;	/* Oops - restore this byte */
  		return -ENODEV;
  	}
  	if (*sasr_3393 != q) {	/* should still read the same */
  		*sasr_3393 = save_sasr;	/* Oops - restore this byte */
  		return -ENODEV;
  	}
  	if (*scmd_3393 != q)	/* and so should the image at 0x1f */
  		return -ENODEV;
  
  	/*
  	 * Ok, we probably have a wd33c93, but let's check a few other places
  	 * for good measure. Make sure that this works for both 'A and 'B
  	 * chip versions.
  	 */
  
  	*sasr_3393 = WD_SCSI_STATUS;
  	q = *scmd_3393;
  	*sasr_3393 = WD_SCSI_STATUS;
  	*scmd_3393 = ~q;
  	*sasr_3393 = WD_SCSI_STATUS;
  	qq = *scmd_3393;
  	*sasr_3393 = WD_SCSI_STATUS;
  	*scmd_3393 = q;
  	if (qq != q)	/* should be read only */
  		return -ENODEV;
  	*sasr_3393 = 0x1e;	/* this register is unimplemented */
  	q = *scmd_3393;
  	*sasr_3393 = 0x1e;
  	*scmd_3393 = ~q;
  	*sasr_3393 = 0x1e;
  	qq = *scmd_3393;
  	*sasr_3393 = 0x1e;
  	*scmd_3393 = q;
  	if (qq != q || qq != 0xff)	/* should be read only, all 1's */
  		return -ENODEV;
  	*sasr_3393 = WD_TIMEOUT_PERIOD;
  	q = *scmd_3393;
  	*sasr_3393 = WD_TIMEOUT_PERIOD;
  	*scmd_3393 = ~q;
  	*sasr_3393 = WD_TIMEOUT_PERIOD;
  	qq = *scmd_3393;
  	*sasr_3393 = WD_TIMEOUT_PERIOD;
  	*scmd_3393 = q;
  	if (qq != (~q & 0xff))	/* should be read/write */
  		return -ENODEV;
  #endif /* CHECK_WD33C93 */
  
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275

6f0397905   Greg Kroah-Hartman   Drivers: scsi: re...
276
  static int gvp11_probe(struct zorro_dev *z, const struct zorro_device_id *ent)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
  {
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
278
279
  	struct Scsi_Host *instance;
  	unsigned long address;
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
280
  	int error;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
281
  	unsigned int epc;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
282
  	unsigned int default_dma_xfer_mask;
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
283
  	struct gvp11_hostdata *hdata;
349d65fdc   Geert Uytterhoeven   m68k/scsi: gvp11 ...
284
  	struct gvp11_scsiregs *regs;
6869b15ef   Geert Uytterhoeven   m68k/scsi: gvp11 ...
285
  	wd33c93_regs wdregs;
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
286
287
288
289
290
291
  
  	default_dma_xfer_mask = ent->driver_data;
  
  	/*
  	 * Rumors state that some GVP ram boards use the same product
  	 * code as the SCSI controllers. Therefore if the board-size
25985edce   Lucas De Marchi   Fix common misspe...
292
  	 * is not 64KB we assume it is a ram board and bail out.
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
293
294
295
296
297
298
299
  	 */
  	if (zorro_resource_len(z) != 0x10000)
  		return -ENODEV;
  
  	address = z->resource.start;
  	if (!request_mem_region(address, 256, "wd33c93"))
  		return -EBUSY;
6112ea086   Geert Uytterhoeven   zorro: ZTWO_VADDR...
300
  	regs = ZTWO_VADDR(address);
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
301
302
303
304
305
306
  
  	error = check_wd33c93(regs);
  	if (error)
  		goto fail_check_or_alloc;
  
  	instance = scsi_host_alloc(&gvp11_scsi_template,
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
307
  				   sizeof(struct gvp11_hostdata));
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
308
309
310
  	if (!instance) {
  		error = -ENOMEM;
  		goto fail_check_or_alloc;
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
311
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
313
314
  	instance->irq = IRQ_AMIGA_PORTS;
  	instance->unique_id = z->slotaddr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
316
317
318
319
320
321
322
  	regs->secret2 = 1;
  	regs->secret1 = 0;
  	regs->secret3 = 15;
  	while (regs->CNTR & GVP11_DMAC_BUSY)
  		;
  	regs->CNTR = 0;
  	regs->BANK = 0;
68b3aa7c9   Jeff Garzik   [SCSI] allow slee...
323

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
324
325
  	wdregs.SASR = &regs->SASR;
  	wdregs.SCMD = &regs->SCMD;
df0ae2497   Jeff Garzik   [SCSI] allow slee...
326

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
327
328
  	hdata = shost_priv(instance);
  	if (gvp11_xfer_mask)
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
329
  		hdata->wh.dma_xfer_mask = gvp11_xfer_mask;
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
330
  	else
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
331
  		hdata->wh.dma_xfer_mask = default_dma_xfer_mask;
68b3aa7c9   Jeff Garzik   [SCSI] allow slee...
332

cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
333
334
335
336
  	hdata->wh.no_sync = 0xff;
  	hdata->wh.fast = 0;
  	hdata->wh.dma_mode = CTRL_DMA;
  	hdata->regs = regs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
338
339
340
341
342
343
344
  	/*
  	 * Check for 14MHz SCSI clock
  	 */
  	epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000);
  	wd33c93_init(instance, wdregs, dma_setup, dma_stop,
  		     (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10
  					     : WD33C93_FS_12_15);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
346
347
348
349
  	error = request_irq(IRQ_AMIGA_PORTS, gvp11_intr, IRQF_SHARED,
  			    "GVP11 SCSI", instance);
  	if (error)
  		goto fail_irq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
351
  	regs->CNTR = GVP11_DMAC_INT_ENABLE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
353
354
355
  	error = scsi_add_host(instance, NULL);
  	if (error)
  		goto fail_host;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
357
358
359
  	zorro_set_drvdata(z, instance);
  	scsi_scan_host(instance);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
361
362
363
364
365
366
367
368
  fail_host:
  	free_irq(IRQ_AMIGA_PORTS, instance);
  fail_irq:
  	scsi_host_put(instance);
  fail_check_or_alloc:
  	release_mem_region(address, 256);
  	return error;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369

6f0397905   Greg Kroah-Hartman   Drivers: scsi: re...
370
  static void gvp11_remove(struct zorro_dev *z)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371
  {
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
372
  	struct Scsi_Host *instance = zorro_get_drvdata(z);
cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
373
  	struct gvp11_hostdata *hdata = shost_priv(instance);
6869b15ef   Geert Uytterhoeven   m68k/scsi: gvp11 ...
374

cf2ed279f   Geert Uytterhoeven   m68k/scsi: gvp11 ...
375
  	hdata->regs->CNTR = 0;
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
376
  	scsi_remove_host(instance);
bb17b7871   Geert Uytterhoeven   [SCSI] gvp11: Rei...
377
  	free_irq(IRQ_AMIGA_PORTS, instance);
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
378
379
380
381
382
383
384
385
386
  	scsi_host_put(instance);
  	release_mem_region(z->resource.start, 256);
  }
  
  	/*
  	 * This should (hopefully) be the correct way to identify
  	 * all the different GVP SCSI controllers (except for the
  	 * SERIES I though).
  	 */
6f0397905   Greg Kroah-Hartman   Drivers: scsi: re...
387
  static struct zorro_device_id gvp11_zorro_tbl[] = {
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
  	{ ZORRO_PROD_GVP_COMBO_030_R3_SCSI,	~0x00ffffff },
  	{ ZORRO_PROD_GVP_SERIES_II,		~0x00ffffff },
  	{ ZORRO_PROD_GVP_GFORCE_030_SCSI,	~0x01ffffff },
  	{ ZORRO_PROD_GVP_A530_SCSI,		~0x01ffffff },
  	{ ZORRO_PROD_GVP_COMBO_030_R4_SCSI,	~0x01ffffff },
  	{ ZORRO_PROD_GVP_A1291,			~0x07ffffff },
  	{ ZORRO_PROD_GVP_GFORCE_040_SCSI_1,	~0x07ffffff },
  	{ 0 }
  };
  MODULE_DEVICE_TABLE(zorro, gvp11_zorro_tbl);
  
  static struct zorro_driver gvp11_driver = {
  	.name		= "gvp11",
  	.id_table	= gvp11_zorro_tbl,
  	.probe		= gvp11_probe,
6f0397905   Greg Kroah-Hartman   Drivers: scsi: re...
403
  	.remove		= gvp11_remove,
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
404
405
406
407
408
409
410
411
412
413
414
  };
  
  static int __init gvp11_init(void)
  {
  	return zorro_register_driver(&gvp11_driver);
  }
  module_init(gvp11_init);
  
  static void __exit gvp11_exit(void)
  {
  	zorro_unregister_driver(&gvp11_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
  }
c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
416
  module_exit(gvp11_exit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417

c1d288a58   Geert Uytterhoeven   m68k: amiga - GVP...
418
  MODULE_DESCRIPTION("GVP Series II SCSI");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
419
  MODULE_LICENSE("GPL");