diff options
Diffstat (limited to 'drivers/scsi/sun3_scsi_vme.c')
-rw-r--r-- | drivers/scsi/sun3_scsi_vme.c | 584 |
1 files changed, 584 insertions, 0 deletions
diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c new file mode 100644 index 000000000000..9acb5ddebb07 --- /dev/null +++ b/drivers/scsi/sun3_scsi_vme.c | |||
@@ -0,0 +1,584 @@ | |||
1 | /* | ||
2 | * Sun3 SCSI stuff by Erik Verbruggen (erik@bigmama.xtdnet.nl) | ||
3 | * | ||
4 | * Sun3 DMA routines added by Sam Creasey (sammy@sammy.net) | ||
5 | * | ||
6 | * VME support added by Sam Creasey | ||
7 | * | ||
8 | * Adapted from sun3_scsi.c -- see there for other headers | ||
9 | * | ||
10 | * TODO: modify this driver to support multiple Sun3 SCSI VME boards | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #define AUTOSENSE | ||
15 | |||
16 | #include <linux/types.h> | ||
17 | #include <linux/stddef.h> | ||
18 | #include <linux/ctype.h> | ||
19 | #include <linux/delay.h> | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/signal.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/blkdev.h> | ||
27 | |||
28 | #include <asm/io.h> | ||
29 | #include <asm/system.h> | ||
30 | |||
31 | #include <asm/sun3ints.h> | ||
32 | #include <asm/dvma.h> | ||
33 | #include <asm/idprom.h> | ||
34 | #include <asm/machines.h> | ||
35 | |||
36 | #define SUN3_SCSI_VME | ||
37 | |||
38 | #undef SUN3_SCSI_DEBUG | ||
39 | |||
40 | /* dma on! */ | ||
41 | #define REAL_DMA | ||
42 | |||
43 | #include "scsi.h" | ||
44 | #include <scsi/scsi_host.h> | ||
45 | #include "sun3_scsi.h" | ||
46 | #include "NCR5380.h" | ||
47 | |||
48 | extern int sun3_map_test(unsigned long, char *); | ||
49 | |||
50 | #define USE_WRAPPER | ||
51 | /*#define RESET_BOOT */ | ||
52 | #define DRIVER_SETUP | ||
53 | |||
54 | #define NDEBUG 0 | ||
55 | |||
56 | /* | ||
57 | * BUG can be used to trigger a strange code-size related hang on 2.1 kernels | ||
58 | */ | ||
59 | #ifdef BUG | ||
60 | #undef RESET_BOOT | ||
61 | #undef DRIVER_SETUP | ||
62 | #endif | ||
63 | |||
64 | /* #define SUPPORT_TAGS */ | ||
65 | |||
66 | //#define ENABLE_IRQ() enable_irq( SUN3_VEC_VMESCSI0 ); | ||
67 | #define ENABLE_IRQ() | ||
68 | |||
69 | |||
70 | static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp); | ||
71 | static inline unsigned char sun3scsi_read(int reg); | ||
72 | static inline void sun3scsi_write(int reg, int value); | ||
73 | |||
74 | static int setup_can_queue = -1; | ||
75 | module_param(setup_can_queue, int, 0); | ||
76 | static int setup_cmd_per_lun = -1; | ||
77 | module_param(setup_cmd_per_lun, int, 0); | ||
78 | static int setup_sg_tablesize = -1; | ||
79 | module_param(setup_sg_tablesize, int, 0); | ||
80 | #ifdef SUPPORT_TAGS | ||
81 | static int setup_use_tagged_queuing = -1; | ||
82 | module_param(setup_use_tagged_queuing, int, 0); | ||
83 | #endif | ||
84 | static int setup_hostid = -1; | ||
85 | module_param(setup_hostid, int, 0); | ||
86 | |||
87 | static Scsi_Cmnd *sun3_dma_setup_done = NULL; | ||
88 | |||
89 | #define AFTER_RESET_DELAY (HZ/2) | ||
90 | |||
91 | /* ms to wait after hitting dma regs */ | ||
92 | #define SUN3_DMA_DELAY 10 | ||
93 | |||
94 | /* dvma buffer to allocate -- 32k should hopefully be more than sufficient */ | ||
95 | #define SUN3_DVMA_BUFSIZE 0xe000 | ||
96 | |||
97 | /* minimum number of bytes to do dma on */ | ||
98 | #define SUN3_DMA_MINSIZE 128 | ||
99 | |||
100 | static volatile unsigned char *sun3_scsi_regp; | ||
101 | static volatile struct sun3_dma_regs *dregs; | ||
102 | #ifdef OLDDMA | ||
103 | static unsigned char *dmabuf = NULL; /* dma memory buffer */ | ||
104 | #endif | ||
105 | static unsigned char *sun3_dma_orig_addr = NULL; | ||
106 | static unsigned long sun3_dma_orig_count = 0; | ||
107 | static int sun3_dma_active = 0; | ||
108 | static unsigned long last_residual = 0; | ||
109 | |||
110 | /* | ||
111 | * NCR 5380 register access functions | ||
112 | */ | ||
113 | |||
114 | static inline unsigned char sun3scsi_read(int reg) | ||
115 | { | ||
116 | return( sun3_scsi_regp[reg] ); | ||
117 | } | ||
118 | |||
119 | static inline void sun3scsi_write(int reg, int value) | ||
120 | { | ||
121 | sun3_scsi_regp[reg] = value; | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * XXX: status debug | ||
126 | */ | ||
127 | static struct Scsi_Host *default_instance; | ||
128 | |||
129 | /* | ||
130 | * Function : int sun3scsi_detect(Scsi_Host_Template * tpnt) | ||
131 | * | ||
132 | * Purpose : initializes mac NCR5380 driver based on the | ||
133 | * command line / compile time port and irq definitions. | ||
134 | * | ||
135 | * Inputs : tpnt - template for this SCSI adapter. | ||
136 | * | ||
137 | * Returns : 1 if a host adapter was found, 0 if not. | ||
138 | * | ||
139 | */ | ||
140 | |||
141 | static int sun3scsi_detect(Scsi_Host_Template * tpnt) | ||
142 | { | ||
143 | unsigned long ioaddr, irq = 0; | ||
144 | static int called = 0; | ||
145 | struct Scsi_Host *instance; | ||
146 | int i; | ||
147 | unsigned long addrs[3] = { IOBASE_SUN3_VMESCSI, | ||
148 | IOBASE_SUN3_VMESCSI + 0x4000, | ||
149 | 0 }; | ||
150 | unsigned long vecs[3] = { SUN3_VEC_VMESCSI0, | ||
151 | SUN3_VEC_VMESCSI1, | ||
152 | 0 }; | ||
153 | /* check that this machine has an onboard 5380 */ | ||
154 | switch(idprom->id_machtype) { | ||
155 | case SM_SUN3|SM_3_160: | ||
156 | case SM_SUN3|SM_3_260: | ||
157 | break; | ||
158 | |||
159 | default: | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | if(called) | ||
164 | return 0; | ||
165 | |||
166 | tpnt->proc_name = "Sun3 5380 VME SCSI"; | ||
167 | |||
168 | /* setup variables */ | ||
169 | tpnt->can_queue = | ||
170 | (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE; | ||
171 | tpnt->cmd_per_lun = | ||
172 | (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN; | ||
173 | tpnt->sg_tablesize = | ||
174 | (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE; | ||
175 | |||
176 | if (setup_hostid >= 0) | ||
177 | tpnt->this_id = setup_hostid; | ||
178 | else { | ||
179 | /* use 7 as default */ | ||
180 | tpnt->this_id = 7; | ||
181 | } | ||
182 | |||
183 | ioaddr = 0; | ||
184 | for(i = 0; addrs[i] != 0; i++) { | ||
185 | unsigned char x; | ||
186 | |||
187 | ioaddr = (unsigned long)sun3_ioremap(addrs[i], PAGE_SIZE, | ||
188 | SUN3_PAGE_TYPE_VME16); | ||
189 | irq = vecs[i]; | ||
190 | sun3_scsi_regp = (unsigned char *)ioaddr; | ||
191 | |||
192 | dregs = (struct sun3_dma_regs *)(((unsigned char *)ioaddr) + 8); | ||
193 | |||
194 | if(sun3_map_test((unsigned long)dregs, &x)) { | ||
195 | unsigned short oldcsr; | ||
196 | |||
197 | oldcsr = dregs->csr; | ||
198 | dregs->csr = 0; | ||
199 | udelay(SUN3_DMA_DELAY); | ||
200 | if(dregs->csr == 0x1400) | ||
201 | break; | ||
202 | |||
203 | dregs->csr = oldcsr; | ||
204 | } | ||
205 | |||
206 | iounmap((void *)ioaddr); | ||
207 | ioaddr = 0; | ||
208 | } | ||
209 | |||
210 | if(!ioaddr) | ||
211 | return 0; | ||
212 | |||
213 | #ifdef SUPPORT_TAGS | ||
214 | if (setup_use_tagged_queuing < 0) | ||
215 | setup_use_tagged_queuing = USE_TAGGED_QUEUING; | ||
216 | #endif | ||
217 | |||
218 | instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); | ||
219 | if(instance == NULL) | ||
220 | return 0; | ||
221 | |||
222 | default_instance = instance; | ||
223 | |||
224 | instance->io_port = (unsigned long) ioaddr; | ||
225 | instance->irq = irq; | ||
226 | |||
227 | NCR5380_init(instance, 0); | ||
228 | |||
229 | instance->n_io_port = 32; | ||
230 | |||
231 | ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; | ||
232 | |||
233 | if (request_irq(instance->irq, scsi_sun3_intr, | ||
234 | 0, "Sun3SCSI-5380VME", NULL)) { | ||
235 | #ifndef REAL_DMA | ||
236 | printk("scsi%d: IRQ%d not free, interrupts disabled\n", | ||
237 | instance->host_no, instance->irq); | ||
238 | instance->irq = SCSI_IRQ_NONE; | ||
239 | #else | ||
240 | printk("scsi%d: IRQ%d not free, bailing out\n", | ||
241 | instance->host_no, instance->irq); | ||
242 | return 0; | ||
243 | #endif | ||
244 | } | ||
245 | |||
246 | printk("scsi%d: Sun3 5380 VME at port %lX irq", instance->host_no, instance->io_port); | ||
247 | if (instance->irq == SCSI_IRQ_NONE) | ||
248 | printk ("s disabled"); | ||
249 | else | ||
250 | printk (" %d", instance->irq); | ||
251 | printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", | ||
252 | instance->can_queue, instance->cmd_per_lun, | ||
253 | SUN3SCSI_PUBLIC_RELEASE); | ||
254 | printk("\nscsi%d:", instance->host_no); | ||
255 | NCR5380_print_options(instance); | ||
256 | printk("\n"); | ||
257 | |||
258 | dregs->csr = 0; | ||
259 | udelay(SUN3_DMA_DELAY); | ||
260 | dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR; | ||
261 | udelay(SUN3_DMA_DELAY); | ||
262 | dregs->fifo_count = 0; | ||
263 | dregs->fifo_count_hi = 0; | ||
264 | dregs->dma_addr_hi = 0; | ||
265 | dregs->dma_addr_lo = 0; | ||
266 | dregs->dma_count_hi = 0; | ||
267 | dregs->dma_count_lo = 0; | ||
268 | |||
269 | dregs->ivect = VME_DATA24 | (instance->irq & 0xff); | ||
270 | |||
271 | called = 1; | ||
272 | |||
273 | #ifdef RESET_BOOT | ||
274 | sun3_scsi_reset_boot(instance); | ||
275 | #endif | ||
276 | |||
277 | return 1; | ||
278 | } | ||
279 | |||
280 | int sun3scsi_release (struct Scsi_Host *shpnt) | ||
281 | { | ||
282 | if (shpnt->irq != SCSI_IRQ_NONE) | ||
283 | free_irq (shpnt->irq, NULL); | ||
284 | |||
285 | iounmap((void *)sun3_scsi_regp); | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | #ifdef RESET_BOOT | ||
291 | /* | ||
292 | * Our 'bus reset on boot' function | ||
293 | */ | ||
294 | |||
295 | static void sun3_scsi_reset_boot(struct Scsi_Host *instance) | ||
296 | { | ||
297 | unsigned long end; | ||
298 | |||
299 | NCR5380_local_declare(); | ||
300 | NCR5380_setup(instance); | ||
301 | |||
302 | /* | ||
303 | * Do a SCSI reset to clean up the bus during initialization. No | ||
304 | * messing with the queues, interrupts, or locks necessary here. | ||
305 | */ | ||
306 | |||
307 | printk( "Sun3 SCSI: resetting the SCSI bus..." ); | ||
308 | |||
309 | /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */ | ||
310 | // sun3_disable_irq( IRQ_SUN3_SCSI ); | ||
311 | |||
312 | /* get in phase */ | ||
313 | NCR5380_write( TARGET_COMMAND_REG, | ||
314 | PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); | ||
315 | |||
316 | /* assert RST */ | ||
317 | NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); | ||
318 | |||
319 | /* The min. reset hold time is 25us, so 40us should be enough */ | ||
320 | udelay( 50 ); | ||
321 | |||
322 | /* reset RST and interrupt */ | ||
323 | NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); | ||
324 | NCR5380_read( RESET_PARITY_INTERRUPT_REG ); | ||
325 | |||
326 | for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) | ||
327 | barrier(); | ||
328 | |||
329 | /* switch on SCSI IRQ again */ | ||
330 | // sun3_enable_irq( IRQ_SUN3_SCSI ); | ||
331 | |||
332 | printk( " done\n" ); | ||
333 | } | ||
334 | #endif | ||
335 | |||
336 | static const char * sun3scsi_info (struct Scsi_Host *spnt) { | ||
337 | return ""; | ||
338 | } | ||
339 | |||
340 | // safe bits for the CSR | ||
341 | #define CSR_GOOD 0x060f | ||
342 | |||
343 | static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp) | ||
344 | { | ||
345 | unsigned short csr = dregs->csr; | ||
346 | int handled = 0; | ||
347 | |||
348 | dregs->csr &= ~CSR_DMA_ENABLE; | ||
349 | |||
350 | |||
351 | #ifdef SUN3_SCSI_DEBUG | ||
352 | printk("scsi_intr csr %x\n", csr); | ||
353 | #endif | ||
354 | |||
355 | if(csr & ~CSR_GOOD) { | ||
356 | if(csr & CSR_DMA_BUSERR) { | ||
357 | printk("scsi%d: bus error in dma\n", default_instance->host_no); | ||
358 | #ifdef SUN3_SCSI_DEBUG | ||
359 | printk("scsi: residual %x count %x addr %p dmaaddr %x\n", | ||
360 | dregs->fifo_count, | ||
361 | dregs->dma_count_lo | (dregs->dma_count_hi << 16), | ||
362 | sun3_dma_orig_addr, | ||
363 | dregs->dma_addr_lo | (dregs->dma_addr_hi << 16)); | ||
364 | #endif | ||
365 | } | ||
366 | |||
367 | if(csr & CSR_DMA_CONFLICT) { | ||
368 | printk("scsi%d: dma conflict\n", default_instance->host_no); | ||
369 | } | ||
370 | handled = 1; | ||
371 | } | ||
372 | |||
373 | if(csr & (CSR_SDB_INT | CSR_DMA_INT)) { | ||
374 | NCR5380_intr(irq, dummy, fp); | ||
375 | handled = 1; | ||
376 | } | ||
377 | |||
378 | return IRQ_RETVAL(handled); | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; | ||
383 | * reentering NCR5380_print_status seems to have ugly side effects | ||
384 | */ | ||
385 | |||
386 | /* this doesn't seem to get used at all -- sam */ | ||
387 | #if 0 | ||
388 | void sun3_sun3_debug (void) | ||
389 | { | ||
390 | unsigned long flags; | ||
391 | NCR5380_local_declare(); | ||
392 | |||
393 | if (default_instance) { | ||
394 | local_irq_save(flags); | ||
395 | NCR5380_print_status(default_instance); | ||
396 | local_irq_restore(flags); | ||
397 | } | ||
398 | } | ||
399 | #endif | ||
400 | |||
401 | |||
402 | /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */ | ||
403 | static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag) | ||
404 | { | ||
405 | void *addr; | ||
406 | |||
407 | if(sun3_dma_orig_addr != NULL) | ||
408 | dvma_unmap(sun3_dma_orig_addr); | ||
409 | |||
410 | // addr = sun3_dvma_page((unsigned long)data, (unsigned long)dmabuf); | ||
411 | addr = (void *)dvma_map_vme((unsigned long) data, count); | ||
412 | |||
413 | sun3_dma_orig_addr = addr; | ||
414 | sun3_dma_orig_count = count; | ||
415 | |||
416 | #ifdef SUN3_SCSI_DEBUG | ||
417 | printk("scsi: dma_setup addr %p count %x\n", addr, count); | ||
418 | #endif | ||
419 | |||
420 | // dregs->fifo_count = 0; | ||
421 | #if 0 | ||
422 | /* reset fifo */ | ||
423 | dregs->csr &= ~CSR_FIFO; | ||
424 | dregs->csr |= CSR_FIFO; | ||
425 | #endif | ||
426 | /* set direction */ | ||
427 | if(write_flag) | ||
428 | dregs->csr |= CSR_SEND; | ||
429 | else | ||
430 | dregs->csr &= ~CSR_SEND; | ||
431 | |||
432 | /* reset fifo */ | ||
433 | // dregs->csr &= ~CSR_FIFO; | ||
434 | // dregs->csr |= CSR_FIFO; | ||
435 | |||
436 | dregs->csr |= CSR_PACK_ENABLE; | ||
437 | |||
438 | dregs->dma_addr_hi = ((unsigned long)addr >> 16); | ||
439 | dregs->dma_addr_lo = ((unsigned long)addr & 0xffff); | ||
440 | |||
441 | dregs->dma_count_hi = 0; | ||
442 | dregs->dma_count_lo = 0; | ||
443 | dregs->fifo_count_hi = 0; | ||
444 | dregs->fifo_count = 0; | ||
445 | |||
446 | #ifdef SUN3_SCSI_DEBUG | ||
447 | printk("scsi: dma_setup done csr %x\n", dregs->csr); | ||
448 | #endif | ||
449 | return count; | ||
450 | |||
451 | } | ||
452 | |||
453 | static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) | ||
454 | { | ||
455 | return last_residual; | ||
456 | } | ||
457 | |||
458 | static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd, | ||
459 | int write_flag) | ||
460 | { | ||
461 | if(cmd->request->flags & REQ_CMD) | ||
462 | return wanted; | ||
463 | else | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | static int sun3scsi_dma_start(unsigned long count, char *data) | ||
468 | { | ||
469 | |||
470 | unsigned short csr; | ||
471 | |||
472 | csr = dregs->csr; | ||
473 | #ifdef SUN3_SCSI_DEBUG | ||
474 | printk("scsi: dma_start data %p count %x csr %x fifo %x\n", data, count, csr, dregs->fifo_count); | ||
475 | #endif | ||
476 | |||
477 | dregs->dma_count_hi = (sun3_dma_orig_count >> 16); | ||
478 | dregs->dma_count_lo = (sun3_dma_orig_count & 0xffff); | ||
479 | |||
480 | dregs->fifo_count_hi = (sun3_dma_orig_count >> 16); | ||
481 | dregs->fifo_count = (sun3_dma_orig_count & 0xffff); | ||
482 | |||
483 | // if(!(csr & CSR_DMA_ENABLE)) | ||
484 | // dregs->csr |= CSR_DMA_ENABLE; | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | /* clean up after our dma is done */ | ||
490 | static int sun3scsi_dma_finish(int write_flag) | ||
491 | { | ||
492 | unsigned short fifo; | ||
493 | int ret = 0; | ||
494 | |||
495 | sun3_dma_active = 0; | ||
496 | |||
497 | dregs->csr &= ~CSR_DMA_ENABLE; | ||
498 | |||
499 | fifo = dregs->fifo_count; | ||
500 | if(write_flag) { | ||
501 | if((fifo > 0) && (fifo < sun3_dma_orig_count)) | ||
502 | fifo++; | ||
503 | } | ||
504 | |||
505 | last_residual = fifo; | ||
506 | #ifdef SUN3_SCSI_DEBUG | ||
507 | printk("scsi: residual %x total %x\n", fifo, sun3_dma_orig_count); | ||
508 | #endif | ||
509 | /* empty bytes from the fifo which didn't make it */ | ||
510 | if((!write_flag) && (dregs->csr & CSR_LEFT)) { | ||
511 | unsigned char *vaddr; | ||
512 | |||
513 | #ifdef SUN3_SCSI_DEBUG | ||
514 | printk("scsi: got left over bytes\n"); | ||
515 | #endif | ||
516 | |||
517 | vaddr = (unsigned char *)dvma_vmetov(sun3_dma_orig_addr); | ||
518 | |||
519 | vaddr += (sun3_dma_orig_count - fifo); | ||
520 | vaddr--; | ||
521 | |||
522 | switch(dregs->csr & CSR_LEFT) { | ||
523 | case CSR_LEFT_3: | ||
524 | *vaddr = (dregs->bpack_lo & 0xff00) >> 8; | ||
525 | vaddr--; | ||
526 | |||
527 | case CSR_LEFT_2: | ||
528 | *vaddr = (dregs->bpack_hi & 0x00ff); | ||
529 | vaddr--; | ||
530 | |||
531 | case CSR_LEFT_1: | ||
532 | *vaddr = (dregs->bpack_hi & 0xff00) >> 8; | ||
533 | break; | ||
534 | } | ||
535 | |||
536 | |||
537 | } | ||
538 | |||
539 | dvma_unmap(sun3_dma_orig_addr); | ||
540 | sun3_dma_orig_addr = NULL; | ||
541 | |||
542 | dregs->dma_addr_hi = 0; | ||
543 | dregs->dma_addr_lo = 0; | ||
544 | dregs->dma_count_hi = 0; | ||
545 | dregs->dma_count_lo = 0; | ||
546 | |||
547 | dregs->fifo_count = 0; | ||
548 | dregs->fifo_count_hi = 0; | ||
549 | |||
550 | dregs->csr &= ~CSR_SEND; | ||
551 | |||
552 | // dregs->csr |= CSR_DMA_ENABLE; | ||
553 | |||
554 | #if 0 | ||
555 | /* reset fifo */ | ||
556 | dregs->csr &= ~CSR_FIFO; | ||
557 | dregs->csr |= CSR_FIFO; | ||
558 | #endif | ||
559 | sun3_dma_setup_done = NULL; | ||
560 | |||
561 | return ret; | ||
562 | |||
563 | } | ||
564 | |||
565 | #include "sun3_NCR5380.c" | ||
566 | |||
567 | static Scsi_Host_Template driver_template = { | ||
568 | .name = SUN3_SCSI_NAME, | ||
569 | .detect = sun3scsi_detect, | ||
570 | .release = sun3scsi_release, | ||
571 | .info = sun3scsi_info, | ||
572 | .queuecommand = sun3scsi_queue_command, | ||
573 | .eh_abort_handler = sun3scsi_abort, | ||
574 | .eh_bus_reset_handler = sun3scsi_bus_reset, | ||
575 | .can_queue = CAN_QUEUE, | ||
576 | .this_id = 7, | ||
577 | .sg_tablesize = SG_TABLESIZE, | ||
578 | .cmd_per_lun = CMD_PER_LUN, | ||
579 | .use_clustering = DISABLE_CLUSTERING | ||
580 | }; | ||
581 | |||
582 | |||
583 | #include "scsi_module.c" | ||
584 | |||