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