2 * 53c710 driver. Modified from Drew Eckhardts driver
3 * for 53c810 by Richard Hirst [richard@sleepie.demon.co.uk]
4 * Check out PERM_OPTIONS and EXPECTED_CLOCK, which may be defined in the
5 * relevant machine specific file (eg. mvme16x.[ch], amiga7xx.[ch]).
6 * There are also currently some defines at the top of 53c7xx.scr.
7 * The chip type is #defined in script_asm.pl, as well as the Makefile.
8 * Host scsi ID expected to be 7 - see NCR53c7x0_init().
10 * I have removed the PCI code and some of the 53c8xx specific code -
11 * simply to make this file smaller and easier to manage.
14 * Problems trying to read any chip registers in NCR53c7x0_init(), as they
15 * may never have been set by 16xBug (eg. If kernel has come in over tftp).
19 * Adapted for Linux/m68k Amiga platforms for the A4000T/A4091 and
20 * WarpEngine SCSI controllers.
21 * By Alan Hourihane <alanh@fairlite.demon.co.uk>
22 * Thanks to Richard Hirst for making it possible with the MVME additions
26 * 53c710 rev 0 doesn't support add with carry. Rev 1 and 2 does. To
27 * overcome this problem you can define FORCE_DSA_ALIGNMENT, which ensures
28 * that the DSA address is always xxxxxx00. If disconnection is not allowed,
29 * then the script only ever tries to add small (< 256) positive offsets to
30 * DSA, so lack of carry isn't a problem. FORCE_DSA_ALIGNMENT can, of course,
31 * be defined for all chip revisions at a small cost in memory usage.
34 #define FORCE_DSA_ALIGNMENT
37 * Selection timer does not always work on the 53c710, depending on the
38 * timing at the last disconnect, if this is a problem for you, try
39 * using validids as detailed below.
41 * Options for the NCR7xx driver
43 * noasync:0 - disables sync and asynchronous negotiation
44 * nosync:0 - disables synchronous negotiation (does async)
45 * nodisconnect:0 - disables disconnection
46 * validids:0x?? - Bitmask field that disallows certain ID's.
47 * - e.g. 0x03 allows ID 0,1
48 * - 0x1F allows ID 0,1,2,3,4
49 * opthi:n - replace top word of options with 'n'
50 * optlo:n - replace bottom word of options with 'n'
51 * - ALWAYS SPECIFY opthi THEN optlo <<<<<<<<<<
55 * PERM_OPTIONS are driver options which will be enabled for all NCR boards
56 * in the system at driver initialization time.
58 * Don't THINK about touching these in PERM_OPTIONS :
59 * OPTION_MEMORY_MAPPED
60 * 680x0 doesn't have an IO map!
63 * Test 1 does bus mastering and interrupt tests, which will help weed
64 * out brain damaged main boards.
66 * Other PERM_OPTIONS settings are listed below. Note the actual options
67 * required are set in the relevant file (mvme16x.c, amiga7xx.c, etc):
70 * Don't negotiate for asynchronous transfers on the first command
71 * when OPTION_ALWAYS_SYNCHRONOUS is set. Useful for dain bramaged
72 * devices which do something bad rather than sending a MESSAGE
73 * REJECT back to us like they should if they can't cope.
76 * Enable support for synchronous transfers. Target negotiated
77 * synchronous transfers will be responded to. To initiate
78 * a synchronous transfer request, call
80 * request_synchronous (hostno, target)
84 * OPTION_ALWAYS_SYNCHRONOUS
85 * Negotiate for synchronous transfers with every target after
86 * driver initialization or a SCSI bus reset. This is a bit dangerous,
87 * since there are some dain bramaged SCSI devices which will accept
88 * SDTR messages but keep talking asynchronously.
91 * Enable support for disconnect/reconnect. To change the
92 * default setting on a given host adapter, call
94 * request_disconnect (hostno, allow)
96 * where allow is non-zero to allow, 0 to disallow.
98 * If you really want to run 10MHz FAST SCSI-II transfers, you should
99 * know that the NCR driver currently ignores parity information. Most
100 * systems do 5MHz SCSI fine. I've seen a lot that have problems faster
101 * than 8MHz. To play it safe, we only request 5MHz transfers.
103 * If you'd rather get 10MHz transfers, edit sdtr_message and change
104 * the fourth byte from 50 to 25.
109 * iX Multiuser Multitasking Magazine
113 * Copyright 1993, 1994, 1995 Drew Eckhardt
114 * Visionary Computing
115 * (Unix and Linux consulting and custom programming)
116 * drew@PoohSticks.ORG
119 * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
121 * For more information, please consult
128 * PCI-SCSI I/O Processor
132 * PCI-SCSI I/O Processor Design In Guide
134 * For literature on Symbios Logic Inc. formerly NCR, SCSI,
135 * and Communication products please call (800) 334-5454 or
138 * PCI BIOS Specification Revision
139 * PCI Local Bus Specification
140 * PCI System Design Guide
142 * PCI Special Interest Group
144 * 5200 N.E. Elam Young Parkway
145 * Hillsboro, Oregon 97124-6497
152 * The cumulative latency needed to propagate a read/write request
153 * through the file system, buffer cache, driver stacks, SCSI host, and
154 * SCSI device is ultimately the limiting factor in throughput once we
155 * have a sufficiently fast host adapter.
157 * So, to maximize performance we want to keep the ratio of latency to data
158 * transfer time to a minimum by
159 * 1. Minimizing the total number of commands sent (typical command latency
160 * including drive and bus mastering host overhead is as high as 4.5ms)
161 * to transfer a given amount of data.
163 * This is accomplished by placing no arbitrary limit on the number
164 * of scatter/gather buffers supported, since we can transfer 1K
165 * per scatter/gather buffer without Eric's cluster patches,
168 * 2. Minimizing the number of fatal interrupts serviced, since
169 * fatal interrupts halt the SCSI I/O processor. Basically,
170 * this means offloading the practical maximum amount of processing
173 * On the NCR53c810/820/720, this is accomplished by using
174 * interrupt-on-the-fly signals when commands complete,
175 * and only handling fatal errors and SDTR / WDTR messages
178 * On the NCR53c710, interrupts are generated as on the NCR53c8x0,
179 * only the lack of a interrupt-on-the-fly facility complicates
180 * things. Also, SCSI ID registers and commands are
181 * bit fielded rather than binary encoded.
183 * On the NCR53c700 and NCR53c700-66, operations that are done via
184 * indirect, table mode on the more advanced chips must be
185 * replaced by calls through a jump table which
186 * acts as a surrogate for the DSA. Unfortunately, this
187 * will mean that we must service an interrupt for each
188 * disconnect/reconnect.
190 * 3. Eliminating latency by pipelining operations at the different levels.
192 * This driver allows a configurable number of commands to be enqueued
193 * for each target/lun combination (experimentally, I have discovered
194 * that two seems to work best) and will ultimately allow for
195 * SCSI-II tagged queuing.
199 * This driver is built around a Linux queue of commands waiting to
200 * be executed, and a shared Linux/NCR array of commands to start. Commands
201 * are transfered to the array by the run_process_issue_queue() function
202 * which is called whenever a command completes.
204 * As commands are completed, the interrupt routine is triggered,
205 * looks for commands in the linked list of completed commands with
206 * valid status, removes these commands from a list of running commands,
207 * calls the done routine, and flags their target/luns as not busy.
209 * Due to limitations in the intelligence of the NCR chips, certain
210 * concessions are made. In many cases, it is easier to dynamically
211 * generate/fix-up code rather than calculate on the NCR at run time.
212 * So, code is generated or fixed up for
214 * - Handling data transfers, using a variable number of MOVE instructions
215 * interspersed with CALL MSG_IN, WHEN MSGIN instructions.
217 * The DATAIN and DATAOUT routines are separate, so that an incorrect
218 * direction can be trapped, and space isn't wasted.
220 * It may turn out that we're better off using some sort
221 * of table indirect instruction in a loop with a variable
222 * sized table on the NCR53c710 and newer chips.
224 * - Checking for reselection (NCR53c710 and better)
226 * - Handling the details of SCSI context switches (NCR53c710 and better),
227 * such as reprogramming appropriate synchronous parameters,
228 * removing the dsa structure from the NCR's queue of outstanding
234 #include <linux/module.h>
237 #include <linux/config.h>
239 #include <linux/types.h>
240 #include <asm/setup.h>
243 #include <asm/system.h>
244 #include <linux/delay.h>
245 #include <linux/signal.h>
246 #include <linux/sched.h>
247 #include <linux/errno.h>
248 #include <linux/proc_fs.h>
249 #include <linux/string.h>
250 #include <linux/malloc.h>
251 #include <linux/vmalloc.h>
252 #include <linux/mm.h>
253 #include <linux/ioport.h>
254 #include <linux/time.h>
255 #include <linux/blk.h>
256 #include <linux/spinlock.h>
257 #include <asm/pgtable.h>
260 #include <asm/amigahw.h>
261 #include <asm/amigaints.h>
268 #ifdef CONFIG_MVME16x
269 #include <asm/mvme16xhw.h>
276 #ifdef CONFIG_BVME6000
277 #include <asm/bvme6000hw.h>
287 #include "constants.h"
289 #include <linux/stat.h>
290 #include <linux/stddef.h>
294 * The following make the definitions in 53c7xx.h (write8, etc) smaller,
295 * we don't have separate i/o space anyway.
311 static int check_address (unsigned long addr
, int size
);
312 static void dump_events (struct Scsi_Host
*host
, int count
);
313 static Scsi_Cmnd
* return_outstanding_commands (struct Scsi_Host
*host
,
314 int free
, int issue
);
315 static void hard_reset (struct Scsi_Host
*host
);
316 static void ncr_scsi_reset (struct Scsi_Host
*host
);
317 static void print_lots (struct Scsi_Host
*host
);
318 static void set_synchronous (struct Scsi_Host
*host
, int target
, int sxfer
,
319 int scntl3
, int now_connected
);
320 static int datapath_residual (struct Scsi_Host
*host
);
321 static const char * sbcl_to_phase (int sbcl
);
322 static void print_progress (Scsi_Cmnd
*cmd
);
323 static void print_queues (struct Scsi_Host
*host
);
324 static void process_issue_queue (unsigned long flags
);
325 static int shutdown (struct Scsi_Host
*host
);
326 static void abnormal_finished (struct NCR53c7x0_cmd
*cmd
, int result
);
327 static int disable (struct Scsi_Host
*host
);
328 static int NCR53c7xx_run_tests (struct Scsi_Host
*host
);
329 static void NCR53c7x0_intr(int irq
, void *dev_id
, struct pt_regs
* regs
);
330 static void NCR53c7x0_intfly (struct Scsi_Host
*host
);
331 static int ncr_halt (struct Scsi_Host
*host
);
332 static void intr_phase_mismatch (struct Scsi_Host
*host
, struct NCR53c7x0_cmd
334 static void intr_dma (struct Scsi_Host
*host
, struct NCR53c7x0_cmd
*cmd
);
335 static void print_dsa (struct Scsi_Host
*host
, u32
*dsa
,
337 static int print_insn (struct Scsi_Host
*host
, const u32
*insn
,
338 const char *prefix
, int kernel
);
340 static void NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd
*cmd
);
341 static void NCR53c7x0_init_fixup (struct Scsi_Host
*host
);
342 static int NCR53c7x0_dstat_sir_intr (struct Scsi_Host
*host
, struct
344 static void NCR53c7x0_soft_reset (struct Scsi_Host
*host
);
346 /* Size of event list (per host adapter) */
347 static int track_events
= 0;
348 static struct Scsi_Host
*first_host
= NULL
; /* Head of list of NCR boards */
349 static Scsi_Host_Template
*the_template
= NULL
;
351 /* NCR53c710 script handling code */
353 #include "53c7xx_d.h"
354 #ifdef A_int_debug_sync
355 #define DEBUG_SYNC_INTR A_int_debug_sync
357 int NCR53c7xx_script_len
= sizeof (SCRIPT
);
358 int NCR53c7xx_dsa_len
= A_dsa_end
+ Ent_dsa_zero
- Ent_dsa_code_template
;
359 #ifdef FORCE_DSA_ALIGNMENT
360 int CmdPageStart
= (0 - Ent_dsa_zero
- sizeof(struct NCR53c7x0_cmd
)) & 0xff;
363 static char *setup_strings
[] =
364 {"","","","","","","",""};
366 #define MAX_SETUP_STRINGS (sizeof(setup_strings) / sizeof(char *))
367 #define SETUP_BUFFER_SIZE 200
368 static char setup_buffer
[SETUP_BUFFER_SIZE
];
369 static char setup_used
[MAX_SETUP_STRINGS
];
371 void ncr53c7xx_setup (char *str
, int *ints
)
379 strncpy(p1
, str
, SETUP_BUFFER_SIZE
- strlen(setup_buffer
));
380 setup_buffer
[SETUP_BUFFER_SIZE
- 1] = '\0';
383 while (*p1
&& (i
< MAX_SETUP_STRINGS
)) {
384 p2
= strchr(p1
, ',');
388 setup_strings
[i
] = p1
;
393 setup_strings
[i
] = p1
;
397 for (i
=0; i
<MAX_SETUP_STRINGS
; i
++)
402 /* check_setup_strings() returns index if key found, 0 if not
405 static int check_setup_strings(char *key
, int *flags
, int *val
, char *buf
)
410 for (x
=0; x
<MAX_SETUP_STRINGS
; x
++) {
413 if (!strncmp(setup_strings
[x
], key
, strlen(key
)))
415 if (!strncmp(setup_strings
[x
], "next", strlen("next")))
418 if (x
== MAX_SETUP_STRINGS
)
421 cp
= setup_strings
[x
] + strlen(key
);
426 if ((*cp
>= '0') && (*cp
<= '9')) {
427 *val
= simple_strtoul(cp
,NULL
,0);
436 * - There is some sort of conflict when the PPP driver is compiled with
437 * support for 16 channels?
439 * - On systems which predate the 1.3.x initialization order change,
440 * the NCR driver will cause Cannot get free page messages to appear.
441 * These are harmless, but I don't know of an easy way to avoid them.
443 * - With OPTION_DISCONNECT, on two systems under unknown circumstances,
444 * we get a PHASE MISMATCH with DSA set to zero (suggests that we
445 * are occurring somewhere in the reselection code) where
446 * DSP=some value DCMD|DBC=same value.
448 * Closer inspection suggests that we may be trying to execute
449 * some portion of the DSA?
450 * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO)
451 * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO)
452 * scsi0 : no current command : unexpected phase MSGIN.
453 * DSP=0x1c46cc, DCMD|DBC=0x1c46ac, DSA=0x0
454 * DSPS=0x0, TEMP=0x1c3e70, DMODE=0x80
456 * 001c46cc : 0x001c46cc 0x00000000
457 * 001c46d4 : 0x001c5ea0 0x000011f8
459 * Changed the print code in the phase_mismatch handler so
460 * that we call print_lots to try to diagnose this.
465 * Possible future direction of architecture for max performance :
467 * We're using a single start array for the NCR chip. This is
468 * sub-optimal, because we cannot add a command which would conflict with
469 * an executing command to this start queue, and therefore must insert the
470 * next command for a given I/T/L combination after the first has completed;
471 * incurring our interrupt latency between SCSI commands.
473 * To allow further pipelining of the NCR and host CPU operation, we want
474 * to set things up so that immediately on termination of a command destined
475 * for a given LUN, we get that LUN busy again.
477 * To do this, we need to add a 32 bit pointer to which is jumped to
478 * on completion of a command. If no new command is available, this
479 * would point to the usual DSA issue queue select routine.
481 * If one were, it would point to a per-NCR53c7x0_cmd select routine
482 * which starts execution immediately, inserting the command at the head
483 * of the start queue if the NCR chip is selected or reselected.
485 * We would change so that we keep a list of outstanding commands
486 * for each unit, rather than a single running_list. We'd insert
487 * a new command into the right running list; if the NCR didn't
488 * have something running for that yet, we'd put it in the
489 * start queue as well. Some magic needs to happen to handle the
490 * race condition between the first command terminating before the
491 * new one is written.
493 * Potential for profiling :
494 * Call do_gettimeofday(struct timeval *tv) to get 800ns resolution.
500 * 1. To support WIDE transfers, not much needs to happen. We
501 * should do CHMOVE instructions instead of MOVEs when
502 * we have scatter/gather segments of uneven length. When
503 * we do this, we need to handle the case where we disconnect
506 * 2. Currently, when Icky things happen we do a FATAL(). Instead,
507 * we want to do an integrity check on the parts of the NCR hostdata
508 * structure which were initialized at boot time; FATAL() if that
509 * fails, and otherwise try to recover. Keep track of how many
510 * times this has happened within a single SCSI command; if it
511 * gets excessive, then FATAL().
513 * 3. Parity checking is currently disabled, and a few things should
514 * happen here now that we support synchronous SCSI transfers :
515 * 1. On soft-reset, we shoould set the EPC (Enable Parity Checking)
516 * and AAP (Assert SATN/ on parity error) bits in SCNTL0.
518 * 2. We should enable the parity interrupt in the SIEN0 register.
520 * 3. intr_phase_mismatch() needs to believe that message out is
521 * always an "acceptable" phase to have a mismatch in. If
522 * the old phase was MSG_IN, we should send a MESSAGE PARITY
523 * error. If the old phase was something else, we should send
524 * a INITIATOR_DETECTED_ERROR message. Note that this could
525 * cause a RESTORE POINTERS message; so we should handle that
526 * correctly first. Instead, we should probably do an
529 * 4. MPEE bit of CTEST4 should be set so we get interrupted if
530 * we detect an error.
533 * 5. The initial code has been tested on the NCR53c810. I don't
534 * have access to NCR53c700, 700-66 (Forex boards), NCR53c710
535 * (NCR Pentium systems), NCR53c720, NCR53c820, or NCR53c825 boards to
536 * finish development on those platforms.
538 * NCR53c820/825/720 - need to add wide transfer support, including WDTR
539 * negotiation, programming of wide transfer capabilities
540 * on reselection and table indirect selection.
542 * NCR53c710 - need to add fatal interrupt or GEN code for
543 * command completion signaling. Need to modify all
544 * SDID, SCID, etc. registers, and table indirect select code
545 * since these use bit fielded (ie 1<<target) instead of
546 * binary encoded target ids. Need to accommodate
547 * different register mappings, probably scan through
548 * the SCRIPT code and change the non SFBR register operand
549 * of all MOVE instructions.
551 * It is rather worse than this actually, the 710 corrupts
552 * both TEMP and DSA when you do a MOVE MEMORY. This
553 * screws you up all over the place. MOVE MEMORY 4 with a
554 * destination of DSA seems to work OK, which helps some.
555 * Richard Hirst richard@sleepie.demon.co.uk
557 * NCR53c700/700-66 - need to add code to refix addresses on
558 * every nexus change, eliminate all table indirect code,
561 * 6. The NCR53c7x0 series is very popular on other platforms that
562 * could be running Linux - ie, some high performance AMIGA SCSI
565 * So, I should include #ifdef'd code so that it is
566 * compatible with these systems.
568 * Specifically, the little Endian assumptions I made in my
569 * bit fields need to change, and if the NCR doesn't see memory
570 * the right way, we need to provide options to reverse words
571 * when the scripts are relocated.
573 * 7. Use vremap() to access memory mapped boards.
577 * Allow for simultaneous existence of multiple SCSI scripts so we
578 * can have a single driver binary for all of the family.
580 * - one for NCR53c700 and NCR53c700-66 chips (not yet supported)
581 * - one for rest (only the NCR53c810, 815, 820, and 825 are currently
584 * So that we only need two SCSI scripts, we need to modify things so
585 * that we fixup register accesses in READ/WRITE instructions, and
586 * we'll also have to accommodate the bit vs. binary encoding of IDs
587 * with the 7xx chips.
590 #define ROUNDUP(adr,type) \
591 ((void *) (((long) (adr) + sizeof(type) - 1) & ~(sizeof(type) - 1)))
595 * Function: issue_to_cmd
597 * Purpose: convert jump instruction in issue array to NCR53c7x0_cmd
600 * Inputs; issue - pointer to start of NOP or JUMP instruction
603 * Returns: pointer to command on success; 0 if opcode is NOP.
606 static inline struct NCR53c7x0_cmd
*
607 issue_to_cmd (struct Scsi_Host
*host
, struct NCR53c7x0_hostdata
*hostdata
,
610 return (issue
[0] != hostdata
->NOP_insn
) ?
612 * If the IF TRUE bit is set, it's a JUMP instruction. The
613 * operand is a bus pointer to the dsa_begin routine for this DSA. The
614 * dsa field of the NCR53c7x0_cmd structure starts with the
615 * DSA code template. By converting to a virtual address,
616 * subtracting the code template size, and offset of the
617 * dsa field, we end up with a pointer to the start of the
618 * structure (alternatively, we could use the
619 * dsa_cmnd field, an anachronism from when we weren't
620 * sure what the relationship between the NCR structures
621 * and host structures were going to be.
623 (struct NCR53c7x0_cmd
*) ((char *) bus_to_virt (issue
[1]) -
624 (hostdata
->E_dsa_code_begin
- hostdata
->E_dsa_code_template
) -
625 offsetof(struct NCR53c7x0_cmd
, dsa
))
626 /* If the IF TRUE bit is not set, it's a NOP */
632 * FIXME: we should junk these, in favor of synchronous_want and
633 * wide_want in the NCR53c7x0_hostdata structure.
636 /* Template for "preferred" synchronous transfer parameters. */
638 static const unsigned char sdtr_message
[] = {
639 #ifdef CONFIG_SCSI_NCR53C7xx_FAST
640 EXTENDED_MESSAGE
, 3 /* length */, EXTENDED_SDTR
, 25 /* *4ns */, 8 /* off */
642 EXTENDED_MESSAGE
, 3 /* length */, EXTENDED_SDTR
, 50 /* *4ns */, 8 /* off */
646 /* Template to request asynchronous transfers */
648 static const unsigned char async_message
[] = {
649 EXTENDED_MESSAGE
, 3 /* length */, EXTENDED_SDTR
, 0, 0 /* asynchronous */
652 /* Template for "preferred" WIDE transfer parameters */
654 static const unsigned char wdtr_message
[] = {
655 EXTENDED_MESSAGE
, 2 /* length */, EXTENDED_WDTR
, 1 /* 2^1 bytes */
660 * Function : struct Scsi_Host *find_host (int host)
662 * Purpose : KGDB support function which translates a host number
663 * to a host structure.
665 * Inputs : host - number of SCSI host
667 * Returns : NULL on failure, pointer to host structure on success.
670 static struct Scsi_Host
*
671 find_host (int host
) {
673 for (h
= first_host
; h
&& h
->host_no
!= host
; h
= h
->next
);
675 printk (KERN_ALERT
"scsi%d not found\n", host
);
677 } else if (h
->hostt
!= the_template
) {
678 printk (KERN_ALERT
"scsi%d is not a NCR board\n", host
);
686 * Function : request_synchronous (int host, int target)
688 * Purpose : KGDB interface which will allow us to negotiate for
689 * synchronous transfers. This ill be replaced with a more
690 * integrated function; perhaps a new entry in the scsi_host
691 * structure, accessible via an ioctl() or perhaps /proc/scsi.
693 * Inputs : host - number of SCSI host; target - number of target.
695 * Returns : 0 when negotiation has been setup for next SCSI command,
700 request_synchronous (int host
, int target
) {
702 struct NCR53c7x0_hostdata
*hostdata
;
705 printk (KERN_ALERT
"target %d is bogus\n", target
);
708 if (!(h
= find_host (host
)))
710 else if (h
->this_id
== target
) {
711 printk (KERN_ALERT
"target %d is host ID\n", target
);
714 else if (target
> h
->max_id
) {
715 printk (KERN_ALERT
"target %d exceeds maximum of %d\n", target
,
719 hostdata
= (struct NCR53c7x0_hostdata
*)h
->hostdata
[0];
723 if (hostdata
->initiate_sdtr
& (1 << target
)) {
724 restore_flags(flags
);
725 printk (KERN_ALERT
"target %d already doing SDTR\n", target
);
728 hostdata
->initiate_sdtr
|= (1 << target
);
729 restore_flags(flags
);
735 * Function : request_disconnect (int host, int on_or_off)
737 * Purpose : KGDB support function, tells us to allow or disallow
740 * Inputs : host - number of SCSI host; on_or_off - non-zero to allow,
743 * Returns : 0 on success, * -1 on failure.
747 request_disconnect (int host
, int on_or_off
) {
749 struct NCR53c7x0_hostdata
*hostdata
;
750 if (!(h
= find_host (host
)))
752 hostdata
= (struct NCR53c7x0_hostdata
*) h
->hostdata
[0];
754 hostdata
->options
|= OPTION_DISCONNECT
;
756 hostdata
->options
&= ~OPTION_DISCONNECT
;
762 * Function : static void NCR53c7x0_driver_init (struct Scsi_Host *host)
764 * Purpose : Initialize internal structures, as required on startup, or
765 * after a SCSI bus reset.
767 * Inputs : host - pointer to this host adapter's structure
771 NCR53c7x0_driver_init (struct Scsi_Host
*host
) {
772 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
777 for (i
= 0; i
< 16; ++i
) {
778 hostdata
->request_sense
[i
] = 0;
779 for (j
= 0; j
< 8; ++j
)
780 hostdata
->busy
[i
][j
] = 0;
781 set_synchronous (host
, i
, /* sxfer */ 0, hostdata
->saved_scntl3
, 0);
783 hostdata
->issue_queue
= NULL
;
784 hostdata
->running_list
= hostdata
->finished_queue
=
785 hostdata
->ncrcurrent
= NULL
;
786 for (i
= 0, ncrcurrent
= (u32
*) hostdata
->schedule
;
787 i
< host
->can_queue
; ++i
, ncrcurrent
+= 2) {
788 ncrcurrent
[0] = hostdata
->NOP_insn
;
789 ncrcurrent
[1] = 0xdeadbeef;
791 ncrcurrent
[0] = ((DCMD_TYPE_TCI
|DCMD_TCI_OP_JUMP
) << 24) | DBC_TCI_TRUE
;
792 ncrcurrent
[1] = (u32
) virt_to_bus (hostdata
->script
) +
793 hostdata
->E_wait_reselect
;
794 hostdata
->reconnect_dsa_head
= 0;
795 hostdata
->addr_reconnect_dsa_head
= (u32
)
796 virt_to_bus((void *) &(hostdata
->reconnect_dsa_head
));
797 hostdata
->expecting_iid
= 0;
798 hostdata
->expecting_sto
= 0;
799 if (hostdata
->options
& OPTION_ALWAYS_SYNCHRONOUS
)
800 hostdata
->initiate_sdtr
= 0xffff;
802 hostdata
->initiate_sdtr
= 0;
803 hostdata
->talked_to
= 0;
808 * Function : static int clock_to_ccf_710 (int clock)
810 * Purpose : Return the clock conversion factor for a given SCSI clock.
812 * Inputs : clock - SCSI clock expressed in Hz.
814 * Returns : ccf on success, -1 on failure.
818 clock_to_ccf_710 (int clock
) {
819 if (clock
<= 16666666)
821 if (clock
<= 25000000)
822 return 2; /* Divide by 1.0 */
823 else if (clock
<= 37500000)
824 return 1; /* Divide by 1.5 */
825 else if (clock
<= 50000000)
826 return 0; /* Divide by 2.0 */
827 else if (clock
<= 66000000)
828 return 3; /* Divide by 3.0 */
834 * Function : static int NCR53c7x0_init (struct Scsi_Host *host)
836 * Purpose : initialize the internal structures for a given SCSI host
838 * Inputs : host - pointer to this host adapter's structure
840 * Preconditions : when this function is called, the chip_type
841 * field of the hostdata structure MUST have been set.
843 * Returns : 0 on success, -1 on failure.
847 NCR53c7x0_init (struct Scsi_Host
*host
) {
848 NCR53c7x0_local_declare();
850 unsigned char revision
;
851 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
854 * There are some things which we need to know about in order to provide
855 * a semblance of support. Print 'em if they aren't what we expect,
856 * otherwise don't add to the noise.
858 * -1 means we don't know what to expect.
862 int expected_id
= -1;
863 int expected_clock
= -1;
864 int uninitialized
= 0;
866 int expected_mapping
= OPTION_MEMORY_MAPPED
;
868 int expected_mapping
= OPTION_IO_MAPPED
;
871 hostdata
->valid_ids
[i
] = 1; /* Default all ID's to scan */
873 /* Parse commandline flags */
874 if (check_setup_strings("noasync",&flags
,&val
,buf
))
876 hostdata
->options
|= OPTION_NO_ASYNC
;
877 hostdata
->options
&= ~(OPTION_SYNCHRONOUS
| OPTION_ALWAYS_SYNCHRONOUS
);
880 if (check_setup_strings("nosync",&flags
,&val
,buf
))
882 hostdata
->options
&= ~(OPTION_SYNCHRONOUS
| OPTION_ALWAYS_SYNCHRONOUS
);
885 if (check_setup_strings("nodisconnect",&flags
,&val
,buf
))
886 hostdata
->options
&= ~OPTION_DISCONNECT
;
888 if (check_setup_strings("validids",&flags
,&val
,buf
))
891 hostdata
->valid_ids
[i
] = val
& (1<<i
);
894 if ((i
= check_setup_strings("next",&flags
,&val
,buf
)))
900 if (check_setup_strings("opthi",&flags
,&val
,buf
))
901 hostdata
->options
= (long long)val
<< 32;
902 if (check_setup_strings("optlo",&flags
,&val
,buf
))
903 hostdata
->options
|= val
;
905 NCR53c7x0_local_setup(host
);
906 switch (hostdata
->chip
) {
909 hostdata
->dstat_sir_intr
= NCR53c7x0_dstat_sir_intr
;
910 hostdata
->init_save_regs
= NULL
;
911 hostdata
->dsa_fixup
= NCR53c7xx_dsa_fixup
;
912 hostdata
->init_fixup
= NCR53c7x0_init_fixup
;
913 hostdata
->soft_reset
= NCR53c7x0_soft_reset
;
914 hostdata
->run_tests
= NCR53c7xx_run_tests
;
915 expected_clock
= hostdata
->scsi_clock
;
919 printk ("scsi%d : chip type of %d is not supported yet, detaching.\n",
920 host
->host_no
, hostdata
->chip
);
921 scsi_unregister (host
);
925 /* Assign constants accessed by NCR */
926 hostdata
->NCR53c7xx_zero
= 0;
927 hostdata
->NCR53c7xx_msg_reject
= MESSAGE_REJECT
;
928 hostdata
->NCR53c7xx_msg_abort
= ABORT
;
929 hostdata
->NCR53c7xx_msg_nop
= NOP
;
930 hostdata
->NOP_insn
= (DCMD_TYPE_TCI
|DCMD_TCI_OP_JUMP
) << 24;
931 if (expected_mapping
== -1 ||
932 (hostdata
->options
& (OPTION_MEMORY_MAPPED
)) !=
933 (expected_mapping
& OPTION_MEMORY_MAPPED
))
934 printk ("scsi%d : using %s mapped access\n", host
->host_no
,
935 (hostdata
->options
& OPTION_MEMORY_MAPPED
) ? "memory" :
938 hostdata
->dmode
= (hostdata
->chip
== 700 || hostdata
->chip
== 70066) ?
939 DMODE_REG_00
: DMODE_REG_10
;
940 hostdata
->istat
= ((hostdata
->chip
/ 100) == 8) ?
941 ISTAT_REG_800
: ISTAT_REG_700
;
943 /* We have to assume that this may be the first access to the chip, so
944 * we must set EA in DCNTL. */
946 NCR53c7x0_write8 (DCNTL_REG
, DCNTL_10_EA
|DCNTL_10_COM
);
949 /* Only the ISTAT register is readable when the NCR is running, so make
954 * XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc,
955 * as does the 710 with one bit per SCSI ID. Conversely, the NCR
956 * uses a normal, 3 bit binary representation of these values.
958 * Get the rest of the NCR documentation, and FIND OUT where the change
963 /* May not be able to do this - chip my not have been set up yet */
964 tmp
= hostdata
->this_id_mask
= NCR53c7x0_read8(SCID_REG
);
965 for (host
->this_id
= 0; tmp
!= 1; tmp
>>=1, ++host
->this_id
);
971 * Note : we should never encounter a board setup for ID0. So,
972 * if we see ID0, assume that it was uninitialized and set it
973 * to the industry standard 7.
975 if (!host
->this_id
) {
976 printk("scsi%d : initiator ID was %d, changing to 7\n",
977 host
->host_no
, host
->this_id
);
979 hostdata
->this_id_mask
= 1 << 7;
983 if (expected_id
== -1 || host
->this_id
!= expected_id
)
984 printk("scsi%d : using initiator ID %d\n", host
->host_no
,
988 * Save important registers to allow a soft reset.
992 * CTEST7 controls cache snooping, burst mode, and support for
993 * external differential drivers. This isn't currently used - the
994 * default value may not be optimal anyway.
995 * Even worse, it may never have been set up since reset.
997 hostdata
->saved_ctest7
= NCR53c7x0_read8(CTEST7_REG
) & CTEST7_SAVE
;
998 revision
= (NCR53c7x0_read8(CTEST8_REG
) & 0xF0) >> 4;
1000 case 1: revision
= 0; break;
1001 case 2: revision
= 1; break;
1002 case 4: revision
= 2; break;
1003 case 8: revision
= 3; break;
1004 default: revision
= 255; break;
1006 printk("scsi%d: Revision 0x%x\n",host
->host_no
,revision
);
1008 if ((revision
== 0 || revision
== 255) && (hostdata
->options
& (OPTION_SYNCHRONOUS
|OPTION_DISCONNECT
|OPTION_ALWAYS_SYNCHRONOUS
)))
1010 printk ("scsi%d: Disabling sync working and disconnect/reselect\n",
1012 hostdata
->options
&= ~(OPTION_SYNCHRONOUS
|OPTION_DISCONNECT
|OPTION_ALWAYS_SYNCHRONOUS
);
1016 * On NCR53c700 series chips, DCNTL controls the SCSI clock divisor,
1017 * on 800 series chips, it allows for a totem-pole IRQ driver.
1018 * NOTE saved_dcntl currently overwritten in init function.
1019 * The value read here may be garbage anyway, MVME16x board at least
1020 * does not initialise chip if kernel arrived via tftp.
1023 hostdata
->saved_dcntl
= NCR53c7x0_read8(DCNTL_REG
);
1026 * DMODE controls DMA burst length, and on 700 series chips,
1027 * 286 mode and bus width
1028 * NOTE: On MVME16x, chip may have been reset, so this could be a
1029 * power-on/reset default value.
1031 hostdata
->saved_dmode
= NCR53c7x0_read8(hostdata
->dmode
);
1034 * Now that burst length and enabled/disabled status is known,
1035 * clue the user in on it.
1038 ccf
= clock_to_ccf_710 (expected_clock
);
1040 for (i
= 0; i
< 16; ++i
)
1041 hostdata
->cmd_allocated
[i
] = 0;
1043 if (hostdata
->init_save_regs
)
1044 hostdata
->init_save_regs (host
);
1045 if (hostdata
->init_fixup
)
1046 hostdata
->init_fixup (host
);
1048 if (!the_template
) {
1049 the_template
= host
->hostt
;
1054 * Linux SCSI drivers have always been plagued with initialization
1055 * problems - some didn't work with the BIOS disabled since they expected
1056 * initialization from it, some didn't work when the networking code
1057 * was enabled and registers got scrambled, etc.
1059 * To avoid problems like this, in the future, we will do a soft
1060 * reset on the SCSI chip, taking it back to a sane state.
1063 hostdata
->soft_reset (host
);
1066 hostdata
->debug_count_limit
= -1;
1068 hostdata
->debug_count_limit
= 1;
1070 hostdata
->intrs
= -1;
1071 hostdata
->resets
= -1;
1072 memcpy ((void *) hostdata
->synchronous_want
, (void *) sdtr_message
,
1073 sizeof (hostdata
->synchronous_want
));
1075 NCR53c7x0_driver_init (host
);
1077 if (request_irq(host
->irq
, NCR53c7x0_intr
, SA_SHIRQ
, "53c7xx", host
))
1079 printk("scsi%d : IRQ%d not free, detaching\n",
1080 host
->host_no
, host
->irq
);
1081 scsi_unregister (host
);
1085 if ((hostdata
->run_tests
&& hostdata
->run_tests(host
) == -1) ||
1086 (hostdata
->options
& OPTION_DEBUG_TESTS_ONLY
)) {
1087 /* XXX Should disable interrupts, etc. here */
1088 scsi_unregister (host
);
1091 if (host
->io_port
) {
1092 host
->n_io_port
= 128;
1093 request_region (host
->io_port
, host
->n_io_port
, "ncr53c7xx");
1097 if (NCR53c7x0_read8 (SBCL_REG
) & SBCL_BSY
) {
1098 printk ("scsi%d : bus wedge, doing SCSI reset\n", host
->host_no
);
1105 * Function : static int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board,
1106 * int chip, u32 base, int io_port, int irq, int dma, long long options,
1109 * Purpose : initializes a NCR53c7,8x0 based on base addresses,
1110 * IRQ, and DMA channel.
1112 * Inputs : tpnt - Template for this SCSI adapter, board - board level
1113 * product, chip - 710
1115 * Returns : 0 on success, -1 on failure.
1120 ncr53c7xx_init (Scsi_Host_Template
*tpnt
, int board
, int chip
,
1121 u32 base
, int io_port
, int irq
, int dma
, long long options
, int clock
)
1123 struct Scsi_Host
*instance
;
1124 struct NCR53c7x0_hostdata
*hostdata
;
1126 int script_len
= 0, dsa_len
= 0, size
= 0, max_cmd_size
= 0,
1127 schedule_size
= 0, ok
= 0;
1133 schedule_size
= (tpnt
->can_queue
+ 1) * 8 /* JUMP instruction size */;
1134 script_len
= NCR53c7xx_script_len
;
1135 dsa_len
= NCR53c7xx_dsa_len
;
1136 options
|= OPTION_INTFLY
;
1137 sprintf (chip_str
, "NCR53c%d", chip
);
1140 printk("scsi-ncr53c7xx : unsupported SCSI chip %d\n", chip
);
1144 printk("scsi-ncr53c7xx : %s at memory 0x%x, io 0x%x, irq %d",
1145 chip_str
, (unsigned) base
, io_port
, irq
);
1146 if (dma
== DMA_NONE
)
1149 printk(", dma %d\n", dma
);
1151 if (options
& OPTION_DEBUG_PROBE_ONLY
) {
1152 printk ("scsi-ncr53c7xx : probe only enabled, aborting initialization\n");
1156 max_cmd_size
= sizeof(struct NCR53c7x0_cmd
) + dsa_len
+
1157 /* Size of dynamic part of command structure : */
1158 2 * /* Worst case : we don't know if we need DATA IN or DATA out */
1159 ( 2 * /* Current instructions per scatter/gather segment */
1160 tpnt
->sg_tablesize
+
1161 3 /* Current startup / termination required per phase */
1163 8 /* Each instruction is eight bytes */;
1165 /* Allocate fixed part of hostdata, dynamic part to hold appropriate
1166 SCSI SCRIPT(tm) plus a single, maximum-sized NCR53c7x0_cmd structure.
1168 We need a NCR53c7x0_cmd structure for scan_scsis() when we are
1169 not loaded as a module, and when we're loaded as a module, we
1170 can't use a non-dynamically allocated structure because modules
1171 are vmalloc()'d, which can allow structures to cross page
1172 boundaries and breaks our physical/virtual address assumptions
1175 So, we stick it past the end of our hostdata structure.
1178 Regardless of how many simultaneous SCSI commands we allow,
1179 the probe code only executes a _single_ instruction at a time,
1180 so we only need one here, and don't need to allocate NCR53c7x0_cmd
1181 structures for each target until we are no longer in scan_scsis
1182 and kmalloc() has become functional (memory_init() happens
1183 after all device driver initialization).
1186 size
= sizeof(struct NCR53c7x0_hostdata
) + script_len
+
1187 /* Note that alignment will be guaranteed, since we put the command
1188 allocated at probe time after the fixed-up SCSI script, which
1189 consists of 32 bit words, aligned on a 32 bit boundary. But
1190 on a 64bit machine we need 8 byte alignment for hostdata->free, so
1191 we add in another 4 bytes to take care of potential misalignment
1193 (sizeof(void *) - sizeof(u32
)) + max_cmd_size
+ schedule_size
;
1195 #ifdef FORCE_DSA_ALIGNMENT
1197 * 53c710 rev.0 doesn't have an add-with-carry instruction.
1198 * Ensure we allocate enough memory to force DSA alignment.
1202 /* Size should be < 8K, so we can fit it in two pages. */
1204 panic("53c7xx: hostdata > 8K");
1205 instance
= scsi_register (tpnt
, 4);
1208 instance
->hostdata
[0] = __get_free_pages(GFP_ATOMIC
, 1);
1209 if (instance
->hostdata
[0] == 0)
1210 panic ("53c7xx: Couldn't get hostdata memory");
1211 memset((void *)instance
->hostdata
[0], 0, 8192);
1212 cache_push(virt_to_phys((void *)(instance
->hostdata
[0])), 8192);
1213 cache_clear(virt_to_phys((void *)(instance
->hostdata
[0])), 8192);
1214 kernel_set_cachemode(instance
->hostdata
[0], 8192, IOMAP_NOCACHE_SER
);
1216 /* FIXME : if we ever support an ISA NCR53c7xx based board, we
1217 need to check if the chip is running in a 16 bit mode, and if so
1218 unregister it if it is past the 16M (0x1000000) mark */
1220 hostdata
= (struct NCR53c7x0_hostdata
*)instance
->hostdata
[0];
1221 hostdata
->size
= size
;
1222 hostdata
->script_count
= script_len
/ sizeof(u32
);
1223 hostdata
->board
= board
;
1224 hostdata
->chip
= chip
;
1227 * Being memory mapped is more desirable, since
1229 * - Memory accesses may be faster.
1231 * - The destination and source address spaces are the same for
1232 * all instructions, meaning we don't have to twiddle dmode or
1233 * any other registers.
1235 * So, we try for memory mapped, and if we don't get it,
1236 * we go for port mapped, and that failing we tell the user
1241 instance
->base
= (unsigned char *) (unsigned long) base
;
1242 /* Check for forced I/O mapping */
1243 if (!(options
& OPTION_IO_MAPPED
)) {
1244 options
|= OPTION_MEMORY_MAPPED
;
1248 options
&= ~OPTION_MEMORY_MAPPED
;
1252 instance
->io_port
= io_port
;
1253 options
|= OPTION_IO_MAPPED
;
1256 options
&= ~OPTION_IO_MAPPED
;
1260 printk ("scsi%d : not initializing, no I/O or memory mapping known \n",
1262 scsi_unregister (instance
);
1265 instance
->irq
= irq
;
1266 instance
->dma_channel
= dma
;
1268 hostdata
->options
= options
;
1269 hostdata
->dsa_len
= dsa_len
;
1270 hostdata
->max_cmd_size
= max_cmd_size
;
1271 hostdata
->num_cmds
= 1;
1272 hostdata
->scsi_clock
= clock
;
1273 /* Initialize single command */
1274 tmp
= (hostdata
->script
+ hostdata
->script_count
);
1275 #ifdef FORCE_DSA_ALIGNMENT
1277 void *t
= ROUNDUP(tmp
, void *);
1278 if (((u32
)t
& 0xff) > CmdPageStart
)
1279 t
= (void *)((u32
)t
+ 255);
1280 t
= (void *)(((u32
)t
& ~0xff) + CmdPageStart
);
1283 printk ("scsi: Registered size increased by 256 to %d\n", size
);
1284 printk ("scsi: CmdPageStart = 0x%02x\n", CmdPageStart
);
1285 printk ("scsi: tmp = 0x%08x, hostdata->free set to 0x%08x\n",
1290 hostdata
->free
= ROUNDUP(tmp
, void *);
1292 hostdata
->free
->real
= tmp
;
1293 hostdata
->free
->size
= max_cmd_size
;
1294 hostdata
->free
->free
= NULL
;
1295 hostdata
->free
->next
= NULL
;
1296 hostdata
->extra_allocate
= 0;
1298 /* Allocate command start code space */
1299 hostdata
->schedule
= (chip
== 700 || chip
== 70066) ?
1300 NULL
: (u32
*) ((char *)hostdata
->free
+ max_cmd_size
);
1303 * For diagnostic purposes, we don't really care how fast things blaze.
1304 * For profiling, we want to access the 800ns resolution system clock,
1305 * using a 'C' call on the host processor.
1307 * Therefore, there's no need for the NCR chip to directly manipulate
1308 * this data, and we should put it wherever is most convenient for
1312 hostdata
->events
= (struct NCR53c7x0_event
*) (track_events
?
1313 vmalloc (sizeof (struct NCR53c7x0_event
) * track_events
) : NULL
);
1315 hostdata
->events
= NULL
;
1317 if (hostdata
->events
) {
1318 memset ((void *) hostdata
->events
, 0, sizeof(struct NCR53c7x0_event
) *
1320 hostdata
->event_size
= track_events
;
1321 hostdata
->event_index
= 0;
1323 hostdata
->event_size
= 0;
1325 return NCR53c7x0_init(instance
);
1330 * Function : static void NCR53c7x0_init_fixup (struct Scsi_Host *host)
1332 * Purpose : copy and fixup the SCSI SCRIPTS(tm) code for this device.
1334 * Inputs : host - pointer to this host adapter's structure
1339 NCR53c7x0_init_fixup (struct Scsi_Host
*host
) {
1340 NCR53c7x0_local_declare();
1341 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
1344 int i
, ncr_to_memory
, memory_to_ncr
;
1346 NCR53c7x0_local_setup(host
);
1349 /* XXX - NOTE : this code MUST be made endian aware */
1350 /* Copy code into buffer that was allocated at detection time. */
1351 memcpy ((void *) hostdata
->script
, (void *) SCRIPT
,
1354 for (i
= 0; i
< PATCHES
; ++i
)
1355 hostdata
->script
[LABELPATCHES
[i
]] +=
1356 virt_to_bus(hostdata
->script
);
1357 /* Fixup addresses of constants that used to be EXTERNAL */
1359 patch_abs_32 (hostdata
->script
, 0, NCR53c7xx_msg_abort
,
1360 virt_to_bus(&(hostdata
->NCR53c7xx_msg_abort
)));
1361 patch_abs_32 (hostdata
->script
, 0, NCR53c7xx_msg_reject
,
1362 virt_to_bus(&(hostdata
->NCR53c7xx_msg_reject
)));
1363 patch_abs_32 (hostdata
->script
, 0, NCR53c7xx_zero
,
1364 virt_to_bus(&(hostdata
->NCR53c7xx_zero
)));
1365 patch_abs_32 (hostdata
->script
, 0, NCR53c7xx_sink
,
1366 virt_to_bus(&(hostdata
->NCR53c7xx_sink
)));
1367 patch_abs_32 (hostdata
->script
, 0, NOP_insn
,
1368 virt_to_bus(&(hostdata
->NOP_insn
)));
1369 patch_abs_32 (hostdata
->script
, 0, schedule
,
1370 virt_to_bus((void *) hostdata
->schedule
));
1372 /* Fixup references to external variables: */
1373 for (i
= 0; i
< EXTERNAL_PATCHES_LEN
; ++i
)
1374 hostdata
->script
[EXTERNAL_PATCHES
[i
].offset
] +=
1375 virt_to_bus(EXTERNAL_PATCHES
[i
].address
);
1378 * Fixup absolutes set at boot-time.
1380 * All non-code absolute variables suffixed with "dsa_" and "int_"
1381 * are constants, and need no fixup provided the assembler has done
1382 * it for us (I don't know what the "real" NCR assembler does in
1383 * this case, my assembler does the right magic).
1386 patch_abs_rwri_data (hostdata
->script
, 0, dsa_save_data_pointer
,
1387 Ent_dsa_code_save_data_pointer
- Ent_dsa_zero
);
1388 patch_abs_rwri_data (hostdata
->script
, 0, dsa_restore_pointers
,
1389 Ent_dsa_code_restore_pointers
- Ent_dsa_zero
);
1390 patch_abs_rwri_data (hostdata
->script
, 0, dsa_check_reselect
,
1391 Ent_dsa_code_check_reselect
- Ent_dsa_zero
);
1394 * Just for the hell of it, preserve the settings of
1395 * Burst Length and Enable Read Line bits from the DMODE
1396 * register. Make sure SCRIPTS start automagically.
1399 #if defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000)
1400 /* We know better what we want than 16xBug does! */
1401 tmp
= DMODE_10_BL_8
| DMODE_10_FC2
;
1403 tmp
= NCR53c7x0_read8(DMODE_REG_10
);
1404 tmp
&= (DMODE_BL_MASK
| DMODE_10_FC2
| DMODE_10_FC1
| DMODE_710_PD
|
1408 if (!(hostdata
->options
& OPTION_MEMORY_MAPPED
)) {
1409 base
= (u32
) host
->io_port
;
1410 memory_to_ncr
= tmp
|DMODE_800_DIOM
;
1411 ncr_to_memory
= tmp
|DMODE_800_SIOM
;
1413 base
= virt_to_bus(host
->base
);
1414 memory_to_ncr
= ncr_to_memory
= tmp
;
1417 /* SCRATCHB_REG_10 == SCRATCHA_REG_800, as it happens */
1418 patch_abs_32 (hostdata
->script
, 0, addr_scratch
, base
+ SCRATCHA_REG_800
);
1419 patch_abs_32 (hostdata
->script
, 0, addr_temp
, base
+ TEMP_REG
);
1420 patch_abs_32 (hostdata
->script
, 0, addr_dsa
, base
+ DSA_REG
);
1423 * I needed some variables in the script to be accessible to
1424 * both the NCR chip and the host processor. For these variables,
1425 * I made the arbitrary decision to store them directly in the
1426 * hostdata structure rather than in the RELATIVE area of the
1431 patch_abs_rwri_data (hostdata
->script
, 0, dmode_memory_to_memory
, tmp
);
1432 patch_abs_rwri_data (hostdata
->script
, 0, dmode_memory_to_ncr
, memory_to_ncr
);
1433 patch_abs_rwri_data (hostdata
->script
, 0, dmode_ncr_to_memory
, ncr_to_memory
);
1435 patch_abs_32 (hostdata
->script
, 0, msg_buf
,
1436 virt_to_bus((void *)&(hostdata
->msg_buf
)));
1437 patch_abs_32 (hostdata
->script
, 0, reconnect_dsa_head
,
1438 virt_to_bus((void *)&(hostdata
->reconnect_dsa_head
)));
1439 patch_abs_32 (hostdata
->script
, 0, addr_reconnect_dsa_head
,
1440 virt_to_bus((void *)&(hostdata
->addr_reconnect_dsa_head
)));
1441 patch_abs_32 (hostdata
->script
, 0, reselected_identify
,
1442 virt_to_bus((void *)&(hostdata
->reselected_identify
)));
1443 /* reselected_tag is currently unused */
1445 patch_abs_32 (hostdata
->script
, 0, reselected_tag
,
1446 virt_to_bus((void *)&(hostdata
->reselected_tag
)));
1449 patch_abs_32 (hostdata
->script
, 0, test_dest
,
1450 virt_to_bus((void*)&hostdata
->test_dest
));
1451 patch_abs_32 (hostdata
->script
, 0, test_src
,
1452 virt_to_bus(&hostdata
->test_source
));
1453 patch_abs_32 (hostdata
->script
, 0, saved_dsa
,
1454 virt_to_bus(&hostdata
->saved2_dsa
));
1455 patch_abs_32 (hostdata
->script
, 0, emulfly
,
1456 virt_to_bus(&hostdata
->emulated_intfly
));
1458 patch_abs_rwri_data (hostdata
->script
, 0, dsa_check_reselect
,
1459 (unsigned char)(Ent_dsa_code_check_reselect
- Ent_dsa_zero
));
1461 /* These are for event logging; the ncr_event enum contains the
1462 actual interrupt numbers. */
1463 #ifdef A_int_EVENT_SELECT
1464 patch_abs_32 (hostdata
->script
, 0, int_EVENT_SELECT
, (u32
) EVENT_SELECT
);
1466 #ifdef A_int_EVENT_DISCONNECT
1467 patch_abs_32 (hostdata
->script
, 0, int_EVENT_DISCONNECT
, (u32
) EVENT_DISCONNECT
);
1469 #ifdef A_int_EVENT_RESELECT
1470 patch_abs_32 (hostdata
->script
, 0, int_EVENT_RESELECT
, (u32
) EVENT_RESELECT
);
1472 #ifdef A_int_EVENT_COMPLETE
1473 patch_abs_32 (hostdata
->script
, 0, int_EVENT_COMPLETE
, (u32
) EVENT_COMPLETE
);
1475 #ifdef A_int_EVENT_IDLE
1476 patch_abs_32 (hostdata
->script
, 0, int_EVENT_IDLE
, (u32
) EVENT_IDLE
);
1478 #ifdef A_int_EVENT_SELECT_FAILED
1479 patch_abs_32 (hostdata
->script
, 0, int_EVENT_SELECT_FAILED
,
1480 (u32
) EVENT_SELECT_FAILED
);
1482 #ifdef A_int_EVENT_BEFORE_SELECT
1483 patch_abs_32 (hostdata
->script
, 0, int_EVENT_BEFORE_SELECT
,
1484 (u32
) EVENT_BEFORE_SELECT
);
1486 #ifdef A_int_EVENT_RESELECT_FAILED
1487 patch_abs_32 (hostdata
->script
, 0, int_EVENT_RESELECT_FAILED
,
1488 (u32
) EVENT_RESELECT_FAILED
);
1492 * Make sure the NCR and Linux code agree on the location of
1496 hostdata
->E_accept_message
= Ent_accept_message
;
1497 hostdata
->E_command_complete
= Ent_command_complete
;
1498 hostdata
->E_cmdout_cmdout
= Ent_cmdout_cmdout
;
1499 hostdata
->E_data_transfer
= Ent_data_transfer
;
1500 hostdata
->E_debug_break
= Ent_debug_break
;
1501 hostdata
->E_dsa_code_template
= Ent_dsa_code_template
;
1502 hostdata
->E_dsa_code_template_end
= Ent_dsa_code_template_end
;
1503 hostdata
->E_end_data_transfer
= Ent_end_data_transfer
;
1504 hostdata
->E_initiator_abort
= Ent_initiator_abort
;
1505 hostdata
->E_msg_in
= Ent_msg_in
;
1506 hostdata
->E_other_transfer
= Ent_other_transfer
;
1507 hostdata
->E_other_in
= Ent_other_in
;
1508 hostdata
->E_other_out
= Ent_other_out
;
1509 hostdata
->E_reject_message
= Ent_reject_message
;
1510 hostdata
->E_respond_message
= Ent_respond_message
;
1511 hostdata
->E_select
= Ent_select
;
1512 hostdata
->E_select_msgout
= Ent_select_msgout
;
1513 hostdata
->E_target_abort
= Ent_target_abort
;
1515 hostdata
->E_test_0
= Ent_test_0
;
1517 hostdata
->E_test_1
= Ent_test_1
;
1518 hostdata
->E_test_2
= Ent_test_2
;
1520 hostdata
->E_test_3
= Ent_test_3
;
1522 hostdata
->E_wait_reselect
= Ent_wait_reselect
;
1523 hostdata
->E_dsa_code_begin
= Ent_dsa_code_begin
;
1525 hostdata
->dsa_cmdout
= A_dsa_cmdout
;
1526 hostdata
->dsa_cmnd
= A_dsa_cmnd
;
1527 hostdata
->dsa_datain
= A_dsa_datain
;
1528 hostdata
->dsa_dataout
= A_dsa_dataout
;
1529 hostdata
->dsa_end
= A_dsa_end
;
1530 hostdata
->dsa_msgin
= A_dsa_msgin
;
1531 hostdata
->dsa_msgout
= A_dsa_msgout
;
1532 hostdata
->dsa_msgout_other
= A_dsa_msgout_other
;
1533 hostdata
->dsa_next
= A_dsa_next
;
1534 hostdata
->dsa_select
= A_dsa_select
;
1535 hostdata
->dsa_start
= Ent_dsa_code_template
- Ent_dsa_zero
;
1536 hostdata
->dsa_status
= A_dsa_status
;
1537 hostdata
->dsa_jump_dest
= Ent_dsa_code_fix_jump
- Ent_dsa_zero
+
1538 8 /* destination operand */;
1541 if (A_dsa_fields_start
!= Ent_dsa_code_template_end
-
1543 printk("scsi%d : NCR dsa_fields start is %d not %d\n",
1544 host
->host_no
, A_dsa_fields_start
, Ent_dsa_code_template_end
-
1547 printk("scsi%d : NCR code relocated to 0x%lx (virt 0x%p)\n", host
->host_no
,
1548 virt_to_bus(hostdata
->script
), hostdata
->script
);
1552 * Function : static int NCR53c7xx_run_tests (struct Scsi_Host *host)
1554 * Purpose : run various verification tests on the NCR chip,
1555 * including interrupt generation, and proper bus mastering
1558 * Inputs : host - a properly initialized Scsi_Host structure
1560 * Preconditions : the NCR chip must be in a halted state.
1562 * Returns : 0 if all tests were successful, -1 on error.
1567 NCR53c7xx_run_tests (struct Scsi_Host
*host
) {
1568 NCR53c7x0_local_declare();
1569 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
1571 unsigned long timeout
;
1574 unsigned long flags
;
1575 NCR53c7x0_local_setup(host
);
1577 /* The NCR chip _must_ be idle to run the test scripts */
1581 if (!hostdata
->idle
) {
1582 printk ("scsi%d : chip not idle, aborting tests\n", host
->host_no
);
1583 restore_flags(flags
);
1588 * Check for functional interrupts, this could work as an
1589 * autoprobe routine.
1592 if ((hostdata
->options
& OPTION_DEBUG_TEST1
) &&
1593 hostdata
->state
!= STATE_DISABLED
) {
1595 hostdata
->test_running
= 1;
1596 hostdata
->test_completed
= -1;
1597 hostdata
->test_dest
= 0;
1598 hostdata
->test_source
= 0xdeadbeef;
1599 start
= virt_to_bus (hostdata
->script
) + hostdata
->E_test_1
;
1600 hostdata
->state
= STATE_RUNNING
;
1601 printk ("scsi%d : test 1", host
->host_no
);
1602 NCR53c7x0_write32 (DSP_REG
, start
);
1603 if (hostdata
->options
& OPTION_DEBUG_TRACE
)
1604 NCR53c7x0_write8 (DCNTL_REG
, hostdata
->saved_dcntl
| DCNTL_SSM
|
1606 printk (" started\n");
1607 restore_flags(flags
);
1610 * This is currently a .5 second timeout, since (in theory) no slow
1611 * board will take that long. In practice, we've seen one
1612 * pentium which occassionally fails with this, but works with
1616 timeout
= jiffies
+ 5 * HZ
/ 10;
1617 while ((hostdata
->test_completed
== -1) && jiffies
< timeout
)
1621 if (hostdata
->test_completed
== -1)
1622 printk ("scsi%d : driver test 1 timed out%s\n",host
->host_no
,
1623 (hostdata
->test_dest
== 0xdeadbeef) ?
1624 " due to lost interrupt.\n"
1625 " Please verify that the correct IRQ is being used for your board,\n"
1627 else if (hostdata
->test_completed
!= 1)
1628 printk ("scsi%d : test 1 bad interrupt value (%d)\n",
1629 host
->host_no
, hostdata
->test_completed
);
1631 failed
= (hostdata
->test_dest
!= 0xdeadbeef);
1633 if (hostdata
->test_dest
!= 0xdeadbeef) {
1634 printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n"
1635 " probable cache invalidation problem. Please configure caching\n"
1636 " as write-through or disabled\n",
1637 host
->host_no
, hostdata
->test_dest
);
1641 printk ("scsi%d : DSP = 0x%p (script at 0x%p, start at 0x%x)\n",
1642 host
->host_no
, bus_to_virt(NCR53c7x0_read32(DSP_REG
)),
1643 hostdata
->script
, start
);
1644 printk ("scsi%d : DSPS = 0x%x\n", host
->host_no
,
1645 NCR53c7x0_read32(DSPS_REG
));
1646 restore_flags(flags
);
1649 hostdata
->test_running
= 0;
1652 if ((hostdata
->options
& OPTION_DEBUG_TEST2
) &&
1653 hostdata
->state
!= STATE_DISABLED
) {
1655 unsigned char identify
= IDENTIFY(0, 0);
1656 unsigned char cmd
[6];
1657 unsigned char data
[36];
1658 unsigned char status
= 0xff;
1659 unsigned char msg
= 0xff;
1662 cmd
[1] = cmd
[2] = cmd
[3] = cmd
[5] = 0;
1663 cmd
[4] = sizeof(data
);
1666 dsa
[3] = virt_to_bus(&identify
);
1668 dsa
[5] = virt_to_bus(&cmd
);
1669 dsa
[6] = sizeof(data
);
1670 dsa
[7] = virt_to_bus(&data
);
1672 dsa
[9] = virt_to_bus(&status
);
1674 dsa
[11] = virt_to_bus(&msg
);
1676 for (i
= 0; i
< 6; ++i
) {
1678 if (!hostdata
->valid_ids
[i
])
1682 if (!hostdata
->idle
) {
1683 printk ("scsi%d : chip not idle, aborting tests\n", host
->host_no
);
1684 restore_flags(flags
);
1688 /* 710: bit mapped scsi ID, async */
1689 dsa
[0] = (1 << i
) << 16;
1691 hostdata
->test_running
= 2;
1692 hostdata
->test_completed
= -1;
1693 start
= virt_to_bus(hostdata
->script
) + hostdata
->E_test_2
;
1694 hostdata
->state
= STATE_RUNNING
;
1695 NCR53c7x0_write32 (DSA_REG
, virt_to_bus(dsa
));
1696 NCR53c7x0_write32 (DSP_REG
, start
);
1697 if (hostdata
->options
& OPTION_DEBUG_TRACE
)
1698 NCR53c7x0_write8 (DCNTL_REG
, hostdata
->saved_dcntl
|
1699 DCNTL_SSM
| DCNTL_STD
);
1700 restore_flags(flags
);
1702 timeout
= jiffies
+ 5 * HZ
; /* arbitrary */
1703 while ((hostdata
->test_completed
== -1) && jiffies
< timeout
)
1706 NCR53c7x0_write32 (DSA_REG
, 0);
1708 if (hostdata
->test_completed
== 2) {
1710 printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n",
1711 host
->host_no
, i
, data
+ 8);
1712 printk ("scsi%d : status ", host
->host_no
);
1713 print_status (status
);
1714 printk ("\nscsi%d : message ", host
->host_no
);
1717 } else if (hostdata
->test_completed
== 3) {
1718 printk("scsi%d : test 2 no connection with target %d\n",
1720 if (!hostdata
->idle
) {
1721 printk("scsi%d : not idle\n", host
->host_no
);
1722 restore_flags(flags
);
1725 } else if (hostdata
->test_completed
== -1) {
1726 printk ("scsi%d : test 2 timed out\n", host
->host_no
);
1727 restore_flags(flags
);
1730 hostdata
->test_running
= 0;
1734 restore_flags(flags
);
1739 * Function : static void NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd)
1741 * Purpose : copy the NCR53c8xx dsa structure into cmd's dsa buffer,
1742 * performing all necessary relocation.
1744 * Inputs : cmd, a NCR53c7x0_cmd structure with a dsa area large
1745 * enough to hold the NCR53c8xx dsa.
1749 NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd
*cmd
) {
1750 Scsi_Cmnd
*c
= cmd
->cmd
;
1751 struct Scsi_Host
*host
= c
->host
;
1752 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
1756 memcpy (cmd
->dsa
, hostdata
->script
+ (hostdata
->E_dsa_code_template
/ 4),
1757 hostdata
->E_dsa_code_template_end
- hostdata
->E_dsa_code_template
);
1760 * Note : within the NCR 'C' code, dsa points to the _start_
1761 * of the DSA structure, and _not_ the offset of dsa_zero within
1762 * that structure used to facilitate shorter signed offsets
1763 * for the 8 bit ALU.
1765 * The implications of this are that
1767 * - 32 bit A_dsa_* absolute values require an additional
1768 * dsa_zero added to their value to be correct, since they are
1769 * relative to dsa_zero which is in essentially a separate
1770 * space from the code symbols.
1772 * - All other symbols require no special treatment.
1775 patch_abs_tci_data (cmd
->dsa
, Ent_dsa_code_template
/ sizeof(u32
),
1776 dsa_temp_lun
, c
->lun
);
1777 patch_abs_32 (cmd
->dsa
, Ent_dsa_code_template
/ sizeof(u32
),
1778 dsa_temp_addr_next
, virt_to_bus(&cmd
->dsa_next_addr
));
1779 patch_abs_32 (cmd
->dsa
, Ent_dsa_code_template
/ sizeof(u32
),
1780 dsa_temp_next
, virt_to_bus(cmd
->dsa
) + Ent_dsa_zero
-
1781 Ent_dsa_code_template
+ A_dsa_next
);
1782 patch_abs_32 (cmd
->dsa
, Ent_dsa_code_template
/ sizeof(u32
),
1783 dsa_temp_sync
, virt_to_bus((void *)hostdata
->sync
[c
->target
].script
));
1784 patch_abs_32 (cmd
->dsa
, Ent_dsa_code_template
/ sizeof(u32
),
1785 dsa_sscf_710
, virt_to_bus((void *)&hostdata
->sync
[c
->target
].sscf_710
));
1786 patch_abs_tci_data (cmd
->dsa
, Ent_dsa_code_template
/ sizeof(u32
),
1787 dsa_temp_target
, 1 << c
->target
);
1788 /* XXX - new pointer stuff */
1789 patch_abs_32 (cmd
->dsa
, Ent_dsa_code_template
/ sizeof(u32
),
1790 dsa_temp_addr_saved_pointer
, virt_to_bus(&cmd
->saved_data_pointer
));
1791 patch_abs_32 (cmd
->dsa
, Ent_dsa_code_template
/ sizeof(u32
),
1792 dsa_temp_addr_saved_residual
, virt_to_bus(&cmd
->saved_residual
));
1793 patch_abs_32 (cmd
->dsa
, Ent_dsa_code_template
/ sizeof(u32
),
1794 dsa_temp_addr_residual
, virt_to_bus(&cmd
->residual
));
1796 /* XXX - new start stuff */
1798 patch_abs_32 (cmd
->dsa
, Ent_dsa_code_template
/ sizeof(u32
),
1799 dsa_temp_addr_dsa_value
, virt_to_bus(&cmd
->dsa_addr
));
1803 * Function : run_process_issue_queue (void)
1805 * Purpose : insure that the coroutine is running and will process our
1806 * request. process_issue_queue_running is checked/set here (in an
1807 * inline function) rather than in process_issue_queue itself to reduce
1808 * the chances of stack overflow.
1812 static volatile int process_issue_queue_running
= 0;
1814 static __inline__
void
1815 run_process_issue_queue(void) {
1816 unsigned long flags
;
1819 if (!process_issue_queue_running
) {
1820 process_issue_queue_running
= 1;
1821 process_issue_queue(flags
);
1823 * process_issue_queue_running is cleared in process_issue_queue
1824 * once it can't do more work, and process_issue_queue exits with
1825 * interrupts disabled.
1828 restore_flags (flags
);
1832 * Function : static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int
1835 * Purpose : mark SCSI command as finished, OR'ing the host portion
1836 * of the result word into the result field of the corresponding
1837 * Scsi_Cmnd structure, and removing it from the internal queues.
1839 * Inputs : cmd - command, result - entire result field
1841 * Preconditions : the NCR chip should be in a halted state when
1842 * abnormal_finished is run, since it modifies structures which
1843 * the NCR expects to have exclusive access to.
1847 abnormal_finished (struct NCR53c7x0_cmd
*cmd
, int result
) {
1848 Scsi_Cmnd
*c
= cmd
->cmd
;
1849 struct Scsi_Host
*host
= c
->host
;
1850 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
1852 unsigned long flags
;
1854 volatile struct NCR53c7x0_cmd
* linux_search
;
1855 volatile struct NCR53c7x0_cmd
* volatile *linux_prev
;
1856 volatile u32
*ncr_prev
, *ncrcurrent
, ncr_search
;
1859 printk ("scsi%d: abnormal finished\n", host
->host_no
);
1866 * Traverse the NCR issue array until we find a match or run out
1867 * of instructions. Instructions in the NCR issue array are
1868 * either JUMP or NOP instructions, which are 2 words in length.
1872 for (found
= 0, left
= host
->can_queue
, ncrcurrent
= hostdata
->schedule
;
1873 left
> 0; --left
, ncrcurrent
+= 2)
1875 if (issue_to_cmd (host
, hostdata
, (u32
*) ncrcurrent
) == cmd
)
1877 ncrcurrent
[0] = hostdata
->NOP_insn
;
1878 ncrcurrent
[1] = 0xdeadbeef;
1885 * Traverse the NCR reconnect list of DSA structures until we find
1886 * a pointer to this dsa or have found too many command structures.
1887 * We let prev point at the next field of the previous element or
1888 * head of the list, so we don't do anything different for removing
1892 for (left
= host
->can_queue
,
1893 ncr_search
= hostdata
->reconnect_dsa_head
,
1894 ncr_prev
= &hostdata
->reconnect_dsa_head
;
1895 left
>= 0 && ncr_search
&&
1896 ((char*)bus_to_virt(ncr_search
) + hostdata
->dsa_start
)
1897 != (char *) cmd
->dsa
;
1898 ncr_prev
= (u32
*) ((char*)bus_to_virt(ncr_search
) +
1899 hostdata
->dsa_next
), ncr_search
= *ncr_prev
, --left
);
1902 printk("scsi%d: loop detected in ncr reconncect list\n",
1904 else if (ncr_search
) {
1906 printk("scsi%d: scsi %ld in ncr issue array and reconnect lists\n",
1907 host
->host_no
, c
->pid
);
1909 volatile u32
* next
= (u32
*)
1910 ((char *)bus_to_virt(ncr_search
) + hostdata
->dsa_next
);
1912 /* If we're at the tail end of the issue queue, update that pointer too. */
1918 * Traverse the host running list until we find this command or discover
1919 * we have too many elements, pointing linux_prev at the next field of the
1920 * linux_previous element or head of the list, search at this element.
1923 for (left
= host
->can_queue
, linux_search
= hostdata
->running_list
,
1924 linux_prev
= &hostdata
->running_list
;
1925 left
>= 0 && linux_search
&& linux_search
!= cmd
;
1926 linux_prev
= &(linux_search
->next
),
1927 linux_search
= linux_search
->next
, --left
);
1930 printk ("scsi%d: loop detected in host running list for scsi pid %ld\n",
1931 host
->host_no
, c
->pid
);
1932 else if (linux_search
) {
1933 *linux_prev
= linux_search
->next
;
1934 --hostdata
->busy
[c
->target
][c
->lun
];
1937 /* Return the NCR command structure to the free list */
1938 cmd
->next
= hostdata
->free
;
1939 hostdata
->free
= cmd
;
1940 c
->host_scribble
= NULL
;
1946 restore_flags(flags
);
1947 run_process_issue_queue();
1951 * Function : static void intr_break (struct Scsi_Host *host,
1952 * struct NCR53c7x0_cmd *cmd)
1954 * Purpose : Handler for breakpoint interrupts from a SCSI script
1956 * Inputs : host - pointer to this host adapter's structure,
1957 * cmd - pointer to the command (if any) dsa was pointing
1963 intr_break (struct Scsi_Host
*host
, struct
1964 NCR53c7x0_cmd
*cmd
) {
1965 NCR53c7x0_local_declare();
1966 struct NCR53c7x0_break
*bp
;
1968 Scsi_Cmnd
*c
= cmd
? cmd
->cmd
: NULL
;
1971 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
1973 unsigned long flags
;
1974 NCR53c7x0_local_setup(host
);
1977 * Find the break point corresponding to this address, and
1978 * dump the appropriate debugging information to standard
1983 dsp
= (u32
*) bus_to_virt(NCR53c7x0_read32(DSP_REG
));
1984 for (bp
= hostdata
->breakpoints
; bp
&& bp
->address
!= dsp
;
1987 panic("scsi%d : break point interrupt from %p with no breakpoint!",
1988 host
->host_no
, dsp
);
1991 * Configure the NCR chip for manual start mode, so that we can
1992 * point the DSP register at the instruction that follows the
1993 * INT int_debug_break instruction.
1996 NCR53c7x0_write8 (hostdata
->dmode
,
1997 NCR53c7x0_read8(hostdata
->dmode
)|DMODE_MAN
);
2000 * And update the DSP register, using the size of the old
2001 * instruction in bytes.
2004 restore_flags(flags
);
2007 * Function : static void print_synchronous (const char *prefix,
2008 * const unsigned char *msg)
2010 * Purpose : print a pretty, user and machine parsable representation
2011 * of a SDTR message, including the "real" parameters, data
2012 * clock so we can tell transfer rate at a glance.
2014 * Inputs ; prefix - text to prepend, msg - SDTR message (5 bytes)
2018 print_synchronous (const char *prefix
, const unsigned char *msg
) {
2020 int Hz
= 1000000000 / (msg
[3] * 4);
2021 int integer
= Hz
/ 1000000;
2022 int fraction
= (Hz
- (integer
* 1000000)) / 10000;
2023 printk ("%speriod %dns offset %d %d.%02dMHz %s SCSI%s\n",
2024 prefix
, (int) msg
[3] * 4, (int) msg
[4], integer
, fraction
,
2025 (((msg
[3] * 4) < 200) ? "FAST" : "synchronous"),
2026 (((msg
[3] * 4) < 200) ? "-II" : ""));
2028 printk ("%sasynchronous SCSI\n", prefix
);
2032 * Function : static void set_synchronous (struct Scsi_Host *host,
2033 * int target, int sxfer, int scntl3, int now_connected)
2035 * Purpose : reprogram transfers between the selected SCSI initiator and
2036 * target with the given register values; in the indirect
2037 * select operand, reselection script, and chip registers.
2039 * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id,
2040 * sxfer and scntl3 - NCR registers. now_connected - if non-zero,
2041 * we should reprogram the registers now too.
2043 * NOTE: For 53c710, scntl3 is actually used for SCF bits from
2044 * SBCL, as we don't have a SCNTL3.
2048 set_synchronous (struct Scsi_Host
*host
, int target
, int sxfer
, int scntl3
,
2049 int now_connected
) {
2050 NCR53c7x0_local_declare();
2051 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
2054 NCR53c7x0_local_setup(host
);
2056 /* These are eight bit registers */
2060 hostdata
->sync
[target
].sxfer_sanity
= sxfer
;
2061 hostdata
->sync
[target
].scntl3_sanity
= scntl3
;
2064 * HARD CODED : synchronous script is EIGHT words long. This
2065 * must agree with 53c7.8xx.h
2068 if ((hostdata
->chip
!= 700) && (hostdata
->chip
!= 70066)) {
2069 hostdata
->sync
[target
].select_indirect
= (1 << target
) << 16 |
2071 hostdata
->sync
[target
].sscf_710
= scntl3
;
2073 script
= (u32
*) hostdata
->sync
[target
].script
;
2075 /* XXX - add NCR53c7x0 code to reprogram SCF bits if we want to */
2076 script
[0] = ((DCMD_TYPE_RWRI
| DCMD_RWRI_OPC_MODIFY
|
2077 DCMD_RWRI_OP_MOVE
) << 24) |
2078 (SBCL_REG
<< 16) | (scntl3
<< 8);
2082 script
[0] = ((DCMD_TYPE_RWRI
| DCMD_RWRI_OPC_MODIFY
|
2083 DCMD_RWRI_OP_MOVE
) << 24) |
2084 (SXFER_REG
<< 16) | (sxfer
<< 8);
2088 #ifdef DEBUG_SYNC_INTR
2089 if (hostdata
->options
& OPTION_DEBUG_DISCONNECT
) {
2090 script
[0] = ((DCMD_TYPE_TCI
|DCMD_TCI_OP_INT
) << 24) | DBC_TCI_TRUE
;
2091 script
[1] = DEBUG_SYNC_INTR
;
2096 script
[0] = ((DCMD_TYPE_TCI
|DCMD_TCI_OP_RETURN
) << 24) | DBC_TCI_TRUE
;
2101 if (hostdata
->options
& OPTION_DEBUG_SYNCHRONOUS
)
2102 printk ("scsi%d : target %d sync parameters are sxfer=0x%x, scntl3=0x%x\n",
2103 host
->host_no
, target
, sxfer
, scntl3
);
2105 if (now_connected
) {
2106 NCR53c7x0_write8(SBCL_REG
, scntl3
);
2107 NCR53c7x0_write8(SXFER_REG
, sxfer
);
2113 * Function : static int asynchronous (struct Scsi_Host *host, int target)
2115 * Purpose : reprogram between the selected SCSI Host adapter and target
2116 * (assumed to be currently connected) for asynchronous transfers.
2118 * Inputs : host - SCSI host structure, target - numeric target ID.
2120 * Preconditions : the NCR chip should be in one of the halted states
2124 asynchronous (struct Scsi_Host
*host
, int target
) {
2125 NCR53c7x0_local_declare();
2126 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
2128 NCR53c7x0_local_setup(host
);
2129 set_synchronous (host
, target
, /* no offset */ 0, hostdata
->saved_scntl3
,
2131 printk ("scsi%d : setting target %d to asynchronous SCSI\n",
2132 host
->host_no
, target
);
2136 * XXX - do we want to go out of our way (ie, add extra code to selection
2137 * in the NCR53c710/NCR53c720 script) to reprogram the synchronous
2138 * conversion bits, or can we be content in just setting the
2139 * sxfer bits? I chose to do so [richard@sleepie.demon.co.uk]
2142 /* Table for NCR53c8xx synchronous values */
2144 /* This table is also correct for 710, allowing that scf=4 is equivalent
2145 * of SSCF=0 (ie use DCNTL, divide by 3) for a 50.01-66.00MHz clock.
2146 * For any other clock values, we cannot use entries with SCF values of
2147 * 4. I guess that for a 66MHz clock, the slowest it will set is 2MHz,
2148 * and for a 50MHz clock, the slowest will be 2.27Mhz. Should check
2149 * that a device doesn't try and negotiate sync below these limits!
2152 static const struct {
2153 int div
; /* Total clock divisor * 10 */
2154 unsigned char scf
; /* */
2155 unsigned char tp
; /* 4 + tp = xferp divisor */
2157 /* div scf tp div scf tp div scf tp */
2158 { 40, 1, 0}, { 50, 1, 1}, { 60, 1, 2},
2159 { 70, 1, 3}, { 75, 2, 1}, { 80, 1, 4},
2160 { 90, 1, 5}, { 100, 1, 6}, { 105, 2, 3},
2161 { 110, 1, 7}, { 120, 2, 4}, { 135, 2, 5},
2162 { 140, 3, 3}, { 150, 2, 6}, { 160, 3, 4},
2163 { 165, 2, 7}, { 180, 3, 5}, { 200, 3, 6},
2164 { 210, 4, 3}, { 220, 3, 7}, { 240, 4, 4},
2165 { 270, 4, 5}, { 300, 4, 6}, { 330, 4, 7}
2169 * Function : static void synchronous (struct Scsi_Host *host, int target,
2172 * Purpose : reprogram transfers between the selected SCSI initiator and
2173 * target for synchronous SCSI transfers such that the synchronous
2174 * offset is less than that requested and period at least as long
2175 * as that requested. Also modify *msg such that it contains
2176 * an appropriate response.
2178 * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id,
2179 * msg - synchronous transfer request.
2184 synchronous (struct Scsi_Host
*host
, int target
, char *msg
) {
2185 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
2187 int desire
, divisor
, i
, limit
;
2188 unsigned char scntl3
, sxfer
;
2189 /* The diagnostic message fits on one line, even with max. width integers */
2192 /* Desired transfer clock in Hz */
2193 desire
= 1000000000L / (msg
[3] * 4);
2194 /* Scale the available SCSI clock by 10 so we get tenths */
2195 divisor
= (hostdata
->scsi_clock
* 10) / desire
;
2197 /* NCR chips can handle at most an offset of 8 */
2201 if (hostdata
->options
& OPTION_DEBUG_SDTR
)
2202 printk("scsi%d : optimal synchronous divisor of %d.%01d\n",
2203 host
->host_no
, divisor
/ 10, divisor
% 10);
2205 limit
= (sizeof(syncs
) / sizeof(syncs
[0]) -1);
2206 for (i
= 0; (i
< limit
) && (divisor
> syncs
[i
].div
); ++i
);
2208 if (hostdata
->options
& OPTION_DEBUG_SDTR
)
2209 printk("scsi%d : selected synchronous divisor of %d.%01d\n",
2210 host
->host_no
, syncs
[i
].div
/ 10, syncs
[i
].div
% 10);
2212 msg
[3] = ((1000000000L / hostdata
->scsi_clock
) * syncs
[i
].div
/ 10 / 4);
2214 if (hostdata
->options
& OPTION_DEBUG_SDTR
)
2215 printk("scsi%d : selected synchronous period of %dns\n", host
->host_no
,
2218 scntl3
= syncs
[i
].scf
;
2219 sxfer
= (msg
[4] << SXFER_MO_SHIFT
) | (syncs
[i
].tp
<< 4);
2220 if (hostdata
->options
& OPTION_DEBUG_SDTR
)
2221 printk ("scsi%d : sxfer=0x%x scntl3=0x%x\n",
2222 host
->host_no
, (int) sxfer
, (int) scntl3
);
2223 set_synchronous (host
, target
, sxfer
, scntl3
, 1);
2224 sprintf (buf
, "scsi%d : setting target %d to ", host
->host_no
, target
);
2225 print_synchronous (buf
, msg
);
2229 * Function : static int NCR53c7x0_dstat_sir_intr (struct Scsi_Host *host,
2230 * struct NCR53c7x0_cmd *cmd)
2232 * Purpose : Handler for INT generated instructions for the
2233 * NCR53c810/820 SCSI SCRIPT
2235 * Inputs : host - pointer to this host adapter's structure,
2236 * cmd - pointer to the command (if any) dsa was pointing
2242 NCR53c7x0_dstat_sir_intr (struct Scsi_Host
*host
, struct
2243 NCR53c7x0_cmd
*cmd
) {
2244 NCR53c7x0_local_declare();
2246 Scsi_Cmnd
*c
= cmd
? cmd
->cmd
: NULL
;
2247 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
2249 u32 dsps
,*dsp
; /* Argument of the INT instruction */
2251 NCR53c7x0_local_setup(host
);
2252 dsps
= NCR53c7x0_read32(DSPS_REG
);
2253 dsp
= (u32
*) bus_to_virt(NCR53c7x0_read32(DSP_REG
));
2255 /* RGH 150597: Frig. Commands which fail with Check Condition are
2256 * Flagged as successful - hack dsps to indicate check condition */
2258 /* RGH 200597: Need to disable for BVME6000, as it gets Check Conditions
2259 * and then dies. Seems to handle Check Condition at startup, but
2260 * not mid kernel build. */
2261 if (dsps
== A_int_norm_emulateintfly
&& cmd
&& cmd
->result
== 2)
2262 dsps
= A_int_err_check_condition
;
2265 if (hostdata
->options
& OPTION_DEBUG_INTR
)
2266 printk ("scsi%d : DSPS = 0x%x\n", host
->host_no
, dsps
);
2271 switch (hostdata
->msg_buf
[0]) {
2273 * Unless we've initiated synchronous negotiation, I don't
2274 * think that this should happen.
2276 case MESSAGE_REJECT
:
2277 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_accept_message
/
2279 hostdata
->dsp_changed
= 1;
2280 if (cmd
&& (cmd
->flags
& CMD_FLAG_SDTR
)) {
2281 printk ("scsi%d : target %d rejected SDTR\n", host
->host_no
,
2283 cmd
->flags
&= ~CMD_FLAG_SDTR
;
2284 asynchronous (host
, c
->target
);
2288 case INITIATE_RECOVERY
:
2289 printk ("scsi%d : extended contingent allegiance not supported yet, rejecting\n",
2291 /* Fall through to default */
2292 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_reject_message
/
2294 hostdata
->dsp_changed
= 1;
2297 printk ("scsi%d : unsupported message, rejecting\n",
2299 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_reject_message
/
2301 hostdata
->dsp_changed
= 1;
2304 printk ("scsi%d : received message", host
->host_no
);
2306 printk (" from target %d lun %d ", c
->target
, c
->lun
);
2307 print_msg ((unsigned char *) hostdata
->msg_buf
);
2311 return SPECIFIC_INT_NOTHING
;
2314 case A_int_msg_sdtr
:
2316 * At this point, hostdata->msg_buf contains
2317 * 0 EXTENDED MESSAGE
2326 sprintf (buf
, "scsi%d : target %d %s ", host
->host_no
, c
->target
,
2327 (cmd
->flags
& CMD_FLAG_SDTR
) ? "accepting" : "requesting");
2328 print_synchronous (buf
, (unsigned char *) hostdata
->msg_buf
);
2331 * Initiator initiated, won't happen unless synchronous
2332 * transfers are enabled. If we get a SDTR message in
2333 * response to our SDTR, we should program our parameters
2335 * offset <= requested offset
2336 * period >= requested period
2338 if (cmd
->flags
& CMD_FLAG_SDTR
) {
2339 cmd
->flags
&= ~CMD_FLAG_SDTR
;
2340 if (hostdata
->msg_buf
[4])
2341 synchronous (host
, c
->target
, (unsigned char *)
2344 asynchronous (host
, c
->target
);
2345 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_accept_message
/
2347 hostdata
->dsp_changed
= 1;
2348 return SPECIFIC_INT_NOTHING
;
2350 if (hostdata
->options
& OPTION_SYNCHRONOUS
) {
2351 cmd
->flags
|= CMD_FLAG_DID_SDTR
;
2352 synchronous (host
, c
->target
, (unsigned char *)
2355 hostdata
->msg_buf
[4] = 0; /* 0 offset = async */
2356 asynchronous (host
, c
->target
);
2358 patch_dsa_32 (cmd
->dsa
, dsa_msgout_other
, 0, 5);
2359 patch_dsa_32 (cmd
->dsa
, dsa_msgout_other
, 1, (u32
)
2360 virt_to_bus ((void *)&hostdata
->msg_buf
));
2361 hostdata
->dsp
= hostdata
->script
+
2362 hostdata
->E_respond_message
/ sizeof(u32
);
2363 hostdata
->dsp_changed
= 1;
2365 return SPECIFIC_INT_NOTHING
;
2367 /* Fall through to abort if we couldn't find a cmd, and
2368 therefore a dsa structure to twiddle */
2369 case A_int_msg_wdtr
:
2370 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_reject_message
/
2372 hostdata
->dsp_changed
= 1;
2373 return SPECIFIC_INT_NOTHING
;
2374 case A_int_err_unexpected_phase
:
2375 if (hostdata
->options
& OPTION_DEBUG_INTR
)
2376 printk ("scsi%d : unexpected phase\n", host
->host_no
);
2377 return SPECIFIC_INT_ABORT
;
2378 case A_int_err_selected
:
2379 if ((hostdata
->chip
/ 100) == 8)
2380 printk ("scsi%d : selected by target %d\n", host
->host_no
,
2381 (int) NCR53c7x0_read8(SDID_REG_800
) &7);
2383 printk ("scsi%d : selected by target LCRC=0x%02x\n", host
->host_no
,
2384 (int) NCR53c7x0_read8(LCRC_REG_10
));
2385 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_target_abort
/
2387 hostdata
->dsp_changed
= 1;
2388 return SPECIFIC_INT_NOTHING
;
2389 case A_int_err_unexpected_reselect
:
2390 if ((hostdata
->chip
/ 100) == 8)
2391 printk ("scsi%d : unexpected reselect by target %d lun %d\n",
2392 host
->host_no
, (int) NCR53c7x0_read8(SDID_REG_800
) & 7,
2393 hostdata
->reselected_identify
& 7);
2395 printk ("scsi%d : unexpected reselect LCRC=0x%02x\n", host
->host_no
,
2396 (int) NCR53c7x0_read8(LCRC_REG_10
));
2397 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_initiator_abort
/
2399 hostdata
->dsp_changed
= 1;
2400 return SPECIFIC_INT_NOTHING
;
2402 * Since contingent allegiance conditions are cleared by the next
2403 * command issued to a target, we must issue a REQUEST SENSE
2404 * command after receiving a CHECK CONDITION status, before
2405 * another command is issued.
2407 * Since this NCR53c7x0_cmd will be freed after use, we don't
2408 * care if we step on the various fields, so modify a few things.
2410 case A_int_err_check_condition
:
2412 if (hostdata
->options
& OPTION_DEBUG_INTR
)
2414 printk ("scsi%d : CHECK CONDITION\n", host
->host_no
);
2416 printk("scsi%d : CHECK CONDITION with no SCSI command\n",
2418 return SPECIFIC_INT_PANIC
;
2422 * FIXME : this uses the normal one-byte selection message.
2423 * We may want to renegotiate for synchronous & WIDE transfers
2424 * since these could be the crux of our problem.
2426 hostdata->NOP_insn* FIXME : once SCSI-II tagged queuing is implemented, we'll
2427 * have to set this up so that the rest of the DSA
2428 * agrees with this being an untagged queue'd command.
2431 patch_dsa_32 (cmd
->dsa
, dsa_msgout
, 0, 1);
2434 * Modify the table indirect for COMMAND OUT phase, since
2435 * Request Sense is a six byte command.
2438 patch_dsa_32 (cmd
->dsa
, dsa_cmdout
, 0, 6);
2441 * The CDB is now mirrored in our local non-cached
2442 * structure, but keep the old structure up to date as well,
2443 * just in case anyone looks at it.
2447 * XXX Need to worry about data buffer alignment/cache state
2448 * XXX here, but currently never get A_int_err_check_condition,
2449 * XXX so ignore problem for now.
2451 cmd
->cmnd
[0] = c
->cmnd
[0] = REQUEST_SENSE
;
2452 cmd
->cmnd
[0] = c
->cmnd
[1] &= 0xe0; /* Zero all but LUN */
2453 cmd
->cmnd
[0] = c
->cmnd
[2] = 0;
2454 cmd
->cmnd
[0] = c
->cmnd
[3] = 0;
2455 cmd
->cmnd
[0] = c
->cmnd
[4] = sizeof(c
->sense_buffer
);
2456 cmd
->cmnd
[0] = c
->cmnd
[5] = 0;
2459 * Disable dataout phase, and program datain to transfer to the
2460 * sense buffer, and add a jump to other_transfer after the
2461 * command so overflow/underrun conditions are detected.
2464 patch_dsa_32 (cmd
->dsa
, dsa_dataout
, 0,
2465 virt_to_bus(hostdata
->script
) + hostdata
->E_other_transfer
);
2466 patch_dsa_32 (cmd
->dsa
, dsa_datain
, 0,
2467 virt_to_bus(cmd
->data_transfer_start
));
2468 cmd
->data_transfer_start
[0] = (((DCMD_TYPE_BMI
| DCMD_BMI_OP_MOVE_I
|
2469 DCMD_BMI_IO
)) << 24) | sizeof(c
->sense_buffer
);
2470 cmd
->data_transfer_start
[1] = (u32
) virt_to_bus(c
->sense_buffer
);
2472 cmd
->data_transfer_start
[2] = ((DCMD_TYPE_TCI
| DCMD_TCI_OP_JUMP
)
2473 << 24) | DBC_TCI_TRUE
;
2474 cmd
->data_transfer_start
[3] = (u32
) virt_to_bus(hostdata
->script
) +
2475 hostdata
->E_other_transfer
;
2478 * Currently, this command is flagged as completed, ie
2479 * it has valid status and message data. Reflag it as
2480 * incomplete. Q - need to do something so that original
2481 * status, etc are used.
2484 cmd
->result
= cmd
->cmd
->result
= 0xffff;
2487 * Restart command as a REQUEST SENSE.
2489 hostdata
->dsp
= (u32
*) hostdata
->script
+ hostdata
->E_select
/
2491 hostdata
->dsp_changed
= 1;
2492 return SPECIFIC_INT_NOTHING
;
2493 case A_int_debug_break
:
2494 return SPECIFIC_INT_BREAK
;
2495 case A_int_norm_aborted
:
2496 hostdata
->dsp
= (u32
*) hostdata
->schedule
;
2497 hostdata
->dsp_changed
= 1;
2499 abnormal_finished (cmd
, DID_ERROR
<< 16);
2500 return SPECIFIC_INT_NOTHING
;
2501 case A_int_norm_emulateintfly
:
2502 NCR53c7x0_intfly(host
);
2503 return SPECIFIC_INT_NOTHING
;
2507 hostdata
->test_completed
= (dsps
- A_int_test_1
) / 0x00010000 + 1;
2508 if (hostdata
->options
& OPTION_DEBUG_INTR
)
2509 printk("scsi%d : test%d complete\n", host
->host_no
,
2510 hostdata
->test_completed
);
2511 return SPECIFIC_INT_NOTHING
;
2512 #ifdef A_int_debug_reselected_ok
2513 case A_int_debug_reselected_ok
:
2514 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
|
2515 OPTION_DEBUG_DISCONNECT
)) {
2517 * Note - this dsa is not based on location relative to
2518 * the command structure, but to location relative to the
2522 dsa
= (u32
*) bus_to_virt (NCR53c7x0_read32(DSA_REG
));
2524 printk("scsi%d : reselected_ok (DSA = 0x%x (virt 0x%p)\n",
2525 host
->host_no
, NCR53c7x0_read32(DSA_REG
), dsa
);
2526 printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
2527 host
->host_no
, cmd
->saved_data_pointer
,
2528 bus_to_virt(cmd
->saved_data_pointer
));
2529 print_insn (host
, hostdata
->script
+ Ent_reselected_ok
/
2530 sizeof(u32
), "", 1);
2531 if ((hostdata
->chip
/ 100) == 8)
2532 printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
2533 host
->host_no
, NCR53c7x0_read8(SXFER_REG
),
2534 NCR53c7x0_read8(SCNTL3_REG_800
));
2536 printk ("scsi%d : sxfer=0x%x, cannot read SBCL\n",
2537 host
->host_no
, NCR53c7x0_read8(SXFER_REG
));
2539 print_insn (host
, (u32
*)
2540 hostdata
->sync
[c
->target
].script
, "", 1);
2541 print_insn (host
, (u32
*)
2542 hostdata
->sync
[c
->target
].script
+ 2, "", 1);
2545 return SPECIFIC_INT_RESTART
;
2547 #ifdef A_int_debug_reselect_check
2548 case A_int_debug_reselect_check
:
2549 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
)) {
2555 * Note - this dsa is not based on location relative to
2556 * the command structure, but to location relative to the
2559 dsa
= bus_to_virt (NCR53c7x0_read32(DSA_REG
));
2560 printk("scsi%d : reselected_check_next (DSA = 0x%lx (virt 0x%p))\n",
2561 host
->host_no
, virt_to_bus(dsa
), dsa
);
2563 printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
2564 host
->host_no
, cmd
->saved_data_pointer
,
2565 bus_to_virt (cmd
->saved_data_pointer
));
2567 printk("scsi%d : template code :\n", host
->host_no
);
2568 for (code
= dsa
+ (Ent_dsa_code_check_reselect
- Ent_dsa_zero
)
2569 / sizeof(u32
); code
< (dsa
+ Ent_dsa_zero
/ sizeof(u32
));
2570 code
+= print_insn (host
, code
, "", 1));
2573 print_insn (host
, hostdata
->script
+ Ent_reselected_ok
/
2574 sizeof(u32
), "", 1);
2576 return SPECIFIC_INT_RESTART
;
2578 #ifdef A_int_debug_dsa_schedule
2579 case A_int_debug_dsa_schedule
:
2580 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
)) {
2583 * Note - this dsa is not based on location relative to
2584 * the command structure, but to location relative to the
2587 dsa
= (u32
*) bus_to_virt (NCR53c7x0_read32(DSA_REG
));
2588 printk("scsi%d : dsa_schedule (old DSA = 0x%lx (virt 0x%p))\n",
2589 host
->host_no
, virt_to_bus(dsa
), dsa
);
2591 printk("scsi%d : resume address is 0x%x (virt 0x%p)\n"
2592 " (temp was 0x%x (virt 0x%p))\n",
2593 host
->host_no
, cmd
->saved_data_pointer
,
2594 bus_to_virt (cmd
->saved_data_pointer
),
2595 NCR53c7x0_read32 (TEMP_REG
),
2596 bus_to_virt (NCR53c7x0_read32(TEMP_REG
)));
2598 return SPECIFIC_INT_RESTART
;
2600 #ifdef A_int_debug_scheduled
2601 case A_int_debug_scheduled
:
2602 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
)) {
2603 printk("scsi%d : new I/O 0x%x (virt 0x%p) scheduled\n",
2604 host
->host_no
, NCR53c7x0_read32(DSA_REG
),
2605 bus_to_virt(NCR53c7x0_read32(DSA_REG
)));
2607 return SPECIFIC_INT_RESTART
;
2609 #ifdef A_int_debug_idle
2610 case A_int_debug_idle
:
2611 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
)) {
2612 printk("scsi%d : idle\n", host
->host_no
);
2614 return SPECIFIC_INT_RESTART
;
2616 #ifdef A_int_debug_cmd
2617 case A_int_debug_cmd
:
2618 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
)) {
2619 printk("scsi%d : command sent\n");
2621 return SPECIFIC_INT_RESTART
;
2623 #ifdef A_int_debug_dsa_loaded
2624 case A_int_debug_dsa_loaded
:
2625 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
)) {
2626 printk("scsi%d : DSA loaded with 0x%x (virt 0x%p)\n", host
->host_no
,
2627 NCR53c7x0_read32(DSA_REG
),
2628 bus_to_virt(NCR53c7x0_read32(DSA_REG
)));
2630 return SPECIFIC_INT_RESTART
;
2632 #ifdef A_int_debug_reselected
2633 case A_int_debug_reselected
:
2634 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
|
2635 OPTION_DEBUG_DISCONNECT
)) {
2636 if ((hostdata
->chip
/ 100) == 8)
2637 printk("scsi%d : reselected by target %d lun %d\n",
2638 host
->host_no
, (int) NCR53c7x0_read8(SDID_REG_800
) & ~0x80,
2639 (int) hostdata
->reselected_identify
& 7);
2641 printk("scsi%d : reselected by LCRC=0x%02x lun %d\n",
2642 host
->host_no
, (int) NCR53c7x0_read8(LCRC_REG_10
),
2643 (int) hostdata
->reselected_identify
& 7);
2646 return SPECIFIC_INT_RESTART
;
2648 #ifdef A_int_debug_disconnect_msg
2649 case A_int_debug_disconnect_msg
:
2650 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
)) {
2652 printk("scsi%d : target %d lun %d disconnecting\n",
2653 host
->host_no
, c
->target
, c
->lun
);
2655 printk("scsi%d : unknown target disconnecting\n",
2658 return SPECIFIC_INT_RESTART
;
2660 #ifdef A_int_debug_disconnected
2661 case A_int_debug_disconnected
:
2662 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
|
2663 OPTION_DEBUG_DISCONNECT
)) {
2664 printk ("scsi%d : disconnected, new queues are\n",
2668 /* Not valid on ncr53c710! */
2669 printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
2670 host
->host_no
, NCR53c7x0_read8(SXFER_REG
),
2671 NCR53c7x0_read8(SCNTL3_REG_800
));
2674 print_insn (host
, (u32
*)
2675 hostdata
->sync
[c
->target
].script
, "", 1);
2676 print_insn (host
, (u32
*)
2677 hostdata
->sync
[c
->target
].script
+ 2, "", 1);
2680 return SPECIFIC_INT_RESTART
;
2682 #ifdef A_int_debug_panic
2683 case A_int_debug_panic
:
2684 printk("scsi%d : int_debug_panic received\n", host
->host_no
);
2686 return SPECIFIC_INT_PANIC
;
2688 #ifdef A_int_debug_saved
2689 case A_int_debug_saved
:
2690 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
|
2691 OPTION_DEBUG_DISCONNECT
)) {
2692 printk ("scsi%d : saved data pointer 0x%x (virt 0x%p)\n",
2693 host
->host_no
, cmd
->saved_data_pointer
,
2694 bus_to_virt (cmd
->saved_data_pointer
));
2697 return SPECIFIC_INT_RESTART
;
2699 #ifdef A_int_debug_restored
2700 case A_int_debug_restored
:
2701 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
|
2702 OPTION_DEBUG_DISCONNECT
)) {
2705 printk ("scsi%d : restored data pointer 0x%x (virt 0x%p)\n",
2706 host
->host_no
, cmd
->saved_data_pointer
, bus_to_virt (
2707 cmd
->saved_data_pointer
));
2708 size
= print_insn (host
, (u32
*)
2709 bus_to_virt(cmd
->saved_data_pointer
), "", 1);
2710 size
= print_insn (host
, (u32
*)
2711 bus_to_virt(cmd
->saved_data_pointer
) + size
, "", 1);
2715 printk ("scsi%d : datapath residual %d\n",
2716 host
->host_no
, datapath_residual (host
)) ;
2719 return SPECIFIC_INT_RESTART
;
2721 #ifdef A_int_debug_sync
2722 case A_int_debug_sync
:
2723 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
|
2724 OPTION_DEBUG_DISCONNECT
|OPTION_DEBUG_SDTR
)) {
2725 unsigned char sxfer
= NCR53c7x0_read8 (SXFER_REG
), scntl3
;
2726 if ((hostdata
->chip
/ 100) == 8) {
2727 scntl3
= NCR53c7x0_read8 (SCNTL3_REG_800
);
2729 if (sxfer
!= hostdata
->sync
[c
->target
].sxfer_sanity
||
2730 scntl3
!= hostdata
->sync
[c
->target
].scntl3_sanity
) {
2731 printk ("scsi%d : sync sanity check failed sxfer=0x%x, scntl3=0x%x",
2732 host
->host_no
, sxfer
, scntl3
);
2733 NCR53c7x0_write8 (SXFER_REG
, sxfer
);
2734 NCR53c7x0_write8 (SCNTL3_REG_800
, scntl3
);
2737 printk ("scsi%d : unknown command sxfer=0x%x, scntl3=0x%x\n",
2738 host
->host_no
, (int) sxfer
, (int) scntl3
);
2741 if (sxfer
!= hostdata
->sync
[c
->target
].sxfer_sanity
) {
2742 printk ("scsi%d : sync sanity check failed sxfer=0x%x",
2743 host
->host_no
, sxfer
);
2744 NCR53c7x0_write8 (SXFER_REG
, sxfer
);
2745 NCR53c7x0_write8 (SBCL_REG
,
2746 hostdata
->sync
[c
->target
].sscf_710
);
2749 printk ("scsi%d : unknown command sxfer=0x%x\n",
2750 host
->host_no
, (int) sxfer
);
2753 return SPECIFIC_INT_RESTART
;
2755 #ifdef A_int_debug_datain
2756 case A_int_debug_datain
:
2757 if (hostdata
->options
& (OPTION_DEBUG_SCRIPT
|OPTION_DEBUG_INTR
|
2758 OPTION_DEBUG_DISCONNECT
|OPTION_DEBUG_SDTR
)) {
2760 if ((hostdata
->chip
/ 100) == 8)
2761 printk ("scsi%d : In do_datain (%s) sxfer=0x%x, scntl3=0x%x\n"
2762 " datapath residual=%d\n",
2763 host
->host_no
, sbcl_to_phase (NCR53c7x0_read8 (SBCL_REG
)),
2764 (int) NCR53c7x0_read8(SXFER_REG
),
2765 (int) NCR53c7x0_read8(SCNTL3_REG_800
),
2766 datapath_residual (host
)) ;
2768 printk ("scsi%d : In do_datain (%s) sxfer=0x%x\n"
2769 " datapath residual=%d\n",
2770 host
->host_no
, sbcl_to_phase (NCR53c7x0_read8 (SBCL_REG
)),
2771 (int) NCR53c7x0_read8(SXFER_REG
),
2772 datapath_residual (host
)) ;
2773 print_insn (host
, dsp
, "", 1);
2774 size
= print_insn (host
, (u32
*) bus_to_virt(dsp
[1]), "", 1);
2775 print_insn (host
, (u32
*) bus_to_virt(dsp
[1]) + size
, "", 1);
2777 return SPECIFIC_INT_RESTART
;
2779 #ifdef A_int_debug_check_dsa
2780 case A_int_debug_check_dsa
:
2781 if (NCR53c7x0_read8 (SCNTL1_REG
) & SCNTL1_CON
) {
2785 if (hostdata
->chip
/ 100 == 8)
2786 sdid
= NCR53c7x0_read8 (SDID_REG_800
) & 15;
2788 tmp
= NCR53c7x0_read8 (SDID_REG_700
);
2790 panic ("SDID_REG_700 = 0");
2798 where
= dsp
- NCR53c7x0_insn_size(NCR53c7x0_read8
2799 (DCMD_REG
)) == hostdata
->script
+
2800 Ent_select_check_dsa
/ sizeof(u32
) ?
2801 "selection" : "reselection";
2802 if (c
&& sdid
!= c
->target
) {
2803 printk ("scsi%d : SDID target %d != DSA target %d at %s\n",
2804 host
->host_no
, sdid
, c
->target
, where
);
2806 dump_events (host
, 20);
2807 return SPECIFIC_INT_PANIC
;
2810 return SPECIFIC_INT_RESTART
;
2813 if ((dsps
& 0xff000000) == 0x03000000) {
2814 printk ("scsi%d : misc debug interrupt 0x%x\n",
2815 host
->host_no
, dsps
);
2816 return SPECIFIC_INT_RESTART
;
2817 } else if ((dsps
& 0xff000000) == 0x05000000) {
2818 if (hostdata
->events
) {
2819 struct NCR53c7x0_event
*event
;
2820 ++hostdata
->event_index
;
2821 if (hostdata
->event_index
>= hostdata
->event_size
)
2822 hostdata
->event_index
= 0;
2823 event
= (struct NCR53c7x0_event
*) hostdata
->events
+
2824 hostdata
->event_index
;
2825 event
->event
= (enum ncr_event
) dsps
;
2826 event
->dsa
= bus_to_virt(NCR53c7x0_read32(DSA_REG
));
2827 if (NCR53c7x0_read8 (SCNTL1_REG
) & SCNTL1_CON
) {
2828 if (hostdata
->chip
/ 100 == 8)
2829 event
->target
= NCR53c7x0_read8(SSID_REG_800
);
2831 unsigned char tmp
, sdid
;
2832 tmp
= NCR53c7x0_read8 (SDID_REG_700
);
2834 panic ("SDID_REG_700 = 0");
2841 event
->target
= sdid
;
2845 event
->target
= 255;
2847 if (event
->event
== EVENT_RESELECT
)
2848 event
->lun
= hostdata
->reselected_identify
& 0xf;
2850 event
->lun
= c
->lun
;
2853 do_gettimeofday(&(event
->time
));
2855 event
->pid
= c
->pid
;
2856 memcpy ((void *) event
->cmnd
, (void *) c
->cmnd
,
2857 sizeof (event
->cmnd
));
2862 return SPECIFIC_INT_RESTART
;
2865 printk ("scsi%d : unknown user interrupt 0x%x\n",
2866 host
->host_no
, (unsigned) dsps
);
2867 return SPECIFIC_INT_PANIC
;
2872 * XXX - the stock NCR assembler won't output the scriptu.h file,
2873 * which undefine's all #define'd CPP symbols from the script.h
2874 * file, which will create problems if you use multiple scripts
2875 * with the same symbol names.
2877 * If you insist on using NCR's assembler, you could generate
2878 * scriptu.h from script.h using something like
2880 * grep #define script.h | \
2881 * sed 's/#define[ ][ ]*\([_a-zA-Z][_a-zA-Z0-9]*\).*$/#undefine \1/' \
2885 #include "53c7xx_u.h"
2887 /* XXX - add alternate script handling code here */
2891 * Function : static void NCR537xx_soft_reset (struct Scsi_Host *host)
2893 * Purpose : perform a soft reset of the NCR53c7xx chip
2895 * Inputs : host - pointer to this host adapter's structure
2897 * Preconditions : NCR53c7x0_init must have been called for this
2903 NCR53c7x0_soft_reset (struct Scsi_Host
*host
) {
2904 NCR53c7x0_local_declare();
2905 unsigned long flags
;
2906 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
2908 NCR53c7x0_local_setup(host
);
2913 /* Disable scsi chip and s/w level 7 ints */
2915 #ifdef CONFIG_MVME16x
2916 if (MACH_IS_MVME16x
)
2918 volatile unsigned long v
;
2920 v
= *(volatile unsigned long *)0xfff4006c;
2922 *(volatile unsigned long *)0xfff4006c = v
;
2923 v
= *(volatile unsigned long *)0xfff4202c;
2925 *(volatile unsigned long *)0xfff4202c = v
;
2928 /* Anything specific for your hardware? */
2931 * Do a soft reset of the chip so that everything is
2932 * reinitialized to the power-on state.
2934 * Basically follow the procedure outlined in the NCR53c700
2935 * data manual under Chapter Six, How to Use, Steps Necessary to
2936 * Start SCRIPTS, with the exception of actually starting the
2937 * script and setting up the synchronous transfer gunk.
2940 /* Should we reset the scsi bus here??????????????????? */
2942 NCR53c7x0_write8(ISTAT_REG_700
, ISTAT_10_SRST
);
2943 NCR53c7x0_write8(ISTAT_REG_700
, 0);
2946 * saved_dcntl is set up in NCR53c7x0_init() before it is overwritten
2947 * here. We should have some better way of working out the CF bit
2951 hostdata
->saved_dcntl
= DCNTL_10_EA
|DCNTL_10_COM
;
2952 if (hostdata
->scsi_clock
> 50000000)
2953 hostdata
->saved_dcntl
|= DCNTL_700_CF_3
;
2955 if (hostdata
->scsi_clock
> 37500000)
2956 hostdata
->saved_dcntl
|= DCNTL_700_CF_2
;
2959 /* Any clocks less than 37.5MHz? */
2962 if (hostdata
->options
& OPTION_DEBUG_TRACE
)
2963 NCR53c7x0_write8(DCNTL_REG
, hostdata
->saved_dcntl
| DCNTL_SSM
);
2965 NCR53c7x0_write8(DCNTL_REG
, hostdata
->saved_dcntl
);
2966 /* Following disables snooping - snooping is not required, as non-
2967 * cached pages are used for shared data, and appropriate use is
2968 * made of cache_push/cache_clear. Indeed, for 68060
2969 * enabling snooping causes disk corruption of ext2fs free block
2970 * bitmaps and the like. If you have a 68060 with snooping hardwared
2971 * on, then you need to enable CONFIG_060_WRITETHROUGH.
2973 NCR53c7x0_write8(CTEST7_REG
, CTEST7_10_TT1
|CTEST7_STD
);
2974 /* Actually burst of eight, according to my 53c710 databook */
2975 NCR53c7x0_write8(hostdata
->dmode
, DMODE_10_BL_8
| DMODE_10_FC2
);
2976 NCR53c7x0_write8(SCID_REG
, 1 << host
->this_id
);
2977 NCR53c7x0_write8(SBCL_REG
, 0);
2978 NCR53c7x0_write8(SCNTL1_REG
, SCNTL1_ESR_700
);
2979 NCR53c7x0_write8(SCNTL0_REG
, ((hostdata
->options
& OPTION_PARITY
) ?
2980 SCNTL0_EPC
: 0) | SCNTL0_EPG_700
| SCNTL0_ARB1
| SCNTL0_ARB2
);
2983 * Enable all interrupts, except parity which we only want when
2984 * the user requests it.
2987 NCR53c7x0_write8(DIEN_REG
, DIEN_700_BF
|
2988 DIEN_ABRT
| DIEN_SSI
| DIEN_SIR
| DIEN_700_OPC
);
2990 NCR53c7x0_write8(SIEN_REG_700
, ((hostdata
->options
& OPTION_PARITY
) ?
2991 SIEN_PAR
: 0) | SIEN_700_STO
| SIEN_RST
| SIEN_UDC
|
2992 SIEN_SGE
| SIEN_MA
);
2994 #ifdef CONFIG_MVME16x
2995 if (MACH_IS_MVME16x
)
2997 volatile unsigned long v
;
2999 /* Enable scsi chip and s/w level 7 ints */
3000 v
= *(volatile unsigned long *)0xfff40080;
3001 v
= (v
& ~(0xf << 28)) | (4 << 28);
3002 *(volatile unsigned long *)0xfff40080 = v
;
3003 v
= *(volatile unsigned long *)0xfff4006c;
3005 *(volatile unsigned long *)0xfff4006c = v
;
3006 v
= *(volatile unsigned long *)0xfff4202c;
3007 v
= (v
& ~0xff) | 0x10 | 4;
3008 *(volatile unsigned long *)0xfff4202c = v
;
3011 /* Anything needed for your hardware? */
3012 restore_flags(flags
);
3017 * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd)
3019 * Purpose : Return the first free NCR53c7x0_cmd structure (which are
3020 * reused in a LIFO manner to minimize cache thrashing).
3022 * Side effects : If we haven't yet scheduled allocation of NCR53c7x0_cmd
3023 * structures for this device, do so. Attempt to complete all scheduled
3024 * allocations using get_free_page(), putting NCR53c7x0_cmd structures on
3025 * the free list. Teach programmers not to drink and hack.
3027 * Inputs : cmd - SCSI command
3029 * Returns : NCR53c7x0_cmd structure allocated on behalf of cmd;
3034 my_free_page (void *addr
, int dummy
)
3036 /* XXX This assumes default cache mode to be IOMAP_FULL_CACHING, which
3037 * XXX may be invalid (CONFIG_060_WRITETHROUGH)
3039 kernel_set_cachemode((u32
)addr
, 4096, IOMAP_FULL_CACHING
);
3040 free_page ((u32
)addr
);
3043 static struct NCR53c7x0_cmd
*
3044 allocate_cmd (Scsi_Cmnd
*cmd
) {
3045 struct Scsi_Host
*host
= cmd
->host
;
3046 struct NCR53c7x0_hostdata
*hostdata
=
3047 (struct NCR53c7x0_hostdata
*) host
->hostdata
[0];
3048 u32 real
; /* Real address */
3049 int size
; /* Size of *tmp */
3050 struct NCR53c7x0_cmd
*tmp
;
3051 unsigned long flags
;
3053 if (hostdata
->options
& OPTION_DEBUG_ALLOCATION
)
3054 printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
3055 " target = %d, lun = %d, %s\n",
3056 host
->host_no
, hostdata
->num_cmds
, host
->can_queue
,
3057 cmd
->target
, cmd
->lun
, (hostdata
->cmd_allocated
[cmd
->target
] &
3058 (1 << cmd
->lun
)) ? "already allocated" : "not allocated");
3061 * If we have not yet reserved commands for this I_T_L nexus, and
3062 * the device exists (as indicated by permanent Scsi_Cmnd structures
3063 * being allocated under 1.3.x, or being outside of scan_scsis in
3064 * 1.2.x), do so now.
3066 if (!(hostdata
->cmd_allocated
[cmd
->target
] & (1 << cmd
->lun
)) &&
3067 cmd
->device
&& cmd
->device
->has_cmdblocks
) {
3068 if ((hostdata
->extra_allocate
+ hostdata
->num_cmds
) < host
->can_queue
)
3069 hostdata
->extra_allocate
+= host
->cmd_per_lun
;
3070 hostdata
->cmd_allocated
[cmd
->target
] |= (1 << cmd
->lun
);
3073 for (; hostdata
->extra_allocate
> 0 ; --hostdata
->extra_allocate
,
3074 ++hostdata
->num_cmds
) {
3075 /* historically, kmalloc has returned unaligned addresses; pad so we
3076 have enough room to ROUNDUP */
3077 size
= hostdata
->max_cmd_size
+ sizeof (void *);
3078 #ifdef FORCE_DSA_ALIGNMENT
3080 * 53c710 rev.0 doesn't have an add-with-carry instruction.
3081 * Ensure we allocate enough memory to force alignment.
3085 /* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
3088 panic ("53c7xx: allocate_cmd size > 4K");
3089 real
= get_free_page(GFP_ATOMIC
);
3091 panic ("53c7xx: Couldn't get memory for allocate_cmd");
3092 memset((void *)real
, 0, 4096);
3093 cache_push(virt_to_phys((void *)real
), 4096);
3094 cache_clear(virt_to_phys((void *)real
), 4096);
3095 kernel_set_cachemode(real
, 4096, IOMAP_NOCACHE_SER
);
3096 tmp
= ROUNDUP(real
, void *);
3097 #ifdef FORCE_DSA_ALIGNMENT
3099 if (((u32
)tmp
& 0xff) > CmdPageStart
)
3100 tmp
= (struct NCR53c7x0_cmd
*)((u32
)tmp
+ 255);
3101 tmp
= (struct NCR53c7x0_cmd
*)(((u32
)tmp
& ~0xff) + CmdPageStart
);
3103 printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
3104 size
, real
, (u32
)tmp
);
3108 tmp
->real
= (void *)real
;
3110 tmp
->free
= ((void (*)(void *, int)) my_free_page
);
3113 tmp
->next
= hostdata
->free
;
3114 hostdata
->free
= tmp
;
3115 restore_flags (flags
);
3119 tmp
= (struct NCR53c7x0_cmd
*) hostdata
->free
;
3121 hostdata
->free
= tmp
->next
;
3123 restore_flags(flags
);
3125 printk ("scsi%d : can't allocate command for target %d lun %d\n",
3126 host
->host_no
, cmd
->target
, cmd
->lun
);
3131 * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd)
3134 * Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the
3135 * Scsi_Cmnd structure passed in cmd, including dsa and Linux field
3136 * initialization, and dsa code relocation.
3138 * Inputs : cmd - SCSI command
3140 * Returns : NCR53c7x0_cmd structure corresponding to cmd,
3143 static struct NCR53c7x0_cmd
*
3144 create_cmd (Scsi_Cmnd
*cmd
) {
3145 NCR53c7x0_local_declare();
3146 struct Scsi_Host
*host
= cmd
->host
;
3147 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
3149 struct NCR53c7x0_cmd
*tmp
; /* NCR53c7x0_cmd structure for this command */
3150 int datain
, /* Number of instructions per phase */
3152 int data_transfer_instructions
, /* Count of dynamic instructions */
3154 u32
*cmd_datain
, /* Address of datain/dataout code */
3155 *cmd_dataout
; /* Incremented as we assemble */
3157 unsigned char *msgptr
; /* Current byte in select message */
3158 int msglen
; /* Length of whole select message */
3160 unsigned long flags
;
3161 u32 exp_select_indirect
; /* Used in sanity check */
3162 NCR53c7x0_local_setup(cmd
->host
);
3164 if (!(tmp
= allocate_cmd (cmd
)))
3168 * Copy CDB and initialised result fields from Scsi_Cmnd to NCR53c7x0_cmd.
3169 * We do this because NCR53c7x0_cmd may have a special cache mode
3170 * selected to cope with lack of bus snooping, etc.
3173 memcpy(tmp
->cmnd
, cmd
->cmnd
, 12);
3174 tmp
->result
= cmd
->result
;
3177 * Decide whether we need to generate commands for DATA IN,
3178 * DATA OUT, neither, or both based on the SCSI command
3181 switch (cmd
->cmnd
[0]) {
3182 /* These commands do DATA IN */
3189 case READ_BLOCK_LIMITS
:
3191 datain
= 2 * (cmd
->use_sg
? cmd
->use_sg
: 1) + 3;
3194 /* These commands do DATA OUT */
3199 printk("scsi%d : command is ", host
->host_no
);
3200 print_command(cmd
->cmnd
);
3203 printk ("scsi%d : %d scatter/gather segments\n", host
->host_no
,
3207 dataout
= 2 * (cmd
->use_sg
? cmd
->use_sg
: 1) + 3;
3209 hostdata
->options
|= OPTION_DEBUG_INTR
;
3213 * These commands do no data transfer, we should force an
3214 * interrupt if a data phase is attempted on them.
3216 case TEST_UNIT_READY
:
3217 case ALLOW_MEDIUM_REMOVAL
:
3219 datain
= dataout
= 0;
3222 * We don't know about these commands, so generate code to handle
3223 * both DATA IN and DATA OUT phases. More efficient to identify them
3224 * and add them to the above cases.
3227 printk("scsi%d : datain+dataout for command ", host
->host_no
);
3228 print_command(cmd
->cmnd
);
3229 datain
= dataout
= 2 * (cmd
->use_sg
? cmd
->use_sg
: 1) + 3;
3233 * New code : so that active pointers work correctly regardless
3234 * of where the saved data pointer is at, we want to immediately
3235 * enter the dynamic code after selection, and on a non-data
3236 * phase perform a CALL to the non-data phase handler, with
3237 * returns back to this address.
3239 * If a phase mismatch is encountered in the middle of a
3240 * Block MOVE instruction, we want to _leave_ that instruction
3241 * unchanged as the current case is, modify a temporary buffer,
3242 * and point the active pointer (TEMP) at that.
3244 * Furthermore, we want to implement a saved data pointer,
3245 * set by the SAVE_DATA_POINTERs message.
3247 * So, the data transfer segments will change to
3248 * CALL data_transfer, WHEN NOT data phase
3249 * MOVE x, x, WHEN data phase
3251 * JUMP other_transfer
3254 data_transfer_instructions
= datain
+ dataout
;
3257 * When we perform a request sense, we overwrite various things,
3258 * including the data transfer code. Make sure we have enough
3262 if (data_transfer_instructions
< 2)
3263 data_transfer_instructions
= 2;
3267 * The saved data pointer is set up so that a RESTORE POINTERS message
3268 * will start the data transfer over at the begining.
3271 tmp
->saved_data_pointer
= virt_to_bus (hostdata
->script
) +
3272 hostdata
->E_data_transfer
;
3275 * Initialize Linux specific fields.
3281 tmp
->dsa_next_addr
= virt_to_bus(tmp
->dsa
) + hostdata
->dsa_next
-
3282 hostdata
->dsa_start
;
3283 tmp
->dsa_addr
= virt_to_bus(tmp
->dsa
) - hostdata
->dsa_start
;
3286 * Calculate addresses of dynamic code to fill in DSA
3289 tmp
->data_transfer_start
= tmp
->dsa
+ (hostdata
->dsa_end
-
3290 hostdata
->dsa_start
) / sizeof(u32
);
3291 tmp
->data_transfer_end
= tmp
->data_transfer_start
+
3292 2 * data_transfer_instructions
;
3294 cmd_datain
= datain
? tmp
->data_transfer_start
: NULL
;
3295 cmd_dataout
= dataout
? (datain
? cmd_datain
+ 2 * datain
: tmp
->
3296 data_transfer_start
) : NULL
;
3299 * Fill in the NCR53c7x0_cmd structure as follows
3300 * dsa, with fixed up DSA code
3305 /* Copy template code into dsa and perform all necessary fixups */
3306 if (hostdata
->dsa_fixup
)
3307 hostdata
->dsa_fixup(tmp
);
3309 patch_dsa_32(tmp
->dsa
, dsa_next
, 0, 0);
3311 * XXX is this giving 53c710 access to the Scsi_Cmnd in some way?
3312 * Do we need to change it for caching reasons?
3314 patch_dsa_32(tmp
->dsa
, dsa_cmnd
, 0, virt_to_bus(cmd
));
3316 if (hostdata
->options
& OPTION_DEBUG_SYNCHRONOUS
) {
3318 exp_select_indirect
= ((1 << cmd
->target
) << 16) |
3319 (hostdata
->sync
[cmd
->target
].sxfer_sanity
<< 8);
3321 if (hostdata
->sync
[cmd
->target
].select_indirect
!=
3322 exp_select_indirect
) {
3323 printk ("scsi%d : sanity check failed select_indirect=0x%x\n",
3324 host
->host_no
, hostdata
->sync
[cmd
->target
].select_indirect
);
3330 patch_dsa_32(tmp
->dsa
, dsa_select
, 0,
3331 hostdata
->sync
[cmd
->target
].select_indirect
);
3334 * Right now, we'll do the WIDE and SYNCHRONOUS negotiations on
3335 * different commands; although it should be trivial to do them
3336 * both at the same time.
3338 if (hostdata
->initiate_wdtr
& (1 << cmd
->target
)) {
3339 memcpy ((void *) (tmp
->select
+ 1), (void *) wdtr_message
,
3340 sizeof(wdtr_message
));
3341 patch_dsa_32(tmp
->dsa
, dsa_msgout
, 0, 1 + sizeof(wdtr_message
));
3344 hostdata
->initiate_wdtr
&= ~(1 << cmd
->target
);
3345 restore_flags(flags
);
3346 } else if (hostdata
->initiate_sdtr
& (1 << cmd
->target
)) {
3347 memcpy ((void *) (tmp
->select
+ 1), (void *) sdtr_message
,
3348 sizeof(sdtr_message
));
3349 patch_dsa_32(tmp
->dsa
, dsa_msgout
, 0, 1 + sizeof(sdtr_message
));
3350 tmp
->flags
|= CMD_FLAG_SDTR
;
3353 hostdata
->initiate_sdtr
&= ~(1 << cmd
->target
);
3354 restore_flags(flags
);
3358 else if (!(hostdata
->talked_to
& (1 << cmd
->target
)) &&
3359 !(hostdata
->options
& OPTION_NO_ASYNC
)) {
3361 memcpy ((void *) (tmp
->select
+ 1), (void *) async_message
,
3362 sizeof(async_message
));
3363 patch_dsa_32(tmp
->dsa
, dsa_msgout
, 0, 1 + sizeof(async_message
));
3364 tmp
->flags
|= CMD_FLAG_SDTR
;
3368 patch_dsa_32(tmp
->dsa
, dsa_msgout
, 0, 1);
3370 hostdata
->talked_to
|= (1 << cmd
->target
);
3371 tmp
->select
[0] = (hostdata
->options
& OPTION_DISCONNECT
) ?
3372 IDENTIFY (1, cmd
->lun
) : IDENTIFY (0, cmd
->lun
);
3373 patch_dsa_32(tmp
->dsa
, dsa_msgout
, 1, virt_to_bus(tmp
->select
));
3374 patch_dsa_32(tmp
->dsa
, dsa_cmdout
, 0, cmd
->cmd_len
);
3375 patch_dsa_32(tmp
->dsa
, dsa_cmdout
, 1, virt_to_bus(tmp
->cmnd
));
3376 patch_dsa_32(tmp
->dsa
, dsa_dataout
, 0, cmd_dataout
?
3377 virt_to_bus (cmd_dataout
)
3378 : virt_to_bus (hostdata
->script
) + hostdata
->E_other_transfer
);
3379 patch_dsa_32(tmp
->dsa
, dsa_datain
, 0, cmd_datain
?
3380 virt_to_bus (cmd_datain
)
3381 : virt_to_bus (hostdata
->script
) + hostdata
->E_other_transfer
);
3383 * XXX - need to make endian aware, should use separate variables
3384 * for both status and message bytes.
3386 patch_dsa_32(tmp
->dsa
, dsa_msgin
, 0, 1);
3388 * FIXME : these only works for little endian. We probably want to
3389 * provide message and status fields in the NCR53c7x0_cmd
3390 * structure, and assign them to cmd->result when we're done.
3393 patch_dsa_32(tmp
->dsa
, dsa_msgin
, 1, virt_to_bus(&tmp
->result
) + 2);
3394 patch_dsa_32(tmp
->dsa
, dsa_status
, 0, 1);
3395 patch_dsa_32(tmp
->dsa
, dsa_status
, 1, virt_to_bus(&tmp
->result
) + 3);
3397 patch_dsa_32(tmp
->dsa
, dsa_msgin
, 1, virt_to_bus(&tmp
->result
) + 1);
3398 patch_dsa_32(tmp
->dsa
, dsa_status
, 0, 1);
3399 patch_dsa_32(tmp
->dsa
, dsa_status
, 1, virt_to_bus(&tmp
->result
));
3401 patch_dsa_32(tmp
->dsa
, dsa_msgout_other
, 0, 1);
3402 patch_dsa_32(tmp
->dsa
, dsa_msgout_other
, 1,
3403 virt_to_bus(&(hostdata
->NCR53c7xx_msg_nop
)));
3406 * Generate code for zero or more of the DATA IN, DATA OUT phases
3409 * CALL data_transfer, WHEN NOT phase
3410 * MOVE first buffer length, first buffer address, WHEN phase
3412 * MOVE last buffer length, last buffer address, WHEN phase
3413 * JUMP other_transfer
3417 * See if we're getting to data transfer by generating an unconditional
3422 cmd_datain
[0] = 0x98080000;
3423 cmd_datain
[1] = 0x03ffd00d;
3429 * XXX - I'm undecided whether all of this nonsense is faster
3430 * in the long run, or whether I should just go and implement a loop
3431 * on the NCR chip using table indirect mode?
3433 * In any case, this is how it _must_ be done for 53c700/700-66 chips,
3434 * so this stays even when we come up with something better.
3436 * When we're limited to 1 simultaneous command, no overlapping processing,
3437 * we're seeing 630K/sec, with 7% CPU usage on a slow Syquest 45M
3440 * Not bad, not good. We'll see.
3443 tmp
->bounce
.len
= 0; /* Assume aligned buffer */
3445 for (i
= 0; cmd
->use_sg
? (i
< cmd
->use_sg
) : !i
; cmd_datain
+= 4,
3446 cmd_dataout
+= 4, ++i
) {
3447 u32 vbuf
= cmd
->use_sg
?
3448 (u32
)(((struct scatterlist
*)cmd
->buffer
)[i
].address
) :
3449 (u32
)(cmd
->request_buffer
);
3450 u32 bbuf
= virt_to_bus((void *)vbuf
);
3451 u32 count
= cmd
->use_sg
?
3452 ((struct scatterlist
*)cmd
->buffer
)[i
].length
:
3453 cmd
->request_bufflen
;
3456 * If we have buffers which are not aligned with 16 byte cache
3457 * lines, then we just hope nothing accesses the other parts of
3458 * those cache lines while the transfer is in progress. That would
3459 * fill the cache, and subsequent reads of the dma data would pick
3460 * up the wrong thing.
3461 * XXX We need a bounce buffer to handle that correctly.
3464 if (((bbuf
& 15) || (count
& 15)) && (datain
|| dataout
))
3466 /* Bounce buffer needed */
3468 printk ("53c7xx: Non-aligned buffer with use_sg\n");
3469 else if (datain
&& dataout
)
3470 printk ("53c7xx: Non-aligned buffer with datain && dataout\n");
3471 else if (count
> 256)
3472 printk ("53c7xx: Non-aligned transfer > 256 bytes\n");
3477 tmp
->bounce
.len
= count
;
3478 tmp
->bounce
.addr
= vbuf
;
3479 bbuf
= virt_to_bus(tmp
->bounce
.buf
);
3480 tmp
->bounce
.buf
[0] = 0xff;
3481 tmp
->bounce
.buf
[1] = 0xfe;
3482 tmp
->bounce
.buf
[2] = 0xfd;
3483 tmp
->bounce
.buf
[3] = 0xfc;
3487 memcpy ((void *)tmp
->bounce
.buf
, (void *)vbuf
, count
);
3488 bbuf
= virt_to_bus(tmp
->bounce
.buf
);
3494 cache_clear(virt_to_phys((void *)vbuf
), count
);
3495 /* CALL other_in, WHEN NOT DATA_IN */
3496 cmd_datain
[0] = ((DCMD_TYPE_TCI
| DCMD_TCI_OP_CALL
|
3497 DCMD_TCI_IO
) << 24) |
3498 DBC_TCI_WAIT_FOR_VALID
| DBC_TCI_COMPARE_PHASE
;
3499 cmd_datain
[1] = virt_to_bus (hostdata
->script
) +
3500 hostdata
->E_other_in
;
3501 /* MOVE count, buf, WHEN DATA_IN */
3502 cmd_datain
[2] = ((DCMD_TYPE_BMI
| DCMD_BMI_OP_MOVE_I
| DCMD_BMI_IO
)
3504 cmd_datain
[3] = bbuf
;
3506 print_insn (host
, cmd_datain
, "dynamic ", 1);
3507 print_insn (host
, cmd_datain
+ 2, "dynamic ", 1);
3511 cache_push(virt_to_phys((void *)vbuf
), count
);
3512 /* CALL other_out, WHEN NOT DATA_OUT */
3513 cmd_dataout
[0] = ((DCMD_TYPE_TCI
| DCMD_TCI_OP_CALL
) << 24) |
3514 DBC_TCI_WAIT_FOR_VALID
| DBC_TCI_COMPARE_PHASE
;
3515 cmd_dataout
[1] = virt_to_bus(hostdata
->script
) +
3516 hostdata
->E_other_out
;
3517 /* MOVE count, buf, WHEN DATA+OUT */
3518 cmd_dataout
[2] = ((DCMD_TYPE_BMI
| DCMD_BMI_OP_MOVE_I
) << 24)
3520 cmd_dataout
[3] = bbuf
;
3522 print_insn (host
, cmd_dataout
, "dynamic ", 1);
3523 print_insn (host
, cmd_dataout
+ 2, "dynamic ", 1);
3529 * Install JUMP instructions after the data transfer routines to return
3530 * control to the do_other_transfer routines.
3535 cmd_datain
[0] = ((DCMD_TYPE_TCI
| DCMD_TCI_OP_JUMP
) << 24) |
3537 cmd_datain
[1] = virt_to_bus(hostdata
->script
) +
3538 hostdata
->E_other_transfer
;
3540 print_insn (host
, cmd_datain
, "dynamic jump ", 1);
3546 cmd_datain
[0] = 0x98080000;
3547 cmd_datain
[1] = 0x03ffdeed;
3552 cmd_dataout
[0] = ((DCMD_TYPE_TCI
| DCMD_TCI_OP_JUMP
) << 24) |
3554 cmd_dataout
[1] = virt_to_bus(hostdata
->script
) +
3555 hostdata
->E_other_transfer
;
3557 print_insn (host
, cmd_dataout
, "dynamic jump ", 1);
3566 * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd,
3567 * void (*done)(Scsi_Cmnd *))
3569 * Purpose : enqueues a SCSI command
3571 * Inputs : cmd - SCSI command, done - function called on completion, with
3572 * a pointer to the command descriptor.
3577 * cmd is added to the per instance driver issue_queue, with major
3578 * twiddling done to the host specific fields of cmd. If the
3579 * process_issue_queue coroutine isn't running, it is restarted.
3581 * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to
3582 * hold our own data, and pervert the ptr field of the SCp field
3583 * to create a linked list.
3587 NCR53c7xx_queue_command (Scsi_Cmnd
*cmd
, void (* done
)(Scsi_Cmnd
*)) {
3588 struct Scsi_Host
*host
= cmd
->host
;
3589 struct NCR53c7x0_hostdata
*hostdata
=
3590 (struct NCR53c7x0_hostdata
*) host
->hostdata
[0];
3591 unsigned long flags
;
3594 cmd
->scsi_done
= done
;
3595 cmd
->host_scribble
= NULL
;
3596 cmd
->SCp
.ptr
= NULL
;
3597 cmd
->SCp
.buffer
= NULL
;
3600 /* Ignore commands on invalid IDs */
3601 if (!hostdata
->valid_ids
[cmd
->target
]) {
3602 printk("scsi%d : ignoring target %d lun %d\n", host
->host_no
,
3603 cmd
->target
, cmd
->lun
);
3604 cmd
->result
= (DID_BAD_TARGET
<< 16);
3612 if ((hostdata
->options
& (OPTION_DEBUG_INIT_ONLY
|OPTION_DEBUG_PROBE_ONLY
))
3613 || ((hostdata
->options
& OPTION_DEBUG_TARGET_LIMIT
) &&
3614 !(hostdata
->debug_lun_limit
[cmd
->target
] & (1 << cmd
->lun
)))
3618 || cmd
->target
> host
->max_id
3620 || cmd
->target
== host
->this_id
3621 || hostdata
->state
== STATE_DISABLED
) {
3622 printk("scsi%d : disabled or bad target %d lun %d\n", host
->host_no
,
3623 cmd
->target
, cmd
->lun
);
3624 cmd
->result
= (DID_BAD_TARGET
<< 16);
3626 restore_flags (flags
);
3630 if ((hostdata
->options
& OPTION_DEBUG_NCOMMANDS_LIMIT
) &&
3631 (hostdata
->debug_count_limit
== 0)) {
3632 printk("scsi%d : maximum commands exceeded\n", host
->host_no
);
3633 cmd
->result
= (DID_BAD_TARGET
<< 16);
3635 restore_flags (flags
);
3639 if (hostdata
->options
& OPTION_DEBUG_READ_ONLY
) {
3640 switch (cmd
->cmnd
[0]) {
3643 printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
3645 cmd
->result
= (DID_BAD_TARGET
<< 16);
3647 restore_flags (flags
);
3652 if ((hostdata
->options
& OPTION_DEBUG_TARGET_LIMIT
) &&
3653 hostdata
->debug_count_limit
!= -1)
3654 --hostdata
->debug_count_limit
;
3656 cmd
->result
= 0xffff; /* The NCR will overwrite message
3657 and status with valid data */
3658 cmd
->host_scribble
= (unsigned char *) tmp
= create_cmd (cmd
);
3661 * REQUEST SENSE commands are inserted at the head of the queue
3662 * so that we do not clear the contingent allegiance condition
3663 * they may be looking at.
3666 if (!(hostdata
->issue_queue
) || (cmd
->cmnd
[0] == REQUEST_SENSE
)) {
3667 cmd
->SCp
.ptr
= (unsigned char *) hostdata
->issue_queue
;
3668 hostdata
->issue_queue
= cmd
;
3670 for (tmp
= (Scsi_Cmnd
*) hostdata
->issue_queue
; tmp
->SCp
.ptr
;
3671 tmp
= (Scsi_Cmnd
*) tmp
->SCp
.ptr
);
3672 tmp
->SCp
.ptr
= (unsigned char *) cmd
;
3674 restore_flags (flags
);
3675 run_process_issue_queue();
3680 * Function : void to_schedule_list (struct Scsi_Host *host,
3681 * struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd)
3683 * Purpose : takes a SCSI command which was just removed from the
3684 * issue queue, and deals with it by inserting it in the first
3685 * free slot in the schedule list or by terminating it immediately.
3688 * host - SCSI host adapter; hostdata - hostdata structure for
3689 * this adapter; cmd - a pointer to the command; should have
3690 * the host_scribble field initialized to point to a valid
3693 * cmd is added to the per instance schedule list, with minor
3694 * twiddling done to the host specific fields of cmd.
3698 static __inline__
void
3699 to_schedule_list (struct Scsi_Host
*host
, struct NCR53c7x0_hostdata
*hostdata
,
3700 struct NCR53c7x0_cmd
*cmd
) {
3701 NCR53c7x0_local_declare();
3702 Scsi_Cmnd
*tmp
= cmd
->cmd
;
3703 unsigned long flags
;
3704 /* dsa start is negative, so subtraction is used */
3705 volatile u32
*ncrcurrent
;
3708 NCR53c7x0_local_setup(host
);
3710 printk("scsi%d : new dsa is 0x%lx (virt 0x%p)\n", host
->host_no
,
3711 virt_to_bus(hostdata
->dsa
), hostdata
->dsa
);
3718 * Work around race condition : if an interrupt fired and we
3719 * got disabled forget about this command.
3722 if (hostdata
->state
== STATE_DISABLED
) {
3723 printk("scsi%d : driver disabled\n", host
->host_no
);
3724 tmp
->result
= (DID_BAD_TARGET
<< 16);
3725 cmd
->next
= (struct NCR53c7x0_cmd
*) hostdata
->free
;
3726 hostdata
->free
= cmd
;
3727 tmp
->scsi_done(tmp
);
3728 restore_flags (flags
);
3732 for (i
= host
->can_queue
, ncrcurrent
= hostdata
->schedule
;
3733 i
> 0 && ncrcurrent
[0] != hostdata
->NOP_insn
;
3734 --i
, ncrcurrent
+= 2 /* JUMP instructions are two words */);
3737 ++hostdata
->busy
[tmp
->target
][tmp
->lun
];
3738 cmd
->next
= hostdata
->running_list
;
3739 hostdata
->running_list
= cmd
;
3741 /* Restore this instruction to a NOP once the command starts */
3742 cmd
->dsa
[(hostdata
->dsa_jump_dest
- hostdata
->dsa_start
) /
3743 sizeof(u32
)] = (u32
) virt_to_bus ((void *)ncrcurrent
);
3744 /* Replace the current jump operand. */
3746 virt_to_bus ((void *) cmd
->dsa
) + hostdata
->E_dsa_code_begin
-
3747 hostdata
->E_dsa_code_template
;
3748 /* Replace the NOP instruction with a JUMP */
3749 ncrcurrent
[0] = ((DCMD_TYPE_TCI
|DCMD_TCI_OP_JUMP
) << 24) |
3752 printk ("scsi%d: no free slot\n", host
->host_no
);
3754 tmp
->result
= (DID_ERROR
<< 16);
3755 cmd
->next
= (struct NCR53c7x0_cmd
*) hostdata
->free
;
3756 hostdata
->free
= cmd
;
3757 tmp
->scsi_done(tmp
);
3758 restore_flags (flags
);
3763 * If the NCR chip is in an idle state, start it running the scheduler
3764 * immediately. Otherwise, signal the chip to jump to schedule as
3765 * soon as it is idle.
3768 if (hostdata
->idle
) {
3770 hostdata
->state
= STATE_RUNNING
;
3771 NCR53c7x0_write32 (DSP_REG
, virt_to_bus ((void *)hostdata
->schedule
));
3772 if (hostdata
->options
& OPTION_DEBUG_TRACE
)
3773 NCR53c7x0_write8 (DCNTL_REG
, hostdata
->saved_dcntl
|
3774 DCNTL_SSM
| DCNTL_STD
);
3776 NCR53c7x0_write8(hostdata
->istat
, ISTAT_10_SIGP
);
3779 restore_flags(flags
);
3783 * Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata
3784 * *hostdata, Scsi_Cmnd *cmd)
3786 * Purpose : decide if we can pass the given SCSI command on to the
3787 * device in question or not.
3789 * Returns : non-zero when we're busy, 0 when we aren't.
3792 static __inline__
int
3793 busyp (struct Scsi_Host
*host
, struct NCR53c7x0_hostdata
*hostdata
,
3795 /* FIXME : in the future, this needs to accommodate SCSI-II tagged
3796 queuing, and we may be able to play with fairness here a bit.
3798 return hostdata
->busy
[cmd
->target
][cmd
->lun
];
3802 * Function : process_issue_queue (void)
3804 * Purpose : transfer commands from the issue queue to NCR start queue
3805 * of each NCR53c7/8xx in the system, avoiding kernel stack
3806 * overflows when the scsi_done() function is invoked recursively.
3808 * NOTE : process_issue_queue exits with interrupts *disabled*, so the
3809 * caller must reenable them if it desires.
3811 * NOTE : process_issue_queue should be called from both
3812 * NCR53c7x0_queue_command() and from the interrupt handler
3813 * after command completion in case NCR53c7x0_queue_command()
3814 * isn't invoked again but we've freed up resources that are
3819 process_issue_queue (unsigned long flags
) {
3820 Scsi_Cmnd
*tmp
, *prev
;
3821 struct Scsi_Host
*host
;
3822 struct NCR53c7x0_hostdata
*hostdata
;
3826 * We run (with interrupts disabled) until we're sure that none of
3827 * the host adapters have anything that can be done, at which point
3828 * we set process_issue_queue_running to 0 and exit.
3830 * Interrupts are enabled before doing various other internal
3831 * instructions, after we've decided that we need to run through
3837 cli(); /* Freeze request queues */
3839 for (host
= first_host
; host
&& host
->hostt
== the_template
;
3840 host
= host
->next
) {
3841 hostdata
= (struct NCR53c7x0_hostdata
*) host
->hostdata
[0];
3843 if (hostdata
->issue_queue
) {
3844 if (hostdata
->state
== STATE_DISABLED
) {
3845 tmp
= (Scsi_Cmnd
*) hostdata
->issue_queue
;
3846 hostdata
->issue_queue
= (Scsi_Cmnd
*) tmp
->SCp
.ptr
;
3847 tmp
->result
= (DID_BAD_TARGET
<< 16);
3848 if (tmp
->host_scribble
) {
3849 ((struct NCR53c7x0_cmd
*)tmp
->host_scribble
)->next
=
3852 (struct NCR53c7x0_cmd
*)tmp
->host_scribble
;
3853 tmp
->host_scribble
= NULL
;
3855 tmp
->scsi_done (tmp
);
3858 for (tmp
= (Scsi_Cmnd
*) hostdata
->issue_queue
,
3859 prev
= NULL
; tmp
; prev
= tmp
, tmp
= (Scsi_Cmnd
*)
3861 if (!tmp
->host_scribble
||
3862 !busyp (host
, hostdata
, tmp
)) {
3864 prev
->SCp
.ptr
= tmp
->SCp
.ptr
;
3866 hostdata
->issue_queue
= (Scsi_Cmnd
*)
3868 tmp
->SCp
.ptr
= NULL
;
3869 if (tmp
->host_scribble
) {
3870 if (hostdata
->options
& OPTION_DEBUG_QUEUES
)
3871 printk ("scsi%d : moving command for target %d lun %d to start list\n",
3872 host
->host_no
, tmp
->target
, tmp
->lun
);
3875 to_schedule_list (host
, hostdata
,
3876 (struct NCR53c7x0_cmd
*)
3877 tmp
->host_scribble
);
3879 if (((tmp
->result
& 0xff) == 0xff) ||
3880 ((tmp
->result
& 0xff00) == 0xff00)) {
3881 printk ("scsi%d : danger Will Robinson!\n",
3883 tmp
->result
= DID_ERROR
<< 16;
3886 tmp
->scsi_done(tmp
);
3889 } /* if target/lun is not busy */
3890 } /* if hostdata->issue_queue */
3892 restore_flags (flags
);
3895 process_issue_queue_running
= 0;
3899 * Function : static void intr_scsi (struct Scsi_Host *host,
3900 * struct NCR53c7x0_cmd *cmd)
3902 * Purpose : handle all SCSI interrupts, indicated by the setting
3903 * of the SIP bit in the ISTAT register.
3905 * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
3910 intr_scsi (struct Scsi_Host
*host
, struct NCR53c7x0_cmd
*cmd
) {
3911 NCR53c7x0_local_declare();
3912 struct NCR53c7x0_hostdata
*hostdata
=
3913 (struct NCR53c7x0_hostdata
*) host
->hostdata
[0];
3914 unsigned char sstat0_sist0
, sist1
, /* Registers */
3915 fatal
; /* Did a fatal interrupt
3918 NCR53c7x0_local_setup(host
);
3922 sstat0_sist0
= NCR53c7x0_read8(SSTAT0_REG
);
3925 if (hostdata
->options
& OPTION_DEBUG_INTR
)
3926 printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0x\n", host
->host_no
,
3927 sstat0_sist0
, sist1
);
3929 /* 250ms selection timeout */
3930 if (sstat0_sist0
& SSTAT0_700_STO
) {
3932 if (hostdata
->options
& OPTION_DEBUG_INTR
) {
3933 printk ("scsi%d : Selection Timeout\n", host
->host_no
);
3935 printk("scsi%d : target %d, lun %d, command ",
3936 host
->host_no
, cmd
->cmd
->target
, cmd
->cmd
->lun
);
3937 print_command (cmd
->cmd
->cmnd
);
3938 printk("scsi%d : dsp = 0x%x (virt 0x%p)\n", host
->host_no
,
3939 NCR53c7x0_read32(DSP_REG
),
3940 bus_to_virt(NCR53c7x0_read32(DSP_REG
)));
3942 printk("scsi%d : no command\n", host
->host_no
);
3946 * XXX - question : how do we want to handle the Illegal Instruction
3947 * interrupt, which may occur before or after the Selection Timeout
3953 hostdata
->expecting_sto
= 0;
3955 if (hostdata
->test_running
) {
3956 hostdata
->test_running
= 0;
3957 hostdata
->test_completed
= 3;
3959 abnormal_finished(cmd
, DID_BAD_TARGET
<< 16);
3962 hostdata
->intrs
= 0;
3968 * FIXME : in theory, we can also get a UDC when a STO occurs.
3970 if (sstat0_sist0
& SSTAT0_UDC
) {
3973 printk("scsi%d : target %d lun %d unexpected disconnect\n",
3974 host
->host_no
, cmd
->cmd
->target
, cmd
->cmd
->lun
);
3976 abnormal_finished(cmd
, DID_ERROR
<< 16);
3978 printk("scsi%d : unexpected disconnect (no command)\n",
3981 hostdata
->dsp
= (u32
*) hostdata
->schedule
;
3982 hostdata
->dsp_changed
= 1;
3985 /* SCSI PARITY error */
3986 if (sstat0_sist0
& SSTAT0_PAR
) {
3988 if (cmd
&& cmd
->cmd
) {
3989 printk("scsi%d : target %d lun %d parity error.\n",
3990 host
->host_no
, cmd
->cmd
->target
, cmd
->cmd
->lun
);
3991 abnormal_finished (cmd
, DID_PARITY
<< 16);
3993 printk("scsi%d : parity error\n", host
->host_no
);
3994 /* Should send message out, parity error */
3996 /* XXX - Reduce synchronous transfer rate! */
3997 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_initiator_abort
/
3999 hostdata
->dsp_changed
= 1;
4000 /* SCSI GROSS error */
4003 if (sstat0_sist0
& SSTAT0_SGE
) {
4005 printk("scsi%d : gross error, saved2_dsa = 0x%x\n", host
->host_no
,
4006 (unsigned int)hostdata
->saved2_dsa
);
4010 * A SCSI gross error may occur when we have
4012 * - A synchronous offset which causes the SCSI FIFO to be overwritten.
4014 * - A REQ which causes the maximum synchronous offset programmed in
4015 * the SXFER register to be exceeded.
4017 * - A phase change with an outstanding synchronous offset.
4019 * - Residual data in the synchronous data FIFO, with a transfer
4020 * other than a synchronous receive is started.$#
4024 /* XXX Should deduce synchronous transfer rate! */
4025 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_initiator_abort
/
4027 hostdata
->dsp_changed
= 1;
4028 /* Phase mismatch */
4031 if (sstat0_sist0
& SSTAT0_MA
) {
4033 if (hostdata
->options
& OPTION_DEBUG_INTR
)
4034 printk ("scsi%d : SSTAT0_MA\n", host
->host_no
);
4035 intr_phase_mismatch (host
, cmd
);
4039 if (sstat0_sist0
& SIST0_800_RSL
)
4040 printk ("scsi%d : Oh no Mr. Bill!\n", host
->host_no
);
4044 * If a fatal SCSI interrupt occurs, we must insure that the DMA and
4045 * SCSI FIFOs were flushed.
4049 if (!hostdata
->dstat_valid
) {
4050 hostdata
->dstat
= NCR53c7x0_read8(DSTAT_REG
);
4051 hostdata
->dstat_valid
= 1;
4054 if (!(hostdata
->dstat
& DSTAT_DFE
)) {
4055 printk ("scsi%d : DMA FIFO not empty\n", host
->host_no
);
4057 * Really need to check this code for 710 RGH.
4058 * Havn't seen any problems, but maybe we should FLUSH before
4059 * clearing sometimes.
4061 NCR53c7x0_write8 (CTEST8_REG
, CTEST8_10_CLF
);
4062 while (NCR53c7x0_read8 (CTEST8_REG
) & CTEST8_10_CLF
)
4064 hostdata
->dstat
|= DSTAT_DFE
;
4072 * The following implements a cyclic log of instructions executed, if you turn
4073 * TRACE on. It will also print the log for you. Very useful when debugging
4074 * 53c710 support, possibly not really needed any more.
4078 u32 insn_log_index
= 0;
4082 insn_log
[insn_log_index
++] = i
;
4083 if (insn_log_index
== 4096)
4087 void log_insn (u32
*ip
)
4092 if (((*ip
>> 24) & DCMD_TYPE_MASK
) == DCMD_TYPE_MMI
)
4099 int i
= insn_log_index
;
4101 struct Scsi_Host
*host
= first_host
;
4103 while (cnt
< 4096) {
4104 printk ("%08x (+%6x): ", insn_log
[i
], (insn_log
[i
] - (u32
)&(((struct NCR53c7x0_hostdata
*)host
->hostdata
[0])->script
))/4);
4108 if (((insn_log
[i
] >> 24) & DCMD_TYPE_MASK
) == DCMD_TYPE_MMI
)
4113 printk ("%08x ", insn_log
[i
]);
4125 * Function : static void NCR53c7x0_intfly (struct Scsi_Host *host)
4127 * Purpose : Scan command queue for specified host, looking for completed
4130 * Inputs : Scsi_Host pointer.
4132 * This is called from the interrupt handler, when a simulated INTFLY
4137 NCR53c7x0_intfly (struct Scsi_Host
*host
)
4139 NCR53c7x0_local_declare();
4140 struct NCR53c7x0_hostdata
*hostdata
; /* host->hostdata[0] */
4141 struct NCR53c7x0_cmd
*cmd
, /* command which halted */
4143 unsigned long flags
;
4144 char search_found
= 0; /* Got at least one ? */
4146 hostdata
= (struct NCR53c7x0_hostdata
*) host
->hostdata
[0];
4147 NCR53c7x0_local_setup(host
);
4149 if (hostdata
->options
& OPTION_DEBUG_INTR
)
4150 printk ("scsi%d : INTFLY\n", host
->host_no
);
4153 * Traverse our list of running commands, and look
4154 * for those with valid (non-0xff ff) status and message
4155 * bytes encoded in the result which signify command
4162 for (cmd_prev_ptr
= (struct NCR53c7x0_cmd
**)&(hostdata
->running_list
),
4163 cmd
= (struct NCR53c7x0_cmd
*) hostdata
->running_list
; cmd
;
4164 cmd_prev_ptr
= (struct NCR53c7x0_cmd
**) &(cmd
->next
),
4165 cmd
= (struct NCR53c7x0_cmd
*) cmd
->next
)
4170 printk("scsi%d : very weird.\n", host
->host_no
);
4174 if (!(tmp
= cmd
->cmd
)) {
4175 printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n",
4179 /* Copy the result over now; may not be complete,
4180 * but subsequent tests may as well be done on
4183 tmp
->result
= cmd
->result
;
4185 if (((tmp
->result
& 0xff) == 0xff) ||
4186 ((tmp
->result
& 0xff00) == 0xff00))
4191 if (cmd
->bounce
.len
)
4192 memcpy ((void *)cmd
->bounce
.addr
,
4193 (void *)cmd
->bounce
.buf
, cmd
->bounce
.len
);
4195 /* Important - remove from list _before_ done is called */
4197 *cmd_prev_ptr
= (struct NCR53c7x0_cmd
*) cmd
->next
;
4199 --hostdata
->busy
[tmp
->target
][tmp
->lun
];
4200 cmd
->next
= hostdata
->free
;
4201 hostdata
->free
= cmd
;
4203 tmp
->host_scribble
= NULL
;
4205 if (hostdata
->options
& OPTION_DEBUG_INTR
) {
4206 printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ",
4207 host
->host_no
, tmp
->pid
, tmp
->target
, tmp
->lun
, tmp
->result
);
4208 print_command (tmp
->cmnd
);
4211 tmp
->scsi_done(tmp
);
4214 restore_flags(flags
);
4216 if (!search_found
) {
4217 printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
4220 run_process_issue_queue();
4226 * Function : static void NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs)
4228 * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing
4229 * the same IRQ line.
4231 * Inputs : Since we're using the SA_INTERRUPT interrupt handler
4232 * semantics, irq indicates the interrupt which invoked
4235 * On the 710 we simualte an INTFLY with a script interrupt, and the
4236 * script interrupt handler will call back to this function.
4240 NCR53c7x0_intr (int irq
, void *dev_id
, struct pt_regs
* regs
) {
4241 NCR53c7x0_local_declare();
4242 struct Scsi_Host
*host
; /* Host we are looking at */
4243 unsigned char istat
; /* Values of interrupt regs */
4244 struct NCR53c7x0_hostdata
*hostdata
; /* host->hostdata[0] */
4245 struct NCR53c7x0_cmd
*cmd
; /* command which halted */
4249 char buf
[80]; /* Debugging sprintf buffer */
4250 size_t buflen
; /* Length of same */
4253 host
= (struct Scsi_Host
*)dev_id
;
4254 hostdata
= (struct NCR53c7x0_hostdata
*) host
->hostdata
[0];
4255 NCR53c7x0_local_setup(host
);
4258 * Only read istat once per loop, since reading it again will unstack
4262 while ((istat
= NCR53c7x0_read8(hostdata
->istat
)) & (ISTAT_SIP
|ISTAT_DIP
)) {
4263 hostdata
->dsp_changed
= 0;
4264 hostdata
->dstat_valid
= 0;
4265 hostdata
->state
= STATE_HALTED
;
4267 if (NCR53c7x0_read8 (SSTAT2_REG
) & SSTAT2_FF_MASK
)
4268 printk ("scsi%d : SCSI FIFO not empty\n", host
->host_no
);
4271 * NCR53c700 and NCR53c700-66 change the current SCSI
4272 * process, hostdata->ncrcurrent, in the Linux driver so
4273 * cmd = hostdata->ncrcurrent.
4275 * With other chips, we must look through the commands
4276 * executing and find the command structure which
4277 * corresponds to the DSA register.
4280 if (hostdata
->options
& OPTION_700
) {
4281 cmd
= (struct NCR53c7x0_cmd
*) hostdata
->ncrcurrent
;
4283 dsa
= bus_to_virt(NCR53c7x0_read32(DSA_REG
));
4284 for (cmd
= (struct NCR53c7x0_cmd
*) hostdata
->running_list
;
4285 cmd
&& (dsa
+ (hostdata
->dsa_start
/ sizeof(u32
))) != cmd
->dsa
;
4286 cmd
= (struct NCR53c7x0_cmd
*)(cmd
->next
))
4289 if (hostdata
->options
& OPTION_DEBUG_INTR
) {
4291 printk("scsi%d : interrupt for pid %lu, id %d, lun %d ",
4292 host
->host_no
, cmd
->cmd
->pid
, (int) cmd
->cmd
->target
,
4293 (int) cmd
->cmd
->lun
);
4294 print_command (cmd
->cmd
->cmnd
);
4296 printk("scsi%d : no active command\n", host
->host_no
);
4300 if (istat
& ISTAT_SIP
) {
4301 if (hostdata
->options
& OPTION_DEBUG_INTR
)
4302 printk ("scsi%d : ISTAT_SIP\n", host
->host_no
);
4303 intr_scsi (host
, cmd
);
4306 if (istat
& ISTAT_DIP
) {
4307 if (hostdata
->options
& OPTION_DEBUG_INTR
)
4308 printk ("scsi%d : ISTAT_DIP\n", host
->host_no
);
4309 intr_dma (host
, cmd
);
4312 if (!hostdata
->dstat_valid
) {
4313 hostdata
->dstat
= NCR53c7x0_read8(DSTAT_REG
);
4314 hostdata
->dstat_valid
= 1;
4317 if (!(hostdata
->dstat
& DSTAT_DFE
)) {
4318 printk ("scsi%d : DMA FIFO not empty\n", host
->host_no
);
4319 /* Really need to check this out for 710 RGH */
4320 NCR53c7x0_write8 (CTEST8_REG
, CTEST8_10_CLF
);
4321 while (NCR53c7x0_read8 (CTEST8_REG
) & CTEST8_10_CLF
)
4323 hostdata
->dstat
|= DSTAT_DFE
;
4326 if (!hostdata
->idle
&& hostdata
->state
== STATE_HALTED
) {
4327 if (!hostdata
->dsp_changed
)
4328 hostdata
->dsp
= (u32
*)bus_to_virt(NCR53c7x0_read32(DSP_REG
));
4330 printk("scsi%d : new dsp is 0x%lx (virt 0x%p)\n",
4331 host
->host_no
, virt_to_bus(hostdata
->dsp
), hostdata
->dsp
);
4334 hostdata
->state
= STATE_RUNNING
;
4335 NCR53c7x0_write32 (DSP_REG
, virt_to_bus(hostdata
->dsp
));
4336 if (hostdata
->options
& OPTION_DEBUG_TRACE
) {
4338 log_insn (hostdata
->dsp
);
4340 print_insn (host
, hostdata
->dsp
, "t ", 1);
4342 NCR53c7x0_write8 (DCNTL_REG
,
4343 hostdata
->saved_dcntl
| DCNTL_SSM
| DCNTL_STD
);
4351 * Function : static int abort_connected (struct Scsi_Host *host)
4353 * Purpose : Assuming that the NCR SCSI processor is currently
4354 * halted, break the currently established nexus. Clean
4355 * up of the NCR53c7x0_cmd and Scsi_Cmnd structures should
4356 * be done on receipt of the abort interrupt.
4358 * Inputs : host - SCSI host
4363 abort_connected (struct Scsi_Host
*host
) {
4365 NCR53c7x0_local_declare();
4367 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
4369 /* FIXME : this probably should change for production kernels; at the
4370 least, counter should move to a per-host structure. */
4371 static int counter
= 5;
4373 int sstat
, phase
, offset
;
4375 NCR53c7x0_local_setup(host
);
4378 if (--counter
<= 0) {
4383 printk ("scsi%d : DANGER : abort_connected() called \n",
4389 * New strategy : Rather than using a generic abort routine,
4390 * we'll specifically try to source or sink the appropriate
4391 * amount of data for the phase we're currently in (taking into
4392 * account the current synchronous offset)
4395 sstat
= (NCR53c8x0_read8 (SSTAT2_REG
);
4396 offset
= OFFSET (sstat
& SSTAT2_FF_MASK
) >> SSTAT2_FF_SHIFT
;
4397 phase
= sstat
& SSTAT2_PHASE_MASK
;
4401 * MOVE source_or_sink, WHEN CURRENT PHASE
4402 * < repeat for each outstanding byte >
4403 * JUMP send_abort_message
4406 script
= hostdata
->abort_script
= kmalloc (
4407 8 /* instruction size */ * (
4409 (!offset
? 1 : offset
) /* One transfer per outstanding byte */ +
4410 1 /* send abort message */),
4414 #else /* def NEW_ABORT */
4415 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_initiator_abort
/
4417 #endif /* def NEW_ABORT */
4418 hostdata
->dsp_changed
= 1;
4420 /* XXX - need to flag the command as aborted after the abort_connected
4427 * Function : static int datapath_residual (Scsi_Host *host)
4429 * Purpose : return residual data count of what's in the chip.
4431 * Inputs : host - SCSI host
4435 datapath_residual (struct Scsi_Host
*host
) {
4436 NCR53c7x0_local_declare();
4437 int count
, synchronous
, sstat
;
4440 NCR53c7x0_local_setup(host
);
4441 /* COMPAT : the 700 and 700-66 need to use DFIFO_00_BO_MASK */
4442 count
= ((NCR53c7x0_read8 (DFIFO_REG
) & DFIFO_10_BO_MASK
) -
4443 (NCR53c7x0_read32 (DBC_REG
) & DFIFO_10_BO_MASK
)) & DFIFO_10_BO_MASK
;
4444 synchronous
= NCR53c7x0_read8 (SXFER_REG
) & SXFER_MO_MASK
;
4445 /* COMPAT : DDIR is elsewhere on non-'8xx chips. */
4446 ddir
= NCR53c7x0_read8 (CTEST0_REG_700
) & CTEST0_700_DDIR
;
4451 count
+= (NCR53c7x0_read8 (SSTAT2_REG
) & SSTAT2_FF_MASK
) >> SSTAT2_FF_SHIFT
;
4453 if (NCR53c7x0_read8 (SSTAT1_REG
) & SSTAT1_ILF
)
4457 sstat
= NCR53c7x0_read8 (SSTAT1_REG
);
4458 if (sstat
& SSTAT1_OLF
)
4460 if (synchronous
&& (sstat
& SSTAT1_ORF
))
4467 * Function : static const char * sbcl_to_phase (int sbcl)_
4469 * Purpose : Convert SBCL register to user-parsable phase representation
4471 * Inputs : sbcl - value of sbcl register
4476 sbcl_to_phase (int sbcl
) {
4477 switch (sbcl
& SBCL_PHASE_MASK
) {
4478 case SBCL_PHASE_DATAIN
:
4480 case SBCL_PHASE_DATAOUT
:
4482 case SBCL_PHASE_MSGIN
:
4484 case SBCL_PHASE_MSGOUT
:
4486 case SBCL_PHASE_CMDOUT
:
4488 case SBCL_PHASE_STATIN
:
4496 * Function : static const char * sstat2_to_phase (int sstat)_
4498 * Purpose : Convert SSTAT2 register to user-parsable phase representation
4500 * Inputs : sstat - value of sstat register
4505 sstat2_to_phase (int sstat
) {
4506 switch (sstat
& SSTAT2_PHASE_MASK
) {
4507 case SSTAT2_PHASE_DATAIN
:
4509 case SSTAT2_PHASE_DATAOUT
:
4511 case SSTAT2_PHASE_MSGIN
:
4513 case SSTAT2_PHASE_MSGOUT
:
4515 case SSTAT2_PHASE_CMDOUT
:
4517 case SSTAT2_PHASE_STATIN
:
4525 * Function : static void intr_phase_mismatch (struct Scsi_Host *host,
4526 * struct NCR53c7x0_cmd *cmd)
4528 * Purpose : Handle phase mismatch interrupts
4530 * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
4533 * Side effects : The abort_connected() routine is called or the NCR chip
4534 * is restarted, jumping to the command_complete entry point, or
4535 * patching the address and transfer count of the current instruction
4536 * and calling the msg_in entry point as appropriate.
4540 intr_phase_mismatch (struct Scsi_Host
*host
, struct NCR53c7x0_cmd
*cmd
) {
4541 NCR53c7x0_local_declare();
4542 u32 dbc_dcmd
, *dsp
, *dsp_next
;
4543 unsigned char dcmd
, sbcl
;
4544 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
4547 enum {ACTION_ABORT
, ACTION_ABORT_PRINT
, ACTION_CONTINUE
} action
=
4549 const char *where
= NULL
;
4551 NCR53c7x0_local_setup(host
);
4554 * Corrective action is based on where in the SCSI SCRIPT(tm) the error
4555 * occurred, as well as which SCSI phase we are currently in.
4557 dsp_next
= bus_to_virt(NCR53c7x0_read32(DSP_REG
));
4560 * Fetch the current instruction, and remove the operands for easier
4563 dbc_dcmd
= NCR53c7x0_read32(DBC_REG
);
4564 dcmd
= (dbc_dcmd
& 0xff000000) >> 24;
4566 * Like other processors, the NCR adjusts the instruction pointer before
4567 * instruction decode. Set the DSP address back to what it should
4568 * be for this instruction based on its size (2 or 3 32 bit words).
4570 dsp
= dsp_next
- NCR53c7x0_insn_size(dcmd
);
4574 * Read new SCSI phase from the SBCL lines. Since all of our code uses
4575 * a WHEN conditional instead of an IF conditional, we don't need to
4576 * wait for a new REQ.
4578 sbcl
= NCR53c7x0_read8(SBCL_REG
) & SBCL_PHASE_MASK
;
4581 action
= ACTION_ABORT_PRINT
;
4582 where
= "no current command";
4584 * The way my SCSI SCRIPTS(tm) are architected, recoverable phase
4585 * mismatches should only occur where we're doing a multi-byte
4586 * BMI instruction. Specifically, this means
4588 * - select messages (a SCSI-I target may ignore additional messages
4589 * after the IDENTIFY; any target may reject a SDTR or WDTR)
4591 * - command out (targets may send a message to signal an error
4592 * condition, or go into STATUSIN after they've decided
4593 * they don't like the command.
4595 * - reply_message (targets may reject a multi-byte message in the
4598 * - data transfer routines (command completion with buffer space
4599 * left, disconnect message, or error message)
4601 } else if (((dsp
>= cmd
->data_transfer_start
&&
4602 dsp
< cmd
->data_transfer_end
)) || dsp
== (cmd
->residual
+ 2)) {
4603 if ((dcmd
& (DCMD_TYPE_MASK
|DCMD_BMI_OP_MASK
|DCMD_BMI_INDIRECT
|
4604 DCMD_BMI_MSG
|DCMD_BMI_CD
)) == (DCMD_TYPE_BMI
|
4605 DCMD_BMI_OP_MOVE_I
)) {
4606 residual
= datapath_residual (host
);
4607 if (hostdata
->options
& OPTION_DEBUG_DISCONNECT
)
4608 printk ("scsi%d : handling residual transfer (+ %d bytes from DMA FIFO)\n",
4609 host
->host_no
, residual
);
4612 * The first instruction is a CALL to the alternate handler for
4613 * this data transfer phase, so we can do calls to
4614 * munge_msg_restart as we would if control were passed
4615 * from normal dynamic code.
4617 if (dsp
!= cmd
->residual
+ 2) {
4618 cmd
->residual
[0] = ((DCMD_TYPE_TCI
| DCMD_TCI_OP_CALL
|
4619 ((dcmd
& DCMD_BMI_IO
) ? DCMD_TCI_IO
: 0)) << 24) |
4620 DBC_TCI_WAIT_FOR_VALID
| DBC_TCI_COMPARE_PHASE
;
4621 cmd
->residual
[1] = virt_to_bus(hostdata
->script
)
4622 + ((dcmd
& DCMD_BMI_IO
)
4623 ? hostdata
->E_other_in
: hostdata
->E_other_out
);
4627 * The second instruction is the a data transfer block
4628 * move instruction, reflecting the pointer and count at the
4629 * time of the phase mismatch.
4631 cmd
->residual
[2] = dbc_dcmd
+ residual
;
4632 cmd
->residual
[3] = NCR53c7x0_read32(DNAD_REG
) - residual
;
4635 * The third and final instruction is a jump to the instruction
4636 * which follows the instruction which had to be 'split'
4638 if (dsp
!= cmd
->residual
+ 2) {
4639 cmd
->residual
[4] = ((DCMD_TYPE_TCI
|DCMD_TCI_OP_JUMP
)
4640 << 24) | DBC_TCI_TRUE
;
4641 cmd
->residual
[5] = virt_to_bus(dsp_next
);
4645 * For the sake of simplicity, transfer control to the
4646 * conditional CALL at the start of the residual buffer.
4648 hostdata
->dsp
= cmd
->residual
;
4649 hostdata
->dsp_changed
= 1;
4650 action
= ACTION_CONTINUE
;
4652 where
= "non-BMI dynamic DSA code";
4653 action
= ACTION_ABORT_PRINT
;
4655 } else if (dsp
== (hostdata
->script
+ hostdata
->E_select_msgout
/ 4 + 2)) {
4656 /* RGH 290697: Added +2 above, to compensate for the script
4657 * instruction which disables the selection timer. */
4659 NCR53c7x0_write8 (SOCL_REG
, 0);
4662 * Some devices (SQ555 come to mind) grab the IDENTIFY message
4663 * sent on selection, and decide to go into COMMAND OUT phase
4664 * rather than accepting the rest of the messages or rejecting
4665 * them. Handle these devices gracefully.
4667 case SBCL_PHASE_CMDOUT
:
4668 hostdata
->dsp
= dsp
+ 2 /* two _words_ */;
4669 hostdata
->dsp_changed
= 1;
4670 printk ("scsi%d : target %d ignored SDTR and went into COMMAND OUT\n",
4671 host
->host_no
, cmd
->cmd
->target
);
4672 cmd
->flags
&= ~CMD_FLAG_SDTR
;
4673 action
= ACTION_CONTINUE
;
4675 case SBCL_PHASE_MSGIN
:
4676 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_msg_in
/
4678 hostdata
->dsp_changed
= 1;
4679 action
= ACTION_CONTINUE
;
4682 where
="select message out";
4683 action
= ACTION_ABORT_PRINT
;
4686 * Some SCSI devices will interpret a command as they read the bytes
4687 * off the SCSI bus, and may decide that the command is Bogus before
4688 * they've read the entire command off the bus.
4690 } else if (dsp
== hostdata
->script
+ hostdata
->E_cmdout_cmdout
/ sizeof
4692 hostdata
->dsp
= hostdata
->script
+ hostdata
->E_data_transfer
/
4694 hostdata
->dsp_changed
= 1;
4695 action
= ACTION_CONTINUE
;
4696 /* FIXME : we need to handle message reject, etc. within msg_respond. */
4698 } else if (dsp
== hostdata
->script
+ hostdata
->E_reply_message
) {
4700 /* Any other phase mismatches abort the currently executing command. */
4703 where
= "unknown location";
4704 action
= ACTION_ABORT_PRINT
;
4707 /* Flush DMA FIFO */
4708 if (!hostdata
->dstat_valid
) {
4709 hostdata
->dstat
= NCR53c7x0_read8(DSTAT_REG
);
4710 hostdata
->dstat_valid
= 1;
4712 if (!(hostdata
->dstat
& DSTAT_DFE
)) {
4713 /* Really need to check this out for 710 RGH */
4714 NCR53c7x0_write8 (CTEST8_REG
, CTEST8_10_CLF
);
4715 while (NCR53c7x0_read8 (CTEST8_REG
) & CTEST8_10_CLF
);
4716 hostdata
->dstat
|= DSTAT_DFE
;
4720 case ACTION_ABORT_PRINT
:
4721 printk("scsi%d : %s : unexpected phase %s.\n",
4722 host
->host_no
, where
? where
: "unknown location",
4723 sbcl_to_phase(sbcl
));
4725 /* Fall through to ACTION_ABORT */
4727 abort_connected (host
);
4729 case ACTION_CONTINUE
:
4734 if (hostdata
->dsp_changed
) {
4735 printk("scsi%d: new dsp 0x%p\n", host
->host_no
, hostdata
->dsp
);
4736 print_insn (host
, hostdata
->dsp
, "", 1);
4742 * Function : static void intr_bf (struct Scsi_Host *host,
4743 * struct NCR53c7x0_cmd *cmd)
4745 * Purpose : handle BUS FAULT interrupts
4747 * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
4752 intr_bf (struct Scsi_Host
*host
, struct NCR53c7x0_cmd
*cmd
) {
4753 NCR53c7x0_local_declare();
4755 *next_dsp
, /* Current dsp */
4757 dbc_dcmd
; /* DCMD (high eight bits) + DBC */
4758 char *reason
= NULL
;
4759 /* Default behavior is for a silent error, with a retry until we've
4760 exhausted retries. */
4761 enum {MAYBE
, ALWAYS
, NEVER
} retry
= MAYBE
;
4763 NCR53c7x0_local_setup(host
);
4765 dbc_dcmd
= NCR53c7x0_read32 (DBC_REG
);
4766 next_dsp
= bus_to_virt (NCR53c7x0_read32(DSP_REG
));
4767 dsp
= next_dsp
- NCR53c7x0_insn_size ((dbc_dcmd
>> 24) & 0xff);
4768 /* FIXME - check chip type */
4769 dsa
= bus_to_virt (NCR53c7x0_read32(DSA_REG
));
4772 * Bus faults can be caused by either a Bad Address or
4773 * Target Abort. We should check the Received Target Abort
4774 * bit of the PCI status register and Master Abort Bit.
4776 * - Master Abort bit indicates that no device claimed
4777 * the address with DEVSEL within five clocks
4779 * - Target Abort bit indicates that a target claimed it,
4780 * but changed its mind once it saw the byte enables.
4784 /* 53c710, not PCI system */
4791 if (report
&& reason
)
4793 printk(KERN_ALERT
"scsi%d : BUS FAULT reason = %s\n",
4794 host
->host_no
, reason
? reason
: "unknown");
4803 * TODO : we should attempt to recover from any spurious bus
4804 * faults. After X retries, we should figure that things are
4805 * sufficiently wedged, and call NCR53c7xx_reset.
4807 * This code should only get executed once we've decided that we
4811 if (retry
== NEVER
) {
4812 printk(KERN_ALERT
" mail richard@sleepie.demon.co.uk\n");
4818 * Function : static void intr_dma (struct Scsi_Host *host,
4819 * struct NCR53c7x0_cmd *cmd)
4821 * Purpose : handle all DMA interrupts, indicated by the setting
4822 * of the DIP bit in the ISTAT register.
4824 * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
4829 intr_dma (struct Scsi_Host
*host
, struct NCR53c7x0_cmd
*cmd
) {
4830 NCR53c7x0_local_declare();
4831 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
4833 unsigned char dstat
; /* DSTAT */
4835 *next_dsp
, /* Current dsp */
4837 dbc_dcmd
; /* DCMD (high eight bits) + DBC */
4839 unsigned long flags
;
4840 NCR53c7x0_local_setup(host
);
4842 if (!hostdata
->dstat_valid
) {
4843 hostdata
->dstat
= NCR53c7x0_read8(DSTAT_REG
);
4844 hostdata
->dstat_valid
= 1;
4847 dstat
= hostdata
->dstat
;
4849 if (hostdata
->options
& OPTION_DEBUG_INTR
)
4850 printk("scsi%d : DSTAT=0x%x\n", host
->host_no
, (int) dstat
);
4852 dbc_dcmd
= NCR53c7x0_read32 (DBC_REG
);
4853 next_dsp
= bus_to_virt(NCR53c7x0_read32(DSP_REG
));
4854 dsp
= next_dsp
- NCR53c7x0_insn_size ((dbc_dcmd
>> 24) & 0xff);
4855 /* XXX - check chip type */
4856 dsa
= bus_to_virt(NCR53c7x0_read32(DSA_REG
));
4859 * DSTAT_ABRT is the aborted interrupt. This is set whenever the
4860 * SCSI chip is aborted.
4862 * With NCR53c700 and NCR53c700-66 style chips, we should only
4863 * get this when the chip is currently running the accept
4864 * reselect/select code and we have set the abort bit in the
4869 if (dstat
& DSTAT_ABRT
) {
4871 /* XXX - add code here to deal with normal abort */
4872 if ((hostdata
->options
& OPTION_700
) && (hostdata
->state
==
4877 printk(KERN_ALERT
"scsi%d : unexpected abort interrupt at\n"
4878 " ", host
->host_no
);
4879 print_insn (host
, dsp
, KERN_ALERT
"s ", 1);
4885 * DSTAT_SSI is the single step interrupt. Should be generated
4886 * whenever we have single stepped or are tracing.
4889 if (dstat
& DSTAT_SSI
) {
4890 if (hostdata
->options
& OPTION_DEBUG_TRACE
) {
4891 /* Don't print instr. until we write DSP at end of intr function */
4892 } else if (hostdata
->options
& OPTION_DEBUG_SINGLE
) {
4893 print_insn (host
, dsp
, "s ", 0);
4896 /* XXX - should we do this, or can we get away with writing dsp? */
4898 NCR53c7x0_write8 (DCNTL_REG
, (NCR53c7x0_read8(DCNTL_REG
) &
4899 ~DCNTL_SSM
) | DCNTL_STD
);
4900 restore_flags(flags
);
4902 printk(KERN_ALERT
"scsi%d : unexpected single step interrupt at\n"
4903 " ", host
->host_no
);
4904 print_insn (host
, dsp
, KERN_ALERT
"", 1);
4905 printk(KERN_ALERT
" mail drew@PoohSticks.ORG\n");
4911 * DSTAT_IID / DSTAT_OPC (same bit, same meaning, only the name
4912 * is different) is generated whenever an illegal instruction is
4915 * XXX - we may want to emulate INTFLY here, so we can use
4916 * the same SCSI SCRIPT (tm) for NCR53c710 through NCR53c810
4920 if (dstat
& DSTAT_OPC
) {
4922 * Ascertain if this IID interrupts occurred before or after a STO
4923 * interrupt. Since the interrupt handling code now leaves
4924 * DSP unmodified until _after_ all stacked interrupts have been
4925 * processed, reading the DSP returns the original DSP register.
4926 * This means that if dsp lies between the select code, and
4927 * message out following the selection code (where the IID interrupt
4928 * would have to have occurred by due to the implicit wait for REQ),
4929 * we have an IID interrupt resulting from a STO condition and
4933 if (((dsp
>= (hostdata
->script
+ hostdata
->E_select
/ sizeof(u32
))) &&
4934 (dsp
<= (hostdata
->script
+ hostdata
->E_select_msgout
/
4935 sizeof(u32
) + 8))) || (hostdata
->test_running
== 2)) {
4936 if (hostdata
->options
& OPTION_DEBUG_INTR
)
4937 printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STO\n",
4939 if (hostdata
->expecting_iid
) {
4940 hostdata
->expecting_iid
= 0;
4942 if (hostdata
->test_running
== 2) {
4943 hostdata
->test_running
= 0;
4944 hostdata
->test_completed
= 3;
4946 abnormal_finished (cmd
, DID_BAD_TARGET
<< 16);
4948 hostdata
->expecting_sto
= 1;
4951 * We can't guarantee we'll be able to execute the WAIT DISCONNECT
4952 * instruction within the 3.4us of bus free and arbitration delay
4953 * that a target can RESELECT in and assert REQ after we've dropped
4954 * ACK. If this happens, we'll get an illegal instruction interrupt.
4955 * Doing away with the WAIT DISCONNECT instructions broke everything,
4956 * so instead I'll settle for moving one WAIT DISCONNECT a few
4957 * instructions closer to the CLEAR ACK before it to minimize the
4958 * chances of this happening, and handle it if it occurs anyway.
4960 * Simply continue with what we were doing, and control should
4961 * be transfered to the schedule routine which will ultimately
4962 * pass control onto the reselection or selection (not yet)
4965 } else if (dbc_dcmd
== 0x48000000 && (NCR53c7x0_read8 (SBCL_REG
) &
4967 if (!(hostdata
->options
& OPTION_NO_PRINT_RACE
))
4969 printk("scsi%d: REQ before WAIT DISCONNECT IID\n",
4971 hostdata
->options
|= OPTION_NO_PRINT_RACE
;
4974 printk(KERN_ALERT
"scsi%d : illegal instruction\n", host
->host_no
);
4976 printk(KERN_ALERT
" mail Richard@sleepie.demon.co.uk with ALL\n"
4977 " boot messages and diagnostic output\n");
4983 * DSTAT_BF are bus fault errors. DSTAT_800_BF is valid for 710 also.
4986 if (dstat
& DSTAT_800_BF
) {
4987 intr_bf (host
, cmd
);
4992 * DSTAT_SIR interrupts are generated by the execution of
4993 * the INT instruction. Since the exact values available
4994 * are determined entirely by the SCSI script running,
4995 * and are local to a particular script, a unique handler
4996 * is called for each script.
4999 if (dstat
& DSTAT_SIR
) {
5000 if (hostdata
->options
& OPTION_DEBUG_INTR
)
5001 printk ("scsi%d : DSTAT_SIR\n", host
->host_no
);
5002 switch ((tmp
= hostdata
->dstat_sir_intr (host
, cmd
))) {
5003 case SPECIFIC_INT_NOTHING
:
5004 case SPECIFIC_INT_RESTART
:
5006 case SPECIFIC_INT_ABORT
:
5007 abort_connected(host
);
5009 case SPECIFIC_INT_PANIC
:
5010 printk(KERN_ALERT
"scsi%d : failure at ", host
->host_no
);
5011 print_insn (host
, dsp
, KERN_ALERT
"", 1);
5012 printk(KERN_ALERT
" dstat_sir_intr() returned SPECIFIC_INT_PANIC\n");
5015 case SPECIFIC_INT_BREAK
:
5016 intr_break (host
, cmd
);
5019 printk(KERN_ALERT
"scsi%d : failure at ", host
->host_no
);
5020 print_insn (host
, dsp
, KERN_ALERT
"", 1);
5021 printk(KERN_ALERT
" dstat_sir_intr() returned unknown value %d\n",
5029 * Function : static int print_insn (struct Scsi_Host *host,
5030 * u32 *insn, int kernel)
5032 * Purpose : print numeric representation of the instruction pointed
5033 * to by insn to the debugging or kernel message buffer
5036 * If desired, a user level program can interpret this
5039 * Inputs : host, insn - host, pointer to instruction, prefix -
5040 * string to prepend, kernel - use printk instead of debugging buffer.
5042 * Returns : size, in u32s, of instruction printed.
5046 * FIXME: should change kernel parameter so that it takes an ENUM
5047 * specifying severity - either KERN_ALERT or KERN_PANIC so
5048 * all panic messages are output with the same severity.
5052 print_insn (struct Scsi_Host
*host
, const u32
*insn
,
5053 const char *prefix
, int kernel
) {
5054 char buf
[160], /* Temporary buffer and pointer. ICKY
5055 arbitrary length. */
5059 unsigned char dcmd
; /* dcmd register for *insn */
5063 * Check to see if the instruction pointer is not bogus before
5064 * indirecting through it; avoiding red-zone at start of
5067 * FIXME: icky magic needs to happen here on non-intel boxes which
5068 * don't have kernel memory mapped in like this. Might be reasonable
5072 if (MAP_NR(insn
) < 1 || MAP_NR(insn
+ 8) > MAP_NR(high_memory
) ||
5073 ((((dcmd
= (insn
[0] >> 24) & 0xff) & DCMD_TYPE_MMI
) == DCMD_TYPE_MMI
) &&
5074 MAP_NR(insn
+ 12) > MAP_NR(high_memory
))) {
5076 sprintf (buf
, "%s%p: address out of range\n",
5080 * FIXME : (void *) cast in virt_to_bus should be unnecessary, because
5081 * it should take const void * as argument.
5083 #if !defined(CONFIG_MVME16x) && !defined(CONFIG_BVME6000)
5084 sprintf(buf
, "%s0x%lx (virt 0x%p) : 0x%08x 0x%08x (virt 0x%p)",
5085 (prefix
? prefix
: ""), virt_to_bus((void *) insn
), insn
,
5086 insn
[0], insn
[1], bus_to_virt (insn
[1]));
5088 /* Remove virtual addresses to reduce output, as they are the same */
5089 sprintf(buf
, "%s0x%x (+%x) : 0x%08x 0x%08x",
5090 (prefix
? prefix
: ""), (u32
)insn
, ((u32
)insn
-
5091 (u32
)&(((struct NCR53c7x0_hostdata
*)host
->hostdata
[0])->script
))/4,
5094 tmp
= buf
+ strlen(buf
);
5095 if ((dcmd
& DCMD_TYPE_MASK
) == DCMD_TYPE_MMI
) {
5096 #if !defined(CONFIG_MVME16x) && !defined(CONFIG_BVME6000)
5097 sprintf (tmp
, " 0x%08x (virt 0x%p)\n", insn
[2],
5098 bus_to_virt(insn
[2]));
5100 /* Remove virtual addr to reduce output, as it is the same */
5101 sprintf (tmp
, " 0x%08x\n", insn
[2]);
5105 sprintf (tmp
, "\n");
5114 size_t len
= strlen(buf
);
5115 debugger_kernel_write(host
, buf
, len
);
5122 * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd)
5124 * Purpose : Abort an errant SCSI command, doing all necessary
5125 * cleanup of the issue_queue, running_list, shared Linux/NCR
5126 * dsa issue and reconnect queues.
5128 * Inputs : cmd - command to abort, code - entire result field
5130 * Returns : 0 on success, -1 on failure.
5134 NCR53c7xx_abort (Scsi_Cmnd
*cmd
) {
5135 NCR53c7x0_local_declare();
5136 struct Scsi_Host
*host
= cmd
->host
;
5137 struct NCR53c7x0_hostdata
*hostdata
= host
? (struct NCR53c7x0_hostdata
*)
5138 host
->hostdata
[0] : NULL
;
5139 unsigned long flags
;
5140 struct NCR53c7x0_cmd
*curr
, **prev
;
5141 Scsi_Cmnd
*me
, **last
;
5143 static long cache_pid
= -1;
5148 printk ("Bogus SCSI command pid %ld; no host structure\n",
5150 return SCSI_ABORT_ERROR
;
5151 } else if (!hostdata
) {
5152 printk ("Bogus SCSI host %d; no hostdata\n", host
->host_no
);
5153 return SCSI_ABORT_ERROR
;
5155 NCR53c7x0_local_setup(host
);
5158 * CHECK : I don't think that reading ISTAT will unstack any interrupts,
5159 * since we need to write the INTF bit to clear it, and SCSI/DMA
5160 * interrupts don't clear until we read SSTAT/SIST and DSTAT registers.
5162 * See that this is the case. Appears to be correct on the 710, at least.
5164 * I suspect that several of our failures may be coming from a new fatal
5165 * interrupt (possibly due to a phase mismatch) happening after we've left
5166 * the interrupt handler, but before the PIC has had the interrupt condition
5170 if (NCR53c7x0_read8(hostdata
->istat
) & (ISTAT_DIP
|ISTAT_SIP
)) {
5171 printk ("scsi%d : dropped interrupt for command %ld\n", host
->host_no
,
5173 NCR53c7x0_intr (host
->irq
, NULL
, NULL
);
5174 return SCSI_ABORT_BUSY
;
5180 if (cache_pid
== cmd
->pid
)
5181 panic ("scsi%d : bloody fetus %d\n", host
->host_no
, cmd
->pid
);
5183 cache_pid
= cmd
->pid
;
5188 * The command could be hiding in the issue_queue. This would be very
5189 * nice, as commands can't be moved from the high level driver's issue queue
5190 * into the shared queue until an interrupt routine is serviced, and this
5193 * If this is the case, we don't have to worry about anything - we simply
5194 * pull the command out of the old queue, and call it aborted.
5197 for (me
= (Scsi_Cmnd
*) hostdata
->issue_queue
,
5198 last
= (Scsi_Cmnd
**) &(hostdata
->issue_queue
);
5199 me
&& me
!= cmd
; last
= (Scsi_Cmnd
**)&(me
->SCp
.ptr
),
5200 me
= (Scsi_Cmnd
*)me
->SCp
.ptr
);
5203 *last
= (Scsi_Cmnd
*) me
->SCp
.ptr
;
5204 if (me
->host_scribble
) {
5205 ((struct NCR53c7x0_cmd
*)me
->host_scribble
)->next
= hostdata
->free
;
5206 hostdata
->free
= (struct NCR53c7x0_cmd
*) me
->host_scribble
;
5207 me
->host_scribble
= NULL
;
5209 cmd
->result
= DID_ABORT
<< 16;
5210 cmd
->scsi_done(cmd
);
5211 printk ("scsi%d : found command %ld in Linux issue queue\n",
5212 host
->host_no
, me
->pid
);
5213 restore_flags(flags
);
5214 run_process_issue_queue();
5215 return SCSI_ABORT_SUCCESS
;
5219 * That failing, the command could be in our list of already executing
5220 * commands. If this is the case, drastic measures are called for.
5223 for (curr
= (struct NCR53c7x0_cmd
*) hostdata
->running_list
,
5224 prev
= (struct NCR53c7x0_cmd
**) &(hostdata
->running_list
);
5225 curr
&& curr
->cmd
!= cmd
; prev
= (struct NCR53c7x0_cmd
**)
5226 &(curr
->next
), curr
= (struct NCR53c7x0_cmd
*) curr
->next
);
5229 if ((curr
->result
& 0xff) != 0xff && (curr
->result
& 0xff00) != 0xff00) {
5230 cmd
->result
= curr
->result
;
5232 *prev
= (struct NCR53c7x0_cmd
*) curr
->next
;
5233 curr
->next
= (struct NCR53c7x0_cmd
*) hostdata
->free
;
5234 cmd
->host_scribble
= NULL
;
5235 hostdata
->free
= curr
;
5236 cmd
->scsi_done(cmd
);
5237 printk ("scsi%d : found finished command %ld in running list\n",
5238 host
->host_no
, cmd
->pid
);
5239 restore_flags(flags
);
5240 return SCSI_ABORT_NOT_RUNNING
;
5242 printk ("scsi%d : DANGER : command running, can not abort.\n",
5243 cmd
->host
->host_no
);
5244 restore_flags(flags
);
5245 return SCSI_ABORT_BUSY
;
5250 * And if we couldn't find it in any of our queues, it must have been
5251 * a dropped interrupt.
5254 curr
= (struct NCR53c7x0_cmd
*) cmd
->host_scribble
;
5256 curr
->next
= hostdata
->free
;
5257 hostdata
->free
= curr
;
5258 cmd
->host_scribble
= NULL
;
5261 if (curr
== NULL
|| ((curr
->result
& 0xff00) == 0xff00) ||
5262 ((curr
->result
& 0xff) == 0xff)) {
5263 printk ("scsi%d : did this command ever run?\n", host
->host_no
);
5264 cmd
->result
= DID_ABORT
<< 16;
5266 printk ("scsi%d : probably lost INTFLY, normal completion\n",
5268 cmd
->result
= curr
->result
;
5270 * FIXME : We need to add an additional flag which indicates if a
5271 * command was ever counted as BUSY, so if we end up here we can
5272 * decrement the busy count if and only if it is necessary.
5274 --hostdata
->busy
[cmd
->target
][cmd
->lun
];
5276 restore_flags(flags
);
5277 cmd
->scsi_done(cmd
);
5280 * We need to run process_issue_queue since termination of this command
5281 * may allow another queued command to execute first?
5283 return SCSI_ABORT_NOT_RUNNING
;
5287 * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd)
5289 * Purpose : perform a hard reset of the SCSI bus and NCR
5292 * Inputs : cmd - command which caused the SCSI RESET
5294 * Returns : 0 on success.
5298 NCR53c7xx_reset (Scsi_Cmnd
*cmd
, unsigned int reset_flags
) {
5299 NCR53c7x0_local_declare();
5300 unsigned long flags
;
5302 struct NCR53c7x0_cmd
* c
;
5305 * When we call scsi_done(), it's going to wake up anything sleeping on the
5306 * resources which were in use by the aborted commands, and we'll start to
5309 * We can't let this happen until after we've re-initialized the driver
5310 * structures, and can't reinitialize those structures until after we've
5311 * dealt with their contents.
5313 * So, we need to find all of the commands which were running, stick
5314 * them on a linked list of completed commands (we'll use the host_scribble
5315 * pointer), do our reinitialization, and then call the done function for
5318 Scsi_Cmnd
*nuke_list
= NULL
;
5319 struct Scsi_Host
*host
= cmd
->host
;
5320 struct NCR53c7x0_hostdata
*hostdata
=
5321 (struct NCR53c7x0_hostdata
*) host
->hostdata
[0];
5323 NCR53c7x0_local_setup(host
);
5328 dump_events (host
, 30);
5329 ncr_scsi_reset (host
);
5330 for (tmp
= nuke_list
= return_outstanding_commands (host
, 1 /* free */,
5331 0 /* issue */ ); tmp
; tmp
= (Scsi_Cmnd
*) tmp
->SCp
.buffer
)
5338 * If we didn't find the command which caused this reset in our running
5339 * list, then we've lost it. See that it terminates normally anyway.
5342 c
= (struct NCR53c7x0_cmd
*) cmd
->host_scribble
;
5344 cmd
->host_scribble
= NULL
;
5345 c
->next
= hostdata
->free
;
5348 printk ("scsi%d: lost command %ld\n", host
->host_no
, cmd
->pid
);
5349 cmd
->SCp
.buffer
= (struct scatterlist
*) nuke_list
;
5353 NCR53c7x0_driver_init (host
);
5354 hostdata
->soft_reset (host
);
5355 if (hostdata
->resets
== 0)
5357 else if (hostdata
->resets
!= -1)
5359 restore_flags(flags
);
5360 for (; nuke_list
; nuke_list
= tmp
) {
5361 tmp
= (Scsi_Cmnd
*) nuke_list
->SCp
.buffer
;
5362 nuke_list
->result
= DID_RESET
<< 16;
5363 nuke_list
->scsi_done (nuke_list
);
5365 restore_flags(flags
);
5366 return SCSI_RESET_SUCCESS
;
5370 * The NCR SDMS bios follows Annex A of the SCSI-CAM draft, and
5371 * therefore shares the scsicam_bios_param function.
5375 * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn)
5377 * Purpose : convert instructions stored at NCR pointer into data
5380 * Inputs : cmd - SCSI command; insn - pointer to instruction. Either current
5381 * DSP, or saved data pointer.
5383 * Returns : offset on success, -1 on failure.
5388 insn_to_offset (Scsi_Cmnd
*cmd
, u32
*insn
) {
5389 struct NCR53c7x0_hostdata
*hostdata
=
5390 (struct NCR53c7x0_hostdata
*) cmd
->host
->hostdata
[0];
5391 struct NCR53c7x0_cmd
*ncmd
=
5392 (struct NCR53c7x0_cmd
*) cmd
->host_scribble
;
5393 int offset
= 0, buffers
;
5394 struct scatterlist
*segment
;
5399 * With the current code implementation, if the insn is inside dynamically
5400 * generated code, the data pointer will be the instruction preceding
5401 * the next transfer segment.
5404 if (!check_address ((unsigned long) ncmd
, sizeof (struct NCR53c7x0_cmd
)) &&
5405 ((insn
>= ncmd
->data_transfer_start
&&
5406 insn
< ncmd
->data_transfer_end
) ||
5407 (insn
>= ncmd
->residual
&&
5408 insn
< (ncmd
->residual
+
5409 sizeof(ncmd
->residual
))))) {
5410 ptr
= bus_to_virt(insn
[3]);
5412 if ((buffers
= cmd
->use_sg
)) {
5414 segment
= (struct scatterlist
*) cmd
->buffer
;
5415 buffers
&& !((found
= ((ptr
>= segment
->address
) &&
5416 (ptr
< (segment
->address
+ segment
->length
)))));
5417 --buffers
, offset
+= segment
->length
, ++segment
)
5419 printk("scsi%d: comparing 0x%p to 0x%p\n",
5420 cmd
->host
->host_no
, saved
, segment
->address
);
5424 offset
+= ptr
- segment
->address
;
5427 offset
= ptr
- (char *) (cmd
->request_buffer
);
5429 } else if ((insn
>= hostdata
->script
+
5430 hostdata
->E_data_transfer
/ sizeof(u32
)) &&
5431 (insn
<= hostdata
->script
+
5432 hostdata
->E_end_data_transfer
/ sizeof(u32
))) {
5436 return found
? offset
: -1;
5442 * Function : void print_progress (Scsi_Cmnd *cmd)
5444 * Purpose : print the current location of the saved data pointer
5446 * Inputs : cmd - command we are interested in
5451 print_progress (Scsi_Cmnd
*cmd
) {
5452 NCR53c7x0_local_declare();
5453 struct NCR53c7x0_cmd
*ncmd
=
5454 (struct NCR53c7x0_cmd
*) cmd
->host_scribble
;
5458 NCR53c7x0_local_setup (cmd
->host
);
5460 if (check_address ((unsigned long) ncmd
,sizeof (struct NCR53c7x0_cmd
)) == 0)
5462 printk("\nNCR53c7x0_cmd fields:\n");
5463 printk(" bounce.len=0x%x, addr=0x%0x, buf[]=0x%02x %02x %02x %02x\n",
5464 ncmd
->bounce
.len
, ncmd
->bounce
.addr
, ncmd
->bounce
.buf
[0],
5465 ncmd
->bounce
.buf
[1], ncmd
->bounce
.buf
[2], ncmd
->bounce
.buf
[3]);
5466 printk(" result=%04x, cdb[0]=0x%02x\n", ncmd
->result
, ncmd
->cmnd
[0]);
5469 for (i
= 0; i
< 2; ++i
) {
5470 if (check_address ((unsigned long) ncmd
,
5471 sizeof (struct NCR53c7x0_cmd
)) == -1)
5475 ptr
= bus_to_virt(ncmd
->saved_data_pointer
);
5478 ptr
= bus_to_virt (NCR53c7x0_read32 (DSP_REG
) -
5479 NCR53c7x0_insn_size (NCR53c7x0_read8 (DCMD_REG
)) *
5482 offset
= insn_to_offset (cmd
, ptr
);
5485 printk ("scsi%d : %s data pointer at offset %d\n",
5486 cmd
->host
->host_no
, where
, offset
);
5489 printk ("scsi%d : can't determine %s data pointer offset\n",
5490 cmd
->host
->host_no
, where
);
5492 size
= print_insn (cmd
->host
,
5493 bus_to_virt(ncmd
->saved_data_pointer
), "", 1);
5494 print_insn (cmd
->host
,
5495 bus_to_virt(ncmd
->saved_data_pointer
) + size
* sizeof(u32
),
5504 print_dsa (struct Scsi_Host
*host
, u32
*dsa
, const char *prefix
) {
5505 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
5511 if (check_address ((unsigned long) dsa
, hostdata
->dsa_end
-
5512 hostdata
->dsa_start
) == -1) {
5513 printk("scsi%d : bad dsa virt 0x%p\n", host
->host_no
, dsa
);
5516 printk("%sscsi%d : dsa at phys 0x%lx (virt 0x%p)\n"
5517 " + %d : dsa_msgout length = %u, data = 0x%x (virt 0x%p)\n" ,
5518 prefix
? prefix
: "",
5519 host
->host_no
, virt_to_bus (dsa
), dsa
, hostdata
->dsa_msgout
,
5520 dsa
[hostdata
->dsa_msgout
/ sizeof(u32
)],
5521 dsa
[hostdata
->dsa_msgout
/ sizeof(u32
) + 1],
5522 bus_to_virt (dsa
[hostdata
->dsa_msgout
/ sizeof(u32
) + 1]));
5525 * Only print messages if they're sane in length so we don't
5526 * blow the kernel printk buffer on something which won't buy us
5530 if (dsa
[hostdata
->dsa_msgout
/ sizeof(u32
)] <
5531 sizeof (hostdata
->free
->select
))
5532 for (i
= dsa
[hostdata
->dsa_msgout
/ sizeof(u32
)],
5533 ptr
= bus_to_virt (dsa
[hostdata
->dsa_msgout
/ sizeof(u32
) + 1]);
5534 i
> 0 && !check_address ((unsigned long) ptr
, 1);
5535 ptr
+= len
, i
-= len
) {
5537 len
= print_msg (ptr
);
5543 printk(" + %d : select_indirect = 0x%x\n",
5544 hostdata
->dsa_select
, dsa
[hostdata
->dsa_select
/ sizeof(u32
)]);
5545 cmd
= (Scsi_Cmnd
*) bus_to_virt(dsa
[hostdata
->dsa_cmnd
/ sizeof(u32
)]);
5546 printk(" + %d : dsa_cmnd = 0x%x ", hostdata
->dsa_cmnd
,
5547 (u32
) virt_to_bus(cmd
));
5548 /* XXX Maybe we should access cmd->host_scribble->result here. RGH */
5550 printk(" result = 0x%x, target = %d, lun = %d, cmd = ",
5551 cmd
->result
, cmd
->target
, cmd
->lun
);
5552 print_command(cmd
->cmnd
);
5555 printk(" + %d : dsa_next = 0x%x\n", hostdata
->dsa_next
,
5556 dsa
[hostdata
->dsa_next
/ sizeof(u32
)]);
5558 printk("scsi%d target %d : sxfer_sanity = 0x%x, scntl3_sanity = 0x%x\n"
5560 host
->host_no
, cmd
->target
,
5561 hostdata
->sync
[cmd
->target
].sxfer_sanity
,
5562 hostdata
->sync
[cmd
->target
].scntl3_sanity
);
5563 for (i
= 0; i
< (sizeof(hostdata
->sync
[cmd
->target
].script
) / 4); ++i
)
5564 printk ("0x%x ", hostdata
->sync
[cmd
->target
].script
[i
]);
5566 print_progress (cmd
);
5570 * Function : void print_queues (Scsi_Host *host)
5572 * Purpose : print the contents of the NCR issue and reconnect queues
5574 * Inputs : host - SCSI host we are interested in
5579 print_queues (struct Scsi_Host
*host
) {
5580 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
5582 u32
*dsa
, *next_dsa
;
5583 volatile u32
*ncrcurrent
;
5585 Scsi_Cmnd
*cmd
, *next_cmd
;
5586 unsigned long flags
;
5588 printk ("scsi%d : issue queue\n", host
->host_no
);
5590 for (left
= host
->can_queue
, cmd
= (Scsi_Cmnd
*) hostdata
->issue_queue
;
5593 next_cmd
= (Scsi_Cmnd
*) cmd
->SCp
.ptr
;
5596 if (cmd
->host_scribble
) {
5597 if (check_address ((unsigned long) (cmd
->host_scribble
),
5598 sizeof (cmd
->host_scribble
)) == -1)
5599 printk ("scsi%d: scsi pid %ld bad pointer to NCR53c7x0_cmd\n",
5600 host
->host_no
, cmd
->pid
);
5601 /* print_dsa does sanity check on address, no need to check */
5603 print_dsa (host
, ((struct NCR53c7x0_cmd
*) cmd
->host_scribble
)
5606 printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
5607 host
->host_no
, cmd
->pid
, cmd
->target
, cmd
->lun
);
5608 restore_flags(flags
);
5612 printk ("scsi%d : loop detected in issue queue\n",
5617 * Traverse the NCR reconnect and start DSA structures, printing out
5618 * each element until we hit the end or detect a loop. Currently,
5619 * the reconnect structure is a linked list; and the start structure
5620 * is an array. Eventually, the reconnect structure will become a
5621 * list as well, since this simplifies the code.
5624 printk ("scsi%d : schedule dsa array :\n", host
->host_no
);
5625 for (left
= host
->can_queue
, ncrcurrent
= hostdata
->schedule
;
5626 left
> 0; ncrcurrent
+= 2, --left
)
5627 if (ncrcurrent
[0] != hostdata
->NOP_insn
)
5628 /* FIXME : convert pointer to dsa_begin to pointer to dsa. */
5629 print_dsa (host
, bus_to_virt (ncrcurrent
[1] -
5630 (hostdata
->E_dsa_code_begin
-
5631 hostdata
->E_dsa_code_template
)), "");
5632 printk ("scsi%d : end schedule dsa array\n", host
->host_no
);
5634 printk ("scsi%d : reconnect_dsa_head :\n", host
->host_no
);
5636 for (left
= host
->can_queue
,
5637 dsa
= bus_to_virt (hostdata
->reconnect_dsa_head
);
5642 if (check_address ((unsigned long) dsa
, sizeof(dsa
)) == -1) {
5643 printk ("scsi%d: bad DSA pointer 0x%p", host
->host_no
,
5649 next_dsa
= bus_to_virt(dsa
[hostdata
->dsa_next
/ sizeof(u32
)]);
5650 print_dsa (host
, dsa
, "");
5652 restore_flags(flags
);
5654 printk ("scsi%d : end reconnect_dsa_head\n", host
->host_no
);
5656 printk("scsi%d: possible loop in ncr reconnect list\n",
5661 print_lots (struct Scsi_Host
*host
) {
5662 NCR53c7x0_local_declare();
5663 struct NCR53c7x0_hostdata
*hostdata
=
5664 (struct NCR53c7x0_hostdata
*) host
->hostdata
[0];
5665 u32
*dsp_next
, *dsp
, *dsa
, dbc_dcmd
;
5666 unsigned char dcmd
, sbcl
;
5668 NCR53c7x0_local_setup(host
);
5670 if ((dsp_next
= bus_to_virt(NCR53c7x0_read32 (DSP_REG
)))) {
5671 dbc_dcmd
= NCR53c7x0_read32(DBC_REG
);
5672 dcmd
= (dbc_dcmd
& 0xff000000) >> 24;
5673 dsp
= dsp_next
- NCR53c7x0_insn_size(dcmd
);
5674 dsa
= bus_to_virt(NCR53c7x0_read32(DSA_REG
));
5675 sbcl
= NCR53c7x0_read8 (SBCL_REG
);
5678 * For the 53c710, the following will report value 0 for SCNTL3
5679 * and STEST0 - we don't have these registers.
5681 printk ("scsi%d : DCMD|DBC=0x%x, DNAD=0x%x (virt 0x%p)\n"
5682 " DSA=0x%lx (virt 0x%p)\n"
5683 " DSPS=0x%x, TEMP=0x%x (virt 0x%p), DMODE=0x%x\n"
5684 " SXFER=0x%x, SCNTL3=0x%x\n"
5685 " %s%s%sphase=%s, %d bytes in SCSI FIFO\n"
5686 " SCRATCH=0x%x, saved2_dsa=0x%0lx\n",
5687 host
->host_no
, dbc_dcmd
, NCR53c7x0_read32(DNAD_REG
),
5688 bus_to_virt(NCR53c7x0_read32(DNAD_REG
)),
5689 virt_to_bus(dsa
), dsa
,
5690 NCR53c7x0_read32(DSPS_REG
), NCR53c7x0_read32(TEMP_REG
),
5691 bus_to_virt (NCR53c7x0_read32(TEMP_REG
)),
5692 (int) NCR53c7x0_read8(hostdata
->dmode
),
5693 (int) NCR53c7x0_read8(SXFER_REG
),
5694 ((hostdata
->chip
/ 100) == 8) ?
5695 (int) NCR53c7x0_read8(SCNTL3_REG_800
) : 0,
5696 (sbcl
& SBCL_BSY
) ? "BSY " : "",
5697 (sbcl
& SBCL_SEL
) ? "SEL " : "",
5698 (sbcl
& SBCL_REQ
) ? "REQ " : "",
5699 sstat2_to_phase(NCR53c7x0_read8 (((hostdata
->chip
/ 100) == 8) ?
5700 SSTAT1_REG
: SSTAT2_REG
)),
5701 (NCR53c7x0_read8 ((hostdata
->chip
/ 100) == 8 ?
5702 SSTAT1_REG
: SSTAT2_REG
) & SSTAT2_FF_MASK
) >> SSTAT2_FF_SHIFT
,
5703 ((hostdata
->chip
/ 100) == 8) ? NCR53c7x0_read8 (STEST0_REG_800
) :
5704 NCR53c7x0_read32(SCRATCHA_REG_800
),
5705 hostdata
->saved2_dsa
);
5706 printk ("scsi%d : DSP 0x%lx (virt 0x%p) ->\n", host
->host_no
,
5707 virt_to_bus(dsp
), dsp
);
5708 for (i
= 6; i
> 0; --i
, dsp
+= size
)
5709 size
= print_insn (host
, dsp
, "", 1);
5710 if (NCR53c7x0_read8 (SCNTL1_REG
) & SCNTL1_CON
) {
5711 if ((hostdata
->chip
/ 100) == 8)
5712 printk ("scsi%d : connected (SDID=0x%x, SSID=0x%x)\n",
5713 host
->host_no
, NCR53c7x0_read8 (SDID_REG_800
),
5714 NCR53c7x0_read8 (SSID_REG_800
));
5716 printk ("scsi%d : connected (SDID=0x%x)\n",
5717 host
->host_no
, NCR53c7x0_read8 (SDID_REG_700
));
5718 print_dsa (host
, dsa
, "");
5722 print_queues (host
);
5728 * Function : static int shutdown (struct Scsi_Host *host)
5730 * Purpose : does a clean (we hope) shutdown of the NCR SCSI
5731 * chip. Use prior to dumping core, unloading the NCR driver,
5733 * Returns : 0 on success
5736 shutdown (struct Scsi_Host
*host
) {
5737 NCR53c7x0_local_declare();
5738 unsigned long flags
;
5739 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
5741 NCR53c7x0_local_setup(host
);
5744 /* Get in a state where we can reset the SCSI bus */
5746 ncr_scsi_reset (host
);
5747 hostdata
->soft_reset(host
);
5750 restore_flags (flags
);
5755 * Function : void ncr_scsi_reset (struct Scsi_Host *host)
5757 * Purpose : reset the SCSI bus.
5761 ncr_scsi_reset (struct Scsi_Host
*host
) {
5762 NCR53c7x0_local_declare();
5763 unsigned long flags
;
5764 NCR53c7x0_local_setup(host
);
5767 NCR53c7x0_write8(SCNTL1_REG
, SCNTL1_RST
);
5768 udelay(25); /* Minimum amount of time to assert RST */
5769 NCR53c7x0_write8(SCNTL1_REG
, 0);
5770 restore_flags (flags
);
5774 * Function : void hard_reset (struct Scsi_Host *host)
5779 hard_reset (struct Scsi_Host
*host
) {
5780 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
5782 unsigned long flags
;
5785 ncr_scsi_reset(host
);
5786 NCR53c7x0_driver_init (host
);
5787 if (hostdata
->soft_reset
)
5788 hostdata
->soft_reset (host
);
5789 restore_flags(flags
);
5794 * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host,
5795 * int free, int issue)
5797 * Purpose : return a linked list (using the SCp.buffer field as next,
5798 * so we don't perturb hostdata. We don't use a field of the
5799 * NCR53c7x0_cmd structure since we may not have allocated one
5800 * for the command causing the reset.) of Scsi_Cmnd structures that
5801 * had propogated below the Linux issue queue level. If free is set,
5802 * free the NCR53c7x0_cmd structures which are associated with
5803 * the Scsi_Cmnd structures, and clean up any internal
5804 * NCR lists that the commands were on. If issue is set,
5805 * also return commands in the issue queue.
5807 * Returns : linked list of commands
5809 * NOTE : the caller should insure that the NCR chip is halted
5810 * if the free flag is set.
5814 return_outstanding_commands (struct Scsi_Host
*host
, int free
, int issue
) {
5815 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
5817 struct NCR53c7x0_cmd
*c
;
5820 Scsi_Cmnd
*list
= NULL
, *tmp
;
5821 for (c
= (struct NCR53c7x0_cmd
*) hostdata
->running_list
; c
;
5822 c
= (struct NCR53c7x0_cmd
*) c
->next
) {
5823 if (c
->cmd
->SCp
.buffer
) {
5824 printk ("scsi%d : loop detected in running list!\n", host
->host_no
);
5827 printk ("Duh? Bad things happening in the NCR driver\n");
5831 c
->cmd
->SCp
.buffer
= (struct scatterlist
*) list
;
5834 c
->next
= hostdata
->free
;
5840 for (i
= 0, ncrcurrent
= (u32
*) hostdata
->schedule
;
5841 i
< host
->can_queue
; ++i
, ncrcurrent
+= 2) {
5842 ncrcurrent
[0] = hostdata
->NOP_insn
;
5843 ncrcurrent
[1] = 0xdeadbeef;
5845 hostdata
->ncrcurrent
= NULL
;
5849 for (tmp
= (Scsi_Cmnd
*) hostdata
->issue_queue
; tmp
; tmp
= tmp
->next
) {
5850 if (tmp
->SCp
.buffer
) {
5851 printk ("scsi%d : loop detected in issue queue!\n",
5855 tmp
->SCp
.buffer
= (struct scatterlist
*) list
;
5859 hostdata
->issue_queue
= NULL
;
5866 * Function : static int disable (struct Scsi_Host *host)
5868 * Purpose : disables the given NCR host, causing all commands
5869 * to return a driver error. Call this so we can unload the
5870 * module during development and try again. Eventually,
5871 * we should be able to find clean workarounds for these
5874 * Inputs : host - hostadapter to twiddle
5876 * Returns : 0 on success.
5880 disable (struct Scsi_Host
*host
) {
5881 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
5883 unsigned long flags
;
5884 Scsi_Cmnd
*nuke_list
, *tmp
;
5887 if (hostdata
->state
!= STATE_HALTED
)
5889 nuke_list
= return_outstanding_commands (host
, 1 /* free */, 1 /* issue */);
5891 hostdata
->state
= STATE_DISABLED
;
5892 restore_flags(flags
);
5893 printk ("scsi%d : nuking commands\n", host
->host_no
);
5894 for (; nuke_list
; nuke_list
= tmp
) {
5895 tmp
= (Scsi_Cmnd
*) nuke_list
->SCp
.buffer
;
5896 nuke_list
->result
= DID_ERROR
<< 16;
5897 nuke_list
->scsi_done(nuke_list
);
5899 printk ("scsi%d : done. \n", host
->host_no
);
5900 printk (KERN_ALERT
"scsi%d : disabled. Unload and reload\n",
5906 * Function : static int ncr_halt (struct Scsi_Host *host)
5908 * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
5910 * Inputs : host - SCSI chip to halt
5912 * Returns : 0 on success
5916 ncr_halt (struct Scsi_Host
*host
) {
5917 NCR53c7x0_local_declare();
5918 unsigned long flags
;
5919 unsigned char istat
, tmp
;
5920 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
5923 NCR53c7x0_local_setup(host
);
5927 /* Stage 0 : eat all interrupts
5929 Stage 2 : eat all but abort interrupts
5930 Stage 3 : eat all interrupts
5934 NCR53c7x0_write8(hostdata
->istat
, ISTAT_ABRT
);
5937 istat
= NCR53c7x0_read8 (hostdata
->istat
);
5938 if (istat
& ISTAT_SIP
) {
5939 tmp
= NCR53c7x0_read8(SSTAT0_REG
);
5940 } else if (istat
& ISTAT_DIP
) {
5941 tmp
= NCR53c7x0_read8(DSTAT_REG
);
5943 if (tmp
& DSTAT_ABRT
) {
5944 NCR53c7x0_write8(hostdata
->istat
, 0);
5947 printk(KERN_ALERT
"scsi%d : could not halt NCR chip\n",
5953 if (!(istat
& (ISTAT_SIP
|ISTAT_DIP
))) {
5956 else if (stage
== 3)
5960 hostdata
->state
= STATE_HALTED
;
5961 restore_flags(flags
);
5969 * Function: event_name (int event)
5971 * Purpose: map event enum into user-readable strings.
5975 event_name (int event
) {
5977 case EVENT_NONE
: return "none";
5978 case EVENT_ISSUE_QUEUE
: return "to issue queue";
5979 case EVENT_START_QUEUE
: return "to start queue";
5980 case EVENT_SELECT
: return "selected";
5981 case EVENT_DISCONNECT
: return "disconnected";
5982 case EVENT_RESELECT
: return "reselected";
5983 case EVENT_COMPLETE
: return "completed";
5984 case EVENT_IDLE
: return "idle";
5985 case EVENT_SELECT_FAILED
: return "select failed";
5986 case EVENT_BEFORE_SELECT
: return "before select";
5987 case EVENT_RESELECT_FAILED
: return "reselect failed";
5988 default: return "unknown";
5993 * Function : void dump_events (struct Scsi_Host *host, count)
5995 * Purpose : print last count events which have occurred.
5998 dump_events (struct Scsi_Host
*host
, int count
) {
5999 struct NCR53c7x0_hostdata
*hostdata
= (struct NCR53c7x0_hostdata
*)
6001 struct NCR53c7x0_event event
;
6003 unsigned long flags
;
6004 if (hostdata
->events
) {
6005 if (count
> hostdata
->event_size
)
6006 count
= hostdata
->event_size
;
6007 for (i
= hostdata
->event_index
; count
> 0;
6008 i
= (i
? i
- 1 : hostdata
->event_size
-1), --count
) {
6011 * By copying the event we're currently examining with interrupts
6012 * disabled, we can do multiple printk(), etc. operations and
6013 * still be guaranteed that they're happening on the same
6018 event
= hostdata
->events
[i
];
6020 memcpy ((void *) &event
, (void *) &(hostdata
->events
[i
]),
6024 restore_flags(flags
);
6025 printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n",
6026 host
->host_no
, event_name (event
.event
), count
,
6027 (long) event
.time
.tv_sec
, (long) event
.time
.tv_usec
,
6028 event
.target
, event
.lun
);
6030 printk (" event for dsa 0x%lx (virt 0x%p)\n",
6031 virt_to_bus(event
.dsa
), event
.dsa
);
6032 if (event
.pid
!= -1) {
6033 printk (" event for pid %ld ", event
.pid
);
6034 print_command (event
.cmnd
);
6041 * Function: check_address
6043 * Purpose: Check to see if a possibly corrupt pointer will fault the
6046 * Inputs: addr - address; size - size of area
6048 * Returns: 0 if area is OK, -1 on error.
6050 * NOTES: should be implemented in terms of vverify on kernels
6055 check_address (unsigned long addr
, int size
) {
6056 return (MAP_NR(addr
) < 1 || MAP_NR(addr
+ size
) > MAP_NR(high_memory
) ?
6062 NCR53c7x0_release(struct Scsi_Host
*host
) {
6063 struct NCR53c7x0_hostdata
*hostdata
=
6064 (struct NCR53c7x0_hostdata
*) host
->hostdata
[0];
6065 struct NCR53c7x0_cmd
*cmd
, *tmp
;
6067 if (host
->irq
!= IRQ_NONE
)
6070 struct Scsi_Host
*tmp
;
6071 for (irq_count
= 0, tmp
= first_host
; tmp
; tmp
= tmp
->next
)
6072 if (tmp
->hostt
== the_template
&& tmp
->irq
== host
->irq
)
6075 free_irq(host
->irq
, NULL
);
6077 if (host
->dma_channel
!= DMA_NONE
)
6078 free_dma(host
->dma_channel
);
6080 release_region(host
->io_port
, host
->n_io_port
);
6082 for (cmd
= (struct NCR53c7x0_cmd
*) hostdata
->free
; cmd
; cmd
= tmp
,
6083 --hostdata
->num_cmds
) {
6084 tmp
= (struct NCR53c7x0_cmd
*) cmd
->next
;
6086 * If we're going to loop, try to stop it to get a more accurate
6087 * count of the leaked commands.
6091 cmd
->free ((void *) cmd
->real
, cmd
->size
);
6093 if (hostdata
->num_cmds
)
6094 printk ("scsi%d : leaked %d NCR53c7x0_cmd structures\n",
6095 host
->host_no
, hostdata
->num_cmds
);
6096 if (hostdata
->events
)
6097 vfree ((void *)hostdata
->events
);
6099 /* XXX This assumes default cache mode to be IOMAP_FULL_CACHING, which
6100 * XXX may be invalid (CONFIG_060_WRITETHROUGH)
6102 kernel_set_cachemode((u32
)hostdata
, 8192, IOMAP_FULL_CACHING
);
6103 free_pages ((u32
)hostdata
, 1);
6106 Scsi_Host_Template driver_template
= NCR53c7xx
;
6107 #include "scsi_module.c"
6108 #endif /* def MODULE */