|
|
1.1 root 1: /*
2: * PERM_OPTIONS are driver options which will be enabled for all NCR boards
3: * in the system at driver initialization time.
4: *
5: * Don't THINK about touching these in PERM_OPTIONS :
6: * OPTION_IO_MAPPED
7: * Memory mapped IO does not work under i86 Linux.
8: *
9: * OPTION_DEBUG_TEST1
10: * Test 1 does bus mastering and interrupt tests, which will help weed
11: * out brain damaged main boards.
12: *
13: * These are development kernel changes. Code for them included in this
14: * driver release may or may not work. If you turn them on, you should be
15: * running the latest copy of the development sources from
16: *
17: * ftp://tsx-11.mit.edu/pub/linux/ALPHA/scsi/53c7,8xx
18: *
19: * and be subscribed to the [email protected] mailing list. To
20: * subscribe, send mail to [email protected] with
21: *
22: * subscribe ncr53c810
23: *
24: * in the text.
25: *
26: *
27: * OPTION_NOASYNC
28: * Don't negotiate for asynchronous transfers on the first command
29: * when OPTION_ALWAYS_SYNCHRONOUS is set. Useful for dain bramaged
30: * devices which do something bad rather than sending a MESSAGE
31: * REJECT back to us like they should if they can't cope.
32: *
33: * OPTION_SYNCHRONOUS
34: * Enable support for synchronous transfers. Target negotiated
35: * synchronous transfers will be responded to. To initiate
36: * a synchronous transfer request, call
37: *
38: * request_synchronous (hostno, target)
39: *
40: * from within KGDB.
41: *
42: * OPTION_ALWAYS_SYNCHRONOUS
43: * Negotiate for synchronous transfers with every target after
44: * driver initialization or a SCSI bus reset. This is a bit dangerous,
45: * since there are some dain bramaged SCSI devices which will accept
46: * SDTR messages but keep talking asynchronously.
47: *
48: * OPTION_DISCONNECT
49: * Enable support for disconnect/reconnect. To change the
50: * default setting on a given host adapter, call
51: *
52: * request_disconnect (hostno, allow)
53: *
54: * where allow is non-zero to allow, 0 to disallow.
55: *
56: * If you really want to run 10MHz FAST SCSI-II transfers, you should
57: * know that the NCR driver currently ignores parity information. Most
58: * systems do 5MHz SCSI fine. I've seen a lot that have problems faster
59: * than 8MHz. To play it safe, we only request 5MHz transfers.
60: *
61: * If you'd rather get 10MHz transfers, edit sdtr_message and change
62: * the fourth byte from 50 to 25.
63: */
64:
65: #define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1|OPTION_DISCONNECT|\
66: OPTION_SYNCHRONOUS)
67:
68: /*
69: * Sponsored by
70: * iX Multiuser Multitasking Magazine
71: * Hannover, Germany
72: * [email protected]
73: *
74: * Copyright 1993, 1994, 1995 Drew Eckhardt
75: * Visionary Computing
76: * (Unix and Linux consulting and custom programming)
77: * [email protected]
78: * +1 (303) 786-7975
79: *
80: * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
81: *
82: * For more information, please consult
83: *
84: * NCR53C810
85: * SCSI I/O Processor
86: * Programmer's Guide
87: *
88: * NCR 53C810
89: * PCI-SCSI I/O Processor
90: * Data Manual
91: *
92: * NCR 53C810/53C820
93: * PCI-SCSI I/O Processor Design In Guide
94: *
95: * For literature on Symbios Logic Inc. formerly NCR, SCSI,
96: * and Communication products please call (800) 334-5454 or
97: * (719) 536-3300.
98: *
99: * PCI BIOS Specification Revision
100: * PCI Local Bus Specification
101: * PCI System Design Guide
102: *
103: * PCI Special Interest Group
104: * M/S HF3-15A
105: * 5200 N.E. Elam Young Parkway
106: * Hillsboro, Oregon 97124-6497
107: * +1 (503) 696-2000
108: * +1 (800) 433-5177
109: */
110:
111: /*
112: * Design issues :
113: * The cumulative latency needed to propagate a read/write request
114: * through the file system, buffer cache, driver stacks, SCSI host, and
115: * SCSI device is ultimately the limiting factor in throughput once we
116: * have a sufficiently fast host adapter.
117: *
118: * So, to maximize performance we want to keep the ratio of latency to data
119: * transfer time to a minimum by
120: * 1. Minimizing the total number of commands sent (typical command latency
121: * including drive and bus mastering host overhead is as high as 4.5ms)
122: * to transfer a given amount of data.
123: *
124: * This is accomplished by placing no arbitrary limit on the number
125: * of scatter/gather buffers supported, since we can transfer 1K
126: * per scatter/gather buffer without Eric's cluster patches,
127: * 4K with.
128: *
129: * 2. Minimizing the number of fatal interrupts serviced, since
130: * fatal interrupts halt the SCSI I/O processor. Basically,
131: * this means offloading the practical maximum amount of processing
132: * to the SCSI chip.
133: *
134: * On the NCR53c810/820/720, this is accomplished by using
135: * interrupt-on-the-fly signals when commands complete,
136: * and only handling fatal errors and SDTR / WDTR messages
137: * in the host code.
138: *
139: * On the NCR53c710, interrupts are generated as on the NCR53c8x0,
140: * only the lack of a interrupt-on-the-fly facility complicates
141: * things. Also, SCSI ID registers and commands are
142: * bit fielded rather than binary encoded.
143: *
144: * On the NCR53c700 and NCR53c700-66, operations that are done via
145: * indirect, table mode on the more advanced chips must be
146: * replaced by calls through a jump table which
147: * acts as a surrogate for the DSA. Unfortunately, this
148: * will mean that we must service an interrupt for each
149: * disconnect/reconnect.
150: *
151: * 3. Eliminating latency by pipelining operations at the different levels.
152: *
153: * This driver allows a configurable number of commands to be enqueued
154: * for each target/lun combination (experimentally, I have discovered
155: * that two seems to work best) and will ultimately allow for
156: * SCSI-II tagged queuing.
157: *
158: *
159: * Architecture :
160: * This driver is built around a Linux queue of commands waiting to
161: * be executed, and a shared Linux/NCR array of commands to start. Commands
162: * are transfered to the array by the run_process_issue_queue() function
163: * which is called whenever a command completes.
164: *
165: * As commands are completed, the interrupt routine is triggered,
166: * looks for commands in the linked list of completed commands with
167: * valid status, removes these commands from a list of running commands,
168: * calls the done routine, and flags their target/luns as not busy.
169: *
170: * Due to limitations in the intelligence of the NCR chips, certain
171: * concessions are made. In many cases, it is easier to dynamically
172: * generate/fix-up code rather than calculate on the NCR at run time.
173: * So, code is generated or fixed up for
174: *
175: * - Handling data transfers, using a variable number of MOVE instructions
176: * interspersed with CALL MSG_IN, WHEN MSGIN instructions.
177: *
178: * The DATAIN and DATAOUT routines are separate, so that an incorrect
179: * direction can be trapped, and space isn't wasted.
180: *
181: * It may turn out that we're better off using some sort
182: * of table indirect instruction in a loop with a variable
183: * sized table on the NCR53c710 and newer chips.
184: *
185: * - Checking for reselection (NCR53c710 and better)
186: *
187: * - Handling the details of SCSI context switches (NCR53c710 and better),
188: * such as reprogramming appropriate synchronous parameters,
189: * removing the dsa structure from the NCR's queue of outstanding
190: * commands, etc.
191: *
192: */
193:
194: /*
195: * Accommodate differences between stock 1.2.x and 1.3.x asm-i386/types.h
196: * so lusers can drop in 53c7,8xx.* and get something which compiles
197: * without warnings.
198: */
199:
200: #if !defined(LINUX_1_2) && !defined(LINUX_1_3)
201: #include <linux/version.h>
202: #if LINUX_VERSION_CODE > 65536 + 3 * 256
203: #define LINUX_1_3
204: #else
205: #define LINUX_1_2
206: #endif
207: #endif
208:
209: #ifdef LINUX_1_2
210: #define u32 bogus_u32
211: #define s32 bogus_s32
212: #include <asm/types.h>
213: #undef u32
214: #undef s32
215: typedef __signed__ int s32;
216: typedef unsigned int u32;
217: #endif /* def LINUX_1_2 */
218:
219: #ifdef MODULE
220: #include <linux/module.h>
221: #endif
222:
223: #include <asm/dma.h>
224: #include <asm/io.h>
225: #include <asm/system.h>
226: #include <linux/delay.h>
227: #include <linux/signal.h>
228: #include <linux/sched.h>
229: #include <linux/errno.h>
230: #include <linux/bios32.h>
231: #include <linux/pci.h>
232: #include <linux/proc_fs.h>
233: #include <linux/string.h>
234: #include <linux/malloc.h>
235: #include <linux/mm.h>
236: #include <linux/ioport.h>
237: #include <linux/time.h>
238: #ifdef LINUX_1_2
239: #include "../block/blk.h"
240: #else
241: #include <linux/blk.h>
242: #endif
243: #undef current
244:
245: #include "scsi.h"
246: #include "hosts.h"
247: #include "53c7,8xx.h"
248: #include "constants.h"
249: #include "sd.h"
250: #include <linux/stat.h>
251: #include <linux/stddef.h>
252:
253: #ifndef LINUX_1_2
254: struct proc_dir_entry proc_scsi_ncr53c7xx = {
255: PROC_SCSI_NCR53C7xx, 9, "ncr53c7xx",
256: S_IFDIR | S_IRUGO | S_IXUGO, 2
257: };
258: #endif
259:
260: static int check_address (unsigned long addr, int size);
261: static void dump_events (struct Scsi_Host *host, int count);
262: static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host,
263: int free, int issue);
264: static void hard_reset (struct Scsi_Host *host);
265: static void ncr_scsi_reset (struct Scsi_Host *host);
266: static void print_lots (struct Scsi_Host *host);
267: static void set_synchronous (struct Scsi_Host *host, int target, int sxfer,
268: int scntl3, int now_connected);
269: static int datapath_residual (struct Scsi_Host *host);
270: static const char * sbcl_to_phase (int sbcl);
271: static void print_progress (Scsi_Cmnd *cmd);
272: static void print_queues (struct Scsi_Host *host);
273: static void process_issue_queue (unsigned long flags);
274: static int shutdown (struct Scsi_Host *host);
275: static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
276: static int disable (struct Scsi_Host *host);
277: static int NCR53c8xx_run_tests (struct Scsi_Host *host);
278: static int NCR53c8xx_script_len;
279: static int NCR53c8xx_dsa_len;
280: static void NCR53c7x0_intr(int irq, struct pt_regs * regs);
281: static int ncr_halt (struct Scsi_Host *host);
282: static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd
283: *cmd);
284: static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
285: static void print_dsa (struct Scsi_Host *host, u32 *dsa,
286: const char *prefix);
287: static int print_insn (struct Scsi_Host *host, const u32 *insn,
288: const char *prefix, int kernel);
289:
290: static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd);
291: static void NCR53c8x0_init_fixup (struct Scsi_Host *host);
292: static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
293: NCR53c7x0_cmd *cmd);
294: static void NCR53c8x0_soft_reset (struct Scsi_Host *host);
295:
296: /* INSMOD variables */
297: static long long perm_options = PERM_OPTIONS;
298: /* 14 = .5s; 15 is max; decreasing divides by two. */
299: static int selection_timeout = 14;
300: /* Size of event list (per host adapter) */
301: static int track_events = 0;
302:
303: static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */
304: static Scsi_Host_Template *the_template = NULL;
305:
306: /*
307: * KNOWN BUGS :
308: * - There is some sort of conflict when the PPP driver is compiled with
309: * support for 16 channels?
310: *
311: * - On systems which predate the 1.3.x initialization order change,
312: * the NCR driver will cause Cannot get free page messages to appear.
313: * These are harmless, but I don't know of an easy way to avoid them.
314: *
315: * - With OPTION_DISCONNECT, on two systems under unknown circumstances,
316: * we get a PHASE MISMATCH with DSA set to zero (suggests that we
317: * are occurring somewhere in the reselection code) where
318: * DSP=some value DCMD|DBC=same value.
319: *
320: * Closer inspection suggests that we may be trying to execute
321: * some portion of the DSA?
322: * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO)
323: * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO)
324: * scsi0 : no current command : unexpected phase MSGIN.
325: * DSP=0x1c46cc, DCMD|DBC=0x1c46ac, DSA=0x0
326: * DSPS=0x0, TEMP=0x1c3e70, DMODE=0x80
327: * scsi0 : DSP->
328: * 001c46cc : 0x001c46cc 0x00000000
329: * 001c46d4 : 0x001c5ea0 0x000011f8
330: *
331: * Changed the print code in the phase_mismatch handler so
332: * that we call print_lots to try and diagnose this.
333: *
334: */
335:
336: /*
337: * Possible future direction of architecture for max performance :
338: *
339: * We're using a single start array for the NCR chip. This is
340: * sub-optimal, because we cannot add a command which would conflict with
341: * an executing command to this start queue, and therefore must insert the
342: * next command for a given I/T/L combination after the first has completed;
343: * incurring our interrupt latency between SCSI commands.
344: *
345: * To allow furthur pipelining of the NCR and host CPU operation, we want
346: * to set things up so that immediately on termination of a command destined
347: * for a given LUN, we get that LUN busy again.
348: *
349: * To do this, we need to add a 32 bit pointer to which is jumped to
350: * on completion of a command. If no new command is available, this
351: * would point to the usual DSA issue queue select routine.
352: *
353: * If one were, it would point to a per-NCR53c7x0_cmd select routine
354: * which starts execution immediately, inserting the command at the head
355: * of the start queue if the NCR chip is selected or reselected.
356: *
357: * We would chanage so that we keep a list of outstanding commands
358: * for each unit, rather than a single running_list. We'd insert
359: * a new command into the right running list; if the NCR didn't
360: * have something running for that yet, we'd put it in the
361: * start queue as well. Some magic needs to happen to handle the
362: * race condition between the first command terminating before the
363: * new one is written.
364: *
365: * Potential for profiling :
366: * Call do_gettimeofday(struct timeval *tv) to get 800ns resolution.
367: */
368:
369:
370: /*
371: * TODO :
372: * 1. To support WIDE transfers, not much needs to happen. We
373: * should do CHMOVE instructions instead of MOVEs when
374: * we have scatter/gather segments of uneven length. When
375: * we do this, we need to handle the case where we disconnect
376: * between segments.
377: *
378: * 2. Currently, when Icky things happen we do a FATAL(). Instead,
379: * we want to do an integrity check on the parts of the NCR hostdata
380: * structure which were initialized at boot time; FATAL() if that
381: * fails, and otherwise try to recover. Keep track of how many
382: * times this has happened within a single SCSI command; if it
383: * gets excessive, then FATAL().
384: *
385: * 3. Parity checking is currently disabled, and a few things should
386: * happen here now that we support synchronous SCSI transfers :
387: * 1. On soft-reset, we shuld set the EPC (Enable Parity Checking)
388: * and AAP (Assert SATN/ on parity error) bits in SCNTL0.
389: *
390: * 2. We should enable the parity interrupt in the SIEN0 register.
391: *
392: * 3. intr_phase_mismatch() needs to believe that message out is
393: * allways an "acceptable" phase to have a mismatch in. If
394: * the old phase was MSG_IN, we should send a MESSAGE PARITY
395: * error. If the old phase was something else, we should send
396: * a INITIATOR_DETECTED_ERROR message. Note that this could
397: * cause a RESTORE POINTERS message; so we should handle that
398: * correctly first. Instead, we should probably do an
399: * initiator_abort.
400: *
401: * 4. MPEE bit of CTEST4 should be set so we get interrupted if
402: * we detect an error.
403: *
404: *
405: * 5. The initial code has been tested on the NCR53c810. I don't
406: * have access to NCR53c700, 700-66 (Forex boards), NCR53c710
407: * (NCR Pentium systems), NCR53c720, NCR53c820, or NCR53c825 boards to
408: * finish development on those platforms.
409: *
410: * NCR53c820/825/720 - need to add wide transfer support, including WDTR
411: * negotiation, programming of wide transfer capabilities
412: * on reselection and table indirect selection.
413: *
414: * NCR53c710 - need to add fatal interrupt or GEN code for
415: * command completion signaling. Need to modify all
416: * SDID, SCID, etc. registers, and table indirect select code
417: * since these use bit fielded (ie 1<<target) instead of
418: * binary encoded target ids. Need to accomodate
419: * different register mappings, probably scan through
420: * the SCRIPT code and change the non SFBR register operand
421: * of all MOVE instructions.
422: *
423: * NCR53c700/700-66 - need to add code to refix addresses on
424: * every nexus change, eliminate all table indirect code,
425: * very messy.
426: *
427: * 6. The NCR53c7x0 series is very popular on other platforms that
428: * could be running Linux - ie, some high performance AMIGA SCSI
429: * boards use it.
430: *
431: * So, I should include #ifdef'd code so that it is
432: * compatible with these systems.
433: *
434: * Specifically, the little Endian assumptions I made in my
435: * bit fields need to change, and if the NCR doesn't see memory
436: * the right way, we need to provide options to reverse words
437: * when the scripts are relocated.
438: *
439: * 7. Use vremap() to access memory mapped boards.
440: */
441:
442: /*
443: * Allow for simultaneous existence of multiple SCSI scripts so we
444: * can have a single driver binary for all of the family.
445: *
446: * - one for NCR53c700 and NCR53c700-66 chips (not yet supported)
447: * - one for rest (only the NCR53c810, 815, 820, and 825 are currently
448: * supported)
449: *
450: * So that we only need two SCSI scripts, we need to modify things so
451: * that we fixup register accesses in READ/WRITE instructions, and
452: * we'll also have to accomodate the bit vs. binary encoding of IDs
453: * with the 7xx chips.
454: */
455:
456: /*
457: * Use pci_chips_ids to translate in both directions between PCI device ID
458: * and chip numbers.
459: */
460:
461: static struct {
462: unsigned short pci_device_id;
463: int chip;
464: /*
465: * The revision field of the PCI_CLASS_REVISION register is compared
466: * against each of these fields if the field is not -1. If it
467: * is less than min_revision or larger than max_revision, a warning
468: * message is printed.
469: */
470: int max_revision;
471: int min_revision;
472: } pci_chip_ids[] = {
473: {PCI_DEVICE_ID_NCR_53C810, 810, 2, 1},
474: {PCI_DEVICE_ID_NCR_53C815, 815, 3, 2},
475: {PCI_DEVICE_ID_NCR_53C820, 820, -1, -1},
476: {PCI_DEVICE_ID_NCR_53C825, 825, -1, -1}
477: };
478:
479: #define NPCI_CHIP_IDS (sizeof (pci_chip_ids) / sizeof(pci_chip_ids[0]))
480:
481: #define ROUNDUP(adr,type) \
482: ((void *) (((long) (adr) + sizeof(type) - 1) & ~(sizeof(type) - 1)))
483:
484: /*
485: * Forced detection and autoprobe code for various hardware. Currently,
486: * entry points for these are not included in init/main.c because if the
487: * PCI BIOS code isn't working right, you're not going to be able to use
488: * the hardware anyways; this way we force users to solve their
489: * problems rather than forcing detection and blaming us when it
490: * does not work.
491: */
492:
493: static struct override {
494: int chip; /* 700, 70066, 710, 720, 810, 820 */
495: int board; /* Any special board level gunk */
496: unsigned pci:1;
497: union {
498: struct {
499: int base; /* Memory address - indicates memory mapped regs */
500: int io_port;/* I/O port address - indicates I/O mapped regs */
501: int irq; /* IRQ line */
502: int dma; /* DMA channel - often none */
503: } normal;
504: struct {
505: int bus;
506: int device;
507: int function;
508: } pci;
509: } data;
510: long long options;
511: } overrides [4] = {{0,},};
512: static int commandline_current = 0;
513: static int no_overrides = 0;
514:
515: #if 0
516: #define OVERRIDE_LIMIT (sizeof(overrides) / sizeof(struct override))
517: #else
518: #define OVERRIDE_LIMIT commandline_current
519: #endif
520:
521: /*
522: * Function: issue_to_cmd
523: *
524: * Purpose: convert jump instruction in issue array to NCR53c7x0_cmd
525: * structure pointer.
526: *
527: * Inputs; issue - pointer to start of NOP or JUMP instruction
528: * in issue array.
529: *
530: * Returns: pointer to command on success; 0 if opcode is NOP.
531: */
532:
533: static inline struct NCR53c7x0_cmd *
534: issue_to_cmd (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
535: u32 *issue)
536: {
537: return (issue[0] != hostdata->NOP_insn) ?
538: /*
539: * If the IF TRUE bit is set, it's a JUMP instruction. The
540: * operand is a bus pointer to the dsa_begin routine for this DSA. The
541: * dsa field of the NCR53c7x0_cmd structure starts with the
542: * DSA code template. By converting to a virtual address,
543: * subtracting the code template size, and offset of the
544: * dsa field, we end up with a pointer to the start of the
545: * structure (alternatively, we could use the
546: * dsa_cmnd field, an anachronism from when we weren't
547: * sure what the relationship between the NCR structures
548: * and host structures were going to be.
549: */
550: (struct NCR53c7x0_cmd *) ((char *) bus_to_virt (issue[1]) -
551: (hostdata->E_dsa_code_begin - hostdata->E_dsa_code_template) -
552: offsetof(struct NCR53c7x0_cmd, dsa))
553: /* If the IF TRUE bit is not set, it's a NOP */
554: : NULL;
555: }
556:
557:
558: /*
559: * Function : static internal_setup(int board, int chip, char *str, int *ints)
560: *
561: * Purpose : LILO command line initialization of the overrides array,
562: *
563: * Inputs : board - currently, unsupported. chip - 700, 70066, 710, 720
564: * 810, 815, 820, 825, although currently only the NCR53c810 is
565: * supported.
566: *
567: */
568:
569: static void
570: internal_setup(int board, int chip, char *str, int *ints) {
571: unsigned char pci; /* Specifies a PCI override, with bus, device,
572: function */
573:
574: pci = (str && !strcmp (str, "pci")) ? 1 : 0;
575:
576: /*
577: * Override syntaxes are as follows :
578: * ncr53c700,ncr53c700-66,ncr53c710,ncr53c720=mem,io,irq,dma
579: * ncr53c810,ncr53c820,ncr53c825=mem,io,irq or pci,bus,device,function
580: */
581:
582: if (commandline_current < OVERRIDE_LIMIT) {
583: overrides[commandline_current].pci = pci ? 1 : 0;
584: if (!pci) {
585: overrides[commandline_current].data.normal.base = ints[1];
586: overrides[commandline_current].data.normal.io_port = ints[2];
587: overrides[commandline_current].data.normal.irq = ints[3];
588: overrides[commandline_current].data.normal.dma = (ints[0] >= 4) ?
589: ints[4] : DMA_NONE;
590: /* FIXME: options is now a long long */
591: overrides[commandline_current].options = (ints[0] >= 5) ?
592: ints[5] : 0;
593: } else {
594: overrides[commandline_current].data.pci.bus = ints[1];
595: overrides[commandline_current].data.pci.device = ints[2];
596: overrides[commandline_current].data.pci.function = ints[3];
597: /* FIXME: options is now a long long */
598: overrides[commandline_current].options = (ints[0] >= 4) ?
599: ints[4] : 0;
600: }
601: overrides[commandline_current].board = board;
602: overrides[commandline_current].chip = chip;
603: ++commandline_current;
604: ++no_overrides;
605: } else {
606: printk ("53c7,7x0.c:internal_setup() : too many overrides\n");
607: }
608: }
609:
610: /*
611: * XXX - we might want to implement a single override function
612: * with a chip type field, revamp the command line configuration,
613: * etc.
614: */
615:
616: #define setup_wrapper(x) \
617: void ncr53c##x##_setup (char *str, int *ints) { \
618: internal_setup (BOARD_GENERIC, x, str, ints); \
619: }
620:
621: setup_wrapper(700)
622: setup_wrapper(70066)
623: setup_wrapper(710)
624: setup_wrapper(720)
625: setup_wrapper(810)
626: setup_wrapper(815)
627: setup_wrapper(820)
628: setup_wrapper(825)
629:
630: /*
631: * FIXME: we should junk these, in favor of synchronous_want and
632: * wide_want in the NCR53c7x0_hostdata structure.
633: */
634:
635: /* Template for "preferred" synchronous transfer parameters. */
636:
637: static const unsigned char sdtr_message[] = {
638: EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 50 /* *4ns */, 8 /* off */
639: };
640:
641: /* Template to request asynchronous transfers */
642:
643: static const unsigned char async_message[] = {
644: EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */
645: };
646:
647: /* Template for "preferred" WIDE transfer parameters */
648:
649: static const unsigned char wdtr_message[] = {
650: EXTENDED_MESSAGE, 2 /* length */, EXTENDED_WDTR, 1 /* 2^1 bytes */
651: };
652:
653: /*
654: * Function : struct Scsi_Host *find_host (int host)
655: *
656: * Purpose : KGDB support function which translates a host number
657: * to a host structure.
658: *
659: * Inputs : host - number of SCSI host
660: *
661: * Returns : NULL on failure, pointer to host structure on success.
662: */
663:
664: static struct Scsi_Host *
665: find_host (int host) {
666: struct Scsi_Host *h;
667: for (h = first_host; h && h->host_no != host; h = h->next);
668: if (!h) {
669: printk (KERN_ALERT "scsi%d not found\n", host);
670: return NULL;
671: } else if (h->hostt != the_template) {
672: printk (KERN_ALERT "scsi%d is not a NCR board\n", host);
673: return NULL;
674: }
675: return h;
676: }
677:
678: /*
679: * Function : request_synchronous (int host, int target)
680: *
681: * Purpose : KGDB interface which will allow us to negotiate for
682: * synchronous transfers. This ill be replaced with a more
683: * integrated function; perhaps a new entry in the scsi_host
684: * structure, accessable via an ioctl() or perhaps /proc/scsi.
685: *
686: * Inputs : host - number of SCSI host; target - number of target.
687: *
688: * Returns : 0 when negotiation has been setup for next SCSI command,
689: * -1 on failure.
690: */
691:
692: static int
693: request_synchronous (int host, int target) {
694: struct Scsi_Host *h;
695: struct NCR53c7x0_hostdata *hostdata;
696: unsigned long flags;
697: if (target < 0) {
698: printk (KERN_ALERT "target %d is bogus\n", target);
699: return -1;
700: }
701: if (!(h = find_host (host)))
702: return -1;
703: else if (h->this_id == target) {
704: printk (KERN_ALERT "target %d is host ID\n", target);
705: return -1;
706: }
707: #ifndef LINUX_1_2
708: else if (target > h->max_id) {
709: printk (KERN_ALERT "target %d exceeds maximum of %d\n", target,
710: h->max_id);
711: return -1;
712: }
713: #endif
714: hostdata = (struct NCR53c7x0_hostdata *)h->hostdata;
715:
716: save_flags(flags);
717: cli();
718: if (hostdata->initiate_sdtr & (1 << target)) {
719: restore_flags(flags);
720: printk (KERN_ALERT "target %d allready doing SDTR\n", target);
721: return -1;
722: }
723: hostdata->initiate_sdtr |= (1 << target);
724: restore_flags(flags);
725: return 0;
726: }
727:
728: /*
729: * Function : request_disconnect (int host, int on_or_off)
730: *
731: * Purpose : KGDB support function, tells us to allow or disallow
732: * disconnections.
733: *
734: * Inputs : host - number of SCSI host; on_or_off - non-zero to allow,
735: * zero to disallow.
736: *
737: * Returns : 0 on success, * -1 on failure.
738: */
739:
740: static int
741: request_disconnect (int host, int on_or_off) {
742: struct Scsi_Host *h;
743: struct NCR53c7x0_hostdata *hostdata;
744: if (!(h = find_host (host)))
745: return -1;
746: hostdata = (struct NCR53c7x0_hostdata *) h->hostdata;
747: if (on_or_off)
748: hostdata->options |= OPTION_DISCONNECT;
749: else
750: hostdata->options &= ~OPTION_DISCONNECT;
751: return 0;
752: }
753:
754: /*
755: * Function : static void NCR53c7x0_driver_init (struct Scsi_Host *host)
756: *
757: * Purpose : Initialize internal structures, as required on startup, or
758: * after a SCSI bus reset.
759: *
760: * Inputs : host - pointer to this host adapter's structure
761: */
762:
763: static void
764: NCR53c7x0_driver_init (struct Scsi_Host *host) {
765: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
766: host->hostdata;
767: int i, j;
768: u32 *current;
769: for (i = 0; i < 16; ++i) {
770: hostdata->request_sense[i] = 0;
771: for (j = 0; j < 8; ++j)
772: hostdata->busy[i][j] = 0;
773: set_synchronous (host, i, /* sxfer */ 0, hostdata->saved_scntl3, 0);
774: }
775: hostdata->issue_queue = NULL;
776: hostdata->running_list = hostdata->finished_queue =
777: hostdata->current = NULL;
778: for (i = 0, current = (u32 *) hostdata->schedule;
779: i < host->can_queue; ++i, current += 2) {
780: current[0] = hostdata->NOP_insn;
781: current[1] = 0xdeadbeef;
782: }
783: current[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE;
784: current[1] = (u32) virt_to_bus (hostdata->script) +
785: hostdata->E_wait_reselect;
786: hostdata->reconnect_dsa_head = 0;
787: hostdata->addr_reconnect_dsa_head = (u32)
788: virt_to_bus((void *) &(hostdata->reconnect_dsa_head));
789: hostdata->expecting_iid = 0;
790: hostdata->expecting_sto = 0;
791: if (hostdata->options & OPTION_ALWAYS_SYNCHRONOUS)
792: hostdata->initiate_sdtr = 0xffff;
793: else
794: hostdata->initiate_sdtr = 0;
795: hostdata->talked_to = 0;
796: hostdata->idle = 1;
797: }
798:
799: /*
800: * Function : static int ccf_to_clock (int ccf)
801: *
802: * Purpose : Return the largest SCSI clock allowable for a given
803: * clock conversion factor, allowing us to do synchronous periods
804: * when we don't know what the SCSI clock is by taking at least
805: * as long as the device says we can.
806: *
807: * Inputs : ccf
808: *
809: * Returns : clock on success, -1 on failure.
810: */
811:
812: static int
813: ccf_to_clock (int ccf) {
814: switch (ccf) {
815: case 1: return 25000000; /* Divide by 1.0 */
816: case 2: return 37500000; /* Divide by 1.5 */
817: case 3: return 50000000; /* Divide by 2.0 */
818: case 0: /* Divide by 3.0 */
819: case 4: return 66000000;
820: default: return -1;
821: }
822: }
823:
824: /*
825: * Function : static int clock_to_ccf (int clock)
826: *
827: * Purpose : Return the clock conversion factor for a given SCSI clock.
828: *
829: * Inputs : clock - SCSI clock expressed in Hz.
830: *
831: * Returns : ccf on success, -1 on failure.
832: */
833:
834: static int
835: clock_to_ccf (int clock) {
836: if (clock < 16666666)
837: return -1;
838: if (clock < 25000000)
839: return 1; /* Divide by 1.0 */
840: else if (clock < 37500000)
841: return 2; /* Divide by 1.5 */
842: else if (clock < 50000000)
843: return 3; /* Divide by 2.0 */
844: else if (clock < 66000000)
845: return 4; /* Divide by 3.0 */
846: else
847: return -1;
848: }
849:
850: /*
851: * Function : static int NCR53c7x0_init (struct Scsi_Host *host)
852: *
853: * Purpose : initialize the internal structures for a given SCSI host
854: *
855: * Inputs : host - pointer to this host adapter's structure
856: *
857: * Preconditions : when this function is called, the chip_type
858: * field of the hostdata structure MUST have been set.
859: *
860: * Returns : 0 on success, -1 on failure.
861: */
862:
863: static int
864: NCR53c7x0_init (struct Scsi_Host *host) {
865: NCR53c7x0_local_declare();
866: int i, ccf, expected_ccf;
867: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
868: host->hostdata;
869: struct Scsi_Host *search;
870: /*
871: * There are some things which we need to know about in order to provide
872: * a semblance of support. Print 'em if they aren't what we expect,
873: * otherwise don't add to the noise.
874: *
875: * -1 means we don't know what to expect.
876: */
877: int expected_id = -1;
878: int expected_clock = -1;
879: int uninitialized = 0;
880: /*
881: * FIXME : this is only on Intel boxes. On other platforms, this
882: * will differ.
883: */
884: int expected_mapping = OPTION_IO_MAPPED;
885: NCR53c7x0_local_setup(host);
886:
887: switch (hostdata->chip) {
888: case 820:
889: case 825:
890: #ifdef notyet
891: host->max_id = 15;
892: #endif
893: /* Fall through */
894: case 810:
895: case 815:
896: hostdata->dstat_sir_intr = NCR53c8x0_dstat_sir_intr;
897: hostdata->init_save_regs = NULL;
898: hostdata->dsa_fixup = NCR53c8xx_dsa_fixup;
899: hostdata->init_fixup = NCR53c8x0_init_fixup;
900: hostdata->soft_reset = NCR53c8x0_soft_reset;
901: hostdata->run_tests = NCR53c8xx_run_tests;
902: /* Is the SCSI clock ever anything else on these chips? */
903: expected_clock = hostdata->scsi_clock = 40000000;
904: expected_id = 7;
905: break;
906: default:
907: printk ("scsi%d : chip type of %d is not supported yet, detaching.\n",
908: host->host_no, hostdata->chip);
909: scsi_unregister (host);
910: return -1;
911: }
912:
913: /* Assign constants accessed by NCR */
914: hostdata->NCR53c7xx_zero = 0;
915: hostdata->NCR53c7xx_msg_reject = MESSAGE_REJECT;
916: hostdata->NCR53c7xx_msg_abort = ABORT;
917: hostdata->NCR53c7xx_msg_nop = NOP;
918: hostdata->NOP_insn = (DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24;
919:
920: if (expected_mapping == -1 ||
921: (hostdata->options & (OPTION_MEMORY_MAPPED)) !=
922: (expected_mapping & OPTION_MEMORY_MAPPED))
923: printk ("scsi%d : using %s mapped access\n", host->host_no,
924: (hostdata->options & OPTION_MEMORY_MAPPED) ? "memory" :
925: "io");
926:
927: hostdata->dmode = (hostdata->chip == 700 || hostdata->chip == 70066) ?
928: DMODE_REG_00 : DMODE_REG_10;
929: hostdata->istat = ((hostdata->chip / 100) == 8) ?
930: ISTAT_REG_800 : ISTAT_REG_700;
931:
932: /* Only the ISTAT register is readable when the NCR is running, so make
933: sure it's halted. */
934: ncr_halt(host);
935:
936: /*
937: * XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc,
938: * as does the 710 with one bit per SCSI ID. Conversely, the NCR
939: * uses a normal, 3 bit binary representation of these values.
940: *
941: * Get the rest of the NCR documentation, and FIND OUT where the change
942: * was.
943: */
944: #if 0
945: tmp = hostdata->this_id_mask = NCR53c7x0_read8(SCID_REG);
946: for (host->this_id = 0; tmp != 1; tmp >>=1, ++host->this_id);
947: #else
948: host->this_id = NCR53c7x0_read8(SCID_REG) & 15;
949: if (host->this_id == 0)
950: host->this_id = 7; /* sanitize hostid---0 doesn't make sense */
951: hostdata->this_id_mask = 1 << host->this_id;
952: #endif
953:
954: /*
955: * Note : we should never encounter a board setup for ID0. So,
956: * if we see ID0, assume that it was uninitialized and set it
957: * to the industry standard 7.
958: */
959: if (!host->this_id) {
960: printk("scsi%d : initiator ID was %d, changing to 7\n",
961: host->host_no, host->this_id);
962: host->this_id = 7;
963: hostdata->this_id_mask = 1 << 7;
964: uninitialized = 1;
965: };
966:
967: if (expected_id == -1 || host->this_id != expected_id)
968: printk("scsi%d : using initiator ID %d\n", host->host_no,
969: host->this_id);
970:
971: /*
972: * Save important registers to allow a soft reset.
973: */
974:
975: if ((hostdata->chip / 100) == 8) {
976: /*
977: * CTEST4 controls burst mode disable.
978: */
979: hostdata->saved_ctest4 = NCR53c7x0_read8(CTEST4_REG_800) &
980: CTEST4_800_SAVE;
981: } else {
982: /*
983: * CTEST7 controls cache snooping, burst mode, and support for
984: * external differential drivers.
985: */
986: hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE;
987: }
988:
989: /*
990: * On NCR53c700 series chips, DCNTL controls the SCSI clock divisor,
991: * on 800 series chips, it allows for a totem-pole IRQ driver.
992: */
993:
994: hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);
995:
996: /*
997: * DCNTL_800_IRQM controls weather we are using an open drain
998: * driver (reset) or totem pole driver (set). In all cases,
999: * it's level active. I suppose this is an issue when we're trying to
1000: * wire-or the same PCI INTx line?
1001: */
1002: if ((hostdata->chip / 100) == 8)
1003: hostdata->saved_dcntl &= ~DCNTL_800_IRQM;
1004:
1005: /*
1006: * DMODE controls DMA burst length, and on 700 series chips,
1007: * 286 mode and bus width
1008: */
1009: hostdata->saved_dmode = NCR53c7x0_read8(hostdata->dmode);
1010:
1011: /*
1012: * Now that burst length and enabled/disabled status is known,
1013: * clue the user in on it.
1014: */
1015:
1016: if ((hostdata->chip / 100) == 8) {
1017: if (hostdata->saved_ctest4 & CTEST4_800_BDIS) {
1018: printk ("scsi%d : burst mode disabled\n", host->host_no);
1019: } else {
1020: switch (hostdata->saved_dmode & DMODE_BL_MASK) {
1021: case DMODE_BL_2: i = 2; break;
1022: case DMODE_BL_4: i = 4; break;
1023: case DMODE_BL_8: i = 8; break;
1024: case DMODE_BL_16: i = 16; break;
1025: default: i = 0;
1026: }
1027: printk ("scsi%d : burst length %d\n", host->host_no, i);
1028: }
1029: }
1030:
1031: /*
1032: * On NCR53c810 and NCR53c820 chips, SCNTL3 contails the synchronous
1033: * and normal clock conversion factors.
1034: */
1035: if (hostdata->chip / 100 == 8) {
1036: expected_ccf = clock_to_ccf (expected_clock);
1037: hostdata->saved_scntl3 = NCR53c7x0_read8(SCNTL3_REG_800);
1038: ccf = hostdata->saved_scntl3 & SCNTL3_800_CCF_MASK;
1039: if (expected_ccf != -1 && ccf != expected_ccf && !ccf) {
1040: hostdata->saved_scntl3 = (hostdata->saved_scntl3 &
1041: ~SCNTL3_800_CCF_MASK) | expected_ccf;
1042: if (!uninitialized) {
1043: printk ("scsi%d : reset ccf to %d from %d\n",
1044: host->host_no, expected_ccf, ccf);
1045: uninitialized = 1;
1046: }
1047: }
1048: } else
1049: ccf = 0;
1050:
1051: /*
1052: * If we don't have a SCSI clock programmed, pick one on the upper
1053: * bound of that allowed by NCR so that our transfers err on the
1054: * slow side, since transfer period must be >= the agreed
1055: * upon period.
1056: */
1057:
1058: if ((!hostdata->scsi_clock) && (hostdata->scsi_clock = ccf_to_clock (ccf))
1059: == -1) {
1060: printk ("scsi%d : clock conversion factor %d unknown.\n"
1061: " synchronous transfers disabled\n",
1062: host->host_no, ccf);
1063: hostdata->options &= ~OPTION_SYNCHRONOUS;
1064: hostdata->scsi_clock = 0;
1065: }
1066:
1067: if (expected_clock == -1 || hostdata->scsi_clock != expected_clock)
1068: printk ("scsi%d : using %dMHz SCSI clock\n", host->host_no,
1069: hostdata->scsi_clock / 1000000);
1070:
1071: for (i = 0; i < 16; ++i)
1072: hostdata->cmd_allocated[i] = 0;
1073:
1074: if (hostdata->init_save_regs)
1075: hostdata->init_save_regs (host);
1076: if (hostdata->init_fixup)
1077: hostdata->init_fixup (host);
1078:
1079: if (!the_template) {
1080: the_template = host->hostt;
1081: first_host = host;
1082: }
1083:
1084: /*
1085: * Linux SCSI drivers have always been plagued with initialization
1086: * problems - some didn't work with the BIOS disabled since they expected
1087: * initialization from it, some didn't work when the networking code
1088: * was enabled and registers got scrambled, etc.
1089: *
1090: * To avoid problems like this, in the future, we will do a soft
1091: * reset on the SCSI chip, taking it back to a sane state.
1092: */
1093:
1094: hostdata->soft_reset (host);
1095:
1096: #if 1
1097: hostdata->debug_count_limit = -1;
1098: #else
1099: hostdata->debug_count_limit = 1;
1100: #endif
1101: hostdata->intrs = -1;
1102: hostdata->resets = -1;
1103: memcpy ((void *) hostdata->synchronous_want, (void *) sdtr_message,
1104: sizeof (hostdata->synchronous_want));
1105:
1106: NCR53c7x0_driver_init (host);
1107:
1108: /*
1109: * Set up an interrupt handler if we aren't already sharing an IRQ
1110: * with another board.
1111: */
1112:
1113: for (search = first_host; search && !(search->hostt == the_template &&
1114: search->irq == host->irq && search != host); search=search->next);
1115:
1116: if (!search) {
1117: if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) {
1118: printk("scsi%d : IRQ%d not free, detaching\n"
1119: " You have either a configuration problem, or a\n"
1120: " broken BIOS. You may wish to manually assign\n"
1121: " an interrupt to the NCR board rather than using\n"
1122: " an automatic setting.\n",
1123: host->host_no, host->irq);
1124: scsi_unregister (host);
1125: return -1;
1126: }
1127: } else {
1128: printk("scsi%d : using interrupt handler previously installed for scsi%d\n",
1129: host->host_no, search->host_no);
1130: }
1131:
1132:
1133: if ((hostdata->run_tests && hostdata->run_tests(host) == -1) ||
1134: (hostdata->options & OPTION_DEBUG_TESTS_ONLY)) {
1135: /* XXX Should disable interrupts, etc. here */
1136: scsi_unregister (host);
1137: return -1;
1138: } else {
1139: if (host->io_port) {
1140: host->n_io_port = 128;
1141: request_region (host->io_port, host->n_io_port, "ncr53c7,8xx");
1142: }
1143: }
1144:
1145: if (NCR53c7x0_read8 (SBCL_REG) & SBCL_BSY) {
1146: printk ("scsi%d : bus wedge, doing SCSI reset\n", host->host_no);
1147: hard_reset (host);
1148: }
1149: return 0;
1150: }
1151:
1152: /*
1153: * Function : static int normal_init(Scsi_Host_Template *tpnt, int board,
1154: * int chip, u32 base, int io_port, int irq, int dma, int pcivalid,
1155: * unsigned char pci_bus, unsigned char pci_device_fn,
1156: * long long options);
1157: *
1158: * Purpose : initializes a NCR53c7,8x0 based on base addresses,
1159: * IRQ, and DMA channel.
1160: *
1161: * Useful where a new NCR chip is backwards compatible with
1162: * a supported chip, but the DEVICE ID has changed so it
1163: * doesn't show up when the autoprobe does a pcibios_find_device.
1164: *
1165: * Inputs : tpnt - Template for this SCSI adapter, board - board level
1166: * product, chip - 810, 820, or 825, bus - PCI bus, device_fn -
1167: * device and function encoding as used by PCI BIOS calls.
1168: *
1169: * Returns : 0 on success, -1 on failure.
1170: *
1171: */
1172:
1173: static int
1174: normal_init (Scsi_Host_Template *tpnt, int board, int chip,
1175: u32 base, int io_port, int irq, int dma, int pci_valid,
1176: unsigned char pci_bus, unsigned char pci_device_fn, long long options) {
1177: struct Scsi_Host *instance;
1178: struct NCR53c7x0_hostdata *hostdata;
1179: char chip_str[80];
1180: int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0,
1181: schedule_size = 0, ok = 0;
1182: void *tmp;
1183:
1184: options |= perm_options;
1185:
1186: switch (chip) {
1187: case 825:
1188: case 820:
1189: case 815:
1190: case 810:
1191: schedule_size = (tpnt->can_queue + 1) * 8 /* JUMP instruction size */;
1192: script_len = NCR53c8xx_script_len;
1193: dsa_len = NCR53c8xx_dsa_len;
1194: options |= OPTION_INTFLY;
1195: sprintf (chip_str, "NCR53c%d", chip);
1196: break;
1197: default:
1198: printk("scsi-ncr53c7,8xx : unsupported SCSI chip %d\n", chip);
1199: return -1;
1200: }
1201:
1202: printk("scsi-ncr53c7,8xx : %s at memory 0x%x, io 0x%x, irq %d",
1203: chip_str, (unsigned) base, io_port, irq);
1204: if (dma == DMA_NONE)
1205: printk("\n");
1206: else
1207: printk(", dma %d\n", dma);
1208:
1209: if ((chip / 100 == 8) && !pci_valid)
1210: printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n"
1211: " PCI override instead.\n"
1212: " Syntax : ncr53c8{10,15,20,25}=pci,<bus>,<device>,<function>\n"
1213: " <bus> and <device> are usually 0.\n");
1214:
1215: if (options & OPTION_DEBUG_PROBE_ONLY) {
1216: printk ("scsi-ncr53c7,8xx : probe only enabled, aborting initialization\n");
1217: return -1;
1218: }
1219:
1220: max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len +
1221: /* Size of dynamic part of command structure : */
1222: 2 * /* Worst case : we don't know if we need DATA IN or DATA out */
1223: ( 2 * /* Current instructions per scatter/gather segment */
1224: tpnt->sg_tablesize +
1225: 3 /* Current startup / termination required per phase */
1226: ) *
1227: 8 /* Each instruction is eight bytes */;
1228:
1229: /* Allocate fixed part of hostdata, dynamic part to hold appropriate
1230: SCSI SCRIPT(tm) plus a single, maximum-sized NCR53c7x0_cmd structure.
1231:
1232: We need a NCR53c7x0_cmd structure for scan_scsis() when we are
1233: not loaded as a module, and when we're loaded as a module, we
1234: can't use a non-dynamically allocated structure because modules
1235: are vmalloc()'d, which can allow structures to cross page
1236: boundaries and breaks our physical/virtual address assumptions
1237: for DMA.
1238:
1239: So, we stick it past the end of our hostdata structure.
1240:
1241: ASSUMPTION :
1242: Regardless of how many simultaneous SCSI commands we allow,
1243: the probe code only executes a _single_ instruction at a time,
1244: so we only need one here, and don't need to allocate NCR53c7x0_cmd
1245: structures for each target until we are no longer in scan_scsis
1246: and kmalloc() has become functional (memory_init() happens
1247: after all device driver initialization).
1248: */
1249:
1250: size = sizeof(struct NCR53c7x0_hostdata) + script_len +
1251: /* Note that alignment will be guaranteed, since we put the command
1252: allocated at probe time after the fixed-up SCSI script, which
1253: consists of 32 bit words, aligned on a 32 bit boundary. But
1254: on a 64bit machine we need 8 byte alignment for hostdata->free, so
1255: we add in another 4 bytes to take care of potential misalignment
1256: */
1257: (sizeof(void *) - sizeof(u32)) + max_cmd_size + schedule_size;
1258:
1259: instance = scsi_register (tpnt, size);
1260: if (!instance)
1261: return -1;
1262:
1263: /* FIXME : if we ever support an ISA NCR53c7xx based board, we
1264: need to check if the chip is running in a 16 bit mode, and if so
1265: unregister it if it is past the 16M (0x1000000) mark */
1266:
1267: hostdata = (struct NCR53c7x0_hostdata *)
1268: instance->hostdata;
1269: hostdata->size = size;
1270: hostdata->script_count = script_len / sizeof(u32);
1271: hostdata = (struct NCR53c7x0_hostdata *) instance->hostdata;
1272: hostdata->board = board;
1273: hostdata->chip = chip;
1274: if ((hostdata->pci_valid = pci_valid)) {
1275: hostdata->pci_bus = pci_bus;
1276: hostdata->pci_device_fn = pci_device_fn;
1277: }
1278:
1279: /*
1280: * Being memory mapped is more desirable, since
1281: *
1282: * - Memory accesses may be faster.
1283: *
1284: * - The destination and source address spaces are the same for
1285: * all instructions, meaning we don't have to twiddle dmode or
1286: * any other registers.
1287: *
1288: * So, we try for memory mapped, and if we don't get it,
1289: * we go for port mapped, and that failing we tell the user
1290: * it can't work.
1291: */
1292:
1293: if (base) {
1294: instance->base = (unsigned char *) (unsigned long) base;
1295: /* Check for forced I/O mapping */
1296: if (!(options & OPTION_IO_MAPPED)) {
1297: options |= OPTION_MEMORY_MAPPED;
1298: ok = 1;
1299: }
1300: } else {
1301: options &= ~OPTION_MEMORY_MAPPED;
1302: }
1303:
1304: if (io_port) {
1305: instance->io_port = io_port;
1306: options |= OPTION_IO_MAPPED;
1307: ok = 1;
1308: } else {
1309: options &= ~OPTION_IO_MAPPED;
1310: }
1311:
1312: if (!ok) {
1313: printk ("scsi%d : not initializing, no I/O or memory mapping known \n",
1314: instance->host_no);
1315: scsi_unregister (instance);
1316: return -1;
1317: }
1318: instance->irq = irq;
1319: instance->dma_channel = dma;
1320:
1321: hostdata->options = options;
1322: hostdata->dsa_len = dsa_len;
1323: hostdata->max_cmd_size = max_cmd_size;
1324: hostdata->num_cmds = 1;
1325: /* Initialize single command */
1326: tmp = (hostdata->script + hostdata->script_count);
1327: hostdata->free = ROUNDUP(tmp, void *);
1328: hostdata->free->real = tmp;
1329: hostdata->free->size = max_cmd_size;
1330: hostdata->free->free = NULL;
1331: hostdata->free->next = NULL;
1332: hostdata->extra_allocate = 0;
1333:
1334: /* Allocate command start code space */
1335: hostdata->schedule = (chip == 700 || chip == 70066) ?
1336: NULL : (u32 *) ((char *)hostdata->free + max_cmd_size);
1337:
1338: /*
1339: * For diagnostic purposes, we don't really care how fast things blaze.
1340: * For profiling, we want to access the 800ns resolution system clock,
1341: * using a 'C' call on the host processor.
1342: *
1343: * Therefore, there's no need for the NCR chip to directly manipulate
1344: * this data, and we should put it wherever is most convienient for
1345: * Linux.
1346: */
1347: if (track_events)
1348: hostdata->events = (struct NCR53c7x0_event *) (track_events ?
1349: vmalloc (sizeof (struct NCR53c7x0_event) * track_events) : NULL);
1350: else
1351: hostdata->events = NULL;
1352:
1353: if (hostdata->events) {
1354: memset ((void *) hostdata->events, 0, sizeof(struct NCR53c7x0_event) *
1355: track_events);
1356: hostdata->event_size = track_events;
1357: hostdata->event_index = 0;
1358: } else
1359: hostdata->event_size = 0;
1360:
1361: return NCR53c7x0_init(instance);
1362: }
1363:
1364:
1365: /*
1366: * Function : static int ncr_pci_init(Scsi_Host_Template *tpnt, int board,
1367: * int chip, int bus, int device_fn, long long options)
1368: *
1369: * Purpose : initializes a NCR53c800 family based on the PCI
1370: * bus, device, and function location of it. Allows
1371: * reprogramming of latency timer and determining addresses
1372: * and whether bus mastering, etc. are OK.
1373: *
1374: * Useful where a new NCR chip is backwards compatible with
1375: * a supported chip, but the DEVICE ID has changed so it
1376: * doesn't show up when the autoprobe does a pcibios_find_device.
1377: *
1378: * Inputs : tpnt - Template for this SCSI adapter, board - board level
1379: * product, chip - 810, 820, or 825, bus - PCI bus, device_fn -
1380: * device and function encoding as used by PCI BIOS calls.
1381: *
1382: * Returns : 0 on success, -1 on failure.
1383: *
1384: */
1385:
1386: static int
1387: ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip,
1388: unsigned char bus, unsigned char device_fn, long long options) {
1389: unsigned short vendor_id, device_id, command;
1390: #ifdef LINUX_1_2
1391: unsigned long
1392: #else
1393: unsigned int
1394: #endif
1395: base, io_port;
1396: unsigned char irq, revision;
1397: int error, expected_chip;
1398: int expected_id = -1, max_revision = -1, min_revision = -1;
1399: int i;
1400:
1401: printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d, function %d\n",
1402: bus, (int) (device_fn & 0xf8) >> 3,
1403: (int) device_fn & 7);
1404:
1405: if (!pcibios_present()) {
1406: printk("scsi-ncr53c7,8xx : not initializing due to lack of PCI BIOS,\n"
1407: " try using memory, port, irq override instead.\n");
1408: return -1;
1409: }
1410:
1411: if ((error = pcibios_read_config_word (bus, device_fn, PCI_VENDOR_ID,
1412: &vendor_id)) ||
1413: (error = pcibios_read_config_word (bus, device_fn, PCI_DEVICE_ID,
1414: &device_id)) ||
1415: (error = pcibios_read_config_word (bus, device_fn, PCI_COMMAND,
1416: &command)) ||
1417: (error = pcibios_read_config_dword (bus, device_fn,
1418: PCI_BASE_ADDRESS_0, &io_port)) ||
1419: (error = pcibios_read_config_dword (bus, device_fn,
1420: PCI_BASE_ADDRESS_1, &base)) ||
1421: (error = pcibios_read_config_byte (bus, device_fn, PCI_CLASS_REVISION,
1422: &revision)) ||
1423: (error = pcibios_read_config_byte (bus, device_fn, PCI_INTERRUPT_LINE,
1424: &irq))) {
1425: printk ("scsi-ncr53c7,8xx : error %s not initializing due to error reading configuration space\n"
1426: " perhaps you specified an incorrect PCI bus, device, or function.\n"
1427: , pcibios_strerror(error));
1428: return -1;
1429: }
1430:
1431: /* If any one ever clones the NCR chips, this will have to change */
1432:
1433: if (vendor_id != PCI_VENDOR_ID_NCR) {
1434: printk ("scsi-ncr53c7,8xx : not initializing, 0x%04x is not NCR vendor ID\n",
1435: (int) vendor_id);
1436: return -1;
1437: }
1438:
1439:
1440: /*
1441: * Bit 0 is the address space indicator and must be one for I/O
1442: * space mappings, bit 1 is reserved, discard them after checking
1443: * that they have the correct value of 1.
1444: */
1445:
1446: if (command & PCI_COMMAND_IO) {
1447: if ((io_port & 3) != 1) {
1448: printk ("scsi-ncr53c7,8xx : disabling I/O mapping since base address 0 (0x%x)\n"
1449: " bits 0..1 indicate a non-IO mapping\n",
1450: (unsigned) io_port);
1451: io_port = 0;
1452: } else
1453: io_port &= PCI_BASE_ADDRESS_IO_MASK;
1454: } else {
1455: io_port = 0;
1456: }
1457:
1458: if (command & PCI_COMMAND_MEMORY) {
1459: if ((base & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {
1460: printk("scsi-ncr53c7,8xx : disabling memory mapping since base address 1\n"
1461: " contains a non-memory mapping\n");
1462: base = 0;
1463: } else
1464: base &= PCI_BASE_ADDRESS_MEM_MASK;
1465: } else {
1466: base = 0;
1467: }
1468:
1469: if (!io_port && !base) {
1470: printk ("scsi-ncr53c7,8xx : not initializing, both I/O and memory mappings disabled\n");
1471: return -1;
1472: }
1473:
1474: if (!(command & PCI_COMMAND_MASTER)) {
1475: printk ("scsi-ncr53c7,8xx : not initializing, BUS MASTERING was disabled\n");
1476: return -1;
1477: }
1478:
1479: for (i = 0; i < NPCI_CHIP_IDS; ++i) {
1480: if (device_id == pci_chip_ids[i].pci_device_id) {
1481: max_revision = pci_chip_ids[i].max_revision;
1482: min_revision = pci_chip_ids[i].min_revision;
1483: expected_chip = pci_chip_ids[i].chip;
1484: }
1485: if (chip == pci_chip_ids[i].chip)
1486: expected_id = pci_chip_ids[i].pci_device_id;
1487: }
1488:
1489: if (chip && device_id != expected_id)
1490: printk ("scsi-ncr53c7,8xx : warning : device id of 0x%04x doesn't\n"
1491: " match expected 0x%04x\n",
1492: (unsigned int) device_id, (unsigned int) expected_id );
1493:
1494: if (max_revision != -1 && revision > max_revision)
1495: printk ("scsi-ncr53c7,8xx : warning : revision of %d is greater than %d.\n",
1496: (int) revision, max_revision);
1497: else if (min_revision != -1 && revision < min_revision)
1498: printk ("scsi-ncr53c7,8xx : warning : revision of %d is less than %d.\n",
1499: (int) revision, min_revision);
1500:
1501: if (io_port && check_region (io_port, 128)) {
1502: printk ("scsi-ncr53c7,8xx : IO region 0x%x to 0x%x is in use\n",
1503: (unsigned) io_port, (unsigned) io_port + 127);
1504: return -1;
1505: }
1506:
1507: return normal_init (tpnt, board, chip, (int) base, io_port,
1508: (int) irq, DMA_NONE, 1, bus, device_fn, options);
1509: }
1510:
1511:
1512: /*
1513: * Function : int NCR53c7xx_detect(Scsi_Host_Template *tpnt)
1514: *
1515: * Purpose : detects and initializes NCR53c7,8x0 SCSI chips
1516: * that were autoprobed, overridden on the LILO command line,
1517: * or specified at compile time.
1518: *
1519: * Inputs : tpnt - template for this SCSI adapter
1520: *
1521: * Returns : number of host adapters detected
1522: *
1523: */
1524:
1525: int
1526: NCR53c7xx_detect(Scsi_Host_Template *tpnt) {
1527: int i;
1528: int current_override;
1529: int count; /* Number of boards detected */
1530: unsigned char pci_bus, pci_device_fn;
1531: static short pci_index=0; /* Device index to PCI BIOS calls */
1532:
1533: #ifndef LINUX_1_2
1534: tpnt->proc_dir = &proc_scsi_ncr53c7xx;
1535: #endif
1536:
1537: for (current_override = count = 0; current_override < OVERRIDE_LIMIT;
1538: ++current_override) {
1539: if (overrides[current_override].pci ?
1540: !ncr_pci_init (tpnt, overrides[current_override].board,
1541: overrides[current_override].chip,
1542: (unsigned char) overrides[current_override].data.pci.bus,
1543: (((overrides[current_override].data.pci.device
1544: << 3) & 0xf8)|(overrides[current_override].data.pci.function &
1545: 7)), overrides[current_override].options):
1546: !normal_init (tpnt, overrides[current_override].board,
1547: overrides[current_override].chip,
1548: overrides[current_override].data.normal.base,
1549: overrides[current_override].data.normal.io_port,
1550: overrides[current_override].data.normal.irq,
1551: overrides[current_override].data.normal.dma,
1552: 0 /* PCI data invalid */, 0 /* PCI bus place holder */,
1553: 0 /* PCI device_function place holder */,
1554: overrides[current_override].options)) {
1555: ++count;
1556: }
1557: }
1558:
1559: if (pcibios_present()) {
1560: for (i = 0; i < NPCI_CHIP_IDS; ++i)
1561: for (pci_index = 0;
1562: !pcibios_find_device (PCI_VENDOR_ID_NCR,
1563: pci_chip_ids[i].pci_device_id, pci_index, &pci_bus,
1564: &pci_device_fn);
1565: ++pci_index)
1566: if (!ncr_pci_init (tpnt, BOARD_GENERIC, pci_chip_ids[i].chip,
1567: pci_bus, pci_device_fn, /* no options */ 0))
1568: ++count;
1569: }
1570: return count;
1571: }
1572:
1573: /* NCR53c810 and NCR53c820 script handling code */
1574:
1575: #include "53c8xx_d.h"
1576: #ifdef A_int_debug_sync
1577: #define DEBUG_SYNC_INTR A_int_debug_sync
1578: #endif
1579: static int NCR53c8xx_script_len = sizeof (SCRIPT);
1580: static int NCR53c8xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;
1581:
1582: /*
1583: * Function : static void NCR53c8x0_init_fixup (struct Scsi_Host *host)
1584: *
1585: * Purpose : copy and fixup the SCSI SCRIPTS(tm) code for this device.
1586: *
1587: * Inputs : host - pointer to this host adapter's structure
1588: *
1589: */
1590:
1591: static void
1592: NCR53c8x0_init_fixup (struct Scsi_Host *host) {
1593: NCR53c7x0_local_declare();
1594: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1595: host->hostdata;
1596: unsigned char tmp;
1597: int i, ncr_to_memory, memory_to_ncr;
1598: u32 base;
1599: NCR53c7x0_local_setup(host);
1600:
1601:
1602: /* XXX - NOTE : this code MUST be made endian aware */
1603: /* Copy code into buffer that was allocated at detection time. */
1604: memcpy ((void *) hostdata->script, (void *) SCRIPT,
1605: sizeof(SCRIPT));
1606: /* Fixup labels */
1607: for (i = 0; i < PATCHES; ++i)
1608: hostdata->script[LABELPATCHES[i]] +=
1609: virt_to_bus(hostdata->script);
1610: /* Fixup addresses of constants that used to be EXTERNAL */
1611:
1612: patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort,
1613: virt_to_bus(&(hostdata->NCR53c7xx_msg_abort)));
1614: patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject,
1615: virt_to_bus(&(hostdata->NCR53c7xx_msg_reject)));
1616: patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero,
1617: virt_to_bus(&(hostdata->NCR53c7xx_zero)));
1618: patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink,
1619: virt_to_bus(&(hostdata->NCR53c7xx_sink)));
1620: patch_abs_32 (hostdata->script, 0, NOP_insn,
1621: virt_to_bus(&(hostdata->NOP_insn)));
1622: patch_abs_32 (hostdata->script, 0, schedule,
1623: virt_to_bus((void *) hostdata->schedule));
1624:
1625: /* Fixup references to external variables: */
1626: for (i = 0; i < EXTERNAL_PATCHES_LEN; ++i)
1627: hostdata->script[EXTERNAL_PATCHES[i].offset] +=
1628: virt_to_bus(EXTERNAL_PATCHES[i].address);
1629:
1630: /*
1631: * Fixup absolutes set at boot-time.
1632: *
1633: * All non-code absolute variables suffixed with "dsa_" and "int_"
1634: * are constants, and need no fixup provided the assembler has done
1635: * it for us (I don't know what the "real" NCR assembler does in
1636: * this case, my assembler does the right magic).
1637: */
1638:
1639: patch_abs_rwri_data (hostdata->script, 0, dsa_save_data_pointer,
1640: Ent_dsa_code_save_data_pointer - Ent_dsa_zero);
1641: patch_abs_rwri_data (hostdata->script, 0, dsa_restore_pointers,
1642: Ent_dsa_code_restore_pointers - Ent_dsa_zero);
1643: patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect,
1644: Ent_dsa_code_check_reselect - Ent_dsa_zero);
1645:
1646: /*
1647: * Just for the hell of it, preserve the settings of
1648: * Burst Length and Enable Read Line bits from the DMODE
1649: * register. Make sure SCRIPTS start automagically.
1650: */
1651:
1652: tmp = NCR53c7x0_read8(DMODE_REG_10);
1653: tmp &= (DMODE_800_ERL | DMODE_BL_MASK);
1654:
1655: if (!(hostdata->options & OPTION_MEMORY_MAPPED)) {
1656: base = (u32) host->io_port;
1657: memory_to_ncr = tmp|DMODE_800_DIOM;
1658: ncr_to_memory = tmp|DMODE_800_SIOM;
1659: } else {
1660: base = virt_to_bus(host->base);
1661: memory_to_ncr = ncr_to_memory = tmp;
1662: }
1663:
1664: patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);
1665: patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);
1666:
1667: /*
1668: * I needed some variables in the script to be accessible to
1669: * both the NCR chip and the host processor. For these variables,
1670: * I made the arbitrary decision to store them directly in the
1671: * hostdata structure rather than in the RELATIVE area of the
1672: * SCRIPTS.
1673: */
1674:
1675:
1676: patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp);
1677: patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr);
1678: patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);
1679:
1680: patch_abs_32 (hostdata->script, 0, msg_buf,
1681: virt_to_bus((void *)&(hostdata->msg_buf)));
1682: patch_abs_32 (hostdata->script, 0, reconnect_dsa_head,
1683: virt_to_bus((void *)&(hostdata->reconnect_dsa_head)));
1684: patch_abs_32 (hostdata->script, 0, addr_reconnect_dsa_head,
1685: virt_to_bus((void *)&(hostdata->addr_reconnect_dsa_head)));
1686: patch_abs_32 (hostdata->script, 0, reselected_identify,
1687: virt_to_bus((void *)&(hostdata->reselected_identify)));
1688: /* reselected_tag is currently unused */
1689: #if 0
1690: patch_abs_32 (hostdata->script, 0, reselected_tag,
1691: virt_to_bus((void *)&(hostdata->reselected_tag)));
1692: #endif
1693:
1694: patch_abs_32 (hostdata->script, 0, test_dest,
1695: virt_to_bus((void*)&hostdata->test_dest));
1696: patch_abs_32 (hostdata->script, 0, test_src,
1697: virt_to_bus(&hostdata->test_source));
1698:
1699: patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect,
1700: (unsigned char)(Ent_dsa_code_check_reselect - Ent_dsa_zero));
1701:
1702: /* These are for event logging; the ncr_event enum contains the
1703: actual interrupt numbers. */
1704: #ifdef A_int_EVENT_SELECT
1705: patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT, (u32) EVENT_SELECT);
1706: #endif
1707: #ifdef A_int_EVENT_DISCONNECT
1708: patch_abs_32 (hostdata->script, 0, int_EVENT_DISCONNECT, (u32) EVENT_DISCONNECT);
1709: #endif
1710: #ifdef A_int_EVENT_RESELECT
1711: patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT, (u32) EVENT_RESELECT);
1712: #endif
1713: #ifdef A_int_EVENT_COMPLETE
1714: patch_abs_32 (hostdata->script, 0, int_EVENT_COMPLETE, (u32) EVENT_COMPLETE);
1715: #endif
1716: #ifdef A_int_EVENT_IDLE
1717: patch_abs_32 (hostdata->script, 0, int_EVENT_IDLE, (u32) EVENT_IDLE);
1718: #endif
1719: #ifdef A_int_EVENT_SELECT_FAILED
1720: patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT_FAILED,
1721: (u32) EVENT_SELECT_FAILED);
1722: #endif
1723: #ifdef A_int_EVENT_BEFORE_SELECT
1724: patch_abs_32 (hostdata->script, 0, int_EVENT_BEFORE_SELECT,
1725: (u32) EVENT_BEFORE_SELECT);
1726: #endif
1727: #ifdef A_int_EVENT_RESELECT_FAILED
1728: patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT_FAILED,
1729: (u32) EVENT_RESELECT_FAILED);
1730: #endif
1731:
1732: /*
1733: * Make sure the NCR and Linux code agree on the location of
1734: * certain fields.
1735: */
1736:
1737: hostdata->E_accept_message = Ent_accept_message;
1738: hostdata->E_command_complete = Ent_command_complete;
1739: hostdata->E_cmdout_cmdout = Ent_cmdout_cmdout;
1740: hostdata->E_data_transfer = Ent_data_transfer;
1741: hostdata->E_debug_break = Ent_debug_break;
1742: hostdata->E_dsa_code_template = Ent_dsa_code_template;
1743: hostdata->E_dsa_code_template_end = Ent_dsa_code_template_end;
1744: hostdata->E_end_data_transfer = Ent_end_data_transfer;
1745: hostdata->E_initiator_abort = Ent_initiator_abort;
1746: hostdata->E_msg_in = Ent_msg_in;
1747: hostdata->E_other_transfer = Ent_other_transfer;
1748: hostdata->E_other_in = Ent_other_in;
1749: hostdata->E_other_out = Ent_other_out;
1750: hostdata->E_reject_message = Ent_reject_message;
1751: hostdata->E_respond_message = Ent_respond_message;
1752: hostdata->E_select = Ent_select;
1753: hostdata->E_select_msgout = Ent_select_msgout;
1754: hostdata->E_target_abort = Ent_target_abort;
1755: #ifdef Ent_test_0
1756: hostdata->E_test_0 = Ent_test_0;
1757: #endif
1758: hostdata->E_test_1 = Ent_test_1;
1759: hostdata->E_test_2 = Ent_test_2;
1760: #ifdef Ent_test_3
1761: hostdata->E_test_3 = Ent_test_3;
1762: #endif
1763: hostdata->E_wait_reselect = Ent_wait_reselect;
1764: hostdata->E_dsa_code_begin = Ent_dsa_code_begin;
1765:
1766: hostdata->dsa_cmdout = A_dsa_cmdout;
1767: hostdata->dsa_cmnd = A_dsa_cmnd;
1768: hostdata->dsa_datain = A_dsa_datain;
1769: hostdata->dsa_dataout = A_dsa_dataout;
1770: hostdata->dsa_end = A_dsa_end;
1771: hostdata->dsa_msgin = A_dsa_msgin;
1772: hostdata->dsa_msgout = A_dsa_msgout;
1773: hostdata->dsa_msgout_other = A_dsa_msgout_other;
1774: hostdata->dsa_next = A_dsa_next;
1775: hostdata->dsa_select = A_dsa_select;
1776: hostdata->dsa_start = Ent_dsa_code_template - Ent_dsa_zero;
1777: hostdata->dsa_status = A_dsa_status;
1778: hostdata->dsa_jump_dest = Ent_dsa_code_fix_jump - Ent_dsa_zero +
1779: 8 /* destination operand */;
1780:
1781: /* sanity check */
1782: if (A_dsa_fields_start != Ent_dsa_code_template_end -
1783: Ent_dsa_zero)
1784: printk("scsi%d : NCR dsa_fields start is %d not %d\n",
1785: host->host_no, A_dsa_fields_start, Ent_dsa_code_template_end -
1786: Ent_dsa_zero);
1787:
1788: printk("scsi%d : NCR code relocated to 0x%lx (virt 0x%p)\n", host->host_no,
1789: virt_to_bus(hostdata->script), hostdata->script);
1790: }
1791:
1792: /*
1793: * Function : static int NCR53c8xx_run_tests (struct Scsi_Host *host)
1794: *
1795: * Purpose : run various verification tests on the NCR chip,
1796: * including interrupt generation, and proper bus mastering
1797: * operation.
1798: *
1799: * Inputs : host - a properly initialized Scsi_Host structure
1800: *
1801: * Preconditions : the NCR chip must be in a halted state.
1802: *
1803: * Returns : 0 if all tests were successful, -1 on error.
1804: *
1805: */
1806:
1807: static int
1808: NCR53c8xx_run_tests (struct Scsi_Host *host) {
1809: NCR53c7x0_local_declare();
1810: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1811: host->hostdata;
1812: unsigned long timeout;
1813: u32 start;
1814: int failed, i;
1815: unsigned long flags;
1816: NCR53c7x0_local_setup(host);
1817:
1818: /* The NCR chip _must_ be idle to run the test scripts */
1819:
1820: save_flags(flags);
1821: cli();
1822: if (!hostdata->idle) {
1823: printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
1824: restore_flags(flags);
1825: return -1;
1826: }
1827:
1828: /*
1829: * Check for functional interrupts, this could work as an
1830: * autoprobe routine.
1831: */
1832:
1833: if ((hostdata->options & OPTION_DEBUG_TEST1) &&
1834: hostdata->state != STATE_DISABLED) {
1835: hostdata->idle = 0;
1836: hostdata->test_running = 1;
1837: hostdata->test_completed = -1;
1838: hostdata->test_dest = 0;
1839: hostdata->test_source = 0xdeadbeef;
1840: start = virt_to_bus (hostdata->script) + hostdata->E_test_1;
1841: hostdata->state = STATE_RUNNING;
1842: printk ("scsi%d : test 1", host->host_no);
1843: NCR53c7x0_write32 (DSP_REG, start);
1844: printk (" started\n");
1845: sti();
1846:
1847: /*
1848: * This is currently a .5 second timeout, since (in theory) no slow
1849: * board will take that long. In practice, we've seen one
1850: * pentium which ocassionally fails with this, but works with
1851: * 10 times as much?
1852: */
1853:
1854: timeout = jiffies + 5 * HZ / 10;
1855: while ((hostdata->test_completed == -1) && jiffies < timeout)
1856: barrier();
1857:
1858: failed = 1;
1859: if (hostdata->test_completed == -1)
1860: printk ("scsi%d : driver test 1 timed out%s\n",host->host_no ,
1861: (hostdata->test_dest == 0xdeadbeef) ?
1862: " due to lost interrupt.\n"
1863: " Please verify that the correct IRQ is being used for your board,\n"
1864: " and that the motherboard IRQ jumpering matches the PCI setup on\n"
1865: " PCI systems.\n"
1866: " If you are using a NCR53c810 board in a PCI system, you should\n"
1867: " also verify that the board is jumpered to use PCI INTA, since\n"
1868: " most PCI motherboards lack support for INTB, INTC, and INTD.\n"
1869: : "");
1870: else if (hostdata->test_completed != 1)
1871: printk ("scsi%d : test 1 bad interrupt value (%d)\n",
1872: host->host_no, hostdata->test_completed);
1873: else
1874: failed = (hostdata->test_dest != 0xdeadbeef);
1875:
1876: if (hostdata->test_dest != 0xdeadbeef) {
1877: printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n"
1878: " probable cache invalidation problem. Please configure caching\n"
1879: " as write-through or disabled\n",
1880: host->host_no, hostdata->test_dest);
1881: }
1882:
1883: if (failed) {
1884: printk ("scsi%d : DSP = 0x%p (script at 0x%p, start at 0x%x)\n",
1885: host->host_no, bus_to_virt(NCR53c7x0_read32(DSP_REG)),
1886: hostdata->script, start);
1887: printk ("scsi%d : DSPS = 0x%x\n", host->host_no,
1888: NCR53c7x0_read32(DSPS_REG));
1889: restore_flags(flags);
1890: return -1;
1891: }
1892: hostdata->test_running = 0;
1893: }
1894:
1895: if ((hostdata->options & OPTION_DEBUG_TEST2) &&
1896: hostdata->state != STATE_DISABLED) {
1897: u32 dsa[48];
1898: unsigned char identify = IDENTIFY(0, 0);
1899: unsigned char cmd[6];
1900: unsigned char data[36];
1901: unsigned char status = 0xff;
1902: unsigned char msg = 0xff;
1903:
1904: cmd[0] = INQUIRY;
1905: cmd[1] = cmd[2] = cmd[3] = cmd[5] = 0;
1906: cmd[4] = sizeof(data);
1907:
1908: dsa[2] = 1;
1909: dsa[3] = virt_to_bus(&identify);
1910: dsa[4] = 6;
1911: dsa[5] = virt_to_bus(&cmd);
1912: dsa[6] = sizeof(data);
1913: dsa[7] = virt_to_bus(&data);
1914: dsa[8] = 1;
1915: dsa[9] = virt_to_bus(&status);
1916: dsa[10] = 1;
1917: dsa[11] = virt_to_bus(&msg);
1918:
1919: for (i = 0; i < 3; ++i) {
1920: cli();
1921: if (!hostdata->idle) {
1922: printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
1923: restore_flags(flags);
1924: return -1;
1925: }
1926:
1927: /* SCNTL3 SDID */
1928: dsa[0] = (0x33 << 24) | (i << 16) ;
1929: hostdata->idle = 0;
1930: hostdata->test_running = 2;
1931: hostdata->test_completed = -1;
1932: start = virt_to_bus(hostdata->script) + hostdata->E_test_2;
1933: hostdata->state = STATE_RUNNING;
1934: NCR53c7x0_write32 (DSA_REG, virt_to_bus(dsa));
1935: NCR53c7x0_write32 (DSP_REG, start);
1936: sti();
1937:
1938: timeout = jiffies + 5 * HZ; /* arbitrary */
1939: while ((hostdata->test_completed == -1) && jiffies < timeout)
1940: barrier();
1941: NCR53c7x0_write32 (DSA_REG, 0);
1942:
1943: if (hostdata->test_completed == 2) {
1944: data[35] = 0;
1945: printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n",
1946: host->host_no, i, data + 8);
1947: printk ("scsi%d : status ", host->host_no);
1948: print_status (status);
1949: printk ("\nscsi%d : message ", host->host_no);
1950: print_msg (&msg);
1951: printk ("\n");
1952: } else if (hostdata->test_completed == 3) {
1953: printk("scsi%d : test 2 no connection with target %d\n",
1954: host->host_no, i);
1955: if (!hostdata->idle) {
1956: printk("scsi%d : not idle\n", host->host_no);
1957: restore_flags(flags);
1958: return -1;
1959: }
1960: } else if (hostdata->test_completed == -1) {
1961: printk ("scsi%d : test 2 timed out\n", host->host_no);
1962: restore_flags(flags);
1963: return -1;
1964: }
1965: hostdata->test_running = 0;
1966: }
1967: }
1968:
1969: restore_flags(flags);
1970: return 0;
1971: }
1972:
1973: /*
1974: * Function : static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd)
1975: *
1976: * Purpose : copy the NCR53c8xx dsa structure into cmd's dsa buffer,
1977: * performing all necessary relocation.
1978: *
1979: * Inputs : cmd, a NCR53c7x0_cmd structure with a dsa area large
1980: * enough to hold the NCR53c8xx dsa.
1981: */
1982:
1983: static void
1984: NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
1985: Scsi_Cmnd *c = cmd->cmd;
1986: struct Scsi_Host *host = c->host;
1987: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
1988: host->hostdata;
1989: int i;
1990:
1991: memcpy (cmd->dsa, hostdata->script + (hostdata->E_dsa_code_template / 4),
1992: hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template);
1993:
1994: /*
1995: * Note : within the NCR 'C' code, dsa points to the _start_
1996: * of the DSA structure, and _not_ the offset of dsa_zero within
1997: * that structure used to facilitate shorter signed offsets
1998: * for the 8 bit ALU.
1999: *
2000: * The implications of this are that
2001: *
2002: * - 32 bit A_dsa_* absolute values require an additional
2003: * dsa_zero added to their value to be correct, since they are
2004: * relative to dsa_zero which is in essentially a separate
2005: * space from the code symbols.
2006: *
2007: * - All other symbols require no special treatment.
2008: */
2009:
2010: patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
2011: dsa_temp_lun, c->lun);
2012: patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
2013: dsa_temp_addr_next, virt_to_bus(&cmd->dsa_next_addr));
2014: patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
2015: dsa_temp_next, virt_to_bus(cmd->dsa) + Ent_dsa_zero -
2016: Ent_dsa_code_template + A_dsa_next);
2017: patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
2018: dsa_temp_sync, virt_to_bus((void *)hostdata->sync[c->target].script));
2019: patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
2020: dsa_temp_target, c->target);
2021: /* XXX - new pointer stuff */
2022: patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
2023: dsa_temp_addr_saved_pointer, virt_to_bus(&cmd->saved_data_pointer));
2024: patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
2025: dsa_temp_addr_saved_residual, virt_to_bus(&cmd->saved_residual));
2026: patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
2027: dsa_temp_addr_residual, virt_to_bus(&cmd->residual));
2028:
2029: /* XXX - new start stuff */
2030: patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
2031: dsa_temp_addr_dsa_value, virt_to_bus(&cmd->dsa_addr));
2032:
2033: }
2034:
2035: /*
2036: * Function : run_process_issue_queue (void)
2037: *
2038: * Purpose : insure that the coroutine is running and will process our
2039: * request. process_issue_queue_running is checked/set here (in an
2040: * inline function) rather than in process_issue_queue itself to reduce
2041: * the chances of stack overflow.
2042: *
2043: */
2044:
2045: static volatile int process_issue_queue_running = 0;
2046:
2047: static __inline__ void
2048: run_process_issue_queue(void) {
2049: unsigned long flags;
2050: save_flags (flags);
2051: cli();
2052: if (!process_issue_queue_running) {
2053: process_issue_queue_running = 1;
2054: process_issue_queue(flags);
2055: /*
2056: * process_issue_queue_running is cleared in process_issue_queue
2057: * once it can't do more work, and process_issue_queue exits with
2058: * interrupts disabled.
2059: */
2060: }
2061: restore_flags (flags);
2062: }
2063:
2064: /*
2065: * Function : static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int
2066: * result)
2067: *
2068: * Purpose : mark SCSI command as finished, OR'ing the host portion
2069: * of the result word into the result field of the corresponding
2070: * Scsi_Cmnd structure, and removing it from the internal queues.
2071: *
2072: * Inputs : cmd - command, result - entire result field
2073: *
2074: * Preconditions : the NCR chip should be in a halted state when
2075: * abnormal_finished is run, since it modifies structures which
2076: * the NCR expects to have exclusive access to.
2077: */
2078:
2079: static void
2080: abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
2081: Scsi_Cmnd *c = cmd->cmd;
2082: struct Scsi_Host *host = c->host;
2083: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2084: host->hostdata;
2085: unsigned long flags;
2086: int left, found;
2087: volatile struct NCR53c7x0_cmd * linux_search;
2088: volatile struct NCR53c7x0_cmd * volatile *linux_prev;
2089: volatile u32 *ncr_prev, *current, ncr_search;
2090:
2091: #if 0
2092: printk ("scsi%d: abnormal finished\n", host->host_no);
2093: #endif
2094:
2095: save_flags(flags);
2096: cli();
2097: found = 0;
2098: /*
2099: * Traverse the NCR issue array until we find a match or run out
2100: * of instructions. Instructions in the NCR issue array are
2101: * either JUMP or NOP instructions, which are 2 words in length.
2102: */
2103:
2104:
2105: for (found = 0, left = host->can_queue, current = hostdata->schedule;
2106: left > 0; --left, current += 2)
2107: {
2108: if (issue_to_cmd (host, hostdata, (u32 *) current) == cmd)
2109: {
2110: current[0] = hostdata->NOP_insn;
2111: current[1] = 0xdeadbeef;
2112: ++found;
2113: break;
2114: }
2115: }
2116:
2117: /*
2118: * Traverse the NCR reconnect list of DSA structures until we find
2119: * a pointer to this dsa or have found too many command structures.
2120: * We let prev point at the next field of the previous element or
2121: * head of the list, so we don't do anything different for removing
2122: * the head element.
2123: */
2124:
2125: for (left = host->can_queue,
2126: ncr_search = hostdata->reconnect_dsa_head,
2127: ncr_prev = &hostdata->reconnect_dsa_head;
2128: left >= 0 && ncr_search &&
2129: ((char*)bus_to_virt(ncr_search) + hostdata->dsa_start)
2130: != (char *) cmd->dsa;
2131: ncr_prev = (u32*) ((char*)bus_to_virt(ncr_search) +
2132: hostdata->dsa_next), ncr_search = *ncr_prev, --left);
2133:
2134: if (left < 0)
2135: printk("scsi%d: loop detected in ncr reonncect list\n",
2136: host->host_no);
2137: else if (ncr_search)
2138: if (found)
2139: printk("scsi%d: scsi %ld in ncr issue array and reconnect lists\n",
2140: host->host_no, c->pid);
2141: else {
2142: volatile u32 * next = (u32 *)
2143: ((char *)bus_to_virt(ncr_search) + hostdata->dsa_next);
2144: *ncr_prev = *next;
2145: /* If we're at the tail end of the issue queue, update that pointer too. */
2146: found = 1;
2147: }
2148:
2149: /*
2150: * Traverse the host running list until we find this command or discover
2151: * we have too many elements, pointing linux_prev at the next field of the
2152: * linux_previous element or head of the list, search at this element.
2153: */
2154:
2155: for (left = host->can_queue, linux_search = hostdata->running_list,
2156: linux_prev = &hostdata->running_list;
2157: left >= 0 && linux_search && linux_search != cmd;
2158: linux_prev = &(linux_search->next),
2159: linux_search = linux_search->next, --left);
2160:
2161: if (left < 0)
2162: printk ("scsi%d: loop detected in host running list for scsi pid %ld\n",
2163: host->host_no, c->pid);
2164: else if (linux_search) {
2165: *linux_prev = linux_search->next;
2166: --hostdata->busy[c->target][c->lun];
2167: }
2168:
2169: /* Return the NCR command structure to the free list */
2170: cmd->next = hostdata->free;
2171: hostdata->free = cmd;
2172: c->host_scribble = NULL;
2173:
2174: /* And return */
2175: c->result = result;
2176: c->scsi_done(c);
2177:
2178: restore_flags(flags);
2179: run_process_issue_queue();
2180: }
2181:
2182: /*
2183: * Function : static void intr_break (struct Scsi_Host *host,
2184: * struct NCR53c7x0_cmd *cmd)
2185: *
2186: * Purpose : Handler for breakpoint interrupts from a SCSI script
2187: *
2188: * Inputs : host - pointer to this host adapter's structure,
2189: * cmd - pointer to the command (if any) dsa was pointing
2190: * to.
2191: *
2192: */
2193:
2194: static void
2195: intr_break (struct Scsi_Host *host, struct
2196: NCR53c7x0_cmd *cmd) {
2197: NCR53c7x0_local_declare();
2198: struct NCR53c7x0_break *bp;
2199: #if 0
2200: Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
2201: #endif
2202: u32 *dsp;
2203: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2204: host->hostdata;
2205: unsigned long flags;
2206: NCR53c7x0_local_setup(host);
2207:
2208: /*
2209: * Find the break point corresponding to this address, and
2210: * dump the appropriate debugging information to standard
2211: * output.
2212: */
2213: save_flags(flags);
2214: cli();
2215: dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
2216: for (bp = hostdata->breakpoints; bp && bp->address != dsp;
2217: bp = bp->next);
2218: if (!bp)
2219: panic("scsi%d : break point interrupt from %p with no breakpoint!",
2220: host->host_no, dsp);
2221:
2222: /*
2223: * Configure the NCR chip for manual start mode, so that we can
2224: * point the DSP register at the instruction that follows the
2225: * INT int_debug_break instruction.
2226: */
2227:
2228: NCR53c7x0_write8 (hostdata->dmode,
2229: NCR53c7x0_read8(hostdata->dmode)|DMODE_MAN);
2230:
2231: /*
2232: * And update the DSP register, using the size of the old
2233: * instruction in bytes.
2234: */
2235:
2236: restore_flags(flags);
2237: }
2238: /*
2239: * Function : static void print_synchronous (const char *prefix,
2240: * const unsigned char *msg)
2241: *
2242: * Purpose : print a pretty, user and machine parsable representation
2243: * of a SDTR message, including the "real" parameters, data
2244: * clock so we can tell transfer rate at a glance.
2245: *
2246: * Inputs ; prefix - text to prepend, msg - SDTR message (5 bytes)
2247: */
2248:
2249: static void
2250: print_synchronous (const char *prefix, const unsigned char *msg) {
2251: if (msg[4]) {
2252: int Hz = 1000000000 / (msg[3] * 4);
2253: int integer = Hz / 1000000;
2254: int fraction = (Hz - (integer * 1000000)) / 10000;
2255: printk ("%speriod %dns offset %d %d.%02dMHz %s SCSI%s\n",
2256: prefix, (int) msg[3] * 4, (int) msg[4], integer, fraction,
2257: (((msg[3] * 4) < 200) ? "FAST" : "synchronous"),
2258: (((msg[3] * 4) < 200) ? "-II" : ""));
2259: } else
2260: printk ("%sasynchronous SCSI\n", prefix);
2261: }
2262:
2263: /*
2264: * Function : static void set_synchronous (struct Scsi_Host *host,
2265: * int target, int sxfer, int scntl3, int now_connected)
2266: *
2267: * Purpose : reprogram transfers between the selected SCSI initiator and
2268: * target with the given register values; in the indirect
2269: * select operand, reselection script, and chip registers.
2270: *
2271: * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id,
2272: * sxfer and scntl3 - NCR registers. now_connected - if non-zero,
2273: * we should reprogram the registers now too.
2274: */
2275:
2276: static void
2277: set_synchronous (struct Scsi_Host *host, int target, int sxfer, int scntl3,
2278: int now_connected) {
2279: NCR53c7x0_local_declare();
2280: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2281: host->hostdata;
2282: u32 *script;
2283: NCR53c7x0_local_setup(host);
2284:
2285: /* These are eight bit registers */
2286: sxfer &= 0xff;
2287: scntl3 &= 0xff;
2288:
2289: hostdata->sync[target].sxfer_sanity = sxfer;
2290: hostdata->sync[target].scntl3_sanity = scntl3;
2291:
2292: /*
2293: * HARD CODED : synchronous script is EIGHT words long. This
2294: * must agree with 53c7.8xx.h
2295: */
2296:
2297: if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
2298: hostdata->sync[target].select_indirect = (scntl3 << 24) |
2299: (target << 16) | (sxfer << 8);
2300:
2301: script = (u32 *) hostdata->sync[target].script;
2302:
2303: /* XXX - add NCR53c7x0 code to reprogram SCF bits if we want to */
2304: if ((hostdata->chip / 100) == 8) {
2305: script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
2306: DCMD_RWRI_OP_MOVE) << 24) |
2307: (SCNTL3_REG_800 << 16) | (scntl3 << 8);
2308: script[1] = 0;
2309: script += 2;
2310: }
2311:
2312: script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
2313: DCMD_RWRI_OP_MOVE) << 24) |
2314: (SXFER_REG << 16) | (sxfer << 8);
2315: script[1] = 0;
2316: script += 2;
2317:
2318: #ifdef DEBUG_SYNC_INTR
2319: if (hostdata->options & OPTION_DEBUG_DISCONNECT) {
2320: script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_INT) << 24) | DBC_TCI_TRUE;
2321: script[1] = DEBUG_SYNC_INTR;
2322: script += 2;
2323: }
2324: #endif
2325:
2326: script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24) | DBC_TCI_TRUE;
2327: script[1] = 0;
2328: script += 2;
2329: }
2330:
2331: if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS)
2332: printk ("scsi%d : target %d sync parameters are sxfer=0x%x, scntl3=0x%x\n",
2333: host->host_no, target, sxfer, scntl3);
2334:
2335: if (now_connected) {
2336: if ((hostdata->chip / 100) == 8)
2337: NCR53c7x0_write8(SCNTL3_REG_800, scntl3);
2338: NCR53c7x0_write8(SXFER_REG, sxfer);
2339: }
2340: }
2341:
2342:
2343: /*
2344: * Function : static int asynchronous (struct Scsi_Host *host, int target)
2345: *
2346: * Purpose : reprogram between the selected SCSI Host adapter and target
2347: * (assumed to be currently connected) for asynchronous transfers.
2348: *
2349: * Inputs : host - SCSI host structure, target - numeric target ID.
2350: *
2351: * Preconditions : the NCR chip should be in one of the halted states
2352: */
2353:
2354: static void
2355: asynchronous (struct Scsi_Host *host, int target) {
2356: NCR53c7x0_local_declare();
2357: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2358: host->hostdata;
2359: NCR53c7x0_local_setup(host);
2360: set_synchronous (host, target, /* no offset */ 0, hostdata->saved_scntl3,
2361: 1);
2362: printk ("scsi%d : setting target %d to asynchronous SCSI\n",
2363: host->host_no, target);
2364: }
2365:
2366: /*
2367: * XXX - do we want to go out of our way (ie, add extra code to selection
2368: * in the NCR53c710/NCR53c720 script) to reprogram the synchronous
2369: * conversion bits, or can we be content in just setting the
2370: * sxfer bits?
2371: */
2372:
2373: /* Table for NCR53c8xx synchronous values */
2374: static const struct {
2375: int div; /* Total clock divisor * 10 */
2376: unsigned char scf; /* */
2377: unsigned char tp; /* 4 + tp = xferp divisor */
2378: } syncs[] = {
2379: /* div scf tp div scf tp div scf tp */
2380: { 40, 1, 0}, { 50, 1, 1}, { 60, 1, 2},
2381: { 70, 1, 3}, { 75, 2, 1}, { 80, 1, 4},
2382: { 90, 1, 5}, { 100, 1, 6}, { 105, 2, 3},
2383: { 110, 1, 7}, { 120, 2, 4}, { 135, 2, 5},
2384: { 140, 3, 3}, { 150, 2, 6}, { 160, 3, 4},
2385: { 165, 2, 7}, { 180, 3, 5}, { 200, 3, 6},
2386: { 210, 4, 3}, { 220, 3, 7}, { 240, 4, 4},
2387: { 270, 4, 5}, { 300, 4, 6}, { 330, 4, 7}
2388: };
2389:
2390: /*
2391: * Function : static void synchronous (struct Scsi_Host *host, int target,
2392: * char *msg)
2393: *
2394: * Purpose : reprogram transfers between the selected SCSI initiator and
2395: * target for synchronous SCSI transfers such that the synchronous
2396: * offset is less than that requested and period at least as long
2397: * as that requested. Also modify *msg such that it contains
2398: * an appropriate response.
2399: *
2400: * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id,
2401: * msg - synchronous transfer request.
2402: */
2403:
2404:
2405: static void
2406: synchronous (struct Scsi_Host *host, int target, char *msg) {
2407: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2408: host->hostdata;
2409: int desire, divisor, i, limit;
2410: unsigned char scntl3, sxfer;
2411: /* The diagnostic message fits on one line, even with max. width integers */
2412: char buf[80];
2413:
2414: /* Desired transfer clock in Hz */
2415: desire = 1000000000L / (msg[3] * 4);
2416: /* Scale the available SCSI clock by 10 so we get tenths */
2417: divisor = (hostdata->scsi_clock * 10) / desire;
2418:
2419: /* NCR chips can handle at most an offset of 8 */
2420: if (msg[4] > 8)
2421: msg[4] = 8;
2422:
2423: if (hostdata->options & OPTION_DEBUG_SDTR)
2424: printk("scsi%d : optimal synchronous divisor of %d.%01d\n",
2425: host->host_no, divisor / 10, divisor % 10);
2426:
2427: limit = (sizeof(syncs) / sizeof(syncs[0]) -1);
2428: for (i = 0; (i < limit) && (divisor > syncs[i].div); ++i);
2429:
2430: if (hostdata->options & OPTION_DEBUG_SDTR)
2431: printk("scsi%d : selected synchronous divisor of %d.%01d\n",
2432: host->host_no, syncs[i].div / 10, syncs[i].div % 10);
2433:
2434: msg[3] = ((1000000000L / hostdata->scsi_clock) * syncs[i].div / 10 / 4);
2435:
2436: if (hostdata->options & OPTION_DEBUG_SDTR)
2437: printk("scsi%d : selected synchronous period of %dns\n", host->host_no,
2438: msg[3] * 4);
2439:
2440: scntl3 = (hostdata->chip / 100 == 8) ? ((hostdata->saved_scntl3 &
2441: ~SCNTL3_800_SCF_MASK) | (syncs[i].scf << SCNTL3_800_SCF_SHIFT)) : 0;
2442: sxfer = (msg[4] << SXFER_MO_SHIFT) | ((syncs[i].tp) << SXFER_TP_SHIFT);
2443: if (hostdata->options & OPTION_DEBUG_SDTR)
2444: printk ("scsi%d : sxfer=0x%x scntl3=0x%x\n",
2445: host->host_no, (int) sxfer, (int) scntl3);
2446: set_synchronous (host, target, sxfer, scntl3, 1);
2447: sprintf (buf, "scsi%d : setting target %d to ", host->host_no, target);
2448: print_synchronous (buf, msg);
2449: }
2450:
2451: /*
2452: * Function : static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host,
2453: * struct NCR53c7x0_cmd *cmd)
2454: *
2455: * Purpose : Handler for INT generated instructions for the
2456: * NCR53c810/820 SCSI SCRIPT
2457: *
2458: * Inputs : host - pointer to this host adapter's structure,
2459: * cmd - pointer to the command (if any) dsa was pointing
2460: * to.
2461: *
2462: */
2463:
2464: static int
2465: NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
2466: NCR53c7x0_cmd *cmd) {
2467: NCR53c7x0_local_declare();
2468: int print;
2469: Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
2470: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
2471: host->hostdata;
2472: u32 dsps,*dsp; /* Argument of the INT instruction */
2473: NCR53c7x0_local_setup(host);
2474: dsps = NCR53c7x0_read32(DSPS_REG);
2475: dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
2476:
2477: if (hostdata->options & OPTION_DEBUG_INTR)
2478: printk ("scsi%d : DSPS = 0x%x\n", host->host_no, dsps);
2479:
2480: switch (dsps) {
2481: case A_int_msg_1:
2482: print = 1;
2483: switch (hostdata->msg_buf[0]) {
2484: /*
2485: * Unless we've initiated synchronous negotiation, I don't
2486: * think that this should happen.
2487: */
2488: case MESSAGE_REJECT:
2489: hostdata->dsp = hostdata->script + hostdata->E_accept_message /
2490: sizeof(u32);
2491: hostdata->dsp_changed = 1;
2492: if (cmd && (cmd->flags & CMD_FLAG_SDTR)) {
2493: printk ("scsi%d : target %d rejected SDTR\n", host->host_no,
2494: c->target);
2495: cmd->flags &= ~CMD_FLAG_SDTR;
2496: asynchronous (host, c->target);
2497: print = 0;
2498: }
2499: break;
2500: case INITIATE_RECOVERY:
2501: printk ("scsi%d : extended contingent allegiance not supported yet, rejecting\n",
2502: host->host_no);
2503: /* Fall through to default */
2504: hostdata->dsp = hostdata->script + hostdata->E_reject_message /
2505: sizeof(u32);
2506: hostdata->dsp_changed = 1;
2507: break;
2508: default:
2509: printk ("scsi%d : unsupported message, resjecting\n",
2510: host->host_no);
2511: hostdata->dsp = hostdata->script + hostdata->E_reject_message /
2512: sizeof(u32);
2513: hostdata->dsp_changed = 1;
2514: }
2515: if (print) {
2516: printk ("scsi%d : received message", host->host_no);
2517: if (c)
2518: printk (" from target %d lun %d ", c->target, c->lun);
2519: print_msg ((unsigned char *) hostdata->msg_buf);
2520: printk("\n");
2521: }
2522:
2523: return SPECIFIC_INT_NOTHING;
2524:
2525:
2526: case A_int_msg_sdtr:
2527: /*
2528: * At this point, hostdata->msg_buf contains
2529: * 0 EXTENDED MESSAGE
2530: * 1 length
2531: * 2 SDTR
2532: * 3 period * 4ns
2533: * 4 offset
2534: */
2535:
2536: if (cmd) {
2537: char buf[80];
2538: sprintf (buf, "scsi%d : target %d %s ", host->host_no, c->target,
2539: (cmd->flags & CMD_FLAG_SDTR) ? "accepting" : "requesting");
2540: print_synchronous (buf, (unsigned char *) hostdata->msg_buf);
2541:
2542: /*
2543: * Initiator initiated, won't happen unless synchronous
2544: * transfers are enabled. If we get a SDTR message in
2545: * response to our SDTR, we should program our parameters
2546: * such that
2547: * offset <= requested offset
2548: * period >= requested period
2549: */
2550: if (cmd->flags & CMD_FLAG_SDTR) {
2551: cmd->flags &= ~CMD_FLAG_SDTR;
2552: if (hostdata->msg_buf[4])
2553: synchronous (host, c->target, (unsigned char *)
2554: hostdata->msg_buf);
2555: else
2556: asynchronous (host, c->target);
2557: hostdata->dsp = hostdata->script + hostdata->E_accept_message /
2558: sizeof(u32);
2559: hostdata->dsp_changed = 1;
2560: return SPECIFIC_INT_NOTHING;
2561: } else {
2562: if (hostdata->options & OPTION_SYNCHRONOUS) {
2563: cmd->flags |= CMD_FLAG_DID_SDTR;
2564: synchronous (host, c->target, (unsigned char *)
2565: hostdata->msg_buf);
2566: } else {
2567: hostdata->msg_buf[4] = 0; /* 0 offset = async */
2568: asynchronous (host, c->target);
2569: }
2570: patch_dsa_32 (cmd->dsa, dsa_msgout_other, 0, 5);
2571: patch_dsa_32 (cmd->dsa, dsa_msgout_other, 1, (u32)
2572: virt_to_bus ((void *)&hostdata->msg_buf));
2573: hostdata->dsp = hostdata->script +
2574: hostdata->E_respond_message / sizeof(u32);
2575: hostdata->dsp_changed = 1;
2576: }
2577: return SPECIFIC_INT_NOTHING;
2578: }
2579: /* Fall through to abort if we couldn't find a cmd, and
2580: therefore a dsa structure to twiddle */
2581: case A_int_msg_wdtr:
2582: hostdata->dsp = hostdata->script + hostdata->E_reject_message /
2583: sizeof(u32);
2584: hostdata->dsp_changed = 1;
2585: return SPECIFIC_INT_NOTHING;
2586: case A_int_err_unexpected_phase:
2587: if (hostdata->options & OPTION_DEBUG_INTR)
2588: printk ("scsi%d : unexpected phase\n", host->host_no);
2589: return SPECIFIC_INT_ABORT;
2590: case A_int_err_selected:
2591: printk ("scsi%d : selected by target %d\n", host->host_no,
2592: (int) NCR53c7x0_read8(SDID_REG_800) &7);
2593: hostdata->dsp = hostdata->script + hostdata->E_target_abort /
2594: sizeof(u32);
2595: hostdata->dsp_changed = 1;
2596: return SPECIFIC_INT_NOTHING;
2597: case A_int_err_unexpected_reselect:
2598: printk ("scsi%d : unexpected reselect by target %d lun %d\n",
2599: host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & 7,
2600: hostdata->reselected_identify & 7);
2601: hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
2602: sizeof(u32);
2603: hostdata->dsp_changed = 1;
2604: return SPECIFIC_INT_NOTHING;
2605: /*
2606: * Since contingent allegiance conditions are cleared by the next
2607: * command issued to a target, we must issue a REQUEST SENSE
2608: * command after receiving a CHECK CONDITION status, before
2609: * another command is issued.
2610: *
2611: * Since this NCR53c7x0_cmd will be freed after use, we don't
2612: * care if we step on the various fields, so modify a few things.
2613: */
2614: case A_int_err_check_condition:
2615: #if 0
2616: if (hostdata->options & OPTION_DEBUG_INTR)
2617: #endif
2618: printk ("scsi%d : CHECK CONDITION\n", host->host_no);
2619: if (!c) {
2620: printk("scsi%d : CHECK CONDITION with no SCSI command\n",
2621: host->host_no);
2622: return SPECIFIC_INT_PANIC;
2623: }
2624:
2625: /*
2626: * FIXME : this uses the normal one-byte selection message.
2627: * We may want to renegotiate for synchronous & WIDE transfers
2628: * since these could be the crux of our problem.
2629: *
2630: hostdata->NOP_insn* FIXME : once SCSI-II tagged queuing is implemented, we'll
2631: * have to set this up so that the rest of the DSA
2632: * agrees with this being an untagged queue'd command.
2633: */
2634:
2635: patch_dsa_32 (cmd->dsa, dsa_msgout, 0, 1);
2636:
2637: /*
2638: * Modify the table indirect for COMMAND OUT phase, since
2639: * Request Sense is a six byte command.
2640: */
2641:
2642: patch_dsa_32 (cmd->dsa, dsa_cmdout, 0, 6);
2643:
2644: c->cmnd[0] = REQUEST_SENSE;
2645: c->cmnd[1] &= 0xe0; /* Zero all but LUN */
2646: c->cmnd[2] = 0;
2647: c->cmnd[3] = 0;
2648: c->cmnd[4] = sizeof(c->sense_buffer);
2649: c->cmnd[5] = 0;
2650:
2651: /*
2652: * Disable dataout phase, and program datain to transfer to the
2653: * sense buffer, and add a jump to other_transfer after the
2654: * command so overflow/underrun conditions are detected.
2655: */
2656:
2657: patch_dsa_32 (cmd->dsa, dsa_dataout, 0,
2658: virt_to_bus(hostdata->script) + hostdata->E_other_transfer);
2659: patch_dsa_32 (cmd->dsa, dsa_datain, 0,
2660: virt_to_bus(cmd->data_transfer_start));
2661: cmd->data_transfer_start[0] = (((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I |
2662: DCMD_BMI_IO)) << 24) | sizeof(c->sense_buffer);
2663: cmd->data_transfer_start[1] = (u32) virt_to_bus(c->sense_buffer);
2664:
2665: cmd->data_transfer_start[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP)
2666: << 24) | DBC_TCI_TRUE;
2667: cmd->data_transfer_start[3] = (u32) virt_to_bus(hostdata->script) +
2668: hostdata->E_other_transfer;
2669:
2670: /*
2671: * Currently, this command is flagged as completed, ie
2672: * it has valid status and message data. Reflag it as
2673: * incomplete. Q - need to do something so that original
2674: * status, etc are used.
2675: */
2676:
2677: cmd->cmd->result = 0xffff;
2678:
2679: /*
2680: * Restart command as a REQUEST SENSE.
2681: */
2682: hostdata->dsp = (u32 *) hostdata->script + hostdata->E_select /
2683: sizeof(u32);
2684: hostdata->dsp_changed = 1;
2685: return SPECIFIC_INT_NOTHING;
2686: case A_int_debug_break:
2687: return SPECIFIC_INT_BREAK;
2688: case A_int_norm_aborted:
2689: hostdata->dsp = (u32 *) hostdata->schedule;
2690: hostdata->dsp_changed = 1;
2691: if (cmd)
2692: abnormal_finished (cmd, DID_ERROR << 16);
2693: return SPECIFIC_INT_NOTHING;
2694: case A_int_test_1:
2695: case A_int_test_2:
2696: hostdata->idle = 1;
2697: hostdata->test_completed = (dsps - A_int_test_1) / 0x00010000 + 1;
2698: if (hostdata->options & OPTION_DEBUG_INTR)
2699: printk("scsi%d : test%d complete\n", host->host_no,
2700: hostdata->test_completed);
2701: return SPECIFIC_INT_NOTHING;
2702: #ifdef A_int_debug_reselected_ok
2703: case A_int_debug_reselected_ok:
2704: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2705: OPTION_DEBUG_DISCONNECT)) {
2706: /*
2707: * Note - this dsa is not based on location relative to
2708: * the command structure, but to location relative to the
2709: * DSA register
2710: */
2711: u32 *dsa;
2712: dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG));
2713:
2714: printk("scsi%d : reselected_ok (DSA = 0x%x (virt 0x%p)\n",
2715: host->host_no, NCR53c7x0_read32(DSA_REG), dsa);
2716: printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
2717: host->host_no, cmd->saved_data_pointer,
2718: bus_to_virt(cmd->saved_data_pointer));
2719: print_insn (host, hostdata->script + Ent_reselected_ok /
2720: sizeof(u32), "", 1);
2721: printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
2722: host->host_no, NCR53c7x0_read8(SXFER_REG),
2723: NCR53c7x0_read8(SCNTL3_REG_800));
2724: if (c) {
2725: print_insn (host, (u32 *)
2726: hostdata->sync[c->target].script, "", 1);
2727: print_insn (host, (u32 *)
2728: hostdata->sync[c->target].script + 2, "", 1);
2729: }
2730: }
2731: return SPECIFIC_INT_RESTART;
2732: #endif
2733: #ifdef A_int_debug_reselect_check
2734: case A_int_debug_reselect_check:
2735: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2736: u32 *dsa;
2737: #if 0
2738: u32 *code;
2739: #endif
2740: /*
2741: * Note - this dsa is not based on location relative to
2742: * the command structure, but to location relative to the
2743: * DSA register
2744: */
2745: dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
2746: printk("scsi%d : reselected_check_next (DSA = 0x%lx (virt 0x%p))\n",
2747: host->host_no, virt_to_bus(dsa), dsa);
2748: if (dsa) {
2749: printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
2750: host->host_no, cmd->saved_data_pointer,
2751: bus_to_virt (cmd->saved_data_pointer));
2752: #if 0
2753: printk("scsi%d : template code :\n", host->host_no);
2754: for (code = dsa + (Ent_dsa_code_check_reselect - Ent_dsa_zero)
2755: / sizeof(u32); code < (dsa + Ent_dsa_zero / sizeof(u32));
2756: code += print_insn (host, code, "", 1));
2757: #endif
2758: }
2759: print_insn (host, hostdata->script + Ent_reselected_ok /
2760: sizeof(u32), "", 1);
2761: }
2762: return SPECIFIC_INT_RESTART;
2763: #endif
2764: #ifdef A_int_debug_dsa_schedule
2765: case A_int_debug_dsa_schedule:
2766: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2767: u32 *dsa;
2768: /*
2769: * Note - this dsa is not based on location relative to
2770: * the command structure, but to location relative to the
2771: * DSA register
2772: */
2773: dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG));
2774: printk("scsi%d : dsa_schedule (old DSA = 0x%lx (virt 0x%p))\n",
2775: host->host_no, virt_to_bus(dsa), dsa);
2776: if (dsa)
2777: printk("scsi%d : resume address is 0x%x (virt 0x%p)\n"
2778: " (temp was 0x%x (virt 0x%p))\n",
2779: host->host_no, cmd->saved_data_pointer,
2780: bus_to_virt (cmd->saved_data_pointer),
2781: NCR53c7x0_read32 (TEMP_REG),
2782: bus_to_virt (NCR53c7x0_read32(TEMP_REG)));
2783: }
2784: return SPECIFIC_INT_RESTART;
2785: #endif
2786: #ifdef A_int_debug_scheduled
2787: case A_int_debug_scheduled:
2788: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2789: printk("scsi%d : new I/O 0x%x (virt 0x%p) scheduled\n",
2790: host->host_no, NCR53c7x0_read32(DSA_REG),
2791: bus_to_virt(NCR53c7x0_read32(DSA_REG)));
2792: }
2793: return SPECIFIC_INT_RESTART;
2794: #endif
2795: #ifdef A_int_debug_idle
2796: case A_int_debug_idle:
2797: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2798: printk("scsi%d : idle\n", host->host_no);
2799: }
2800: return SPECIFIC_INT_RESTART;
2801: #endif
2802: #ifdef A_int_debug_cmd
2803: case A_int_debug_cmd:
2804: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2805: printk("scsi%d : command sent\n");
2806: }
2807: return SPECIFIC_INT_RESTART;
2808: #endif
2809: #ifdef A_int_debug_dsa_loaded
2810: case A_int_debug_dsa_loaded:
2811: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2812: printk("scsi%d : DSA loaded with 0x%x (virt 0x%p)\n", host->host_no,
2813: NCR53c7x0_read32(DSA_REG),
2814: bus_to_virt(NCR53c7x0_read32(DSA_REG)));
2815: }
2816: return SPECIFIC_INT_RESTART;
2817: #endif
2818: #ifdef A_int_debug_reselected
2819: case A_int_debug_reselected:
2820: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2821: OPTION_DEBUG_DISCONNECT)) {
2822: printk("scsi%d : reselected by target %d lun %d\n",
2823: host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & ~0x80,
2824: (int) hostdata->reselected_identify & 7);
2825: print_queues(host);
2826: }
2827: return SPECIFIC_INT_RESTART;
2828: #endif
2829: #ifdef A_int_debug_disconnect_msg
2830: case A_int_debug_disconnect_msg:
2831: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
2832: if (c)
2833: printk("scsi%d : target %d lun %d disconnecting\n",
2834: host->host_no, c->target, c->lun);
2835: else
2836: printk("scsi%d : unknown target disconnecting\n",
2837: host->host_no);
2838: }
2839: return SPECIFIC_INT_RESTART;
2840: #endif
2841: #ifdef A_int_debug_disconnected
2842: case A_int_debug_disconnected:
2843: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2844: OPTION_DEBUG_DISCONNECT)) {
2845: printk ("scsi%d : disconnected, new queues are\n",
2846: host->host_no);
2847: print_queues(host);
2848: #if 0
2849: printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
2850: host->host_no, NCR53c7x0_read8(SXFER_REG),
2851: NCR53c7x0_read8(SCNTL3_REG_800));
2852: #endif
2853: if (c) {
2854: print_insn (host, (u32 *)
2855: hostdata->sync[c->target].script, "", 1);
2856: print_insn (host, (u32 *)
2857: hostdata->sync[c->target].script + 2, "", 1);
2858: }
2859: }
2860: return SPECIFIC_INT_RESTART;
2861: #endif
2862: #ifdef A_int_debug_panic
2863: case A_int_debug_panic:
2864: printk("scsi%d : int_debug_panic received\n", host->host_no);
2865: print_lots (host);
2866: return SPECIFIC_INT_PANIC;
2867: #endif
2868: #ifdef A_int_debug_saved
2869: case A_int_debug_saved:
2870: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2871: OPTION_DEBUG_DISCONNECT)) {
2872: printk ("scsi%d : saved data pointer 0x%x (virt 0x%p)\n",
2873: host->host_no, cmd->saved_data_pointer,
2874: bus_to_virt (cmd->saved_data_pointer));
2875: print_progress (c);
2876: }
2877: return SPECIFIC_INT_RESTART;
2878: #endif
2879: #ifdef A_int_debug_restored
2880: case A_int_debug_restored:
2881: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2882: OPTION_DEBUG_DISCONNECT)) {
2883: if (cmd) {
2884: int size;
2885: printk ("scsi%d : restored data pointer 0x%x (virt 0x%p)\n",
2886: host->host_no, cmd->saved_data_pointer, bus_to_virt (
2887: cmd->saved_data_pointer));
2888: size = print_insn (host, (u32 *)
2889: bus_to_virt(cmd->saved_data_pointer), "", 1);
2890: size = print_insn (host, (u32 *)
2891: bus_to_virt(cmd->saved_data_pointer) + size, "", 1);
2892: print_progress (c);
2893: }
2894: #if 0
2895: printk ("scsi%d : datapath residual %d\n",
2896: host->host_no, datapath_residual (host)) ;
2897: #endif
2898: }
2899: return SPECIFIC_INT_RESTART;
2900: #endif
2901: #ifdef A_int_debug_sync
2902: case A_int_debug_sync:
2903: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2904: OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) {
2905: unsigned char sxfer = NCR53c7x0_read8 (SXFER_REG),
2906: scntl3 = NCR53c7x0_read8 (SCNTL3_REG_800);
2907: if (c) {
2908: if (sxfer != hostdata->sync[c->target].sxfer_sanity ||
2909: scntl3 != hostdata->sync[c->target].scntl3_sanity) {
2910: printk ("scsi%d : sync sanity check failed sxfer=0x%x, scntl3=0x%x",
2911: host->host_no, sxfer, scntl3);
2912: NCR53c7x0_write8 (SXFER_REG, sxfer);
2913: NCR53c7x0_write8 (SCNTL3_REG_800, scntl3);
2914: }
2915: } else
2916: printk ("scsi%d : unknown command sxfer=0x%x, scntl3=0x%x\n",
2917: host->host_no, (int) sxfer, (int) scntl3);
2918: }
2919: return SPECIFIC_INT_RESTART;
2920: #endif
2921: #ifdef A_int_debug_datain
2922: case A_int_debug_datain:
2923: if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
2924: OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) {
2925: int size;
2926: printk ("scsi%d : In do_datain (%s) sxfer=0x%x, scntl3=0x%x\n"
2927: " datapath residual=%d\n",
2928: host->host_no, sbcl_to_phase (NCR53c7x0_read8 (SBCL_REG)),
2929: (int) NCR53c7x0_read8(SXFER_REG),
2930: (int) NCR53c7x0_read8(SCNTL3_REG_800),
2931: datapath_residual (host)) ;
2932: print_insn (host, dsp, "", 1);
2933: size = print_insn (host, (u32 *) bus_to_virt(dsp[1]), "", 1);
2934: print_insn (host, (u32 *) bus_to_virt(dsp[1]) + size, "", 1);
2935: }
2936: return SPECIFIC_INT_RESTART;
2937: #endif
2938: /*
2939: * FIXME : for 7xx support, we need to read SDID_REG_700 and handle
2940: * the comparison as bitfielded, not binary.
2941: */
2942: #ifdef A_int_debug_check_dsa
2943: case A_int_debug_check_dsa:
2944: if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) {
2945: int sdid = NCR53c7x0_read8 (SDID_REG_800) & 15;
2946: char *where = dsp - NCR53c7x0_insn_size(NCR53c7x0_read8
2947: (DCMD_REG)) == hostdata->script +
2948: Ent_select_check_dsa / sizeof(u32) ?
2949: "selection" : "reselection";
2950: if (c && sdid != c->target) {
2951: printk ("scsi%d : SDID target %d != DSA target %d at %s\n",
2952: host->host_no, sdid, c->target, where);
2953: print_lots(host);
2954: dump_events (host, 20);
2955: return SPECIFIC_INT_PANIC;
2956: }
2957: }
2958: return SPECIFIC_INT_RESTART;
2959: #endif
2960: default:
2961: if ((dsps & 0xff000000) == 0x03000000) {
2962: printk ("scsi%d : misc debug interrupt 0x%x\n",
2963: host->host_no, dsps);
2964: return SPECIFIC_INT_RESTART;
2965: } else if ((dsps & 0xff000000) == 0x05000000) {
2966: if (hostdata->events) {
2967: struct NCR53c7x0_event *event;
2968: ++hostdata->event_index;
2969: if (hostdata->event_index >= hostdata->event_size)
2970: hostdata->event_index = 0;
2971: event = (struct NCR53c7x0_event *) hostdata->events +
2972: hostdata->event_index;
2973: event->event = (enum ncr_event) dsps;
2974: event->dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
2975: /* FIXME : this needs to change for the '7xx family */
2976: if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON)
2977: event->target = NCR53c7x0_read8(SSID_REG_800);
2978: else
2979: event->target = 255;
2980:
2981: if (event->event == EVENT_RESELECT)
2982: event->lun = hostdata->reselected_identify & 0xf;
2983: else if (c)
2984: event->lun = c->lun;
2985: else
2986: event->lun = 255;
2987: do_gettimeofday(&(event->time));
2988: if (c) {
2989: event->pid = c->pid;
2990: memcpy ((void *) event->cmnd, (void *) c->cmnd,
2991: sizeof (event->cmnd));
2992: } else {
2993: event->pid = -1;
2994: }
2995: }
2996: return SPECIFIC_INT_RESTART;
2997: }
2998:
2999: printk ("scsi%d : unknown user interrupt 0x%x\n",
3000: host->host_no, (unsigned) dsps);
3001: return SPECIFIC_INT_PANIC;
3002: }
3003: }
3004:
3005: /*
3006: * XXX - the stock NCR assembler won't output the scriptu.h file,
3007: * which undefine's all #define'd CPP symbols from the script.h
3008: * file, which will create problems if you use multiple scripts
3009: * with the same symbol names.
3010: *
3011: * If you insist on using NCR's assembler, you could generate
3012: * scriptu.h from script.h using something like
3013: *
3014: * grep #define script.h | \
3015: * sed 's/#define[ ][ ]*\([_a-zA-Z][_a-zA-Z0-9]*\).*$/#undefine \1/' \
3016: * > scriptu.h
3017: */
3018:
3019: #include "53c8xx_u.h"
3020:
3021: /* XXX - add alternate script handling code here */
3022:
3023:
3024: #ifdef NCR_DEBUG
3025: /*
3026: * Debugging without a debugger is no fun. So, I've provided
3027: * a debugging interface in the NCR53c7x0 driver. To avoid
3028: * kernel cruft, there's just enough here to act as an interface
3029: * to a user level debugger (aka, GDB).
3030: *
3031: *
3032: * The following restrictions apply to debugger commands :
3033: * 1. The command must be terminated by a newline.
3034: * 2. Command length must be less than 80 bytes including the
3035: * newline.
3036: * 3. The entire command must be written with one system call.
3037: */
3038:
3039: static const char debugger_help =
3040: "bc <addr> - clear breakpoint\n"
3041: "bl - list breakpoints\n"
3042: "bs <addr> - set breakpoint\n"
3043: "g - start\n"
3044: "h - halt\n"
3045: "? - this message\n"
3046: "i - info\n"
3047: "mp <addr> <size> - print memory\n"
3048: "ms <addr> <size> <value> - store memory\n"
3049: "rp <num> <size> - print register\n"
3050: "rs <num> <size> <value> - store register\n"
3051: "s - single step\n"
3052: "tb - begin trace \n"
3053: "te - end trace\n";
3054:
3055: /*
3056: * Whenever we change a break point, we should probably
3057: * set the NCR up so that it is in a single step mode.
3058: */
3059:
3060: static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token,
3061: u32 args[]) {
3062: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3063: instance->hostdata;
3064: struct NCR53c7x0_break *bp, **prev;
3065: unsigned long flags;
3066: save_flags(flags);
3067: cli();
3068: for (bp = (struct NCR53c7x0_break *) instance->breakpoints,
3069: prev = (struct NCR53c7x0_break **) &instance->breakpoints;
3070: bp; prev = (struct NCR53c7x0_break **) &(bp->next),
3071: bp = (struct NCR53c7x0_break *) bp->next);
3072:
3073: if (!bp) {
3074: restore_flags(flags);
3075: return -EIO;
3076: }
3077:
3078: /*
3079: * XXX - we need to insure that the processor is halted
3080: * here in order to prevent a race condition.
3081: */
3082:
3083: memcpy ((void *) bp->addr, (void *) bp->old, sizeof(bp->old));
3084: if (prev)
3085: *prev = bp->next;
3086:
3087: restore_flags(flags);
3088: return 0;
3089: }
3090:
3091:
3092: static int
3093: debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
3094: u32 args[]) {
3095: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3096: host->hostdata;
3097: struct NCR53c7x0_break *bp;
3098: char buf[80];
3099: size_t len;
3100: unsigned long flags;
3101: /*
3102: * XXX - we need to insure that the processor is halted
3103: * here in order to prevent a race condition. So, if the
3104: * processor isn't halted, print an error message and continue.
3105: */
3106:
3107: sprintf (buf, "scsi%d : bp : warning : processor not halted\b",
3108: host->host_no);
3109: debugger_kernel_write (host, buf, strlen(buf));
3110:
3111: save_flags(flags);
3112: cli();
3113: for (bp = (struct NCR53c7x0_break *) host->breakpoints;
3114: bp; bp = (struct NCR53c7x0_break *) bp->next); {
3115: sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x",
3116: bp->addr, bp->old[0], bp->old[1]);
3117: len = strlen(buf);
3118: if ((bp->old[0] & (DCMD_TYPE_MASK << 24)) ==
3119: (DCMD_TYPE_MMI << 24)) {
3120: sprintf(buf + len, "%08x\n", * (u32 *) bp->addr);
3121: } else {
3122: sprintf(buf + len, "\n");
3123: }
3124: len = strlen(buf);
3125: debugger_kernel_write (host, buf, len);
3126: }
3127: restore_flags(flags);
3128: return 0;
3129: }
3130:
3131: static int
3132: debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token,
3133: u32 args[]) {
3134: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3135: host->hostdata;
3136: struct NCR53c7x0_break *bp;
3137: char buf[80];
3138: size_t len;
3139: unsigned long flags;
3140: save_flags(flags);
3141: cli();
3142:
3143: if (hostdata->state != STATE_HALTED) {
3144: sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no);
3145: debugger_kernel_write (host, buf, strlen(buf));
3146: restore_flags(flags);
3147: return -1;
3148: }
3149:
3150: if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) {
3151: printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n",
3152: host->host_no, sizeof(struct NCR53c7x0_break));
3153: restore_flags(flags);
3154: return -1;
3155: }
3156:
3157: bp->address = (u32 *) args[0];
3158: memcpy ((void *) bp->old_instruction, (void *) bp->address, 8);
3159: bp->old_size = (((bp->old_instruction[0] >> 24) & DCMD_TYPE_MASK) ==
3160: DCMD_TYPE_MMI ? 3 : 2;
3161: bp->next = hostdata->breakpoints;
3162: hostdata->breakpoints = bp->next;
3163: memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8);
3164:
3165: restore_flags(flags);
3166: return 0;
3167: }
3168:
3169: #define TOKEN(name,nargs) {#name, nargs, debugger_fn_##name}
3170: static const struct debugger_token {
3171: char *name;
3172: int numargs;
3173: int (*fn)(struct debugger_token *token, u32 args[]);
3174: } debugger_tokens[] = {
3175: TOKEN(bc,1), TOKEN(bl,0), TOKEN(bs,1), TOKEN(g,0), TOKEN(halt,0),
3176: {DT_help, "?", 0} , TOKEN(h,0), TOKEN(i,0), TOKEN(mp,2),
3177: TOKEN(ms,3), TOKEN(rp,2), TOKEN(rs,2), TOKEN(s,0), TOKEN(tb,0), TOKEN(te,0)
3178: };
3179:
3180: #define NDT sizeof(debugger_tokens / sizeof(struct debugger_token))
3181:
3182: static struct Scsi_Host * inode_to_host (struct inode *inode) {
3183: int dev;
3184: struct Scsi_Host *tmp;
3185: for (dev = MINOR(inode->rdev), host = first_host;
3186: (host->hostt == the_template); --dev, host = host->next)
3187: if (!dev) return host;
3188: return NULL;
3189: }
3190:
3191:
3192: static int
3193: debugger_user_write (struct inode *inode,struct file *filp,
3194: char *buf,int count) {
3195: struct Scsi_Host *host; /* This SCSI host */
3196: struct NCR53c7x0_hostadata *hostdata;
3197: char input_buf[80], /* Kernel space copy of buf */
3198: *ptr; /* Pointer to argument list */
3199: u32 args[3]; /* Arguments */
3200: int i, j, error, len;
3201:
3202: if (!(host = inode_to_host(inode)))
3203: return -ENXIO;
3204:
3205: hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
3206:
3207: if (error = verify_area(VERIFY_READ,buf,count))
3208: return error;
3209:
3210: if (count > 80)
3211: return -EIO;
3212:
3213: memcpy_from_fs(input_buf, buf, count);
3214:
3215: if (input_buf[count - 1] != '\n')
3216: return -EIO;
3217:
3218: input_buf[count - 1]=0;
3219:
3220: for (i = 0; i < NDT; ++i) {
3221: len = strlen (debugger_tokens[i].name);
3222: if (!strncmp(input_buf, debugger_tokens[i].name, len))
3223: break;
3224: };
3225:
3226: if (i == NDT)
3227: return -EIO;
3228:
3229: for (ptr = input_buf + len, j = 0; j < debugger_tokens[i].nargs && *ptr;) {
3230: if (*ptr == ' ' || *ptr == '\t') {
3231: ++ptr;
3232: } else if (isdigit(*ptr)) {
3233: args[j++] = simple_strtoul (ptr, &ptr, 0);
3234: } else {
3235: return -EIO;
3236: }
3237: }
3238:
3239: if (j != debugger_tokens[i].nargs)
3240: return -EIO;
3241:
3242: return count;
3243: }
3244:
3245: static int
3246: debugger_user_read (struct inode *inode,struct file *filp,
3247: char *buf,int count) {
3248: struct Scsi_Host *instance;
3249:
3250: }
3251:
3252: static int
3253: debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
3254: buflen) {
3255: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3256: host->hostdata;
3257: int copy, left;
3258: unsigned long flags;
3259: save_flags(flags);
3260: cli();
3261: while (buflen) {
3262: left = (hostdata->debug_buf + hostdata->debug_size - 1) -
3263: hostdata->debug_write;
3264: copy = (buflen <= left) ? buflen : left;
3265: memcpy (hostdata->debug_write, buf, copy);
3266: buf += copy;
3267: buflen -= copy;
3268: hostdata->debug_count += copy;
3269: if ((hostdata->debug_write += copy) ==
3270: (hostdata->debug_buf + hostdata->debug_size))
3271: hosdata->debug_write = hostdata->debug_buf;
3272: }
3273: restore_flags(flags);
3274: }
3275:
3276: #endif /* def NCRDEBUG */
3277:
3278: /*
3279: * Function : static void NCR538xx_soft_reset (struct Scsi_Host *host)
3280: *
3281: * Purpose : perform a soft reset of the NCR53c8xx chip
3282: *
3283: * Inputs : host - pointer to this host adapter's structure
3284: *
3285: * Preconditions : NCR53c7x0_init must have been called for this
3286: * host.
3287: *
3288: */
3289:
3290: static void
3291: NCR53c8x0_soft_reset (struct Scsi_Host *host) {
3292: NCR53c7x0_local_declare();
3293: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3294: host->hostdata;
3295: NCR53c7x0_local_setup(host);
3296:
3297:
3298: /*
3299: * Do a soft reset of the chip so that everything is
3300: * reinitialized to the power-on state.
3301: *
3302: * Basically follow the procedure outlined in the NCR53c700
3303: * data manual under Chapter Six, How to Use, Steps Necessary to
3304: * Start SCRIPTS, with the exception of actually starting the
3305: * script and setting up the synchronous transfer gunk.
3306: */
3307:
3308: NCR53c7x0_write8(ISTAT_REG_800, ISTAT_10_SRST);
3309: NCR53c7x0_write8(ISTAT_REG_800, 0);
3310: NCR53c7x0_write8(hostdata->dmode, hostdata->saved_dmode & ~DMODE_MAN);
3311:
3312:
3313: /*
3314: * Respond to reselection by targets and use our _initiator_ SCSI ID
3315: * for arbitration. If notyet, also respond to SCSI selection.
3316: *
3317: * XXX - Note : we must reprogram this when reselecting as
3318: * a target.
3319: */
3320:
3321: #ifdef notyet
3322: NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE);
3323: #else
3324: NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE);
3325: #endif
3326: NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask);
3327:
3328: /*
3329: * Use a maximum (1.6) second handshake to handshake timeout,
3330: * and SCSI recommended .5s selection timeout.
3331: */
3332:
3333: /*
3334: * The new gcc won't recognize preprocessing directives
3335: * within macro args.
3336: */
3337: #if 0
3338: NCR53c7x0_write8(STIME0_REG_800,
3339: ((selection_timeout << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK)
3340: | ((15 << STIME0_800_HTH_SHIFT) & STIME0_800_HTH_MASK));
3341: #else
3342: /* Disable HTH interrupt */
3343: NCR53c7x0_write8(STIME0_REG_800,
3344: ((selection_timeout << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK));
3345: #endif
3346:
3347:
3348: /*
3349: * Enable active negation for happy synchronous transfers.
3350: */
3351:
3352: NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE);
3353:
3354: /*
3355: * Enable all interrupts, except parity which we only want when
3356: * the user requests it.
3357: */
3358:
3359: NCR53c7x0_write8(DIEN_REG, DIEN_800_MDPE | DIEN_800_BF |
3360: DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_800_IID);
3361:
3362:
3363: NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ?
3364: SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
3365: NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH);
3366:
3367: /*
3368: * Use saved clock frequency divisor and scripts loaded in 16 bit
3369: * mode flags from the saved dcntl.
3370: */
3371:
3372: NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl);
3373: NCR53c7x0_write8(CTEST4_REG_800, hostdata->saved_ctest4);
3374:
3375: /* Enable active negation */
3376: NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE);
3377: }
3378:
3379: /*
3380: * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd)
3381: *
3382: * Purpose : Return the first free NCR53c7x0_cmd structure (which are
3383: * reused in a LIFO maner to minimize cache thrashing).
3384: *
3385: * Side effects : If we haven't yet scheduled allocation of NCR53c7x0_cmd
3386: * structures for this device, do so. Attempt to complete all scheduled
3387: * allocations using kmalloc(), putting NCR53c7x0_cmd structures on
3388: * the free list. Teach programmers not to drink and hack.
3389: *
3390: * Inputs : cmd - SCSI command
3391: *
3392: * Returns : NCR53c7x0_cmd structure allocated on behalf of cmd;
3393: * NULL on failure.
3394: */
3395:
3396: static struct NCR53c7x0_cmd *
3397: allocate_cmd (Scsi_Cmnd *cmd) {
3398: struct Scsi_Host *host = cmd->host;
3399: struct NCR53c7x0_hostdata *hostdata =
3400: (struct NCR53c7x0_hostdata *) host->hostdata;
3401: void *real; /* Real address */
3402: int size; /* Size of *tmp */
3403: struct NCR53c7x0_cmd *tmp;
3404: unsigned long flags;
3405:
3406: if (hostdata->options & OPTION_DEBUG_ALLOCATION)
3407: printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
3408: " target = %d, lun = %d, %s\n",
3409: host->host_no, hostdata->num_cmds, host->can_queue,
3410: cmd->target, cmd->lun, (hostdata->cmd_allocated[cmd->target] &
3411: (1 << cmd->lun)) ? "allready allocated" : "not allocated");
3412:
3413: /*
3414: * If we have not yet reserved commands for this I_T_L nexus, and
3415: * the device exists (as indicated by permanant Scsi_Cmnd structures
3416: * being allocated under 1.3.x, or being outside of scan_scsis in
3417: * 1.2.x), do so now.
3418: */
3419: if (!(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun)) &&
3420: #ifdef LINUX_1_2
3421: !in_scan_scsis
3422: #else
3423: cmd->device && cmd->device->has_cmdblocks
3424: #endif
3425: ) {
3426: if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue)
3427: hostdata->extra_allocate += host->cmd_per_lun;
3428: hostdata->cmd_allocated[cmd->target] |= (1 << cmd->lun);
3429: }
3430:
3431: for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate,
3432: ++hostdata->num_cmds) {
3433: /* historically, kmalloc has returned unaligned addresses; pad so we
3434: have enough room to ROUNDUP */
3435: size = hostdata->max_cmd_size + sizeof (void *);
3436: /* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
3437: real = kmalloc (size, GFP_ATOMIC);
3438: if (!real) {
3439: if (hostdata->options & OPTION_DEBUG_ALLOCATION)
3440: printk ("scsi%d : kmalloc(%d) failed\n",
3441: host->host_no, size);
3442: break;
3443: }
3444: tmp = ROUNDUP(real, void *);
3445: tmp->real = real;
3446: tmp->size = size;
3447: #ifdef LINUX_1_2
3448: tmp->free = ((void (*)(void *, int)) kfree_s);
3449: #else
3450: tmp->free = ((void (*)(void *, int)) kfree);
3451: #endif
3452: save_flags (flags);
3453: cli();
3454: tmp->next = hostdata->free;
3455: hostdata->free = tmp;
3456: restore_flags (flags);
3457: }
3458: save_flags(flags);
3459: cli();
3460: tmp = (struct NCR53c7x0_cmd *) hostdata->free;
3461: if (tmp) {
3462: hostdata->free = tmp->next;
3463: }
3464: restore_flags(flags);
3465: if (!tmp)
3466: printk ("scsi%d : can't allocate command for target %d lun %d\n",
3467: host->host_no, cmd->target, cmd->lun);
3468: return tmp;
3469: }
3470:
3471: /*
3472: * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd)
3473: *
3474: *
3475: * Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the
3476: * Scsi_Cmnd structure passed in cmd, including dsa and Linux field
3477: * initialization, and dsa code relocation.
3478: *
3479: * Inputs : cmd - SCSI command
3480: *
3481: * Returns : NCR53c7x0_cmd structure corresponding to cmd,
3482: * NULL on failure.
3483: */
3484:
3485: static struct NCR53c7x0_cmd *
3486: create_cmd (Scsi_Cmnd *cmd) {
3487: NCR53c7x0_local_declare();
3488: struct Scsi_Host *host = cmd->host;
3489: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
3490: host->hostdata;
3491: struct NCR53c7x0_cmd *tmp; /* NCR53c7x0_cmd structure for this command */
3492: int datain, /* Number of instructions per phase */
3493: dataout;
3494: int data_transfer_instructions, /* Count of dynamic instructions */
3495: i; /* Counter */
3496: u32 *cmd_datain, /* Address of datain/dataout code */
3497: *cmd_dataout; /* Incremented as we assemble */
3498: #ifdef notyet
3499: unsigned char *msgptr; /* Current byte in select message */
3500: int msglen; /* Length of whole select message */
3501: #endif
3502: unsigned long flags;
3503: NCR53c7x0_local_setup(cmd->host);
3504:
3505: if (!(tmp = allocate_cmd (cmd)))
3506: return NULL;
3507:
3508:
3509: /*
3510: * Decide whether we need to generate commands for DATA IN,
3511: * DATA OUT, neither, or both based on the SCSI command
3512: */
3513:
3514: switch (cmd->cmnd[0]) {
3515: /* These commands do DATA IN */
3516: case INQUIRY:
3517: case MODE_SENSE:
3518: case READ_6:
3519: case READ_10:
3520: case READ_CAPACITY:
3521: case REQUEST_SENSE:
3522: datain = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
3523: dataout = 0;
3524: break;
3525: /* These commands do DATA OUT */
3526: case MODE_SELECT:
3527: case WRITE_6:
3528: case WRITE_10:
3529: #if 0
3530: printk("scsi%d : command is ", host->host_no);
3531: print_command(cmd->cmnd);
3532: #endif
3533: #if 0
3534: printk ("scsi%d : %d scatter/gather segments\n", host->host_no,
3535: cmd->use_sg);
3536: #endif
3537: datain = 0;
3538: dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
3539: #if 0
3540: hostdata->options |= OPTION_DEBUG_INTR;
3541: #endif
3542: break;
3543: /*
3544: * These commands do no data transfer, we should force an
3545: * interrupt if a data phase is attempted on them.
3546: */
3547: case START_STOP:
3548: case TEST_UNIT_READY:
3549: datain = dataout = 0;
3550: break;
3551: /*
3552: * We don't know about these commands, so generate code to handle
3553: * both DATA IN and DATA OUT phases.
3554: */
3555: default:
3556: datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
3557: }
3558:
3559: /*
3560: * New code : so that active pointers work correctly irregardless
3561: * of where the saved data pointer is at, we want to immediately
3562: * enter the dynamic code after selection, and on a non-data
3563: * phase perform a CALL to the non-data phase handler, with
3564: * returns back to this address.
3565: *
3566: * If a phase mismatch is encountered in the middle of a
3567: * Block MOVE instruction, we want to _leave_ that instruction
3568: * unchanged as the current case is, modify a temporary buffer,
3569: * and point the active pointer (TEMP) at that.
3570: *
3571: * Furthermore, we want to implement a saved data pointer,
3572: * set by the SAVE_DATA_POINTERs message.
3573: *
3574: * So, the data transfer segments will change to
3575: * CALL data_transfer, WHEN NOT data phase
3576: * MOVE x, x, WHEN data phase
3577: * ( repeat )
3578: * JUMP other_transfer
3579: */
3580:
3581: data_transfer_instructions = datain + dataout;
3582:
3583: /*
3584: * When we perform a request sense, we overwrite various things,
3585: * including the data transfer code. Make sure we have enough
3586: * space to do that.
3587: */
3588:
3589: if (data_transfer_instructions < 2)
3590: data_transfer_instructions = 2;
3591:
3592:
3593: /*
3594: * The saved data pointer is set up so that a RESTORE POINTERS message
3595: * will start the data transfer over at the beggining.
3596: */
3597:
3598: tmp->saved_data_pointer = virt_to_bus (hostdata->script) +
3599: hostdata->E_data_transfer;
3600:
3601: /*
3602: * Initialize Linux specific fields.
3603: */
3604:
3605: tmp->cmd = cmd;
3606: tmp->next = NULL;
3607: tmp->flags = 0;
3608: tmp->dsa_next_addr = virt_to_bus(tmp->dsa) + hostdata->dsa_next -
3609: hostdata->dsa_start;
3610: tmp->dsa_addr = virt_to_bus(tmp->dsa) - hostdata->dsa_start;
3611:
3612: /*
3613: * Calculate addresses of dynamic code to fill in DSA
3614: */
3615:
3616: tmp->data_transfer_start = tmp->dsa + (hostdata->dsa_end -
3617: hostdata->dsa_start) / sizeof(u32);
3618: tmp->data_transfer_end = tmp->data_transfer_start +
3619: 2 * data_transfer_instructions;
3620:
3621: cmd_datain = datain ? tmp->data_transfer_start : NULL;
3622: cmd_dataout = dataout ? (datain ? cmd_datain + 2 * datain : tmp->
3623: data_transfer_start) : NULL;
3624:
3625: /*
3626: * Fill in the NCR53c7x0_cmd structure as follows
3627: * dsa, with fixed up DSA code
3628: * datain code
3629: * dataout code
3630: */
3631:
3632: /* Copy template code into dsa and perform all necessary fixups */
3633: if (hostdata->dsa_fixup)
3634: hostdata->dsa_fixup(tmp);
3635:
3636: patch_dsa_32(tmp->dsa, dsa_next, 0, 0);
3637: patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd));
3638:
3639: if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS)
3640: if (hostdata->sync[cmd->target].select_indirect !=
3641: ((hostdata->sync[cmd->target].scntl3_sanity << 24) |
3642: (cmd->target << 16) |
3643: (hostdata->sync[cmd->target].sxfer_sanity << 8))) {
3644: printk ("scsi%d : sanity check failed select_indirect=0x%x\n",
3645: host->host_no, hostdata->sync[cmd->target].select_indirect);
3646: FATAL(host);
3647:
3648: }
3649:
3650: patch_dsa_32(tmp->dsa, dsa_select, 0, hostdata->sync[cmd->target].
3651: select_indirect);
3652: /*
3653: * Right now, we'll do the WIDE and SYNCHRONOUS negotiations on
3654: * different commands; although it should be trivial to do them
3655: * both at the same time.
3656: */
3657: if (hostdata->initiate_wdtr & (1 << cmd->target)) {
3658: memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
3659: sizeof(wdtr_message));
3660: patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message));
3661: save_flags(flags);
3662: cli();
3663: hostdata->initiate_wdtr &= ~(1 << cmd->target);
3664: restore_flags(flags);
3665: } else if (hostdata->initiate_sdtr & (1 << cmd->target)) {
3666: memcpy ((void *) (tmp->select + 1), (void *) sdtr_message,
3667: sizeof(sdtr_message));
3668: patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message));
3669: tmp->flags |= CMD_FLAG_SDTR;
3670: save_flags(flags);
3671: cli();
3672: hostdata->initiate_sdtr &= ~(1 << cmd->target);
3673: restore_flags(flags);
3674:
3675: }
3676: #if 1
3677: else if (!(hostdata->talked_to & (1 << cmd->target)) &&
3678: !(hostdata->options & OPTION_NO_ASYNC)) {
3679: memcpy ((void *) (tmp->select + 1), (void *) async_message,
3680: sizeof(async_message));
3681: patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(async_message));
3682: tmp->flags |= CMD_FLAG_SDTR;
3683: }
3684: #endif
3685: else
3686: patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
3687: hostdata->talked_to |= (1 << cmd->target);
3688: tmp->select[0] = (hostdata->options & OPTION_DISCONNECT) ?
3689: IDENTIFY (1, cmd->lun) : IDENTIFY (0, cmd->lun);
3690: patch_dsa_32(tmp->dsa, dsa_msgout, 1, virt_to_bus(tmp->select));
3691: patch_dsa_32(tmp->dsa, dsa_cmdout, 0, cmd->cmd_len);
3692: patch_dsa_32(tmp->dsa, dsa_cmdout, 1, virt_to_bus(cmd->cmnd));
3693: patch_dsa_32(tmp->dsa, dsa_dataout, 0, cmd_dataout ?
3694: virt_to_bus (cmd_dataout)
3695: : virt_to_bus (hostdata->script) + hostdata->E_other_transfer);
3696: patch_dsa_32(tmp->dsa, dsa_datain, 0, cmd_datain ?
3697: virt_to_bus (cmd_datain)
3698: : virt_to_bus (hostdata->script) + hostdata->E_other_transfer);
3699: /*
3700: * XXX - need to make endian aware, should use separate variables
3701: * for both status and message bytes.
3702: */
3703: patch_dsa_32(tmp->dsa, dsa_msgin, 0, 1);
3704: /*
3705: * FIXME : these only works for little endian. We probably want to
3706: * provide message and status fields in the NCR53c7x0_cmd
3707: * structure, and assign them to cmd->result when we're done.
3708: */
3709: patch_dsa_32(tmp->dsa, dsa_msgin, 1, virt_to_bus(&cmd->result) + 1);
3710: patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
3711: patch_dsa_32(tmp->dsa, dsa_status, 1, virt_to_bus(&cmd->result));
3712: patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
3713: patch_dsa_32(tmp->dsa, dsa_msgout_other, 1,
3714: virt_to_bus(&(hostdata->NCR53c7xx_msg_nop)));
3715:
3716: /*
3717: * Generate code for zero or more of the DATA IN, DATA OUT phases
3718: * in the format
3719: *
3720: * CALL data_transfer, WHEN NOT phase
3721: * MOVE first buffer length, first buffer address, WHEN phase
3722: * ...
3723: * MOVE last buffer length, last buffer address, WHEN phase
3724: * JUMP other_transfer
3725: */
3726:
3727: /*
3728: * See if we're getting to data transfer by generating an unconditional
3729: * interrupt.
3730: */
3731: #if 0
3732: if (datain) {
3733: cmd_datain[0] = 0x98080000;
3734: cmd_datain[1] = 0x03ffd00d;
3735: cmd_datain += 2;
3736: }
3737: #endif
3738:
3739: /*
3740: * XXX - I'm undecided whether all of this nonsense is faster
3741: * in the long run, or whether I should just go and implement a loop
3742: * on the NCR chip using table indirect mode?
3743: *
3744: * In any case, this is how it _must_ be done for 53c700/700-66 chips,
3745: * so this stays even when we come up with something better.
3746: *
3747: * When we're limited to 1 simultaneous command, no overlapping processing,
3748: * we're seeing 630K/sec, with 7% CPU usage on a slow Syquest 45M
3749: * drive.
3750: *
3751: * Not bad, not good. We'll see.
3752: */
3753:
3754: for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4,
3755: cmd_dataout += 4, ++i) {
3756: u32 buf = cmd->use_sg ?
3757: virt_to_bus(((struct scatterlist *)cmd->buffer)[i].address) :
3758: virt_to_bus(cmd->request_buffer);
3759: u32 count = cmd->use_sg ?
3760: ((struct scatterlist *)cmd->buffer)[i].length :
3761: cmd->request_bufflen;
3762:
3763: if (datain) {
3764: /* CALL other_in, WHEN NOT DATA_IN */
3765: cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
3766: DCMD_TCI_IO) << 24) |
3767: DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
3768: cmd_datain[1] = virt_to_bus (hostdata->script) +
3769: hostdata->E_other_in;
3770: /* MOVE count, buf, WHEN DATA_IN */
3771: cmd_datain[2] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | DCMD_BMI_IO)
3772: << 24) | count;
3773: cmd_datain[3] = buf;
3774: #if 0
3775: print_insn (host, cmd_datain, "dynamic ", 1);
3776: print_insn (host, cmd_datain + 2, "dynamic ", 1);
3777: #endif
3778: }
3779: if (dataout) {
3780: /* CALL other_out, WHEN NOT DATA_OUT */
3781: cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL) << 24) |
3782: DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
3783: cmd_dataout[1] = virt_to_bus(hostdata->script) +
3784: hostdata->E_other_out;
3785: /* MOVE count, buf, WHEN DATA+OUT */
3786: cmd_dataout[2] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I) << 24)
3787: | count;
3788: cmd_dataout[3] = buf;
3789: #if 0
3790: print_insn (host, cmd_dataout, "dynamic ", 1);
3791: print_insn (host, cmd_dataout + 2, "dynamic ", 1);
3792: #endif
3793: }
3794: }
3795:
3796: /*
3797: * Install JUMP instructions after the data transfer routines to return
3798: * control to the do_other_transfer routines.
3799: */
3800:
3801:
3802: if (datain) {
3803: cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
3804: DBC_TCI_TRUE;
3805: cmd_datain[1] = virt_to_bus(hostdata->script) +
3806: hostdata->E_other_transfer;
3807: #if 0
3808: print_insn (host, cmd_datain, "dynamic jump ", 1);
3809: #endif
3810: cmd_datain += 2;
3811: }
3812: #if 0
3813: if (datain) {
3814: cmd_datain[0] = 0x98080000;
3815: cmd_datain[1] = 0x03ffdeed;
3816: cmd_datain += 2;
3817: }
3818: #endif
3819: if (dataout) {
3820: cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
3821: DBC_TCI_TRUE;
3822: cmd_dataout[1] = virt_to_bus(hostdata->script) +
3823: hostdata->E_other_transfer;
3824: #if 0
3825: print_insn (host, cmd_dataout, "dynamic jump ", 1);
3826: #endif
3827: cmd_dataout += 2;
3828: }
3829: return tmp;
3830: }
3831:
3832: /*
3833: * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd,
3834: * void (*done)(Scsi_Cmnd *))
3835: *
3836: * Purpose : enqueues a SCSI command
3837: *
3838: * Inputs : cmd - SCSI command, done - function called on completion, with
3839: * a pointer to the command descriptor.
3840: *
3841: * Returns : 0
3842: *
3843: * Side effects :
3844: * cmd is added to the per instance driver issue_queue, with major
3845: * twiddling done to the host specific fields of cmd. If the
3846: * process_issue_queue corouting isn't running, it is restarted.
3847: *
3848: * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to
3849: * hold our own data, and pervert the ptr field of the SCp field
3850: * to create a linked list.
3851: */
3852:
3853: int
3854: NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
3855: struct Scsi_Host *host = cmd->host;
3856: struct NCR53c7x0_hostdata *hostdata =
3857: (struct NCR53c7x0_hostdata *) host->hostdata;
3858: unsigned long flags;
3859: Scsi_Cmnd *tmp;
3860:
3861: cmd->scsi_done = done;
3862: cmd->host_scribble = NULL;
3863: cmd->SCp.ptr = NULL;
3864: cmd->SCp.buffer = NULL;
3865:
3866: save_flags(flags);
3867: cli();
3868: if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY))
3869: || ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
3870: !(hostdata->debug_lun_limit[cmd->target] & (1 << cmd->lun)))
3871: #ifdef LINUX_1_2
3872: || cmd->target > 7
3873: #else
3874: || cmd->target > host->max_id
3875: #endif
3876: || cmd->target == host->this_id
3877: || hostdata->state == STATE_DISABLED) {
3878: printk("scsi%d : disabled or bad target %d lun %d\n", host->host_no,
3879: cmd->target, cmd->lun);
3880: cmd->result = (DID_BAD_TARGET << 16);
3881: } else if ((hostdata->options & OPTION_DEBUG_NCOMMANDS_LIMIT) &&
3882: (hostdata->debug_count_limit == 0)) {
3883: printk("scsi%d : maximum commands exceeded\n", host->host_no);
3884: cmd->result = (DID_BAD_TARGET << 16);
3885: cmd->result = (DID_BAD_TARGET << 16);
3886: } else if (hostdata->options & OPTION_DEBUG_READ_ONLY) {
3887: switch (cmd->cmnd[0]) {
3888: case WRITE_6:
3889: case WRITE_10:
3890: printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
3891: host->host_no);
3892: cmd->result = (DID_BAD_TARGET << 16);
3893: }
3894: } else {
3895: if ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
3896: hostdata->debug_count_limit != -1)
3897: --hostdata->debug_count_limit;
3898: restore_flags (flags);
3899: cmd->result = 0xffff; /* The NCR will overwrite message
3900: and status with valid data */
3901: cmd->host_scribble = (unsigned char *) tmp = create_cmd (cmd);
3902: }
3903: cli();
3904: /*
3905: * REQUEST SENSE commands are inserted at the head of the queue
3906: * so that we do not clear the contingent allegience condition
3907: * they may be looking at.
3908: */
3909:
3910: if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
3911: cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
3912: hostdata->issue_queue = cmd;
3913: } else {
3914: for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr;
3915: tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
3916: tmp->SCp.ptr = (unsigned char *) cmd;
3917: }
3918: restore_flags (flags);
3919: run_process_issue_queue();
3920: return 0;
3921: }
3922:
3923: /*
3924: * Function : void to_schedule_list (struct Scsi_Host *host,
3925: * struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd)
3926: *
3927: * Purpose : takes a SCSI command which was just removed from the
3928: * issue queue, and deals with it by inserting it in the first
3929: * free slot in the schedule list or by terminating it immediately.
3930: *
3931: * Inputs :
3932: * host - SCSI host adater; hostdata - hostdata structure for
3933: * this adapter; cmd - a pointer to the command; should have
3934: * the host_scribble field initialized to point to a valid
3935: *
3936: * Side effects :
3937: * cmd is added to the per instance schedule list, with minor
3938: * twiddling done to the host specific fields of cmd.
3939: *
3940: */
3941:
3942: static __inline__ void
3943: to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
3944: struct NCR53c7x0_cmd *cmd) {
3945: NCR53c7x0_local_declare();
3946: Scsi_Cmnd *tmp = cmd->cmd;
3947: unsigned long flags;
3948: /* dsa start is negative, so subtraction is used */
3949: volatile u32 *current;
3950:
3951: int i;
3952: NCR53c7x0_local_setup(host);
3953: #if 0
3954: printk("scsi%d : new dsa is 0x%lx (virt 0x%p)\n", host->host_no,
3955: virt_to_bus(dsa), dsa);
3956: #endif
3957:
3958: save_flags(flags);
3959: cli();
3960:
3961: /*
3962: * Work arround race condition : if an interrupt fired and we
3963: * got disabled forget about this command.
3964: */
3965:
3966: if (hostdata->state == STATE_DISABLED) {
3967: printk("scsi%d : driver disabled\n", host->host_no);
3968: tmp->result = (DID_BAD_TARGET << 16);
3969: cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
3970: hostdata->free = cmd;
3971: tmp->scsi_done(tmp);
3972: restore_flags (flags);
3973: return;
3974: }
3975:
3976: for (i = host->can_queue, current = hostdata->schedule;
3977: i > 0 && current[0] != hostdata->NOP_insn;
3978: --i, current += 2 /* JUMP instructions are two words */);
3979:
3980: if (i > 0) {
3981: ++hostdata->busy[tmp->target][tmp->lun];
3982: cmd->next = hostdata->running_list;
3983: hostdata->running_list = cmd;
3984:
3985: /* Restore this instruction to a NOP once the command starts */
3986: cmd->dsa [(hostdata->dsa_jump_dest - hostdata->dsa_start) /
3987: sizeof(u32)] = (u32) virt_to_bus ((void *)current);
3988: /* Replace the current jump operand. */
3989: current[1] =
3990: virt_to_bus ((void *) cmd->dsa) + hostdata->E_dsa_code_begin -
3991: hostdata->E_dsa_code_template;
3992: /* Replace the NOP instruction with a JUMP */
3993: current[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) |
3994: DBC_TCI_TRUE;
3995: } else {
3996: printk ("scsi%d: no free slot\n", host->host_no);
3997: disable(host);
3998: tmp->result = (DID_ERROR << 16);
3999: cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
4000: hostdata->free = cmd;
4001: tmp->scsi_done(tmp);
4002: restore_flags (flags);
4003: return;
4004: }
4005:
4006: /*
4007: * If the NCR chip is in an idle state, start it running the scheduler
4008: * immediately. Otherwise, signal the chip to jump to schedule as
4009: * soon as it is idle.
4010: */
4011: if (hostdata->idle) {
4012: hostdata->idle = 0;
4013: hostdata->state = STATE_RUNNING;
4014: NCR53c7x0_write32 (DSP_REG, virt_to_bus ((void *)hostdata->schedule));
4015: } else {
4016: NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP);
4017: }
4018:
4019: restore_flags(flags);
4020: }
4021:
4022: /*
4023: * Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata
4024: * *hostdata, Scsi_Cmnd *cmd)
4025: *
4026: * Purpose : decide if we can pass the given SCSI command on to the
4027: * device in question or not.
4028: *
4029: * Returns : non-zero when we're busy, 0 when we aren't.
4030: */
4031:
4032: static __inline__ int
4033: busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
4034: Scsi_Cmnd *cmd) {
4035: /* FIXME : in the future, this needs to accomodate SCSI-II tagged
4036: queuing, and we may be able to play with fairness here a bit.
4037: */
4038: return hostdata->busy[cmd->target][cmd->lun];
4039: }
4040:
4041: /*
4042: * Function : process_issue_queue (void)
4043: *
4044: * Purpose : transfer commands from the issue queue to NCR start queue
4045: * of each NCR53c7/8xx in the system, avoiding kernel stack
4046: * overflows when the scsi_done() function is invoked recursively.
4047: *
4048: * NOTE : process_issue_queue exits with interrupts *disabled*, so the
4049: * caller must renable them if it desires.
4050: *
4051: * NOTE : process_issue_queue should be called from both
4052: * NCR53c7x0_queue_command() and from the interrupt handler
4053: * after command completion in case NCR53c7x0_queue_command()
4054: * isn't invoked again but we've freed up resources that are
4055: * needed.
4056: */
4057:
4058: static void
4059: process_issue_queue (unsigned long flags) {
4060: Scsi_Cmnd *tmp, *prev;
4061: struct Scsi_Host *host;
4062: struct NCR53c7x0_hostdata *hostdata;
4063: int done;
4064:
4065: /*
4066: * We run (with interrupts disabled) until we're sure that none of
4067: * the host adapters have anything that can be done, at which point
4068: * we set process_issue_queue_running to 0 and exit.
4069: *
4070: * Interrupts are enabled before doing various other internal
4071: * instructions, after we've decided that we need to run through
4072: * the loop again.
4073: *
4074: */
4075:
4076: do {
4077: cli(); /* Freeze request queues */
4078: done = 1;
4079: for (host = first_host; host && host->hostt == the_template;
4080: host = host->next) {
4081: hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
4082: cli();
4083: if (hostdata->issue_queue) {
4084: if (hostdata->state == STATE_DISABLED) {
4085: tmp = (Scsi_Cmnd *) hostdata->issue_queue;
4086: hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
4087: tmp->result = (DID_BAD_TARGET << 16);
4088: if (tmp->host_scribble) {
4089: ((struct NCR53c7x0_cmd *)tmp->host_scribble)->next =
4090: hostdata->free;
4091: hostdata->free =
4092: (struct NCR53c7x0_cmd *)tmp->host_scribble;
4093: tmp->host_scribble = NULL;
4094: }
4095: tmp->scsi_done (tmp);
4096: done = 0;
4097: } else
4098: for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
4099: prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *)
4100: tmp->SCp.ptr)
4101: if (!tmp->host_scribble ||
4102: !busyp (host, hostdata, tmp)) {
4103: if (prev)
4104: prev->SCp.ptr = tmp->SCp.ptr;
4105: else
4106: hostdata->issue_queue = (Scsi_Cmnd *)
4107: tmp->SCp.ptr;
4108: tmp->SCp.ptr = NULL;
4109: if (tmp->host_scribble) {
4110: if (hostdata->options & OPTION_DEBUG_QUEUES)
4111: printk ("scsi%d : moving command for target %d lun %d to start list\n",
4112: host->host_no, tmp->target, tmp->lun);
4113:
4114:
4115: to_schedule_list (host, hostdata,
4116: (struct NCR53c7x0_cmd *)
4117: tmp->host_scribble);
4118: } else {
4119: if (((tmp->result & 0xff) == 0xff) ||
4120: ((tmp->result & 0xff00) == 0xff00)) {
4121: printk ("scsi%d : danger Will Robinson!\n",
4122: host->host_no);
4123: tmp->result = DID_ERROR << 16;
4124: disable (host);
4125: }
4126: tmp->scsi_done(tmp);
4127: }
4128: done = 0;
4129: } /* if target/lun is not busy */
4130: } /* if hostdata->issue_queue */
4131: if (!done)
4132: restore_flags (flags);
4133: } /* for host */
4134: } while (!done);
4135: process_issue_queue_running = 0;
4136: }
4137:
4138: /*
4139: * Function : static void intr_scsi (struct Scsi_Host *host,
4140: * struct NCR53c7x0_cmd *cmd)
4141: *
4142: * Purpose : handle all SCSI interrupts, indicated by the setting
4143: * of the SIP bit in the ISTAT register.
4144: *
4145: * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
4146: * may be NULL.
4147: */
4148:
4149: static void
4150: intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
4151: NCR53c7x0_local_declare();
4152: struct NCR53c7x0_hostdata *hostdata =
4153: (struct NCR53c7x0_hostdata *) host->hostdata;
4154: unsigned char sstat0_sist0, sist1, /* Registers */
4155: fatal; /* Did a fatal interrupt
4156: occur ? */
4157:
4158: int is_8xx_chip;
4159: NCR53c7x0_local_setup(host);
4160:
4161: fatal = 0;
4162:
4163: is_8xx_chip = ((unsigned) (hostdata->chip - 800)) < 100;
4164: if (is_8xx_chip) {
4165: sstat0_sist0 = NCR53c7x0_read8(SIST0_REG_800);
4166: udelay(1);
4167: sist1 = NCR53c7x0_read8(SIST1_REG_800);
4168: } else {
4169: sstat0_sist0 = NCR53c7x0_read8(SSTAT0_REG);
4170: sist1 = 0;
4171: }
4172:
4173: if (hostdata->options & OPTION_DEBUG_INTR)
4174: printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0x\n", host->host_no,
4175: sstat0_sist0, sist1);
4176:
4177: /* 250ms selection timeout */
4178: if ((is_8xx_chip && (sist1 & SIST1_800_STO)) ||
4179: (!is_8xx_chip && (sstat0_sist0 & SSTAT0_700_STO))) {
4180: fatal = 1;
4181: if (hostdata->options & OPTION_DEBUG_INTR) {
4182: printk ("scsi%d : Selection Timeout\n", host->host_no);
4183: if (cmd) {
4184: printk("scsi%d : target %d, lun %d, command ",
4185: host->host_no, cmd->cmd->target, cmd->cmd->lun);
4186: print_command (cmd->cmd->cmnd);
4187: printk("scsi%d : dsp = 0x%x (virt 0x%p)\n", host->host_no,
4188: NCR53c7x0_read32(DSP_REG),
4189: bus_to_virt(NCR53c7x0_read32(DSP_REG)));
4190: } else {
4191: printk("scsi%d : no command\n", host->host_no);
4192: }
4193: }
4194: /*
4195: * XXX - question : how do we want to handle the Illegal Instruction
4196: * interrupt, which may occur before or after the Selection Timeout
4197: * interrupt?
4198: */
4199:
4200: if (1) {
4201: hostdata->idle = 1;
4202: hostdata->expecting_sto = 0;
4203:
4204: if (hostdata->test_running) {
4205: hostdata->test_running = 0;
4206: hostdata->test_completed = 3;
4207: } else if (cmd) {
4208: abnormal_finished(cmd, DID_BAD_TARGET << 16);
4209: }
4210: #if 0
4211: hostdata->intrs = 0;
4212: #endif
4213: }
4214: }
4215:
4216: /*
4217: * FIXME : in theory, we can also get a UDC when a STO occurs.
4218: */
4219: if (sstat0_sist0 & SSTAT0_UDC) {
4220: fatal = 1;
4221: if (cmd) {
4222: printk("scsi%d : target %d lun %d unexpected disconnect\n",
4223: host->host_no, cmd->cmd->target, cmd->cmd->lun);
4224: print_lots (host);
4225: abnormal_finished(cmd, DID_ERROR << 16);
4226: } else
4227: printk("scsi%d : unexpected disconnect (no command)\n",
4228: host->host_no);
4229:
4230: hostdata->dsp = (u32 *) hostdata->schedule;
4231: hostdata->dsp_changed = 1;
4232: }
4233:
4234: /* SCSI PARITY error */
4235: if (sstat0_sist0 & SSTAT0_PAR) {
4236: fatal = 1;
4237: if (cmd && cmd->cmd) {
4238: printk("scsi%d : target %d lun %d parity error.\n",
4239: host->host_no, cmd->cmd->target, cmd->cmd->lun);
4240: abnormal_finished (cmd, DID_PARITY << 16);
4241: } else
4242: printk("scsi%d : parity error\n", host->host_no);
4243: /* Should send message out, parity error */
4244:
4245: /* XXX - Reduce synchronous transfer rate! */
4246: hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
4247: sizeof(u32);
4248: hostdata->dsp_changed = 1;
4249: /* SCSI GROSS error */
4250: }
4251:
4252: if (sstat0_sist0 & SSTAT0_SGE) {
4253: fatal = 1;
4254: printk("scsi%d : gross error\n", host->host_no);
4255: /* Reset SCSI offset */
4256: if ((hostdata->chip / 100) == 8) {
4257: NCR53c7x0_write8 (STEST2_REG_800, STEST2_800_ROF);
4258: }
4259:
4260: /*
4261: * A SCSI gross error may occur when we have
4262: *
4263: * - A synchronous offset which causes the SCSI FIFO to be overwritten.
4264: *
4265: * - A REQ which causes the maxmimum synchronous offset programmed in
4266: * the SXFER register to be exceeded.
4267: *
4268: * - A phase change with an outstanding synchronous offset.
4269: *
4270: * - Residual data in the synchronous data FIFO, with a transfer
4271: * other than a synchronous receive is started.$#
4272: */
4273:
4274:
4275: /* XXX Should deduce synchronous transfer rate! */
4276: hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
4277: sizeof(u32);
4278: hostdata->dsp_changed = 1;
4279: /* Phase mismatch */
4280: }
4281:
4282: if (sstat0_sist0 & SSTAT0_MA) {
4283: fatal = 1;
4284: if (hostdata->options & OPTION_DEBUG_INTR)
4285: printk ("scsi%d : SSTAT0_MA\n", host->host_no);
4286: intr_phase_mismatch (host, cmd);
4287: }
4288:
4289: #if 0
4290: if (sstat0_sist0 & SIST0_800_RSL)
4291: printk ("scsi%d : Oh no Mr. Bill!\n", host->host_no);
4292: #endif
4293:
4294: /*
4295: * If a fatal SCSI interrupt occurs, we must insure that the DMA and
4296: * SCSI FIFOs were flushed.
4297: */
4298:
4299: if (fatal) {
4300: if (!hostdata->dstat_valid) {
4301: hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
4302: hostdata->dstat_valid = 1;
4303: }
4304:
4305: /* XXX - code check for 700/800 chips */
4306: if (!(hostdata->dstat & DSTAT_DFE)) {
4307: printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
4308: if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
4309: printk ("scsi%d: Flushing DMA FIFO\n",
4310: host->host_no);
4311: NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
4312: while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
4313: DSTAT_DFE));
4314: } else {
4315: NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
4316: while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
4317: }
4318: hostdata->dstat |= DSTAT_DFE;
4319: }
4320: }
4321: }
4322:
4323: /*
4324: * Function : static void NCR53c7x0_intr (int irq, struct pt_regs * regs)
4325: *
4326: * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing
4327: * the same IRQ line.
4328: *
4329: * Inputs : Since we're using the SA_INTERRUPT interrupt handler
4330: * semantics, irq indicates the interrupt which invoked
4331: * this handler.
4332: */
4333:
4334: static void
4335: NCR53c7x0_intr (int irq, struct pt_regs * regs) {
4336: NCR53c7x0_local_declare();
4337: struct Scsi_Host *host; /* Host we are looking at */
4338: unsigned char istat; /* Values of interrupt regs */
4339: struct NCR53c7x0_hostdata *hostdata; /* host->hostdata */
4340: struct NCR53c7x0_cmd *cmd, /* command which halted */
4341: **cmd_prev_ptr;
4342: u32 *dsa; /* DSA */
4343: int done = 1; /* Indicates when handler
4344: should terminate */
4345: int interrupted = 0; /* This HA generated
4346: an interrupt */
4347: int have_intfly; /* Don't print warning
4348: messages when we stack
4349: INTFLYs */
4350: unsigned long flags;
4351:
4352: #ifdef NCR_DEBUG
4353: char buf[80]; /* Debugging sprintf buffer */
4354: size_t buflen; /* Length of same */
4355: #endif
4356:
4357: do {
4358: done = 1;
4359: for (host = first_host; host; host = host->next)
4360: if (host->hostt == the_template && host->irq == irq) {
4361: NCR53c7x0_local_setup(host);
4362:
4363: hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
4364: hostdata->dsp_changed = 0;
4365: interrupted = 0;
4366: have_intfly = 0;
4367:
4368: do {
4369: int is_8xx_chip;
4370:
4371: hostdata->dstat_valid = 0;
4372: interrupted = 0;
4373: /*
4374: * Only read istat once, since reading it again will unstack
4375: * interrupts?
4376: */
4377: istat = NCR53c7x0_read8(hostdata->istat);
4378:
4379: /*
4380: * INTFLY interrupts are used by the NCR53c720, NCR53c810,
4381: * and NCR53c820 to signify completion of a command. Since
4382: * the SCSI processor continues running, we can't just look
4383: * at the contents of the DSA register and continue running.
4384: */
4385: /* XXX - this is too big, offends my sense of aesthetics, and should
4386: move to intr_intfly() */
4387: is_8xx_chip = ((unsigned) (hostdata->chip - 800)) < 100;
4388: if ((hostdata->options & OPTION_INTFLY) &&
4389: (is_8xx_chip && (istat & ISTAT_800_INTF))) {
4390: char search_found = 0; /* Got at least one ? */
4391: done = 0;
4392: interrupted = 1;
4393:
4394: /*
4395: * Clear the INTF bit by writing a one.
4396: * This reset operation is self-clearing.
4397: */
4398: NCR53c7x0_write8(hostdata->istat, istat|ISTAT_800_INTF);
4399:
4400: if (hostdata->options & OPTION_DEBUG_INTR)
4401: printk ("scsi%d : INTFLY\n", host->host_no);
4402:
4403: /*
4404: * Traverse our list of running commands, and look
4405: * for those with valid (non-0xff ff) status and message
4406: * bytes encoded in the result which signify command
4407: * completion.
4408: */
4409:
4410:
4411: save_flags(flags);
4412: cli();
4413: restart:
4414: for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)
4415: &(hostdata->running_list), cmd =
4416: (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
4417: cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next),
4418: cmd = (struct NCR53c7x0_cmd *) cmd->next) {
4419: Scsi_Cmnd *tmp;
4420:
4421: if (!cmd) {
4422: printk("scsi%d : very weird.\n", host->host_no);
4423: break;
4424: }
4425:
4426: if (!(tmp = cmd->cmd)) {
4427: printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n",
4428: host->host_no);
4429: continue;
4430: }
4431: #if 0
4432: printk ("scsi%d : looking at result of 0x%x\n",
4433: host->host_no, cmd->cmd->result);
4434: #endif
4435:
4436: if (((tmp->result & 0xff) == 0xff) ||
4437: ((tmp->result & 0xff00) == 0xff00))
4438: continue;
4439:
4440: search_found = 1;
4441:
4442: /* Important - remove from list _before_ done is called */
4443: if (cmd_prev_ptr)
4444: *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
4445:
4446: --hostdata->busy[tmp->target][tmp->lun];
4447: cmd->next = hostdata->free;
4448: hostdata->free = cmd;
4449:
4450: tmp->host_scribble = NULL;
4451:
4452: if (hostdata->options & OPTION_DEBUG_INTR) {
4453: printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ",
4454: host->host_no, tmp->pid, tmp->target, tmp->lun, tmp->result);
4455: print_command (tmp->cmnd);
4456: }
4457:
4458: #if 0
4459: hostdata->options &= ~OPTION_DEBUG_INTR;
4460: #endif
4461: tmp->scsi_done(tmp);
4462: goto restart;
4463:
4464: }
4465: restore_flags(flags);
4466:
4467: /*
4468: * I think that we're stacking INTFLY interrupts; taking care of
4469: * all the finished commands on the first one, and then getting
4470: * worried when we see the next one. The magic with have_intfly
4471: * should tell if this is the case..
4472: */
4473:
4474: if (!search_found && !have_intfly) {
4475: printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
4476: host->host_no);
4477: } else if (!have_intfly) {
4478: have_intfly = 1;
4479: run_process_issue_queue();
4480: }
4481: }
4482:
4483: if (istat & (ISTAT_SIP|ISTAT_DIP)) {
4484: done = 0;
4485: interrupted = 1;
4486: hostdata->state = STATE_HALTED;
4487:
4488: if (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ?
4489: SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK)
4490: printk ("scsi%d : SCSI FIFO not empty\n",
4491: host->host_no);
4492:
4493: /*
4494: * NCR53c700 and NCR53c700-66 change the current SCSI
4495: * process, hostdata->current, in the Linux driver so
4496: * cmd = hostdata->current.
4497: *
4498: * With other chips, we must look through the commands
4499: * executing and find the command structure which
4500: * corresponds to the DSA register.
4501: */
4502:
4503: if (hostdata->options & OPTION_700) {
4504: cmd = (struct NCR53c7x0_cmd *) hostdata->current;
4505: } else {
4506: dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
4507: for (cmd = (struct NCR53c7x0_cmd *)
4508: hostdata->running_list; cmd &&
4509: (dsa + (hostdata->dsa_start / sizeof(u32))) !=
4510: cmd->dsa;
4511: cmd = (struct NCR53c7x0_cmd *)(cmd->next));
4512: }
4513: if (hostdata->options & OPTION_DEBUG_INTR) {
4514: if (cmd) {
4515: printk("scsi%d : interrupt for pid %lu, id %d, lun %d ",
4516: host->host_no, cmd->cmd->pid, (int) cmd->cmd->target,
4517: (int) cmd->cmd->lun);
4518: print_command (cmd->cmd->cmnd);
4519: } else {
4520: printk("scsi%d : no active command\n", host->host_no);
4521: }
4522: }
4523:
4524: if (istat & ISTAT_SIP) {
4525: if (hostdata->options & OPTION_DEBUG_INTR)
4526: printk ("scsi%d : ISTAT_SIP\n", host->host_no);
4527: intr_scsi (host, cmd);
4528: }
4529:
4530: if (istat & ISTAT_DIP) {
4531: if (hostdata->options & OPTION_DEBUG_INTR)
4532: printk ("scsi%d : ISTAT_DIP\n", host->host_no);
4533: intr_dma (host, cmd);
4534: }
4535:
4536: if (!hostdata->dstat_valid) {
4537: hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
4538: hostdata->dstat_valid = 1;
4539: }
4540:
4541: /* XXX - code check for 700/800 chips */
4542: if (!(hostdata->dstat & DSTAT_DFE)) {
4543: printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
4544: if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
4545: printk ("scsi%d: Flushing DMA FIFO\n",
4546: host->host_no);
4547: NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
4548: while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
4549: DSTAT_DFE));
4550: } else
4551: {
4552: NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
4553: while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
4554: }
4555: hostdata->dstat |= DSTAT_DFE;
4556: }
4557: }
4558: } while (interrupted);
4559:
4560:
4561:
4562: if (hostdata->intrs != -1)
4563: hostdata->intrs++;
4564: #if 0
4565: if (hostdata->intrs > 40) {
4566: printk("scsi%d : too many interrupts, halting", host->host_no);
4567: disable(host);
4568: }
4569: #endif
4570:
4571: if (!hostdata->idle && hostdata->state == STATE_HALTED) {
4572: if (!hostdata->dsp_changed) {
4573: hostdata->dsp = (u32 *)
4574: bus_to_virt(NCR53c7x0_read32(DSP_REG));
4575: }
4576:
4577: #if 0
4578: printk("scsi%d : new dsp is 0x%lx (virt 0x%p)\n",
4579: host->host_no, virt_to_bus(hostdata->dsp), hostdata->dsp);
4580: #endif
4581:
4582: hostdata->state = STATE_RUNNING;
4583: NCR53c7x0_write32 (DSP_REG, virt_to_bus(hostdata->dsp));
4584: }
4585: }
4586: } while (!done);
4587: }
4588:
4589:
4590: /*
4591: * Function : static int abort_connected (struct Scsi_Host *host)
4592: *
4593: * Purpose : Assuming that the NCR SCSI processor is currently
4594: * halted, break the currently established nexus. Clean
4595: * up of the NCR53c7x0_cmd and Scsi_Cmnd structures should
4596: * be done on receipt of the abort interrupt.
4597: *
4598: * Inputs : host - SCSI host
4599: *
4600: */
4601:
4602: static int
4603: abort_connected (struct Scsi_Host *host) {
4604: #ifdef NEW_ABORT
4605: NCR53c7x0_local_declare();
4606: #endif
4607: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
4608: host->hostdata;
4609: /* FIXME : this probably should change for production kernels; at the
4610: least, counter sould move to a per-host structure. */
4611: static int counter = 5;
4612: #ifdef NEW_ABORT
4613: int sstat, phase, offset;
4614: u32 *script;
4615: NCR53c7x0_local_setup(host);
4616: #endif
4617:
4618: if (--counter <= 0) {
4619: disable(host);
4620: return 0;
4621: }
4622:
4623: printk ("scsi%d : DANGER : abort_connected() called \n",
4624: host->host_no);
4625:
4626: #ifdef NEW_ABORT
4627:
4628: /*
4629: * New strategy : Rather than using a generic abort routine,
4630: * we'll specifically try to source or sink the appropriate
4631: * amount of data for the phase we're currently in (taking into
4632: * account the current synchronous offset)
4633: */
4634:
4635: sstat = (NCR53c8x0_read8 ((chip / 100) == 8 ? SSTAT1_REG : SSTAT2_REG);
4636: offset = OFFSET (sstat & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
4637: phase = sstat & SSTAT2_PHASE_MASK;
4638:
4639: /*
4640: * SET ATN
4641: * MOVE source_or_sink, WHEN CURRENT PHASE
4642: * < repeat for each outstanding byte >
4643: * JUMP send_abort_message
4644: */
4645:
4646: script = hostdata->abort_script = kmalloc (
4647: 8 /* instruction size */ * (
4648: 1 /* set ATN */ +
4649: (!offset ? 1 : offset) /* One transfer per outstanding byte */ +
4650: 1 /* send abort message */),
4651: GFP_ATOMIC);
4652:
4653:
4654: #else /* def NEW_ABORT */
4655: hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
4656: sizeof(u32);
4657: #endif /* def NEW_ABORT */
4658: hostdata->dsp_changed = 1;
4659:
4660: /* XXX - need to flag the command as aborted after the abort_connected
4661: code runs
4662: */
4663: return 0;
4664: }
4665:
4666: /*
4667: * Function : static int datapath_residual (Scsi_Host *host)
4668: *
4669: * Purpose : return residual data count of what's in the chip.
4670: *
4671: * Inputs : host - SCSI host
4672: */
4673:
4674: static int
4675: datapath_residual (struct Scsi_Host *host) {
4676: NCR53c7x0_local_declare();
4677: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
4678: host->hostdata;
4679: int count, synchronous, sstat;
4680: NCR53c7x0_local_setup(host);
4681: /* COMPAT : the 700 and 700-66 need to use DFIFO_00_BO_MASK */
4682: count = ((NCR53c7x0_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) -
4683: (NCR53c7x0_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK;
4684: synchronous = NCR53c7x0_read8 (SXFER_REG) & SXFER_MO_MASK;
4685: /* COMPAT : DDIR is elsewhere on non-'8xx chips. */
4686: if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
4687: /* Receive */
4688: if (synchronous)
4689: count += (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ?
4690: SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
4691: else
4692: if (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ?
4693: SSTAT0_REG : SSTAT1_REG) & SSTAT1_ILF)
4694: ++count;
4695: } else {
4696: /* Send */
4697: sstat = ((hostdata->chip / 100) == 8) ? NCR53c7x0_read8 (SSTAT0_REG) :
4698: NCR53c7x0_read8 (SSTAT1_REG);
4699: if (sstat & SSTAT1_OLF)
4700: ++count;
4701: if (synchronous && (sstat & SSTAT1_ORF))
4702: ++count;
4703: }
4704: return count;
4705: }
4706:
4707: /*
4708: * Function : static const char * sbcl_to_phase (int sbcl)_
4709: *
4710: * Purpose : Convert SBCL register to user-parsable phase representation
4711: *
4712: * Inputs : sbcl - value of sbcl register
4713: */
4714:
4715:
4716: static const char *
4717: sbcl_to_phase (int sbcl) {
4718: switch (sbcl & SBCL_PHASE_MASK) {
4719: case SBCL_PHASE_DATAIN:
4720: return "DATAIN";
4721: case SBCL_PHASE_DATAOUT:
4722: return "DATAOUT";
4723: case SBCL_PHASE_MSGIN:
4724: return "MSGIN";
4725: case SBCL_PHASE_MSGOUT:
4726: return "MSGOUT";
4727: case SBCL_PHASE_CMDOUT:
4728: return "CMDOUT";
4729: case SBCL_PHASE_STATIN:
4730: return "STATUSIN";
4731: default:
4732: return "unknown";
4733: }
4734: }
4735:
4736: /*
4737: * Function : static const char * sstat2_to_phase (int sstat)_
4738: *
4739: * Purpose : Convert SSTAT2 register to user-parsable phase representation
4740: *
4741: * Inputs : sstat - value of sstat register
4742: */
4743:
4744:
4745: static const char *
4746: sstat2_to_phase (int sstat) {
4747: switch (sstat & SSTAT2_PHASE_MASK) {
4748: case SSTAT2_PHASE_DATAIN:
4749: return "DATAIN";
4750: case SSTAT2_PHASE_DATAOUT:
4751: return "DATAOUT";
4752: case SSTAT2_PHASE_MSGIN:
4753: return "MSGIN";
4754: case SSTAT2_PHASE_MSGOUT:
4755: return "MSGOUT";
4756: case SSTAT2_PHASE_CMDOUT:
4757: return "CMDOUT";
4758: case SSTAT2_PHASE_STATIN:
4759: return "STATUSIN";
4760: default:
4761: return "unknown";
4762: }
4763: }
4764:
4765: /*
4766: * Function : static void intr_phase_mismatch (struct Scsi_Host *host,
4767: * struct NCR53c7x0_cmd *cmd)
4768: *
4769: * Purpose : Handle phase mismatch interrupts
4770: *
4771: * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
4772: * may be NULL.
4773: *
4774: * Side effects : The abort_connected() routine is called or the NCR chip
4775: * is restarted, jumping to the command_complete entry point, or
4776: * patching the address and transfer count of the current instruction
4777: * and calling the msg_in entry point as appropriate.
4778: */
4779:
4780: static void
4781: intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
4782: NCR53c7x0_local_declare();
4783: u32 dbc_dcmd, *dsp, *dsp_next;
4784: unsigned char dcmd, sbcl;
4785: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
4786: host->hostdata;
4787: int residual;
4788: enum {ACTION_ABORT, ACTION_ABORT_PRINT, ACTION_CONTINUE} action =
4789: ACTION_ABORT_PRINT;
4790: const char *where = NULL;
4791: NCR53c7x0_local_setup(host);
4792:
4793: /*
4794: * Corrective action is based on where in the SCSI SCRIPT(tm) the error
4795: * occurred, as well as which SCSI phase we are currently in.
4796: */
4797: dsp_next = bus_to_virt(NCR53c7x0_read32(DSP_REG));
4798:
4799: /*
4800: * Fetch the current instruction, and remove the operands for easier
4801: * interpretation.
4802: */
4803: dbc_dcmd = NCR53c7x0_read32(DBC_REG);
4804: dcmd = (dbc_dcmd & 0xff000000) >> 24;
4805: /*
4806: * Like other processors, the NCR adjusts the instruction pointer before
4807: * instruction decode. Set the DSP address back to what it should
4808: * be for this instruction based on its size (2 or 3 32 bit words).
4809: */
4810: dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
4811:
4812:
4813: /*
4814: * Read new SCSI phase from the SBCL lines. Since all of our code uses
4815: * a WHEN conditional instead of an IF conditional, we don't need to
4816: * wait for a new REQ.
4817: */
4818: sbcl = NCR53c7x0_read8(SBCL_REG) & SBCL_PHASE_MASK;
4819:
4820: if (!cmd) {
4821: action = ACTION_ABORT_PRINT;
4822: where = "no current command";
4823: /*
4824: * The way my SCSI SCRIPTS(tm) are architected, recoverable phase
4825: * mismatches should only occur where we're doing a multi-byte
4826: * BMI instruction. Specifically, this means
4827: *
4828: * - select messages (a SCSI-I target may ignore additional messages
4829: * after the IDENTIFY; any target may reject a SDTR or WDTR)
4830: *
4831: * - command out (targets may send a message to signal an error
4832: * condition, or go into STATUSIN after they've decided
4833: * they don't like the command.
4834: *
4835: * - reply_message (targets may reject a multi-byte message in the
4836: * middle)
4837: *
4838: * - data transfer routines (command completion with buffer space
4839: * left, disconnect message, or error message)
4840: */
4841: } else if (((dsp >= cmd->data_transfer_start &&
4842: dsp < cmd->data_transfer_end)) || dsp == (cmd->residual + 2)) {
4843: if ((dcmd & (DCMD_TYPE_MASK|DCMD_BMI_OP_MASK|DCMD_BMI_INDIRECT|
4844: DCMD_BMI_MSG|DCMD_BMI_CD)) == (DCMD_TYPE_BMI|
4845: DCMD_BMI_OP_MOVE_I)) {
4846: residual = datapath_residual (host);
4847: if (hostdata->options & OPTION_DEBUG_DISCONNECT)
4848: printk ("scsi%d : handling residual transfer (+ %d bytes from DMA FIFO)\n",
4849: host->host_no, residual);
4850:
4851: /*
4852: * The first instruction is a CALL to the alternate handler for
4853: * this data transfer phase, so we can do calls to
4854: * munge_msg_restart as we would if control were passed
4855: * from normal dynamic code.
4856: */
4857: if (dsp != cmd->residual + 2) {
4858: cmd->residual[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
4859: ((dcmd & DCMD_BMI_IO) ? DCMD_TCI_IO : 0)) << 24) |
4860: DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
4861: cmd->residual[1] = virt_to_bus(hostdata->script)
4862: + ((dcmd & DCMD_BMI_IO)
4863: ? hostdata->E_other_in : hostdata->E_other_out);
4864: }
4865:
4866: /*
4867: * The second instruction is the a data transfer block
4868: * move instruction, reflecting the pointer and count at the
4869: * time of the phase mismatch.
4870: */
4871: cmd->residual[2] = dbc_dcmd + residual;
4872: cmd->residual[3] = NCR53c7x0_read32(DNAD_REG) - residual;
4873:
4874: /*
4875: * The third and final instruction is a jump to the instruction
4876: * which follows the instruction which had to be 'split'
4877: */
4878: if (dsp != cmd->residual + 2) {
4879: cmd->residual[4] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP)
4880: << 24) | DBC_TCI_TRUE;
4881: cmd->residual[5] = virt_to_bus(dsp_next);
4882: }
4883:
4884: /*
4885: * For the sake of simplicity, transfer control to the
4886: * conditional CALL at the start of the residual buffer.
4887: */
4888: hostdata->dsp = cmd->residual;
4889: hostdata->dsp_changed = 1;
4890: action = ACTION_CONTINUE;
4891: } else {
4892: where = "non-BMI dynamic DSA code";
4893: action = ACTION_ABORT_PRINT;
4894: }
4895: } else if (dsp == (hostdata->script + hostdata->E_select_msgout / 4)) {
4896: /* Release ATN */
4897: NCR53c7x0_write8 (SOCL_REG, 0);
4898: switch (sbcl) {
4899: /*
4900: * Some devices (SQ555 come to mind) grab the IDENTIFY message
4901: * sent on selection, and decide to go into COMMAND OUT phase
4902: * rather than accepting the rest of the messages or rejecting
4903: * them. Handle these devices gracefully.
4904: */
4905: case SBCL_PHASE_CMDOUT:
4906: hostdata->dsp = dsp + 2 /* two _words_ */;
4907: hostdata->dsp_changed = 1;
4908: printk ("scsi%d : target %d ignored SDTR and went into COMMAND OUT\n",
4909: host->host_no, cmd->cmd->target);
4910: cmd->flags &= ~CMD_FLAG_SDTR;
4911: action = ACTION_CONTINUE;
4912: break;
4913: case SBCL_PHASE_MSGIN:
4914: hostdata->dsp = hostdata->script + hostdata->E_msg_in /
4915: sizeof(u32);
4916: hostdata->dsp_changed = 1;
4917: action = ACTION_CONTINUE;
4918: break;
4919: default:
4920: where="select message out";
4921: action = ACTION_ABORT_PRINT;
4922: }
4923: /*
4924: * Some SCSI devices will interpret a command as they read the bytes
4925: * off the SCSI bus, and may decide that the command is Bogus before
4926: * they've read the entire commad off the bus.
4927: */
4928: } else if (dsp == hostdata->script + hostdata->E_cmdout_cmdout / sizeof
4929: (u32)) {
4930: hostdata->dsp = hostdata->script + hostdata->E_data_transfer /
4931: sizeof (u32);
4932: hostdata->dsp_changed = 1;
4933: action = ACTION_CONTINUE;
4934: /* FIXME : we need to handle message reject, etc. within msg_respond. */
4935: #ifdef notyet
4936: } else if (dsp == hostdata->script + hostdata->E_reply_message) {
4937: switch (sbcl) {
4938: /* Any other phase mismatches abort the currently executing command. */
4939: #endif
4940: } else {
4941: where = "unknown location";
4942: action = ACTION_ABORT_PRINT;
4943: }
4944:
4945: /* Flush DMA FIFO */
4946: if (!hostdata->dstat_valid) {
4947: hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
4948: hostdata->dstat_valid = 1;
4949: }
4950: if (!(hostdata->dstat & DSTAT_DFE)) {
4951: if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
4952: printk ("scsi%d: Flushing DMA FIFO\n",
4953: host->host_no);
4954: NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
4955: /* FIXME : what about stacked DMA interrupts? */
4956: while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
4957: DSTAT_DFE));
4958: } else {
4959: NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
4960: while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
4961: }
4962: hostdata->dstat |= DSTAT_DFE;
4963: }
4964:
4965: switch (action) {
4966: case ACTION_ABORT_PRINT:
4967: printk("scsi%d : %s : unexpected phase %s.\n",
4968: host->host_no, where ? where : "unknown location",
4969: sbcl_to_phase(sbcl));
4970: print_lots (host);
4971: /* Fall through to ACTION_ABORT */
4972: case ACTION_ABORT:
4973: abort_connected (host);
4974: break;
4975: case ACTION_CONTINUE:
4976: break;
4977: }
4978:
4979: #if 0
4980: if (hostdata->dsp_changed) {
4981: printk("scsi%d: new dsp 0x%p\n", host->host_no, hostdata->dsp);
4982: print_insn (host, hostdata->dsp, "", 1);
4983: }
4984: #endif
4985:
4986: }
4987:
4988: /*
4989: * Function : static void intr_bf (struct Scsi_Host *host,
4990: * struct NCR53c7x0_cmd *cmd)
4991: *
4992: * Purpose : handle BUS FAULT interrupts
4993: *
4994: * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
4995: * may be NULL.
4996: */
4997:
4998: static void
4999: intr_bf (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
5000: NCR53c7x0_local_declare();
5001: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
5002: host->hostdata;
5003: u32 *dsp,
5004: *next_dsp, /* Current dsp */
5005: *dsa,
5006: dbc_dcmd; /* DCMD (high eight bits) + DBC */
5007: unsigned short pci_status;
5008: int tmp;
5009: unsigned long flags;
5010: char *reason = NULL;
5011: /* Default behavior is for a silent error, with a retry until we've
5012: exhausted retries. */
5013: enum {MAYBE, ALWAYS, NEVER} retry = MAYBE;
5014: int report = 0;
5015: NCR53c7x0_local_setup(host);
5016:
5017: dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
5018: next_dsp = bus_to_virt (NCR53c7x0_read32(DSP_REG));
5019: dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
5020: /* FIXME - check chip type */
5021: dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
5022:
5023: /*
5024: * Bus faults can be caused by either a Bad Address or
5025: * Target Abort. We should check the Received Target Abort
5026: * bit of the PCI status register and Master Abort Bit.
5027: *
5028: * - Master Abort bit indicates that no device claimed
5029: * the address with DEVSEL within five clocks
5030: *
5031: * - Target Abort bit indicates that a target claimed it,
5032: * but changed its mind once it saw the byte enables.
5033: *
5034: */
5035:
5036: if ((hostdata->chip / 100) == 8) {
5037: save_flags (flags);
5038: cli();
5039: tmp = pcibios_read_config_word (hostdata->pci_bus,
5040: hostdata->pci_device_fn, PCI_STATUS, &pci_status);
5041: restore_flags (flags);
5042: if (tmp == PCIBIOS_SUCCESSFUL) {
5043: if (pci_status & PCI_STATUS_REC_TARGET_ABORT) {
5044: reason = "PCI target abort";
5045: pci_status &= ~PCI_STATUS_REC_TARGET_ABORT;
5046: } else if (pci_status & PCI_STATUS_REC_MASTER_ABORT) {
5047: reason = "No device asserted PCI DEVSEL within five bus clocks";
5048: pci_status &= ~PCI_STATUS_REC_MASTER_ABORT;
5049: } else if (pci_status & PCI_STATUS_PARITY) {
5050: report = 1;
5051: pci_status &= ~PCI_STATUS_PARITY;
5052: }
5053: } else {
5054: printk ("scsi%d : couldn't read status register : %s\n",
5055: host->host_no, pcibios_strerror (tmp));
5056: retry = NEVER;
5057: }
5058: }
5059:
5060: #ifndef notyet
5061: report = 1;
5062: #endif
5063: if (report && reason) {
5064: printk(KERN_ALERT "scsi%d : BUS FAULT reason = %s\n",
5065: host->host_no, reason ? reason : "unknown");
5066: print_lots (host);
5067: }
5068:
5069: #ifndef notyet
5070: retry = NEVER;
5071: #endif
5072:
5073: /*
5074: * TODO : we should attempt to recover from any spurious bus
5075: * faults. After X retries, we should figure that things are
5076: * sufficiently wedged, and call NCR53c7xx_reset.
5077: *
5078: * This code should only get executed once we've decided that we
5079: * cannot retry.
5080: */
5081:
5082: if (retry == NEVER) {
5083: printk(KERN_ALERT " mail [email protected]\n");
5084: FATAL (host);
5085: }
5086: }
5087:
5088: /*
5089: * Function : static void intr_dma (struct Scsi_Host *host,
5090: * struct NCR53c7x0_cmd *cmd)
5091: *
5092: * Purpose : handle all DMA interrupts, indicated by the setting
5093: * of the DIP bit in the ISTAT register.
5094: *
5095: * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
5096: * may be NULL.
5097: */
5098:
5099: static void
5100: intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
5101: NCR53c7x0_local_declare();
5102: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
5103: host->hostdata;
5104: unsigned char dstat; /* DSTAT */
5105: u32 *dsp,
5106: *next_dsp, /* Current dsp */
5107: *dsa,
5108: dbc_dcmd; /* DCMD (high eight bits) + DBC */
5109: int tmp;
5110: unsigned long flags;
5111: NCR53c7x0_local_setup(host);
5112:
5113: if (!hostdata->dstat_valid) {
5114: hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
5115: hostdata->dstat_valid = 1;
5116: }
5117:
5118: dstat = hostdata->dstat;
5119:
5120: if (hostdata->options & OPTION_DEBUG_INTR)
5121: printk("scsi%d : DSTAT=0x%x\n", host->host_no, (int) dstat);
5122:
5123: dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
5124: next_dsp = bus_to_virt(NCR53c7x0_read32(DSP_REG));
5125: dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
5126: /* XXX - check chip type */
5127: dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
5128:
5129: /*
5130: * DSTAT_ABRT is the aborted interrupt. This is set whenever the
5131: * SCSI chip is aborted.
5132: *
5133: * With NCR53c700 and NCR53c700-66 style chips, we should only
5134: * get this when the chip is currently running the accept
5135: * reselect/select code and we have set the abort bit in the
5136: * ISTAT register.
5137: *
5138: */
5139:
5140: if (dstat & DSTAT_ABRT) {
5141: #if 0
5142: /* XXX - add code here to deal with normal abort */
5143: if ((hostdata->options & OPTION_700) && (hostdata->state ==
5144: STATE_ABORTING)) {
5145: } else
5146: #endif
5147: {
5148: printk(KERN_ALERT "scsi%d : unexpected abort interrupt at\n"
5149: " ", host->host_no);
5150: print_insn (host, dsp, KERN_ALERT "s ", 1);
5151: FATAL (host);
5152: }
5153: }
5154:
5155: /*
5156: * DSTAT_SSI is the single step interrupt. Should be generated
5157: * whenever we have single stepped or are tracing.
5158: */
5159:
5160: if (dstat & DSTAT_SSI) {
5161: if (hostdata->options & OPTION_DEBUG_TRACE) {
5162: } else if (hostdata->options & OPTION_DEBUG_SINGLE) {
5163: print_insn (host, dsp, "s ", 0);
5164: save_flags(flags);
5165: cli();
5166: /* XXX - should we do this, or can we get away with writing dsp? */
5167:
5168: NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) &
5169: ~DCNTL_SSM) | DCNTL_STD);
5170: restore_flags(flags);
5171: } else {
5172: printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n"
5173: " ", host->host_no);
5174: print_insn (host, dsp, KERN_ALERT "", 1);
5175: printk(KERN_ALERT " mail [email protected]\n");
5176: FATAL (host);
5177: }
5178: }
5179:
5180: /*
5181: * DSTAT_IID / DSTAT_OPC (same bit, same meaning, only the name
5182: * is different) is generated whenever an illegal instruction is
5183: * encountered.
5184: *
5185: * XXX - we may want to emulate INTFLY here, so we can use
5186: * the same SCSI SCRIPT (tm) for NCR53c710 through NCR53c810
5187: * chips.
5188: */
5189:
5190: if (dstat & DSTAT_OPC) {
5191: /*
5192: * Ascertain if this IID interrupts occurred before or after a STO
5193: * interrupt. Since the interrupt handling code now leaves
5194: * DSP unmodified until _after_ all stacked interrupts have been
5195: * processed, reading the DSP returns the original DSP register.
5196: * This means that if dsp lies between the select code, and
5197: * message out following the selection code (where the IID interrupt
5198: * would have to have occurred by due to the implicit wait for REQ),
5199: * we have an IID interrupt resulting from a STO condition and
5200: * can ignore it.
5201: */
5202:
5203: if (((dsp >= (hostdata->script + hostdata->E_select / sizeof(u32))) &&
5204: (dsp <= (hostdata->script + hostdata->E_select_msgout /
5205: sizeof(u32) + 8))) || (hostdata->test_running == 2)) {
5206: if (hostdata->options & OPTION_DEBUG_INTR)
5207: printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STO\n",
5208: host->host_no);
5209: if (hostdata->expecting_iid) {
5210: hostdata->expecting_iid = 0;
5211: hostdata->idle = 1;
5212: if (hostdata->test_running == 2) {
5213: hostdata->test_running = 0;
5214: hostdata->test_completed = 3;
5215: } else if (cmd)
5216: abnormal_finished (cmd, DID_BAD_TARGET << 16);
5217: } else {
5218: hostdata->expecting_sto = 1;
5219: }
5220: /*
5221: * We can't guarantee we'll be able to execute the WAIT DISCONNECT
5222: * instruction within the 3.4us of bus free and arbitration delay
5223: * that a target can RESELECT in and assert REQ after we've dropped
5224: * ACK. If this happens, we'll get an illegal instruction interrupt.
5225: * Doing away with the WAIT DISCONNECT instructions broke everything,
5226: * so instead I'll settle for moving one WAIT DISCONNECT a few
5227: * instructions closer to the CLEAR ACK before it to minimize the
5228: * chances of this happening, and handle it if it occurs anyway.
5229: *
5230: * Simply continue with what we were doing, and control should
5231: * be transfered to the schedule routine which will ultimately
5232: * pass control onto the reselection or selection (not yet)
5233: * code.
5234: */
5235: } else if (dbc_dcmd == 0x48000000 && (NCR53c7x0_read8 (SBCL_REG) &
5236: SBCL_REQ)) {
5237: if (!(hostdata->options & OPTION_NO_PRINT_RACE))
5238: {
5239: printk("scsi%d: REQ before WAIT DISCONNECT IID\n",
5240: host->host_no);
5241: hostdata->options |= OPTION_NO_PRINT_RACE;
5242: }
5243: } else {
5244: printk(KERN_ALERT "scsi%d : illegal instruction\n", host->host_no);
5245: print_lots (host);
5246: printk(KERN_ALERT " mail [email protected] with ALL\n"
5247: " boot messages and diagnostic output\n");
5248: FATAL (host);
5249: }
5250: }
5251:
5252: /*
5253: * DSTAT_BF are bus fault errors
5254: */
5255:
5256: if (dstat & DSTAT_800_BF) {
5257: intr_bf (host, cmd);
5258: }
5259:
5260:
5261: /*
5262: * DSTAT_SIR interrupts are generated by the execution of
5263: * the INT instruction. Since the exact values available
5264: * are determined entirely by the SCSI script running,
5265: * and are local to a particular script, a unique handler
5266: * is called for each script.
5267: */
5268:
5269: if (dstat & DSTAT_SIR) {
5270: if (hostdata->options & OPTION_DEBUG_INTR)
5271: printk ("scsi%d : DSTAT_SIR\n", host->host_no);
5272: switch ((tmp = hostdata->dstat_sir_intr (host, cmd))) {
5273: case SPECIFIC_INT_NOTHING:
5274: case SPECIFIC_INT_RESTART:
5275: break;
5276: case SPECIFIC_INT_ABORT:
5277: abort_connected(host);
5278: break;
5279: case SPECIFIC_INT_PANIC:
5280: printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
5281: print_insn (host, dsp, KERN_ALERT "", 1);
5282: printk(KERN_ALERT " dstat_sir_intr() returned SPECIFIC_INT_PANIC\n");
5283: FATAL (host);
5284: break;
5285: case SPECIFIC_INT_BREAK:
5286: intr_break (host, cmd);
5287: break;
5288: default:
5289: printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
5290: print_insn (host, dsp, KERN_ALERT "", 1);
5291: printk(KERN_ALERT" dstat_sir_intr() returned unknown value %d\n",
5292: tmp);
5293: FATAL (host);
5294: }
5295: }
5296:
5297: if ((hostdata->chip / 100) == 8 && (dstat & DSTAT_800_MDPE)) {
5298: printk(KERN_ALERT "scsi%d : Master Data Parity Error\n",
5299: host->host_no);
5300: FATAL (host);
5301: }
5302: }
5303:
5304: /*
5305: * Function : static int print_insn (struct Scsi_Host *host,
5306: * u32 *insn, int kernel)
5307: *
5308: * Purpose : print numeric representation of the instruction pointed
5309: * to by insn to the debugging or kernel message buffer
5310: * as appropriate.
5311: *
5312: * If desired, a user level program can interpret this
5313: * information.
5314: *
5315: * Inputs : host, insn - host, pointer to instruction, prefix -
5316: * string to prepend, kernel - use printk instead of debugging buffer.
5317: *
5318: * Returns : size, in u32s, of instruction printed.
5319: */
5320:
5321: /*
5322: * FIXME: should change kernel parameter so that it takes an ENUM
5323: * specifying severity - either KERN_ALERT or KERN_PANIC so
5324: * all panic messages are output with the same severity.
5325: */
5326:
5327: static int
5328: print_insn (struct Scsi_Host *host, const u32 *insn,
5329: const char *prefix, int kernel) {
5330: char buf[160], /* Temporary buffer and pointer. ICKY
5331: arbitrary length. */
5332:
5333:
5334: *tmp;
5335: unsigned char dcmd; /* dcmd register for *insn */
5336: int size;
5337:
5338: /*
5339: * Check to see if the instruction pointer is not bogus before
5340: * indirecting through it; avoiding red-zone at start of
5341: * memory.
5342: *
5343: * FIXME: icky magic needs to happen here on non-intel boxes which
5344: * don't have kernel memory mapped in like this. Might be reasonable
5345: * to use vverify()?
5346: */
5347:
5348: if (MAP_NR(insn) < 1 || MAP_NR(insn + 8) > MAP_NR(high_memory) ||
5349: ((((dcmd = (insn[0] >> 24) & 0xff) & DCMD_TYPE_MMI) == DCMD_TYPE_MMI) &&
5350: MAP_NR(insn + 12) > MAP_NR(high_memory))) {
5351: size = 0;
5352: sprintf (buf, "%s%p: address out of range\n",
5353: prefix, insn);
5354: } else {
5355: /*
5356: * FIXME : (void *) cast in virt_to_bus should be unecessary, because
5357: * it should take const void * as argument.
5358: */
5359: sprintf(buf, "%s0x%lx (virt 0x%p) : 0x%08x 0x%08x (virt 0x%p)",
5360: (prefix ? prefix : ""), virt_to_bus((void *) insn), insn,
5361: insn[0], insn[1], bus_to_virt (insn[1]));
5362: tmp = buf + strlen(buf);
5363: if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI) {
5364: sprintf (tmp, " 0x%08x (virt 0x%p)\n", insn[2],
5365: bus_to_virt(insn[2]));
5366: size = 3;
5367: } else {
5368: sprintf (tmp, "\n");
5369: size = 2;
5370: }
5371: }
5372:
5373: if (kernel)
5374: printk ("%s", buf);
5375: #ifdef NCR_DEBUG
5376: else {
5377: size_t len = strlen(buf);
5378: debugger_kernel_write(host, buf, len);
5379: }
5380: #endif
5381: return size;
5382: }
5383:
5384: /*
5385: * Function : static const char *ncr_state (int state)
5386: *
5387: * Purpose : convert state (probably from hostdata->state) to a string
5388: *
5389: * Inputs : state
5390: *
5391: * Returns : char * representation of state, "unknown" on error.
5392: */
5393:
5394: static const char *
5395: ncr_state (int state) {
5396: switch (state) {
5397: case STATE_HALTED: return "halted";
5398: case STATE_WAITING: return "waiting";
5399: case STATE_RUNNING: return "running";
5400: case STATE_ABORTING: return "aborting";
5401: case STATE_DISABLED: return "disabled";
5402: default: return "unknown";
5403: }
5404: }
5405:
5406: /*
5407: * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd)
5408: *
5409: * Purpose : Abort an errant SCSI command, doing all necessary
5410: * cleanup of the issue_queue, running_list, shared Linux/NCR
5411: * dsa issue and reconnect queues.
5412: *
5413: * Inputs : cmd - command to abort, code - entire result field
5414: *
5415: * Returns : 0 on success, -1 on failure.
5416: */
5417:
5418: int
5419: NCR53c7xx_abort (Scsi_Cmnd *cmd) {
5420: NCR53c7x0_local_declare();
5421: struct Scsi_Host *host = cmd->host;
5422: struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *)
5423: host->hostdata : NULL;
5424: unsigned long flags;
5425: struct NCR53c7x0_cmd *curr, **prev;
5426: Scsi_Cmnd *me, **last;
5427: #if 0
5428: static long cache_pid = -1;
5429: #endif
5430:
5431:
5432: if (!host) {
5433: printk ("Bogus SCSI command pid %ld; no host structure\n",
5434: cmd->pid);
5435: return SCSI_ABORT_ERROR;
5436: } else if (!hostdata) {
5437: printk ("Bogus SCSI host %d; no hostdata\n", host->host_no);
5438: return SCSI_ABORT_ERROR;
5439: }
5440: NCR53c7x0_local_setup(host);
5441:
5442: /*
5443: * CHECK : I don't think that reading ISTAT will unstack any interrupts,
5444: * since we need to write the INTF bit to clear it, and SCSI/DMA
5445: * interrupts don't clear until we read SSTAT/SIST and DSTAT registers.
5446: *
5447: * See that this is the case.
5448: *
5449: * I suspect that several of our failures may be coming from a new fatal
5450: * interrupt (possibly due to a phase mismatch) happening after we've left
5451: * the interrupt handler, but before the PIC has had the interrupt condition
5452: * cleared.
5453: */
5454:
5455: if (NCR53c7x0_read8(hostdata->istat) &
5456: (ISTAT_DIP|ISTAT_SIP|
5457: (hostdata->chip / 100 == 8 ? ISTAT_800_INTF : 0))) {
5458: printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no,
5459: cmd->pid);
5460: NCR53c7x0_intr (host->irq, NULL);
5461: return SCSI_ABORT_BUSY;
5462: }
5463:
5464: save_flags(flags);
5465: cli();
5466: #if 0
5467: if (cache_pid == cmd->pid)
5468: panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid);
5469: else
5470: cache_pid = cmd->pid;
5471: #endif
5472:
5473:
5474: /*
5475: * The command could be hiding in the issue_queue. This would be very
5476: * nice, as commands can't be moved from the high level driver's issue queue
5477: * into the shared queue until an interrupt routine is serviced, and this
5478: * moving is atomic.
5479: *
5480: * If this is the case, we don't have to worry about anything - we simply
5481: * pull the command out of the old queue, and call it aborted.
5482: */
5483:
5484: for (me = (Scsi_Cmnd *) hostdata->issue_queue,
5485: last = (Scsi_Cmnd **) &(hostdata->issue_queue);
5486: me && me != cmd; last = (Scsi_Cmnd **)&(me->SCp.ptr),
5487: me = (Scsi_Cmnd *)me->SCp.ptr);
5488:
5489: if (me) {
5490: *last = (Scsi_Cmnd *) me->SCp.ptr;
5491: if (me->host_scribble) {
5492: ((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free;
5493: hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble;
5494: me->host_scribble = NULL;
5495: }
5496: cmd->result = DID_ABORT << 16;
5497: cmd->scsi_done(cmd);
5498: printk ("scsi%d : found command %ld in Linux issue queue\n",
5499: host->host_no, me->pid);
5500: restore_flags(flags);
5501: run_process_issue_queue();
5502: return SCSI_ABORT_SUCCESS;
5503: }
5504:
5505: /*
5506: * That failing, the command could be in our list of already executing
5507: * commands. If this is the case, drastic measures are called for.
5508: */
5509:
5510: for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list,
5511: prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
5512: curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
5513: &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
5514:
5515: if (curr) {
5516: if ((cmd->result & 0xff) != 0xff && (cmd->result & 0xff00) != 0xff00) {
5517: if (prev)
5518: *prev = (struct NCR53c7x0_cmd *) curr->next;
5519: curr->next = (struct NCR53c7x0_cmd *) hostdata->free;
5520: cmd->host_scribble = NULL;
5521: hostdata->free = curr;
5522: cmd->scsi_done(cmd);
5523: printk ("scsi%d : found finished command %ld in running list\n",
5524: host->host_no, cmd->pid);
5525: restore_flags(flags);
5526: return SCSI_ABORT_NOT_RUNNING;
5527: } else {
5528: printk ("scsi%d : DANGER : command running, can not abort.\n",
5529: cmd->host->host_no);
5530: restore_flags(flags);
5531: return SCSI_ABORT_BUSY;
5532: }
5533: }
5534:
5535: /*
5536: * And if we couldn't find it in any of our queues, it must have been
5537: * a dropped interrupt.
5538: */
5539:
5540: curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
5541: if (curr) {
5542: curr->next = hostdata->free;
5543: hostdata->free = curr;
5544: cmd->host_scribble = NULL;
5545: }
5546:
5547: if (((cmd->result & 0xff00) == 0xff00) ||
5548: ((cmd->result & 0xff) == 0xff)) {
5549: printk ("scsi%d : did this command ever run?\n", host->host_no);
5550: cmd->result = DID_ABORT << 16;
5551: } else {
5552: printk ("scsi%d : probably lost INTFLY, normal completion\n",
5553: host->host_no);
5554: /*
5555: * FIXME : We need to add an additional flag which indicates if a
5556: * command was ever counted as BUSY, so if we end up here we can
5557: * decrement the busy count if and only if it is necessary.
5558: */
5559: --hostdata->busy[cmd->target][cmd->lun];
5560: }
5561: restore_flags(flags);
5562: cmd->scsi_done(cmd);
5563:
5564: /*
5565: * We need to run process_issue_queue since termination of this command
5566: * may allow another queued command to execute first?
5567: */
5568: return SCSI_ABORT_NOT_RUNNING;
5569: }
5570:
5571: /*
5572: * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd)
5573: *
5574: * Purpose : perform a hard reset of the SCSI bus and NCR
5575: * chip.
5576: *
5577: * Inputs : cmd - command which caused the SCSI RESET
5578: *
5579: * Returns : 0 on success.
5580: */
5581:
5582: int
5583: NCR53c7xx_reset (Scsi_Cmnd *cmd) {
5584: NCR53c7x0_local_declare();
5585: unsigned long flags;
5586: int found = 0;
5587: struct NCR53c7x0_cmd * c;
5588: Scsi_Cmnd *tmp;
5589: /*
5590: * When we call scsi_done(), it's going to wake up anything sleeping on the
5591: * resources which were in use by the aborted commands, and we'll start to
5592: * get new commands.
5593: *
5594: * We can't let this happen until after we've re-initialized the driver
5595: * structures, and can't reinitilize those structures until after we've
5596: * dealt with their contents.
5597: *
5598: * So, we need to find all of the commands which were running, stick
5599: * them on a linked list of completed commands (we'll use the host_scribble
5600: * pointer), do our reinitialization, and then call the done function for
5601: * each command.
5602: */
5603: Scsi_Cmnd *nuke_list = NULL;
5604: struct Scsi_Host *host = cmd->host;
5605: struct NCR53c7x0_hostdata *hostdata =
5606: (struct NCR53c7x0_hostdata *) host->hostdata;
5607:
5608: NCR53c7x0_local_setup(host);
5609: save_flags(flags);
5610: cli();
5611: ncr_halt (host);
5612: print_lots (host);
5613: dump_events (host, 30);
5614: ncr_scsi_reset (host);
5615: for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */,
5616: 0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer)
5617: if (tmp == cmd) {
5618: found = 1;
5619: break;
5620: }
5621:
5622: /*
5623: * If we didn't find the command which caused this reset in our running
5624: * list, then we've lost it. See that it terminates normally anyway.
5625: */
5626: if (!found) {
5627: c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
5628: if (c) {
5629: cmd->host_scribble = NULL;
5630: c->next = hostdata->free;
5631: hostdata->free = c;
5632: } else
5633: printk ("scsi%d: lost command %ld\n", host->host_no, cmd->pid);
5634: cmd->SCp.buffer = (struct scatterlist *) nuke_list;
5635: nuke_list = cmd;
5636: }
5637:
5638: NCR53c7x0_driver_init (host);
5639: hostdata->soft_reset (host);
5640: if (hostdata->resets == 0)
5641: disable(host);
5642: else if (hostdata->resets != -1)
5643: --hostdata->resets;
5644: sti();
5645: for (; nuke_list; nuke_list = tmp) {
5646: tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
5647: nuke_list->result = DID_RESET << 16;
5648: nuke_list->scsi_done (nuke_list);
5649: }
5650: restore_flags(flags);
5651: return SCSI_RESET_SUCCESS;
5652: }
5653:
5654: /*
5655: * The NCR SDMS bios follows Annex A of the SCSI-CAM draft, and
5656: * therefore shares the scsicam_bios_param function.
5657: */
5658:
5659: /*
5660: * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn)
5661: *
5662: * Purpose : convert instructions stored at NCR pointer into data
5663: * pointer offset.
5664: *
5665: * Inputs : cmd - SCSI command; insn - pointer to instruction. Either current
5666: * DSP, or saved data pointer.
5667: *
5668: * Returns : offset on success, -1 on failure.
5669: */
5670:
5671:
5672: static int
5673: insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
5674: struct NCR53c7x0_hostdata *hostdata =
5675: (struct NCR53c7x0_hostdata *) cmd->host->hostdata;
5676: struct NCR53c7x0_cmd *ncmd =
5677: (struct NCR53c7x0_cmd *) cmd->host_scribble;
5678: int offset = 0, buffers;
5679: struct scatterlist *segment;
5680: char *ptr;
5681: int found = 0;
5682:
5683: /*
5684: * With the current code implementation, if the insn is inside dynamically
5685: * generated code, the data pointer will be the instruction preceeding
5686: * the next transfer segment.
5687: */
5688:
5689: if (!check_address ((unsigned long) ncmd, sizeof (struct NCR53c7x0_cmd)) &&
5690: ((insn >= ncmd->data_transfer_start &&
5691: insn < ncmd->data_transfer_end) ||
5692: (insn >= ncmd->residual &&
5693: insn < (ncmd->residual +
5694: sizeof(ncmd->residual))))) {
5695: ptr = bus_to_virt(insn[3]);
5696:
5697: if ((buffers = cmd->use_sg)) {
5698: for (offset = 0,
5699: segment = (struct scatterlist *) cmd->buffer;
5700: buffers && !((found = ((ptr >= segment->address) &&
5701: (ptr < (segment->address + segment->length)))));
5702: --buffers, offset += segment->length, ++segment)
5703: #if 0
5704: printk("scsi%d: comparing 0x%p to 0x%p\n",
5705: cmd->host->host_no, saved, segment->address);
5706: #else
5707: ;
5708: #endif
5709: offset += ptr - segment->address;
5710: } else {
5711: found = 1;
5712: offset = ptr - (char *) (cmd->request_buffer);
5713: }
5714: } else if ((insn >= hostdata->script +
5715: hostdata->E_data_transfer / sizeof(u32)) &&
5716: (insn <= hostdata->script +
5717: hostdata->E_end_data_transfer / sizeof(u32))) {
5718: found = 1;
5719: offset = 0;
5720: }
5721: return found ? offset : -1;
5722: }
5723:
5724:
5725:
5726: /*
5727: * Function : void print_progress (Scsi_Cmnd *cmd)
5728: *
5729: * Purpose : print the current location of the saved data pointer
5730: *
5731: * Inputs : cmd - command we are interested in
5732: *
5733: */
5734:
5735: static void
5736: print_progress (Scsi_Cmnd *cmd) {
5737: NCR53c7x0_local_declare();
5738: struct NCR53c7x0_cmd *ncmd =
5739: (struct NCR53c7x0_cmd *) cmd->host_scribble;
5740: int offset, i;
5741: char *where;
5742: u32 *ptr;
5743: NCR53c7x0_local_setup (cmd->host);
5744: for (i = 0; i < 2; ++i) {
5745: if (check_address ((unsigned long) ncmd,
5746: sizeof (struct NCR53c7x0_cmd)) == -1)
5747: continue;
5748: if (!i) {
5749: where = "saved";
5750: ptr = bus_to_virt(ncmd->saved_data_pointer);
5751: } else {
5752: where = "active";
5753: ptr = bus_to_virt (NCR53c7x0_read32 (DSP_REG) -
5754: NCR53c7x0_insn_size (NCR53c7x0_read8 (DCMD_REG)) *
5755: sizeof(u32));
5756: }
5757: offset = insn_to_offset (cmd, ptr);
5758:
5759: if (offset != -1)
5760: printk ("scsi%d : %s data pointer at offset %d\n",
5761: cmd->host->host_no, where, offset);
5762: else {
5763: int size;
5764: printk ("scsi%d : can't determine %s data pointer offset\n",
5765: cmd->host->host_no, where);
5766: if (ncmd) {
5767: size = print_insn (cmd->host,
5768: bus_to_virt(ncmd->saved_data_pointer), "", 1);
5769: print_insn (cmd->host,
5770: bus_to_virt(ncmd->saved_data_pointer) + size * sizeof(u32),
5771: "", 1);
5772: }
5773: }
5774: }
5775: }
5776:
5777:
5778: static void
5779: print_dsa (struct Scsi_Host *host, u32 *dsa, const char *prefix) {
5780: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
5781: host->hostdata;
5782: int i, len;
5783: char *ptr;
5784: Scsi_Cmnd *cmd;
5785:
5786: if (check_address ((unsigned long) dsa, hostdata->dsa_end -
5787: hostdata->dsa_start) == -1) {
5788: printk("scsi%d : bad dsa virt 0x%p\n", host->host_no, dsa);
5789: return;
5790: }
5791: printk("%sscsi%d : dsa at phys 0x%lx (virt 0x%p)\n"
5792: " + %d : dsa_msgout length = %u, data = 0x%x (virt 0x%p)\n" ,
5793: prefix ? prefix : "",
5794: host->host_no, virt_to_bus (dsa), dsa, hostdata->dsa_msgout,
5795: dsa[hostdata->dsa_msgout / sizeof(u32)],
5796: dsa[hostdata->dsa_msgout / sizeof(u32) + 1],
5797: bus_to_virt (dsa[hostdata->dsa_msgout / sizeof(u32) + 1]));
5798:
5799: /*
5800: * Only print messages if they're sane in length so we don't
5801: * blow the kernel printk buffer on something which won't buy us
5802: * anything.
5803: */
5804:
5805: if (dsa[hostdata->dsa_msgout / sizeof(u32)] <
5806: sizeof (hostdata->free->select))
5807: for (i = dsa[hostdata->dsa_msgout / sizeof(u32)],
5808: ptr = bus_to_virt (dsa[hostdata->dsa_msgout / sizeof(u32) + 1]);
5809: i > 0 && !check_address ((unsigned long) ptr, 1);
5810: ptr += len, i -= len) {
5811: printk(" ");
5812: len = print_msg (ptr);
5813: printk("\n");
5814: if (!len)
5815: break;
5816: }
5817:
5818: printk(" + %d : select_indirect = 0x%x\n",
5819: hostdata->dsa_select, dsa[hostdata->dsa_select / sizeof(u32)]);
5820: cmd = (Scsi_Cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
5821: printk(" + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd,
5822: (u32) virt_to_bus(cmd));
5823: if (cmd) {
5824: printk(" result = 0x%x, target = %d, lun = %d, cmd = ",
5825: cmd->result, cmd->target, cmd->lun);
5826: print_command(cmd->cmnd);
5827: } else
5828: printk("\n");
5829: printk(" + %d : dsa_next = 0x%x\n", hostdata->dsa_next,
5830: dsa[hostdata->dsa_next / sizeof(u32)]);
5831: if (cmd) {
5832: printk("scsi%d target %d : sxfer_sanity = 0x%x, scntl3_sanity = 0x%x\n"
5833: " script : ",
5834: host->host_no, cmd->target,
5835: hostdata->sync[cmd->target].sxfer_sanity,
5836: hostdata->sync[cmd->target].scntl3_sanity);
5837: for (i = 0; i < (sizeof(hostdata->sync[cmd->target].script) / 4); ++i)
5838: printk ("0x%x ", hostdata->sync[cmd->target].script[i]);
5839: printk ("\n");
5840: print_progress (cmd);
5841: }
5842: }
5843: /*
5844: * Function : void print_queues (Scsi_Host *host)
5845: *
5846: * Purpose : print the contents of the NCR issue and reconnect queues
5847: *
5848: * Inputs : host - SCSI host we are interested in
5849: *
5850: */
5851:
5852: static void
5853: print_queues (struct Scsi_Host *host) {
5854: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
5855: host->hostdata;
5856: u32 *dsa, *next_dsa;
5857: volatile u32 *current;
5858: int left;
5859: Scsi_Cmnd *cmd, *next_cmd;
5860: unsigned long flags;
5861:
5862: printk ("scsi%d : issue queue\n", host->host_no);
5863:
5864: for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue;
5865: left >= 0 && cmd;
5866: cmd = next_cmd) {
5867: next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr;
5868: save_flags(flags);
5869: cli();
5870: if (cmd->host_scribble) {
5871: if (check_address ((unsigned long) (cmd->host_scribble),
5872: sizeof (cmd->host_scribble)) == -1)
5873: printk ("scsi%d: scsi pid %ld bad pointer to NCR53c7x0_cmd\n",
5874: host->host_no, cmd->pid);
5875: /* print_dsa does sanity check on address, no need to check */
5876: else
5877: print_dsa (host, ((struct NCR53c7x0_cmd *) cmd->host_scribble)
5878: -> dsa, "");
5879: } else
5880: printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
5881: host->host_no, cmd->pid, cmd->target, cmd->lun);
5882: restore_flags(flags);
5883: }
5884:
5885: if (left <= 0) {
5886: printk ("scsi%d : loop detected in issue queue\n",
5887: host->host_no);
5888: }
5889:
5890: /*
5891: * Traverse the NCR reconnect and start DSA structures, printing out
5892: * each element until we hit the end or detect a loop. Currently,
5893: * the reconnect structure is a linked list; and the start structure
5894: * is an array. Eventually, the reconnect structure will become a
5895: * list as well, since this simplifies the code.
5896: */
5897:
5898: printk ("scsi%d : schedule dsa array :\n", host->host_no);
5899: for (left = host->can_queue, current = hostdata->schedule;
5900: left > 0; current += 2, --left)
5901: if (current[0] != hostdata->NOP_insn)
5902: /* FIXME : convert pointer to dsa_begin to pointer to dsa. */
5903: print_dsa (host, bus_to_virt (current[1] -
5904: (hostdata->E_dsa_code_begin -
5905: hostdata->E_dsa_code_template)), "");
5906: printk ("scsi%d : end schedule dsa array\n", host->host_no);
5907:
5908: printk ("scsi%d : reconnect_dsa_head :\n", host->host_no);
5909:
5910: for (left = host->can_queue,
5911: dsa = bus_to_virt (hostdata->reconnect_dsa_head);
5912: left >= 0 && dsa;
5913: dsa = next_dsa) {
5914: save_flags (flags);
5915: cli();
5916: if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) {
5917: printk ("scsi%d: bad DSA pointer 0x%p", host->host_no,
5918: dsa);
5919: next_dsa = NULL;
5920: }
5921: else
5922: {
5923: next_dsa = bus_to_virt(dsa[hostdata->dsa_next / sizeof(u32)]);
5924: print_dsa (host, dsa, "");
5925: }
5926: restore_flags(flags);
5927: }
5928: printk ("scsi%d : end reconnect_dsa_head\n", host->host_no);
5929: if (left < 0)
5930: printk("scsi%d: possible loop in ncr reconnect list\n",
5931: host->host_no);
5932: }
5933:
5934: static void
5935: print_lots (struct Scsi_Host *host) {
5936: NCR53c7x0_local_declare();
5937: struct NCR53c7x0_hostdata *hostdata =
5938: (struct NCR53c7x0_hostdata *) host->hostdata;
5939: u32 *dsp_next, *dsp, *dsa, dbc_dcmd;
5940: unsigned char dcmd, sbcl;
5941: int i, size;
5942: NCR53c7x0_local_setup(host);
5943:
5944: if ((dsp_next = bus_to_virt(NCR53c7x0_read32 (DSP_REG)))) {
5945: dbc_dcmd = NCR53c7x0_read32(DBC_REG);
5946: dcmd = (dbc_dcmd & 0xff000000) >> 24;
5947: dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
5948: dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
5949: sbcl = NCR53c7x0_read8 (SBCL_REG);
5950:
5951:
5952: printk ("scsi%d : DCMD|DBC=0x%x, DNAD=0x%x (virt 0x%p)\n"
5953: " DSA=0x%lx (virt 0x%p)\n"
5954: " DSPS=0x%x, TEMP=0x%x (virt 0x%p), DMODE=0x%x\n"
5955: " SXFER=0x%x, SCNTL3=0x%x\n"
5956: " %s%s%sphase=%s, %d bytes in SCSI FIFO\n"
5957: " STEST0=0x%x\n",
5958: host->host_no, dbc_dcmd, NCR53c7x0_read32(DNAD_REG),
5959: bus_to_virt(NCR53c7x0_read32(DNAD_REG)),
5960: virt_to_bus(dsa), dsa,
5961: NCR53c7x0_read32(DSPS_REG), NCR53c7x0_read32(TEMP_REG),
5962: bus_to_virt (NCR53c7x0_read32(TEMP_REG)),
5963: (int) NCR53c7x0_read8(hostdata->dmode),
5964: (int) NCR53c7x0_read8(SXFER_REG),
5965: (int) NCR53c7x0_read8(SCNTL3_REG_800),
5966: (sbcl & SBCL_BSY) ? "BSY " : "",
5967: (sbcl & SBCL_SEL) ? "SEL " : "",
5968: (sbcl & SBCL_REQ) ? "REQ " : "",
5969: sstat2_to_phase(NCR53c7x0_read8 (((hostdata->chip / 100) == 8) ?
5970: SSTAT1_REG : SSTAT2_REG)),
5971: (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ?
5972: SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT,
5973: NCR53c7x0_read8 (STEST0_REG_800));
5974: printk ("scsi%d : DSP 0x%lx (virt 0x%p) ->\n", host->host_no,
5975: virt_to_bus(dsp), dsp);
5976: for (i = 6; i > 0; --i, dsp += size)
5977: size = print_insn (host, dsp, "", 1);
5978: if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) {
5979: printk ("scsi%d : connected (SDID=0x%x, SSID=0x%x)\n",
5980: host->host_no, NCR53c7x0_read8 (SDID_REG_800),
5981: NCR53c7x0_read8 (SSID_REG_800));
5982: print_dsa (host, dsa, "");
5983: }
5984:
5985: #if 1
5986: print_queues (host);
5987: #endif
5988: }
5989: }
5990:
5991: /*
5992: * Function : static int shutdown (struct Scsi_Host *host)
5993: *
5994: * Purpose : does a clean (we hope) shutdown of the NCR SCSI
5995: * chip. Use prior to dumping core, unloading the NCR driver,
5996: *
5997: * Returns : 0 on success
5998: */
5999: static int
6000: shutdown (struct Scsi_Host *host) {
6001: NCR53c7x0_local_declare();
6002: unsigned long flags;
6003: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
6004: host->hostdata;
6005: NCR53c7x0_local_setup(host);
6006: save_flags (flags);
6007: cli();
6008: /* Get in a state where we can reset the SCSI bus */
6009: ncr_halt (host);
6010: ncr_scsi_reset (host);
6011: hostdata->soft_reset(host);
6012:
6013: disable (host);
6014: restore_flags (flags);
6015: return 0;
6016: }
6017:
6018: /*
6019: * Function : void ncr_scsi_reset (struct Scsi_Host *host)
6020: *
6021: * Purpose : reset the SCSI bus.
6022: */
6023:
6024: static void
6025: ncr_scsi_reset (struct Scsi_Host *host) {
6026: NCR53c7x0_local_declare();
6027: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
6028: host->hostdata;
6029: unsigned long flags;
6030: int sien = 0;
6031: NCR53c7x0_local_setup(host);
6032: save_flags (flags);
6033: cli();
6034: if ((hostdata->chip / 100) == 8) {
6035: sien = NCR53c7x0_read8(SIEN0_REG_800);
6036: NCR53c7x0_write8(SIEN0_REG_800, sien & ~SIEN_RST);
6037: }
6038: NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
6039: udelay(25); /* Minimum amount of time to assert RST */
6040: NCR53c7x0_write8(SCNTL1_REG, 0);
6041: if ((hostdata->chip / 100) == 8) {
6042: NCR53c7x0_write8(SIEN0_REG_800, sien);
6043: }
6044: restore_flags (flags);
6045: }
6046:
6047: /*
6048: * Function : void hard_reset (struct Scsi_Host *host)
6049: *
6050: */
6051:
6052: static void
6053: hard_reset (struct Scsi_Host *host) {
6054: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
6055: host->hostdata;
6056: unsigned long flags;
6057: save_flags (flags);
6058: cli();
6059: ncr_scsi_reset(host);
6060: NCR53c7x0_driver_init (host);
6061: if (hostdata->soft_reset)
6062: hostdata->soft_reset (host);
6063: restore_flags(flags);
6064: }
6065:
6066:
6067: /*
6068: * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host,
6069: * int free, int issue)
6070: *
6071: * Purpose : return a linked list (using the SCp.buffer field as next,
6072: * so we don't perturb hostdata. We don't use a field of the
6073: * NCR53c7x0_cmd structure since we may not have allocated one
6074: * for the command causing the reset.) of Scsi_Cmnd structures that
6075: * had propogated bellow the Linux issue queue level. If free is set,
6076: * free the NCR53c7x0_cmd structures which are associated with
6077: * the Scsi_Cmnd structures, and clean up any internal
6078: * NCR lists that the commands were on. If issue is set,
6079: * also return commands in the issue queue.
6080: *
6081: * Returns : linked list of commands
6082: *
6083: * NOTE : the caller should insure that the NCR chip is halted
6084: * if the free flag is set.
6085: */
6086:
6087: static Scsi_Cmnd *
6088: return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
6089: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
6090: host->hostdata;
6091: struct NCR53c7x0_cmd *c;
6092: int i;
6093: u32 *current;
6094: Scsi_Cmnd *list = NULL, *tmp;
6095: for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c;
6096: c = (struct NCR53c7x0_cmd *) c->next) {
6097: if (c->cmd->SCp.buffer) {
6098: printk ("scsi%d : loop detected in running list!\n", host->host_no);
6099: break;
6100: } else {
6101: printk ("The sti() implicit in a printk() prevents hangs\n");
6102: break;
6103: }
6104:
6105: c->cmd->SCp.buffer = (struct scatterlist *) list;
6106: list = c->cmd;
6107: if (free) {
6108: c->next = hostdata->free;
6109: hostdata->free = c;
6110: }
6111: }
6112:
6113: if (free) {
6114: for (i = 0, current = (u32 *) hostdata->schedule;
6115: i < host->can_queue; ++i, current += 2) {
6116: current[0] = hostdata->NOP_insn;
6117: current[1] = 0xdeadbeef;
6118: }
6119: hostdata->current = NULL;
6120: }
6121:
6122: if (issue) {
6123: for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) {
6124: if (tmp->SCp.buffer) {
6125: printk ("scsi%d : loop detected in issue queue!\n",
6126: host->host_no);
6127: break;
6128: }
6129: tmp->SCp.buffer = (struct scatterlist *) list;
6130: list = tmp;
6131: }
6132: if (free)
6133: hostdata->issue_queue = NULL;
6134:
6135: }
6136: return list;
6137: }
6138:
6139: /*
6140: * Function : static int disable (struct Scsi_Host *host)
6141: *
6142: * Purpose : disables the given NCR host, causing all commands
6143: * to return a driver error. Call this so we can unload the
6144: * module during development and try again. Eventually,
6145: * we should be able to find clean workarrounds for these
6146: * problems.
6147: *
6148: * Inputs : host - hostadapter to twiddle
6149: *
6150: * Returns : 0 on success.
6151: */
6152:
6153: static int
6154: disable (struct Scsi_Host *host) {
6155: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
6156: host->hostdata;
6157: unsigned long flags;
6158: Scsi_Cmnd *nuke_list, *tmp;
6159: save_flags(flags);
6160: cli();
6161: if (hostdata->state != STATE_HALTED)
6162: ncr_halt (host);
6163: nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */);
6164: hard_reset (host);
6165: hostdata->state = STATE_DISABLED;
6166: restore_flags(flags);
6167: printk ("scsi%d : nuking commands\n", host->host_no);
6168: for (; nuke_list; nuke_list = tmp) {
6169: tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
6170: nuke_list->result = DID_ERROR << 16;
6171: nuke_list->scsi_done(nuke_list);
6172: }
6173: printk ("scsi%d : done. \n", host->host_no);
6174: printk (KERN_ALERT "scsi%d : disabled. Unload and reload\n",
6175: host->host_no);
6176: return 0;
6177: }
6178:
6179: /*
6180: * Function : static int ncr_halt (struct Scsi_Host *host)
6181: *
6182: * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
6183: *
6184: * Inputs : host - SCSI chip to halt
6185: *
6186: * Returns : 0 on success
6187: */
6188:
6189: static int
6190: ncr_halt (struct Scsi_Host *host) {
6191: NCR53c7x0_local_declare();
6192: unsigned long flags;
6193: unsigned char istat, tmp;
6194: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
6195: host->hostdata;
6196: int stage;
6197: NCR53c7x0_local_setup(host);
6198:
6199: save_flags(flags);
6200: cli();
6201: /* Stage 0 : eat all interrupts
6202: Stage 1 : set ABORT
6203: Stage 2 : eat all but abort interrupts
6204: Stage 3 : eat all interrupts
6205: */
6206: for (stage = 0;;) {
6207: if (stage == 1) {
6208: NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT);
6209: ++stage;
6210: }
6211: istat = NCR53c7x0_read8 (hostdata->istat);
6212: if (istat & ISTAT_SIP) {
6213: if ((hostdata->chip / 100) == 8) {
6214: tmp = NCR53c7x0_read8(SIST0_REG_800);
6215: udelay(1);
6216: tmp = NCR53c7x0_read8(SIST1_REG_800);
6217: } else {
6218: tmp = NCR53c7x0_read8(SSTAT0_REG);
6219: }
6220: } else if (istat & ISTAT_DIP) {
6221: tmp = NCR53c7x0_read8(DSTAT_REG);
6222: if (stage == 2) {
6223: if (tmp & DSTAT_ABRT) {
6224: NCR53c7x0_write8(hostdata->istat, 0);
6225: ++stage;
6226: } else {
6227: printk(KERN_ALERT "scsi%d : could not halt NCR chip\n",
6228: host->host_no);
6229: disable (host);
6230: }
6231: }
6232: }
6233: if (!(istat & (ISTAT_SIP|ISTAT_DIP)))
6234: if (stage == 0)
6235: ++stage;
6236: else if (stage == 3)
6237: break;
6238: }
6239: hostdata->state = STATE_HALTED;
6240: restore_flags(flags);
6241: #if 0
6242: print_lots (host);
6243: #endif
6244: return 0;
6245: }
6246:
6247: /*
6248: * Function: event_name (int event)
6249: *
6250: * Purpose: map event enum into user-readable strings.
6251: */
6252:
6253: static const char *
6254: event_name (int event) {
6255: switch (event) {
6256: case EVENT_NONE: return "none";
6257: case EVENT_ISSUE_QUEUE: return "to issue queue";
6258: case EVENT_START_QUEUE: return "to start queue";
6259: case EVENT_SELECT: return "selected";
6260: case EVENT_DISCONNECT: return "disconnected";
6261: case EVENT_RESELECT: return "reselected";
6262: case EVENT_COMPLETE: return "completed";
6263: case EVENT_IDLE: return "idle";
6264: case EVENT_SELECT_FAILED: return "select failed";
6265: case EVENT_BEFORE_SELECT: return "before select";
6266: case EVENT_RESELECT_FAILED: return "reselect failed";
6267: default: return "unknown";
6268: }
6269: }
6270:
6271: /*
6272: * Function : void dump_events (struct Scsi_Host *host, count)
6273: *
6274: * Purpose : print last count events which have occurred.
6275: */
6276: static void
6277: dump_events (struct Scsi_Host *host, int count) {
6278: struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
6279: host->hostdata;
6280: struct NCR53c7x0_event event;
6281: int i;
6282: unsigned long flags;
6283: if (hostdata->events) {
6284: if (count > hostdata->event_size)
6285: count = hostdata->event_size;
6286: for (i = hostdata->event_index; count > 0;
6287: i = (i ? i - 1 : hostdata->event_size -1), --count) {
6288: save_flags(flags);
6289: /*
6290: * By copying the event we're currently examinging with interrupts
6291: * disabled, we can do multiple printk(), etc. operations and
6292: * still be guaranteed that they're happening on the same
6293: * event structure.
6294: */
6295: cli();
6296: #if 0
6297: event = hostdata->events[i];
6298: #else
6299: memcpy ((void *) &event, (void *) &(hostdata->events[i]),
6300: sizeof(event));
6301: #endif
6302:
6303: restore_flags(flags);
6304: printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n",
6305: host->host_no, event_name (event.event), count,
6306: (long) event.time.tv_sec, (long) event.time.tv_usec,
6307: event.target, event.lun);
6308: if (event.dsa)
6309: printk (" event for dsa 0x%lx (virt 0x%p)\n",
6310: virt_to_bus(event.dsa), event.dsa);
6311: if (event.pid != -1) {
6312: printk (" event for pid %ld ", event.pid);
6313: print_command (event.cmnd);
6314: }
6315: }
6316: }
6317: }
6318:
6319: /*
6320: * Function: check_address
6321: *
6322: * Purpose: Check to see if a possibly corrupt pointer will fault the
6323: * kernel.
6324: *
6325: * Inputs: addr - address; size - size of area
6326: *
6327: * Returns: 0 if area is OK, -1 on error.
6328: *
6329: * NOTES: should be implemented in terms of vverify on kernels
6330: * that have it.
6331: */
6332:
6333: static int
6334: check_address (unsigned long addr, int size) {
6335: return (MAP_NR(addr) < 1 || MAP_NR(addr + size) > MAP_NR(high_memory) ?
6336: -1 : 0);
6337: }
6338:
6339: #ifdef MODULE
6340: int
6341: NCR53c7x0_release(struct Scsi_Host *host) {
6342: struct NCR53c7x0_hostdata *hostdata =
6343: (struct NCR53c7x0_hostdata *) host->hostdata;
6344: struct NCR53c7x0_cmd *cmd, *tmp;
6345: shutdown (host);
6346: if (host->irq != IRQ_NONE)
6347: {
6348: int irq_count;
6349: struct Scsi_Host *tmp;
6350: for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
6351: if (tmp->hostt == the_template && tmp->irq == host->irq)
6352: ++irq_count;
6353: if (irq_count == 1)
6354: free_irq(host->irq);
6355: }
6356: if (host->dma_channel != DMA_NONE)
6357: free_dma(host->dma_channel);
6358: if (host->io_port)
6359: release_region(host->io_port, host->n_io_port);
6360:
6361: for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp,
6362: --hostdata->num_cmds) {
6363: tmp = (struct NCR53c7x0_cmd *) cmd->next;
6364: /*
6365: * If we're going to loop, try to stop it to get a more accurate
6366: * count of the leaked commands.
6367: */
6368: cmd->next = NULL;
6369: if (cmd->free)
6370: cmd->free ((void *) cmd->real, cmd->size);
6371: }
6372: if (hostdata->num_cmds)
6373: printk ("scsi%d : leaked %d NCR53c7x0_cmd structures\n",
6374: host->host_no, hostdata->num_cmds);
6375: if (hostdata->events)
6376: vfree ((void *)hostdata->events);
6377: return 1;
6378: }
6379: Scsi_Host_Template driver_template = NCR53c7xx;
6380: #include "scsi_module.c"
6381: #endif /* def MODULE */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.