|
|
1.1 root 1: /*
2: * Generic Generic NCR5380 driver
3: *
4: * Copyright 1993, Drew Eckhardt
5: * Visionary Computing
6: * (Unix and Linux consulting and custom programming)
7: * [email protected]
8: * +1 (303) 440-4894
9: *
10: * NCR53C400 extensions (c) 1994,1995,1996, Kevin Lentin
11: * [email protected]
12: *
13: * ALPHA RELEASE 1.
14: *
15: * For more information, please consult
16: *
17: * NCR 5380 Family
18: * SCSI Protocol Controller
19: * Databook
20: *
21: * NCR Microelectronics
22: * 1635 Aeroplaza Drive
23: * Colorado Springs, CO 80916
24: * 1+ (719) 578-3400
25: * 1+ (800) 334-5454
26: */
27:
28: /*
29: * TODO : flesh out DMA support, find some one actually using this (I have
30: * a memory mapped Trantor board that works fine)
31: */
32:
33: /*
34: * Options :
35: *
36: * PARITY - enable parity checking. Not supported.
37: *
38: * SCSI2 - enable support for SCSI-II tagged queueing. Untested.
39: *
40: * USLEEP - enable support for devices that don't disconnect. Untested.
41: *
42: * The card is detected and initialized in one of several ways :
43: * 1. With command line overrides - NCR5380=port,irq may be
44: * used on the LILO command line to override the defaults.
45: *
46: * 2. With the GENERIC_NCR5380_OVERRIDE compile time define. This is
47: * specified as an array of address, irq, dma, board tuples. Ie, for
48: * one board at 0x350, IRQ5, no dma, I could say
49: * -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NCR5380}}
50: *
51: * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an
52: * IRQ line if overridden on the command line.
53: *
54: * 3. When included as a module, with arguments passed on the command line:
55: * ncr_irq=xx the interrupt
56: * ncr_addr=xx the port or base address (for port or memory
57: * mapped, resp.)
58: * ncr_dma=xx the DMA
59: * ncr_5380=1 to set up for a NCR5380 board
60: * ncr_53c400=1 to set up for a NCR53C400 board
61: * e.g.
62: * modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
63: * for a port mapped NCR5380 board or
64: * modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
65: * for a memory mapped NCR53C400 board with interrupts disabled.
66: *
67: * 255 should be specified for no or DMA interrupt, 254 to autoprobe for an
68: * IRQ line if overridden on the command line.
69: *
70: */
71:
72: #ifdef MACH
73: #define GENERIC_NCR5380_OVERRIDE {{(NCR5380_map_type)0x350,5,0,BOARD_NCR53C400}};
74: #define CONFIG_SCSI_GENERIC_NCR53C400
75: #define CONFIG_SCSI_G_NCR5380_MEM
76: #endif
77:
78: #define AUTOPROBE_IRQ
79: #define AUTOSENSE
80:
81: #include <linux/config.h>
82:
83: #ifdef CONFIG_SCSI_GENERIC_NCR53C400
84: #define NCR53C400_PSEUDO_DMA 1
85: #define PSEUDO_DMA
86: #define NCR53C400
87: #define NCR5380_STATS
88: #undef NCR5380_STAT_LIMIT
89: #endif
90: #if defined(CONFIG_SCSI_G_NCR5380_PORT) && defined(CONFIG_SCSI_G_NCR5380_MEM)
91: #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)
92: #endif
93: #if !defined(CONFIG_SCSI_G_NCR5380_PORT) && !defined(CONFIG_SCSI_G_NCR5380_MEM)
94: #error You must configure the Generic NCR 5380 SCSI Driver for one of memory mapped I/O and port mapped I/O.
95: #endif
96:
97: #include <asm/system.h>
98: #include <asm/io.h>
99: #include <linux/signal.h>
100: #include <linux/sched.h>
101: #include <linux/blk.h>
102: #include "scsi.h"
103: #include "hosts.h"
104: #include "g_NCR5380.h"
105: #include "NCR5380.h"
106: #include "constants.h"
107: #include "sd.h"
108: #include<linux/stat.h>
109:
110: struct proc_dir_entry proc_scsi_g_ncr5380 = {
111: PROC_SCSI_GENERIC_NCR5380, 9, "g_NCR5380",
112: S_IFDIR | S_IRUGO | S_IXUGO, 2
113: };
114:
115: #define NCR_NOT_SET 0
116: static int ncr_irq=NCR_NOT_SET;
117: static int ncr_dma=NCR_NOT_SET;
118: static int ncr_addr=NCR_NOT_SET;
119: static int ncr_5380=NCR_NOT_SET;
120: static int ncr_53c400=NCR_NOT_SET;
121:
122: static struct override {
123: NCR5380_implementation_fields;
124: int irq;
125: int dma;
126: int board; /* Use NCR53c400, Ricoh, etc. extensions ? */
127: } overrides
128: #ifdef GENERIC_NCR5380_OVERRIDE
129: [] = GENERIC_NCR5380_OVERRIDE
130: #else
131: [1] = {{0,},};
132: #endif
133:
134: #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
135:
136: /*
137: * Function : static internal_setup(int board, char *str, int *ints)
138: *
139: * Purpose : LILO command line initialization of the overrides array,
140: *
141: * Inputs : board - either BOARD_NCR5380 for a normal NCR5380 board,
142: * or BOARD_NCR53C400 for a NCR53C400 board. str - unused, ints -
143: * array of integer parameters with ints[0] equal to the number of ints.
144: *
145: */
146:
147: static void internal_setup(int board, char *str, int *ints) {
148: static int commandline_current = 0;
149: switch (board) {
150: case BOARD_NCR5380:
151: if (ints[0] != 2 && ints[0] != 3) {
152: printk("generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
153: return;
154: }
155: case BOARD_NCR53C400:
156: if (ints[0] != 2) {
157: printk("generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
158: return;
159: }
160: }
161:
162: if (commandline_current < NO_OVERRIDES) {
163: overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type)ints[1];
164: overrides[commandline_current].irq = ints[2];
165: if (ints[0] == 3)
166: overrides[commandline_current].dma = ints[3];
167: else
168: overrides[commandline_current].dma = DMA_NONE;
169: overrides[commandline_current].board = board;
170: ++commandline_current;
171: }
172: }
173:
174: /*
175: * Function : generic_NCR5380_setup (char *str, int *ints)
176: *
177: * Purpose : LILO command line initialization of the overrides array,
178: *
179: * Inputs : str - unused, ints - array of integer parameters with ints[0]
180: * equal to the number of ints.
181: */
182:
183: void generic_NCR5380_setup (char *str, int *ints) {
184: internal_setup (BOARD_NCR5380, str, ints);
185: }
186:
187: /*
188: * Function : generic_NCR53C400_setup (char *str, int *ints)
189: *
190: * Purpose : LILO command line initialization of the overrides array,
191: *
192: * Inputs : str - unused, ints - array of integer parameters with ints[0]
193: * equal to the number of ints.
194: */
195:
196: void generic_NCR53C400_setup (char *str, int *ints) {
197: internal_setup (BOARD_NCR53C400, str, ints);
198: }
199:
200: /*
201: * Function : int generic_NCR5380_detect(Scsi_Host_Template * tpnt)
202: *
203: * Purpose : initializes generic NCR5380 driver based on the
204: * command line / compile time port and irq definitions.
205: *
206: * Inputs : tpnt - template for this SCSI adapter.
207: *
208: * Returns : 1 if a host adapter was found, 0 if not.
209: *
210: */
211:
212: int generic_NCR5380_detect(Scsi_Host_Template * tpnt) {
213: static int current_override = 0;
214: int count;
215: int flags = 0;
216: struct Scsi_Host *instance;
217:
218: if (ncr_irq != NCR_NOT_SET)
219: overrides[0].irq=ncr_irq;
220: if (ncr_dma != NCR_NOT_SET)
221: overrides[0].dma=ncr_dma;
222: if (ncr_addr != NCR_NOT_SET)
223: overrides[0].NCR5380_map_name=(NCR5380_map_type)ncr_addr;
224: if (ncr_5380 != NCR_NOT_SET)
225: overrides[0].board=BOARD_NCR5380;
226: else if (ncr_53c400 != NCR_NOT_SET)
227: overrides[0].board=BOARD_NCR53C400;
228:
229: tpnt->proc_dir = &proc_scsi_g_ncr5380;
230:
231: for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
232: if (!(overrides[current_override].NCR5380_map_name))
233: continue;
234:
235: switch (overrides[current_override].board) {
236: case BOARD_NCR5380:
237: flags = FLAG_NO_PSEUDO_DMA;
238: break;
239: case BOARD_NCR53C400:
240: flags = FLAG_NCR53C400;
241: break;
242: }
243:
244: instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
245: instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
246:
247: NCR5380_init(instance, flags);
248:
249: if (overrides[current_override].irq != IRQ_AUTO)
250: instance->irq = overrides[current_override].irq;
251: else
252: instance->irq = NCR5380_probe_irq(instance, 0xffff);
253:
254: if (instance->irq != IRQ_NONE)
255: if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) {
256: printk("scsi%d : IRQ%d not free, interrupts disabled\n",
257: instance->host_no, instance->irq);
258: instance->irq = IRQ_NONE;
259: }
260:
261: if (instance->irq == IRQ_NONE) {
262: printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
263: printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
264: }
265:
266: printk("scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int)instance->NCR5380_instance_name);
267: if (instance->irq == IRQ_NONE)
268: printk (" interrupts disabled");
269: else
270: printk (" irq %d", instance->irq);
271: printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
272: CAN_QUEUE, CMD_PER_LUN, GENERIC_NCR5380_PUBLIC_RELEASE);
273: NCR5380_print_options(instance);
274: printk("\n");
275:
276: ++current_override;
277: ++count;
278: }
279: return count;
280: }
281:
282: const char * generic_NCR5380_info (struct Scsi_Host* host) {
283: static const char string[]="Generic NCR5380/53C400 Driver";
284: return string;
285: }
286:
287: int generic_NCR5380_release_resources(struct Scsi_Host * instance)
288: {
289: NCR5380_local_declare();
290:
291: NCR5380_setup(instance);
292:
293: if (instance->irq != IRQ_NONE)
294: free_irq(instance->irq, NULL);
295:
296: return 0;
297: }
298:
299: #ifdef BIOSPARAM
300: /*
301: * Function : int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
302: *
303: * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for
304: * the specified device / size.
305: *
306: * Inputs : size = size of device in sectors (512 bytes), dev = block device
307: * major / minor, ip[] = {heads, sectors, cylinders}
308: *
309: * Returns : always 0 (success), initializes ip
310: *
311: */
312:
313: /*
314: * XXX Most SCSI boards use this mapping, I could be incorrect. Some one
315: * using hard disks on a trantor should verify that this mapping corresponds
316: * to that used by the BIOS / ASPI driver by running the linux fdisk program
317: * and matching the H_C_S coordinates to what DOS uses.
318: */
319:
320: int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
321: {
322: int size = disk->capacity;
323: ip[0] = 64;
324: ip[1] = 32;
325: ip[2] = size >> 11;
326: return 0;
327: }
328: #endif
329:
330: #if NCR53C400_PSEUDO_DMA
331: static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst, int len)
332: {
333: int blocks = len / 128;
334: int start = 0;
335: int i;
336: int bl;
337: NCR5380_local_declare();
338:
339: NCR5380_setup(instance);
340:
341: #if (NDEBUG & NDEBUG_C400_PREAD)
342: printk("53C400r: About to read %d blocks for %d bytes\n", blocks, len);
343: #endif
344:
345: NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
346: NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
347: while (1) {
348:
349: #if (NDEBUG & NDEBUG_C400_PREAD)
350: printk("53C400r: %d blocks left\n", blocks);
351: #endif
352:
353: if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
354: #if (NDEBUG & NDEBUG_C400_PREAD)
355: if (blocks)
356: printk("53C400r: blocks still == %d\n", blocks);
357: else
358: printk("53C400r: Exiting loop\n");
359: #endif
360: break;
361: }
362:
363: #if 1
364: if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
365: printk("53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
366: return -1;
367: }
368: #endif
369:
370: #if (NDEBUG & NDEBUG_C400_PREAD)
371: printk("53C400r: Waiting for buffer, bl=%d\n", bl);
372: #endif
373:
374: while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
375: ;
376: #if (NDEBUG & NDEBUG_C400_PREAD)
377: printk("53C400r: Transferring 128 bytes\n");
378: #endif
379:
380: #ifdef CONFIG_SCSI_G_NCR5380_PORT
381: for (i=0; i<128; i++)
382: dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
383: #else
384: /* implies CONFIG_SCSI_G_NCR5380_MEM */
385: memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
386: #endif
387: start+=128;
388: blocks--;
389: }
390:
391: if (blocks) {
392: #if (NDEBUG & NDEBUG_C400_PREAD)
393: printk("53C400r: EXTRA: Waiting for buffer\n");
394: #endif
395: while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
396: ;
397:
398: #if (NDEBUG & NDEBUG_C400_PREAD)
399: printk("53C400r: Transferring EXTRA 128 bytes\n");
400: #endif
401: #ifdef CONFIG_SCSI_G_NCR5380_PORT
402: for (i=0; i<128; i++)
403: dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
404: #else
405: /* implies CONFIG_SCSI_G_NCR5380_MEM */
406: memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
407: #endif
408: start+=128;
409: blocks--;
410: }
411: #if (NDEBUG & NDEBUG_C400_PREAD)
412: else
413: printk("53C400r: No EXTRA required\n");
414: #endif
415:
416: #if (NDEBUG & NDEBUG_C400_PREAD)
417: printk("53C400r: Final values: blocks=%d start=%d\n", blocks, start);
418: #endif
419:
420: if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
421: printk("53C400r: no 53C80 gated irq after transfer");
422: #if (NDEBUG & NDEBUG_C400_PREAD)
423: else
424: printk("53C400r: Got 53C80 interrupt and tried to clear it\n");
425: #endif
426:
427: /* DON'T DO THIS - THEY NEVER ARRIVE!
428: printk("53C400r: Waiting for 53C80 registers\n");
429: while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
430: ;
431: */
432:
433: if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
434: printk("53C400r: no end dma signal\n");
435: #if (NDEBUG & NDEBUG_C400_PREAD)
436: else
437: printk("53C400r: end dma as expected\n");
438: #endif
439:
440: NCR5380_write(MODE_REG, MR_BASE);
441: NCR5380_read(RESET_PARITY_INTERRUPT_REG);
442: return 0;
443: }
444:
445: static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src, int len)
446: {
447: int blocks = len / 128;
448: int start = 0;
449: int i;
450: int bl;
451: NCR5380_local_declare();
452:
453: NCR5380_setup(instance);
454:
455: #if (NDEBUG & NDEBUG_C400_PWRITE)
456: printk("53C400w: About to write %d blocks for %d bytes\n", blocks, len);
457: #endif
458:
459: NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
460: NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
461: while (1) {
462: if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
463: printk("53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
464: return -1;
465: }
466:
467: if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
468: #if (NDEBUG & NDEBUG_C400_PWRITE)
469: if (blocks)
470: printk("53C400w: exiting loop, blocks still == %d\n", blocks);
471: else
472: printk("53C400w: exiting loop\n");
473: #endif
474: break;
475: }
476:
477: #if (NDEBUG & NDEBUG_C400_PWRITE)
478: printk("53C400w: %d blocks left\n", blocks);
479:
480: printk("53C400w: waiting for buffer, bl=%d\n", bl);
481: #endif
482: while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
483: ;
484:
485: #if (NDEBUG & NDEBUG_C400_PWRITE)
486: printk("53C400w: transferring 128 bytes\n");
487: #endif
488: #ifdef CONFIG_SCSI_G_NCR5380_PORT
489: for (i=0; i<128; i++)
490: NCR5380_write(C400_HOST_BUFFER, src[start+i]);
491: #else
492: /* implies CONFIG_SCSI_G_NCR5380_MEM */
493: memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
494: #endif
495: start+=128;
496: blocks--;
497: }
498: if (blocks) {
499: #if (NDEBUG & NDEBUG_C400_PWRITE)
500: printk("53C400w: EXTRA waiting for buffer\n");
501: #endif
502: while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
503: ;
504:
505: #if (NDEBUG & NDEBUG_C400_PWRITE)
506: printk("53C400w: transferring EXTRA 128 bytes\n");
507: #endif
508: #ifdef CONFIG_SCSI_G_NCR5380_PORT
509: for (i=0; i<128; i++)
510: NCR5380_write(C400_HOST_BUFFER, src[start+i]);
511: #else
512: /* implies CONFIG_SCSI_G_NCR5380_MEM */
513: memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
514: #endif
515: start+=128;
516: blocks--;
517: }
518: #if (NDEBUG & NDEBUG_C400_PWRITE)
519: else
520: printk("53C400w: No EXTRA required\n");
521: #endif
522:
523: #if (NDEBUG & NDEBUG_C400_PWRITE)
524: printk("53C400w: Final values: blocks=%d start=%d\n", blocks, start);
525: #endif
526:
527: #if 0
528: printk("53C400w: waiting for registers to be available\n");
529: THEY NEVER DO!
530: while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
531: ;
532: printk("53C400w: Got em\n");
533: #endif
534:
535: /* Let's wait for this instead - could be ugly */
536: /* All documentation says to check for this. Maybe my hardware is too
537: * fast. Waiting for it seems to work fine! KLL
538: */
539: while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
540: ;
541:
542: /*
543: * I know. i is certainly != 0 here but the loop is new. See previous
544: * comment.
545: */
546: if (i) {
547: #if (NDEBUG & NDEBUG_C400_PWRITE)
548: printk("53C400w: got 53C80 gated irq (last block)\n");
549: #endif
550: if (!((i=NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
551: printk("53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n",i);
552: #if (NDEBUG & NDEBUG_C400_PWRITE)
553: else
554: printk("53C400w: Got END OF DMA\n");
555: #endif
556: }
557: else
558: printk("53C400w: no 53C80 gated irq after transfer (last block)\n");
559:
560: #if 0
561: if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
562: printk("53C400w: no end dma signal\n");
563: }
564: #endif
565:
566: #if (NDEBUG & NDEBUG_C400_PWRITE)
567: printk("53C400w: waiting for last byte...\n");
568: #endif
569: while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
570: ;
571:
572: #if (NDEBUG & NDEBUG_C400_PWRITE)
573: printk("53C400w: got last byte.\n");
574: printk("53C400w: pwrite exiting with status 0, whoopee!\n");
575: #endif
576: return 0;
577: }
578: #endif /* PSEUDO_DMA */
579:
580: #include "NCR5380.c"
581:
582: #define PRINTP(x) len += sprintf(buffer+len, x)
583: #define ANDP ,
584:
585: static int sprint_opcode(char* buffer, int len, int opcode) {
586: int start = len;
587: PRINTP("0x%02x " ANDP opcode);
588: return len-start;
589: }
590:
591: static int sprint_command (char* buffer, int len, unsigned char *command) {
592: int i,s,start=len;
593: len += sprint_opcode(buffer, len, command[0]);
594: for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
595: PRINTP("%02x " ANDP command[i]);
596: PRINTP("\n");
597: return len-start;
598: }
599:
600: static int sprint_Scsi_Cmnd (char* buffer, int len, Scsi_Cmnd *cmd) {
601: int start = len;
602: PRINTP("host number %d destination target %d, lun %d\n" ANDP
603: cmd->host->host_no ANDP
604: cmd->target ANDP
605: cmd->lun);
606: PRINTP(" command = ");
607: len += sprint_command (buffer, len, cmd->cmnd);
608: return len-start;
609: }
610:
611: int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout)
612: {
613: int len = 0;
614: NCR5380_local_declare();
615: unsigned char status;
616: int i;
617: struct Scsi_Host *scsi_ptr;
618: Scsi_Cmnd *ptr;
619: Scsi_Device *dev;
620: struct NCR5380_hostdata *hostdata;
621:
622: cli();
623:
624: for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr=scsi_ptr->next)
625: if (scsi_ptr->host_no == hostno)
626: break;
627: NCR5380_setup(scsi_ptr);
628: hostdata = (struct NCR5380_hostdata *)scsi_ptr->hostdata;
629:
630: PRINTP("SCSI host number %d : %s\n" ANDP scsi_ptr->host_no ANDP scsi_ptr->hostt->name);
631: PRINTP("Generic NCR5380 driver version %d\n" ANDP GENERIC_NCR5380_PUBLIC_RELEASE);
632: PRINTP("NCR5380 core version %d\n" ANDP NCR5380_PUBLIC_RELEASE);
633: #ifdef NCR53C400
634: PRINTP("NCR53C400 extension version %d\n" ANDP NCR53C400_PUBLIC_RELEASE);
635: PRINTP("NCR53C400 card%s detected\n" ANDP (((struct NCR5380_hostdata *)scsi_ptr->hostdata)->flags & FLAG_NCR53C400)?"":" not");
636: # if NCR53C400_PSEUDO_DMA
637: PRINTP("NCR53C400 pseudo DMA used\n");
638: # endif
639: #else
640: PRINTP("NO NCR53C400 driver extensions\n");
641: #endif
642: PRINTP("Using %s mapping at %s 0x%x, " ANDP STRVAL(NCR5380_map_config) ANDP STRVAL(NCR5380_map_name) ANDP scsi_ptr->NCR5380_instance_name);
643: if (scsi_ptr->irq == IRQ_NONE)
644: PRINTP("no interrupt\n");
645: else
646: PRINTP("on interrupt %d\n" ANDP scsi_ptr->irq);
647:
648: #ifdef NCR5380_STATS
649: if (hostdata->connected || hostdata->issue_queue || hostdata->disconnected_queue)
650: PRINTP("There are commands pending, transfer rates may be crud\n");
651: if (hostdata->pendingr)
652: PRINTP(" %d pending reads" ANDP hostdata->pendingr);
653: if (hostdata->pendingw)
654: PRINTP(" %d pending writes" ANDP hostdata->pendingw);
655: if (hostdata->pendingr || hostdata->pendingw)
656: PRINTP("\n");
657: for (dev = scsi_devices; dev; dev=dev->next) {
658: if (dev->host == scsi_ptr) {
659: unsigned long br = hostdata->bytes_read[dev->id];
660: unsigned long bw = hostdata->bytes_write[dev->id];
661: long tr = hostdata->time_read[dev->id] / HZ;
662: long tw = hostdata->time_write[dev->id] / HZ;
663:
664: PRINTP(" T:%d %s " ANDP dev->id ANDP (dev->type < MAX_SCSI_DEVICE_CODE) ? scsi_device_types[(int)dev->type] : "Unknown");
665: for (i=0; i<8; i++)
666: if (dev->vendor[i] >= 0x20)
667: *(buffer+(len++)) = dev->vendor[i];
668: *(buffer+(len++)) = ' ';
669: for (i=0; i<16; i++)
670: if (dev->model[i] >= 0x20)
671: *(buffer+(len++)) = dev->model[i];
672: *(buffer+(len++)) = ' ';
673: for (i=0; i<4; i++)
674: if (dev->rev[i] >= 0x20)
675: *(buffer+(len++)) = dev->rev[i];
676: *(buffer+(len++)) = ' ';
677:
678: PRINTP("\n%10ld kb read in %5ld secs" ANDP br/1024 ANDP tr);
679: if (tr)
680: PRINTP(" @ %5ld bps" ANDP br / tr);
681:
682: PRINTP("\n%10ld kb written in %5ld secs" ANDP bw/1024 ANDP tw);
683: if (tw)
684: PRINTP(" @ %5ld bps" ANDP bw / tw);
685: PRINTP("\n");
686: }
687: }
688: #endif
689:
690: status = NCR5380_read(STATUS_REG);
691: if (!(status & SR_REQ))
692: PRINTP("REQ not asserted, phase unknown.\n");
693: else {
694: for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
695: (phases[i].value != (status & PHASE_MASK)); ++i)
696: ;
697: PRINTP("Phase %s\n" ANDP phases[i].name);
698: }
699:
700: if (!hostdata->connected) {
701: PRINTP("No currently connected command\n");
702: } else {
703: len += sprint_Scsi_Cmnd (buffer, len, (Scsi_Cmnd *) hostdata->connected);
704: }
705:
706: PRINTP("issue_queue\n");
707:
708: for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr;
709: ptr = (Scsi_Cmnd *) ptr->host_scribble)
710: len += sprint_Scsi_Cmnd (buffer, len, ptr);
711:
712: PRINTP("disconnected_queue\n");
713:
714: for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
715: ptr = (Scsi_Cmnd *) ptr->host_scribble)
716: len += sprint_Scsi_Cmnd (buffer, len, ptr);
717:
718: *start = buffer + offset;
719: len -= offset;
720: if (len > length)
721: len = length;
722: sti();
723: return len;
724: }
725:
726: #undef PRINTP
727: #undef ANDP
728:
729: #ifdef MODULE
730: /* Eventually this will go into an include file, but this will be later */
731: Scsi_Host_Template driver_template = GENERIC_NCR5380;
732:
733: #include <linux/module.h>
734: #include "scsi_module.c"
735: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.