This source file includes following definitions.
- generic_NCR5380_setup
- generic_NCR53C400_setup
- generic_NCR5380_detect
- generic_NCR5380_info
- generic_NCR5380_release_resources
- generic_NCR5380_biosparam
- generic_NCR5380_proc_info
- NCR5380_pread
- NCR5380_pwrite
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 #define AUTOPROBE_IRQ
60 #define AUTOSENSE
61
62 #include <linux/config.h>
63
64 #ifdef CONFIG_SCSI_GENERIC_NCR53C400
65 #define NCR53C400_PSEUDO_DMA 1
66 #define PSEUDO_DMA
67 #define NCR53C400
68 #endif
69 #if defined(CONFIG_SCSI_G_NCR5380_PORT) && defined(CONFIG_SCSI_G_NCR5380_MEM)
70 #error You can not configure the Generic NCR 5380 SCSI Driver for memory mapped I/O and port mapped I/O at the same time (yet)
71 #endif
72 #if !defined(CONFIG_SCSI_G_NCR5380_PORT) && !defined(CONFIG_SCSI_G_NCR5380_MEM)
73 #error You must configure the Generic NCR 5380 SCSI Driver for one of memory mapped I/O and port mapped I/O.
74 #endif
75
76 #include <asm/system.h>
77 #include <asm/io.h>
78 #include <linux/signal.h>
79 #include <linux/sched.h>
80 #include <linux/blk.h>
81 #include "scsi.h"
82 #include "hosts.h"
83 #include "g_NCR5380.h"
84 #include "NCR5380.h"
85 #include "constants.h"
86 #include "sd.h"
87 #include<linux/stat.h>
88
89 struct proc_dir_entry proc_scsi_g_ncr5380 = {
90 PROC_SCSI_GENERIC_NCR5380, 9, "g_NCR5380",
91 S_IFDIR | S_IRUGO | S_IXUGO, 2
92 };
93
94 static struct override {
95 NCR5380_implementation_fields;
96 int irq;
97 int dma;
98 int board;
99 } overrides
100 #ifdef GENERIC_NCR5380_OVERRIDE
101 [] = GENERIC_NCR5380_OVERRIDE
102 #else
103 [1] = {{0,},};
104 #endif
105
106 #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
107
108
109
110
111
112
113
114
115
116
117
118
119 static void internal_setup(int board, char *str, int *ints) {
120 static int commandline_current = 0;
121 switch (board) {
122 case BOARD_NCR5380:
123 if (ints[0] != 2 && ints[0] != 3)
124 printk("generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
125 return;
126 case BOARD_NCR53C400:
127 if (ints[0] != 2)
128 printk("generic_NCR53C400_setup : usage ncr53c400= " STRVAL(NCR5380_map_name) ",irq\n");
129 return;
130 }
131
132 if (commandline_current < NO_OVERRIDES) {
133 overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type)ints[1];
134 overrides[commandline_current].irq = ints[2];
135 if (ints[0] == 3)
136 overrides[commandline_current].dma = ints[3];
137 else
138 overrides[commandline_current].dma = DMA_NONE;
139 overrides[commandline_current].board = board;
140 ++commandline_current;
141 }
142 }
143
144
145
146
147
148
149
150
151
152
153 void generic_NCR5380_setup (char *str, int *ints) {
154 internal_setup (BOARD_NCR5380, str, ints);
155 }
156
157
158
159
160
161
162
163
164
165
166 void generic_NCR53C400_setup (char *str, int *ints) {
167 internal_setup (BOARD_NCR53C400, str, ints);
168 }
169
170
171
172
173
174
175
176
177
178
179
180
181
182 int generic_NCR5380_detect(Scsi_Host_Template * tpnt) {
183 static int current_override = 0;
184 int count;
185 int flags = 0;
186 struct Scsi_Host *instance;
187
188 tpnt->proc_dir = &proc_scsi_g_ncr5380;
189
190 for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
191 if (!(overrides[current_override].NCR5380_map_name))
192 continue;
193
194 switch (overrides[current_override].board) {
195 case BOARD_NCR5380:
196 flags = FLAG_NO_PSEUDO_DMA;
197 break;
198 case BOARD_NCR53C400:
199 flags = FLAG_NCR53C400;
200 break;
201 }
202
203 instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
204 instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
205
206 NCR5380_init(instance, flags);
207
208 if (overrides[current_override].irq != IRQ_AUTO)
209 instance->irq = overrides[current_override].irq;
210 else
211 instance->irq = NCR5380_probe_irq(instance, 0xffff);
212
213 if (instance->irq != IRQ_NONE)
214 if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) {
215 printk("scsi%d : IRQ%d not free, interrupts disabled\n",
216 instance->host_no, instance->irq);
217 instance->irq = IRQ_NONE;
218 }
219
220 if (instance->irq == IRQ_NONE) {
221 printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
222 printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
223 }
224
225 printk("scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int)instance->NCR5380_instance_name);
226 if (instance->irq == IRQ_NONE)
227 printk (" interrupts disabled");
228 else
229 printk (" irq %d", instance->irq);
230 printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
231 CAN_QUEUE, CMD_PER_LUN, GENERIC_NCR5380_PUBLIC_RELEASE);
232 NCR5380_print_options(instance);
233 printk("\n");
234
235 ++current_override;
236 ++count;
237 }
238 return count;
239 }
240
241 const char * generic_NCR5380_info (void) {
242 static const char string[]="Generic NCR5380/53C400 Info";
243 return string;
244 }
245
246 int generic_NCR5380_release_resources(struct Scsi_Host * instance)
247 {
248 NCR5380_local_declare();
249
250 NCR5380_setup(instance);
251
252 free_irq(instance->irq, NULL);
253
254 return 0;
255 }
256
257 #ifdef BIOSPARAM
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278 int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
279 {
280 int size = disk->capacity;
281 ip[0] = 64;
282 ip[1] = 32;
283 ip[2] = size >> 11;
284 return 0;
285 }
286 #endif
287
288 int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout)
289 {
290 int len = 0;
291 struct Scsi_Host *scsi_ptr;
292
293 for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr=scsi_ptr->next)
294 if (scsi_ptr->host_no == hostno)
295 break;
296
297 len += sprintf(buffer+len, "SCSI host number %d : %s\n", scsi_ptr->host_no, scsi_ptr->hostt->name);
298 len += sprintf(buffer+len, "Generic NCR5380 driver version %d\n", GENERIC_NCR5380_PUBLIC_RELEASE);
299 len += sprintf(buffer+len, "NCR5380 driver core version %d\n", NCR5380_PUBLIC_RELEASE);
300 #ifdef NCR53C400
301 len += sprintf(buffer+len, "NCR53C400 driver extension version %d\n", NCR53C400_PUBLIC_RELEASE);
302 len += sprintf(buffer+len, "NCR53C400 card%s detected\n", (((struct NCR5380_hostdata *)scsi_ptr->hostdata)->flags & FLAG_NCR53C400)?"":" not");
303 # if NCR53C400_PSEUDO_DMA
304 len += sprintf(buffer+len, "NCR53C400 pseudo DMA being used\n");
305 # endif
306 #else
307 len += sprintf(buffer+len, "NO NCR53C400 driver extensions\n");
308 #endif
309 len += sprintf(buffer+len, "Using %s mapping at %s 0x%x, ", STRVAL(NCR5380_map_config), STRVAL(NCR5380_map_name), scsi_ptr->NCR5380_instance_name);
310 if (scsi_ptr->irq == IRQ_NONE)
311 len += sprintf(buffer+len, "interrupts disabled\n");
312 else
313 len += sprintf(buffer+len, "on interrupt %d\n", scsi_ptr->irq);
314
315 *start = buffer + offset;
316 len -= offset;
317 if (len > length)
318 len = length;
319 return len;
320 }
321
322 #if NCR53C400_PSEUDO_DMA
323 static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst, int len)
324 {
325 int blocks = len / 128;
326 int start = 0;
327 int i;
328 int bl;
329 NCR5380_local_declare();
330
331 NCR5380_setup(instance);
332
333 #if (NDEBUG & NDEBUG_C400_PREAD)
334 printk("53C400r: About to read %d blocks for %d bytes\n", blocks, len);
335 #endif
336
337 NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
338 NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
339 while (1) {
340
341 #if (NDEBUG & NDEBUG_C400_PREAD)
342 printk("53C400r: %d blocks left\n", blocks);
343 #endif
344
345 if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
346 #if (NDEBUG & NDEBUG_C400_PREAD)
347 if (blocks)
348 printk("53C400r: blocks still == %d\n", blocks);
349 else
350 printk("53C400r: Exiting loop\n");
351 #endif
352 break;
353 }
354
355 #if 1
356 if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
357 printk("53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
358 return -1;
359 }
360 #endif
361
362 #if (NDEBUG & NDEBUG_C400_PREAD)
363 printk("53C400r: Waiting for buffer, bl=%d\n", bl);
364 #endif
365
366 while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
367 ;
368 #if (NDEBUG & NDEBUG_C400_PREAD)
369 printk("53C400r: Transferring 128 bytes\n");
370 #endif
371
372 #ifdef CONFIG_SCSI_G_NCR5380_PORT
373 for (i=0; i<128; i++)
374 dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
375 #else
376
377 memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
378 #endif
379 start+=128;
380 blocks--;
381 }
382
383 #if (NDEBUG & NDEBUG_C400_PREAD)
384 printk("53C400r: EXTRA: Waiting for buffer\n");
385 #endif
386 while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
387 ;
388
389 #if (NDEBUG & NDEBUG_C400_PREAD)
390 printk("53C400r: Transferring EXTRA 128 bytes\n");
391 #endif
392 #ifdef CONFIG_SCSI_G_NCR5380_PORT
393 for (i=0; i<128; i++)
394 dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
395 #else
396
397 memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
398 #endif
399 start+=128;
400 blocks--;
401
402 #if (NDEBUG & NDEBUG_C400_PREAD)
403 printk("53C400r: Final values: blocks=%d start=%d\n", blocks, start);
404 #endif
405
406 if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
407 printk("53C400r: no 53C80 gated irq after transfer");
408 #if (NDEBUG & NDEBUG_C400_PREAD)
409 else
410 printk("53C400r: Got 53C80 interupt and tried to clear it\n");
411 #endif
412
413
414
415
416
417
418
419 if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
420 printk("53C400r: no end dma signal\n");
421 #if (NDEBUG & NDEBUG_C400_PREAD)
422 else
423 printk("53C400r: end dma as expected\n");
424 #endif
425
426 NCR5380_write(MODE_REG, MR_BASE);
427 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
428 return 0;
429 }
430
431 static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src, int len)
432 {
433 int blocks = len / 128;
434 int start = 0;
435 int i;
436 int bl;
437 NCR5380_local_declare();
438
439 NCR5380_setup(instance);
440
441 #if (NDEBUG & NDEBUG_C400_PWRITE)
442 printk("53C400w: About to write %d blocks for %d bytes\n", blocks, len);
443 #endif
444
445 NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
446 NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
447 while (1) {
448 if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
449 printk("53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
450 return -1;
451 }
452
453 if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
454 #if (NDEBUG & NDEBUG_C400_PWRITE)
455 if (blocks)
456 printk("53C400w: exiting loop, blocks still == %d\n", blocks);
457 else
458 printk("53C400w: exiting loop\n");
459 #endif
460 break;
461 }
462
463 #if (NDEBUG & NDEBUG_C400_PWRITE)
464 printk("53C400w: %d blocks left\n", blocks);
465
466 printk("53C400w: waiting for buffer, bl=%d\n", bl);
467 #endif
468 while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
469 ;
470
471 #if (NDEBUG & NDEBUG_C400_PWRITE)
472 printk("53C400w: transferring 128 bytes\n");
473 #endif
474 #ifdef CONFIG_SCSI_G_NCR5380_PORT
475 for (i=0; i<128; i++)
476 NCR5380_write(C400_HOST_BUFFER, src[start+i]);
477 #else
478
479 memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
480 #endif
481 start+=128;
482 blocks--;
483 }
484 if (blocks) {
485 #if (NDEBUG & NDEBUG_C400_PWRITE)
486 printk("53C400w: EXTRA waiting for buffer\n");
487 #endif
488 while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
489 ;
490
491 #if (NDEBUG & NDEBUG_C400_PWRITE)
492 printk("53C400w: transferring EXTRA 128 bytes\n");
493 #endif
494 #ifdef CONFIG_SCSI_G_NCR5380_PORT
495 for (i=0; i<128; i++)
496 NCR5380_write(C400_HOST_BUFFER, src[start+i]);
497 #else
498
499 memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
500 #endif
501 start+=128;
502 blocks--;
503 }
504 #if (NDEBUG & NDEBUG_C400_PWRITE)
505 else
506 printk("53C400w: No EXTRA required\n");
507 #endif
508
509 #if (NDEBUG & NDEBUG_C400_PWRITE)
510 printk("53C400w: Final values: blocks=%d start=%d\n", blocks, start);
511 #endif
512
513 #if 0
514 printk("53C400w: waiting for registers to be available\n");
515 THEY NEVER DO!
516 while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
517 ;
518 printk("53C400w: Got em\n");
519 #endif
520
521
522
523
524
525 while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
526 ;
527
528
529
530
531
532 if (i) {
533 #if (NDEBUG & NDEBUG_C400_PWRITE)
534 prink("53C400w: got 53C80 gated irq (last block)\n");
535 #endif
536 if (!((i=NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
537 printk("53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n",i);
538 #if (NDEBUG & NDEBUG_C400_PWRITE)
539 else
540 printk("53C400w: Got END OF DMA\n");
541 #endif
542 }
543 else
544 printk("53C400w: no 53C80 gated irq after transfer (last block)\n");
545
546 #if 0
547 if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
548 printk("53C400w: no end dma signal\n");
549 }
550 #endif
551
552 #if (NDEBUG & NDEBUG_C400_PWRITE)
553 printk("53C400w: waiting for last byte...\n");
554 #endif
555 while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
556 ;
557
558 #if (NDEBUG & NDEBUG_C400_PWRITE)
559 printk("53C400w: got last byte.\n");
560 printk("53C400w: pwrite exiting with status 0, whoopee!\n");
561 #endif
562 return 0;
563 }
564 #endif
565
566 #include "NCR5380.c"
567 #ifdef MODULE
568
569 Scsi_Host_Template driver_template = GENERIC_NCR5380;
570
571 #include <linux/module.h>
572 #include "scsi_module.c"
573 #endif