]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Oktagon_esp.c -- Driver for bsc Oktagon | |
3 | * | |
4 | * Written by Carsten Pluntke 1998 | |
5 | * | |
6 | * Based on cyber_esp.c | |
7 | */ | |
8 | ||
9 | #include <linux/config.h> | |
10 | ||
11 | #if defined(CONFIG_AMIGA) || defined(CONFIG_APUS) | |
12 | #define USE_BOTTOM_HALF | |
13 | #endif | |
14 | ||
15 | #include <linux/module.h> | |
16 | ||
17 | #include <linux/kernel.h> | |
18 | #include <linux/delay.h> | |
19 | #include <linux/types.h> | |
20 | #include <linux/string.h> | |
21 | #include <linux/slab.h> | |
22 | #include <linux/blkdev.h> | |
23 | #include <linux/proc_fs.h> | |
24 | #include <linux/stat.h> | |
25 | #include <linux/reboot.h> | |
26 | #include <asm/system.h> | |
27 | #include <asm/ptrace.h> | |
28 | #include <asm/pgtable.h> | |
29 | ||
30 | ||
31 | #include "scsi.h" | |
32 | #include <scsi/scsi_host.h> | |
33 | #include "NCR53C9x.h" | |
34 | ||
35 | #include <linux/zorro.h> | |
36 | #include <asm/irq.h> | |
37 | #include <asm/amigaints.h> | |
38 | #include <asm/amigahw.h> | |
39 | ||
40 | #ifdef USE_BOTTOM_HALF | |
41 | #include <linux/workqueue.h> | |
42 | #include <linux/interrupt.h> | |
43 | #endif | |
44 | ||
45 | /* The controller registers can be found in the Z2 config area at these | |
46 | * offsets: | |
47 | */ | |
48 | #define OKTAGON_ESP_ADDR 0x03000 | |
49 | #define OKTAGON_DMA_ADDR 0x01000 | |
50 | ||
51 | ||
52 | static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); | |
53 | static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp); | |
54 | static void dma_dump_state(struct NCR_ESP *esp); | |
55 | static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); | |
56 | static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); | |
57 | static void dma_ints_off(struct NCR_ESP *esp); | |
58 | static void dma_ints_on(struct NCR_ESP *esp); | |
59 | static int dma_irq_p(struct NCR_ESP *esp); | |
60 | static void dma_led_off(struct NCR_ESP *esp); | |
61 | static void dma_led_on(struct NCR_ESP *esp); | |
62 | static int dma_ports_p(struct NCR_ESP *esp); | |
63 | static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); | |
64 | ||
65 | static void dma_irq_exit(struct NCR_ESP *esp); | |
66 | static void dma_invalidate(struct NCR_ESP *esp); | |
67 | ||
68 | static void dma_mmu_get_scsi_one(struct NCR_ESP *,Scsi_Cmnd *); | |
69 | static void dma_mmu_get_scsi_sgl(struct NCR_ESP *,Scsi_Cmnd *); | |
70 | static void dma_mmu_release_scsi_one(struct NCR_ESP *,Scsi_Cmnd *); | |
71 | static void dma_mmu_release_scsi_sgl(struct NCR_ESP *,Scsi_Cmnd *); | |
72 | static void dma_advance_sg(Scsi_Cmnd *); | |
73 | static int oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x); | |
74 | ||
75 | #ifdef USE_BOTTOM_HALF | |
76 | static void dma_commit(void *opaque); | |
77 | ||
78 | long oktag_to_io(long *paddr, long *addr, long len); | |
79 | long oktag_from_io(long *addr, long *paddr, long len); | |
80 | ||
81 | static DECLARE_WORK(tq_fake_dma, dma_commit, NULL); | |
82 | ||
83 | #define DMA_MAXTRANSFER 0x8000 | |
84 | ||
85 | #else | |
86 | ||
87 | /* | |
88 | * No bottom half. Use transfer directly from IRQ. Find a narrow path | |
89 | * between too much IRQ overhead and clogging the IRQ for too long. | |
90 | */ | |
91 | ||
92 | #define DMA_MAXTRANSFER 0x1000 | |
93 | ||
94 | #endif | |
95 | ||
96 | static struct notifier_block oktagon_notifier = { | |
97 | oktagon_notify_reboot, | |
98 | NULL, | |
99 | 0 | |
100 | }; | |
101 | ||
102 | static long *paddress; | |
103 | static long *address; | |
104 | static long len; | |
105 | static long dma_on; | |
106 | static int direction; | |
107 | static struct NCR_ESP *current_esp; | |
108 | ||
109 | ||
110 | static volatile unsigned char cmd_buffer[16]; | |
111 | /* This is where all commands are put | |
112 | * before they are trasfered to the ESP chip | |
113 | * via PIO. | |
114 | */ | |
115 | ||
116 | /***************************************************************** Detection */ | |
d0be4a7d | 117 | int oktagon_esp_detect(struct scsi_host_template *tpnt) |
1da177e4 LT |
118 | { |
119 | struct NCR_ESP *esp; | |
120 | struct zorro_dev *z = NULL; | |
121 | unsigned long address; | |
122 | struct ESP_regs *eregs; | |
123 | ||
124 | while ((z = zorro_find_device(ZORRO_PROD_BSC_OKTAGON_2008, z))) { | |
125 | unsigned long board = z->resource.start; | |
126 | if (request_mem_region(board+OKTAGON_ESP_ADDR, | |
127 | sizeof(struct ESP_regs), "NCR53C9x")) { | |
128 | /* | |
129 | * It is a SCSI controller. | |
130 | * Hardwire Host adapter to SCSI ID 7 | |
131 | */ | |
132 | ||
133 | address = (unsigned long)ZTWO_VADDR(board); | |
134 | eregs = (struct ESP_regs *)(address + OKTAGON_ESP_ADDR); | |
135 | ||
136 | /* This line was 5 lines lower */ | |
137 | esp = esp_allocate(tpnt, (void *)board+OKTAGON_ESP_ADDR); | |
138 | ||
139 | /* we have to shift the registers only one bit for oktagon */ | |
140 | esp->shift = 1; | |
141 | ||
142 | esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7)); | |
143 | udelay(5); | |
144 | if (esp_read(eregs->esp_cfg1) != (ESP_CONFIG1_PENABLE | 7)) | |
145 | return 0; /* Bail out if address did not hold data */ | |
146 | ||
147 | /* Do command transfer with programmed I/O */ | |
148 | esp->do_pio_cmds = 1; | |
149 | ||
150 | /* Required functions */ | |
151 | esp->dma_bytes_sent = &dma_bytes_sent; | |
152 | esp->dma_can_transfer = &dma_can_transfer; | |
153 | esp->dma_dump_state = &dma_dump_state; | |
154 | esp->dma_init_read = &dma_init_read; | |
155 | esp->dma_init_write = &dma_init_write; | |
156 | esp->dma_ints_off = &dma_ints_off; | |
157 | esp->dma_ints_on = &dma_ints_on; | |
158 | esp->dma_irq_p = &dma_irq_p; | |
159 | esp->dma_ports_p = &dma_ports_p; | |
160 | esp->dma_setup = &dma_setup; | |
161 | ||
162 | /* Optional functions */ | |
163 | esp->dma_barrier = 0; | |
164 | esp->dma_drain = 0; | |
165 | esp->dma_invalidate = &dma_invalidate; | |
166 | esp->dma_irq_entry = 0; | |
167 | esp->dma_irq_exit = &dma_irq_exit; | |
168 | esp->dma_led_on = &dma_led_on; | |
169 | esp->dma_led_off = &dma_led_off; | |
170 | esp->dma_poll = 0; | |
171 | esp->dma_reset = 0; | |
172 | ||
173 | esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; | |
174 | esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; | |
175 | esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one; | |
176 | esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl; | |
177 | esp->dma_advance_sg = &dma_advance_sg; | |
178 | ||
179 | /* SCSI chip speed */ | |
180 | /* Looking at the quartz of the SCSI board... */ | |
181 | esp->cfreq = 25000000; | |
182 | ||
183 | /* The DMA registers on the CyberStorm are mapped | |
184 | * relative to the device (i.e. in the same Zorro | |
185 | * I/O block). | |
186 | */ | |
187 | esp->dregs = (void *)(address + OKTAGON_DMA_ADDR); | |
188 | ||
189 | paddress = (long *) esp->dregs; | |
190 | ||
191 | /* ESP register base */ | |
192 | esp->eregs = eregs; | |
193 | ||
194 | /* Set the command buffer */ | |
195 | esp->esp_command = (volatile unsigned char*) cmd_buffer; | |
196 | ||
197 | /* Yes, the virtual address. See below. */ | |
198 | esp->esp_command_dvma = (__u32) cmd_buffer; | |
199 | ||
200 | esp->irq = IRQ_AMIGA_PORTS; | |
201 | request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ, | |
202 | "BSC Oktagon SCSI", esp->ehost); | |
203 | ||
204 | /* Figure out our scsi ID on the bus */ | |
205 | esp->scsi_id = 7; | |
206 | ||
207 | /* We don't have a differential SCSI-bus. */ | |
208 | esp->diff = 0; | |
209 | ||
210 | esp_initialize(esp); | |
211 | ||
212 | printk("ESP_Oktagon Driver 1.1" | |
213 | #ifdef USE_BOTTOM_HALF | |
214 | " [BOTTOM_HALF]" | |
215 | #else | |
216 | " [IRQ]" | |
217 | #endif | |
218 | " registered.\n"); | |
219 | printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use); | |
220 | esps_running = esps_in_use; | |
221 | current_esp = esp; | |
222 | register_reboot_notifier(&oktagon_notifier); | |
223 | return esps_in_use; | |
224 | } | |
225 | } | |
226 | return 0; | |
227 | } | |
228 | ||
229 | ||
230 | /* | |
231 | * On certain configurations the SCSI equipment gets confused on reboot, | |
232 | * so we have to reset it then. | |
233 | */ | |
234 | ||
235 | static int | |
236 | oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x) | |
237 | { | |
238 | struct NCR_ESP *esp; | |
239 | ||
240 | if((code == SYS_DOWN || code == SYS_HALT) && (esp = current_esp)) | |
241 | { | |
242 | esp_bootup_reset(esp,esp->eregs); | |
243 | udelay(500); /* Settle time. Maybe unnecessary. */ | |
244 | } | |
245 | return NOTIFY_DONE; | |
246 | } | |
247 | ||
248 | ||
249 | ||
250 | #ifdef USE_BOTTOM_HALF | |
251 | ||
252 | ||
253 | /* | |
254 | * The bsc Oktagon controller has no real DMA, so we have to do the 'DMA | |
255 | * transfer' in the interrupt (Yikes!) or use a bottom half to not to clutter | |
256 | * IRQ's for longer-than-good. | |
257 | * | |
258 | * FIXME | |
259 | * BIG PROBLEM: 'len' is usually the buffer length, not the expected length | |
260 | * of the data. So DMA may finish prematurely, further reads lead to | |
261 | * 'machine check' on APUS systems (don't know about m68k systems, AmigaOS | |
262 | * deliberately ignores the bus faults) and a normal copy-loop can't | |
263 | * be exited prematurely just at the right moment by the dma_invalidate IRQ. | |
264 | * So do it the hard way, write an own copier in assembler and | |
265 | * catch the exception. | |
266 | * -- Carsten | |
267 | */ | |
268 | ||
269 | ||
270 | static void dma_commit(void *opaque) | |
271 | { | |
272 | long wait,len2,pos; | |
273 | struct NCR_ESP *esp; | |
274 | ||
275 | ESPDATA(("Transfer: %ld bytes, Address 0x%08lX, Direction: %d\n", | |
276 | len,(long) address,direction)); | |
277 | dma_ints_off(current_esp); | |
278 | ||
279 | pos = 0; | |
280 | wait = 1; | |
281 | if(direction) /* write? (memory to device) */ | |
282 | { | |
283 | while(len > 0) | |
284 | { | |
285 | len2 = oktag_to_io(paddress, address+pos, len); | |
286 | if(!len2) | |
287 | { | |
288 | if(wait > 1000) | |
289 | { | |
290 | printk("Expedited DMA exit (writing) %ld\n",len); | |
291 | break; | |
292 | } | |
293 | mdelay(wait); | |
294 | wait *= 2; | |
295 | } | |
296 | pos += len2; | |
297 | len -= len2*sizeof(long); | |
298 | } | |
299 | } else { | |
300 | while(len > 0) | |
301 | { | |
302 | len2 = oktag_from_io(address+pos, paddress, len); | |
303 | if(!len2) | |
304 | { | |
305 | if(wait > 1000) | |
306 | { | |
307 | printk("Expedited DMA exit (reading) %ld\n",len); | |
308 | break; | |
309 | } | |
310 | mdelay(wait); | |
311 | wait *= 2; | |
312 | } | |
313 | pos += len2; | |
314 | len -= len2*sizeof(long); | |
315 | } | |
316 | } | |
317 | ||
318 | /* to make esp->shift work */ | |
319 | esp=current_esp; | |
320 | ||
321 | #if 0 | |
322 | len2 = (esp_read(current_esp->eregs->esp_tclow) & 0xff) | | |
323 | ((esp_read(current_esp->eregs->esp_tcmed) & 0xff) << 8); | |
324 | ||
325 | /* | |
326 | * Uh uh. If you see this, len and transfer count registers were out of | |
327 | * sync. That means really serious trouble. | |
328 | */ | |
329 | ||
330 | if(len2) | |
331 | printk("Eeeek!! Transfer count still %ld!\n",len2); | |
332 | #endif | |
333 | ||
334 | /* | |
335 | * Normally we just need to exit and wait for the interrupt to come. | |
336 | * But at least one device (my Microtek ScanMaker 630) regularly mis- | |
337 | * calculates the bytes it should send which is really ugly because | |
338 | * it locks up the SCSI bus if not accounted for. | |
339 | */ | |
340 | ||
341 | if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)) | |
342 | { | |
343 | long len = 100; | |
344 | long trash[10]; | |
345 | ||
346 | /* | |
347 | * Interrupt bit was not set. Either the device is just plain lazy | |
348 | * so we give it a 10 ms chance or... | |
349 | */ | |
350 | while(len-- && (!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR))) | |
351 | udelay(100); | |
352 | ||
353 | ||
354 | if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)) | |
355 | { | |
356 | /* | |
357 | * So we think that the transfer count is out of sync. Since we | |
358 | * have all we want we are happy and can ditch the trash. | |
359 | */ | |
360 | ||
361 | len = DMA_MAXTRANSFER; | |
362 | ||
363 | while(len-- && (!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR))) | |
364 | oktag_from_io(trash,paddress,2); | |
365 | ||
366 | if(!(esp_read(current_esp->eregs->esp_status) & ESP_STAT_INTR)) | |
367 | { | |
368 | /* | |
369 | * Things really have gone wrong. If we leave the system in that | |
370 | * state, the SCSI bus is locked forever. I hope that this will | |
371 | * turn the system in a more or less running state. | |
372 | */ | |
373 | printk("Device is bolixed, trying bus reset...\n"); | |
374 | esp_bootup_reset(current_esp,current_esp->eregs); | |
375 | } | |
376 | } | |
377 | } | |
378 | ||
379 | ESPDATA(("Transfer_finale: do_data_finale should come\n")); | |
380 | ||
381 | len = 0; | |
382 | dma_on = 0; | |
383 | dma_ints_on(current_esp); | |
384 | } | |
385 | ||
386 | #endif | |
387 | ||
388 | /************************************************************* DMA Functions */ | |
389 | static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count) | |
390 | { | |
391 | /* Since the CyberStorm DMA is fully dedicated to the ESP chip, | |
392 | * the number of bytes sent (to the ESP chip) equals the number | |
393 | * of bytes in the FIFO - there is no buffering in the DMA controller. | |
394 | * XXXX Do I read this right? It is from host to ESP, right? | |
395 | */ | |
396 | return fifo_count; | |
397 | } | |
398 | ||
399 | static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp) | |
400 | { | |
401 | unsigned long sz = sp->SCp.this_residual; | |
402 | if(sz > DMA_MAXTRANSFER) | |
403 | sz = DMA_MAXTRANSFER; | |
404 | return sz; | |
405 | } | |
406 | ||
407 | static void dma_dump_state(struct NCR_ESP *esp) | |
408 | { | |
409 | } | |
410 | ||
411 | /* | |
412 | * What the f$@& is this? | |
413 | * | |
414 | * Some SCSI devices (like my Microtek ScanMaker 630 scanner) want to transfer | |
415 | * more data than requested. How much? Dunno. So ditch the bogus data into | |
416 | * the sink, hoping the device will advance to the next phase sooner or later. | |
417 | * | |
418 | * -- Carsten | |
419 | */ | |
420 | ||
421 | static long oktag_eva_buffer[16]; /* The data sink */ | |
422 | ||
423 | static void oktag_check_dma(void) | |
424 | { | |
425 | struct NCR_ESP *esp; | |
426 | ||
427 | esp=current_esp; | |
428 | if(!len) | |
429 | { | |
430 | address = oktag_eva_buffer; | |
431 | len = 2; | |
432 | /* esp_do_data sets them to zero like len */ | |
433 | esp_write(current_esp->eregs->esp_tclow,2); | |
434 | esp_write(current_esp->eregs->esp_tcmed,0); | |
435 | } | |
436 | } | |
437 | ||
438 | static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) | |
439 | { | |
440 | /* Zorro is noncached, everything else done using processor. */ | |
441 | /* cache_clear(addr, length); */ | |
442 | ||
443 | if(dma_on) | |
444 | panic("dma_init_read while dma process is initialized/running!\n"); | |
445 | direction = 0; | |
446 | address = (long *) vaddress; | |
447 | current_esp = esp; | |
448 | len = length; | |
449 | oktag_check_dma(); | |
450 | dma_on = 1; | |
451 | } | |
452 | ||
453 | static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) | |
454 | { | |
455 | /* cache_push(addr, length); */ | |
456 | ||
457 | if(dma_on) | |
458 | panic("dma_init_write while dma process is initialized/running!\n"); | |
459 | direction = 1; | |
460 | address = (long *) vaddress; | |
461 | current_esp = esp; | |
462 | len = length; | |
463 | oktag_check_dma(); | |
464 | dma_on = 1; | |
465 | } | |
466 | ||
467 | static void dma_ints_off(struct NCR_ESP *esp) | |
468 | { | |
469 | disable_irq(esp->irq); | |
470 | } | |
471 | ||
472 | static void dma_ints_on(struct NCR_ESP *esp) | |
473 | { | |
474 | enable_irq(esp->irq); | |
475 | } | |
476 | ||
477 | static int dma_irq_p(struct NCR_ESP *esp) | |
478 | { | |
479 | /* It's important to check the DMA IRQ bit in the correct way! */ | |
480 | return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR); | |
481 | } | |
482 | ||
483 | static void dma_led_off(struct NCR_ESP *esp) | |
484 | { | |
485 | } | |
486 | ||
487 | static void dma_led_on(struct NCR_ESP *esp) | |
488 | { | |
489 | } | |
490 | ||
491 | static int dma_ports_p(struct NCR_ESP *esp) | |
492 | { | |
493 | return ((custom.intenar) & IF_PORTS); | |
494 | } | |
495 | ||
496 | static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) | |
497 | { | |
498 | /* On the Sparc, DMA_ST_WRITE means "move data from device to memory" | |
499 | * so when (write) is true, it actually means READ! | |
500 | */ | |
501 | if(write){ | |
502 | dma_init_read(esp, addr, count); | |
503 | } else { | |
504 | dma_init_write(esp, addr, count); | |
505 | } | |
506 | } | |
507 | ||
508 | /* | |
509 | * IRQ entry when DMA transfer is ready to be started | |
510 | */ | |
511 | ||
512 | static void dma_irq_exit(struct NCR_ESP *esp) | |
513 | { | |
514 | #ifdef USE_BOTTOM_HALF | |
515 | if(dma_on) | |
516 | { | |
517 | schedule_work(&tq_fake_dma); | |
518 | } | |
519 | #else | |
520 | while(len && !dma_irq_p(esp)) | |
521 | { | |
522 | if(direction) | |
523 | *paddress = *address++; | |
524 | else | |
525 | *address++ = *paddress; | |
526 | len -= (sizeof(long)); | |
527 | } | |
528 | len = 0; | |
529 | dma_on = 0; | |
530 | #endif | |
531 | } | |
532 | ||
533 | /* | |
534 | * IRQ entry when DMA has just finished | |
535 | */ | |
536 | ||
537 | static void dma_invalidate(struct NCR_ESP *esp) | |
538 | { | |
539 | } | |
540 | ||
541 | /* | |
542 | * Since the processor does the data transfer we have to use the custom | |
543 | * mmu interface to pass the virtual address, not the physical. | |
544 | */ | |
545 | ||
546 | void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp) | |
547 | { | |
548 | sp->SCp.ptr = | |
549 | sp->request_buffer; | |
550 | } | |
551 | ||
552 | void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp) | |
553 | { | |
554 | sp->SCp.ptr = page_address(sp->SCp.buffer->page)+ | |
555 | sp->SCp.buffer->offset; | |
556 | } | |
557 | ||
558 | void dma_mmu_release_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp) | |
559 | { | |
560 | } | |
561 | ||
562 | void dma_mmu_release_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp) | |
563 | { | |
564 | } | |
565 | ||
566 | void dma_advance_sg(Scsi_Cmnd *sp) | |
567 | { | |
568 | sp->SCp.ptr = page_address(sp->SCp.buffer->page)+ | |
569 | sp->SCp.buffer->offset; | |
570 | } | |
571 | ||
572 | ||
573 | #define HOSTS_C | |
574 | ||
575 | int oktagon_esp_release(struct Scsi_Host *instance) | |
576 | { | |
577 | #ifdef MODULE | |
578 | unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev; | |
579 | esp_release(); | |
580 | release_mem_region(address, sizeof(struct ESP_regs)); | |
581 | free_irq(IRQ_AMIGA_PORTS, esp_intr); | |
582 | unregister_reboot_notifier(&oktagon_notifier); | |
583 | #endif | |
584 | return 1; | |
585 | } | |
586 | ||
587 | ||
d0be4a7d | 588 | static struct scsi_host_template driver_template = { |
1da177e4 LT |
589 | .proc_name = "esp-oktagon", |
590 | .proc_info = &esp_proc_info, | |
591 | .name = "BSC Oktagon SCSI", | |
592 | .detect = oktagon_esp_detect, | |
593 | .slave_alloc = esp_slave_alloc, | |
594 | .slave_destroy = esp_slave_destroy, | |
595 | .release = oktagon_esp_release, | |
596 | .queuecommand = esp_queue, | |
597 | .eh_abort_handler = esp_abort, | |
598 | .eh_bus_reset_handler = esp_reset, | |
599 | .can_queue = 7, | |
600 | .this_id = 7, | |
601 | .sg_tablesize = SG_ALL, | |
602 | .cmd_per_lun = 1, | |
603 | .use_clustering = ENABLE_CLUSTERING | |
604 | }; | |
605 | ||
606 | ||
607 | #include "scsi_module.c" | |
608 | ||
609 | MODULE_LICENSE("GPL"); |