1/*
2 * sim710.c - Copyright (C) 1999 Richard Hirst <richard@sleepie.demon.co.uk>
3 *
4 *----------------------------------------------------------------------------
5 *  This program is free software; you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation; either version 2 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program; if not, write to the Free Software
17 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *----------------------------------------------------------------------------
19 *
20 * MCA card detection code by Trent McNair.
21 * Fixes to not explicitly nul bss data from Xavier Bestel.
22 * Some multiboard fixes from Rolf Eike Beer.
23 * Auto probing of EISA config space from Trevor Hemsley.
24 *
25 * Various bits of code in this driver have been copied from 53c7,8xx,c,
26 * which is coyright Drew Eckhardt.  The scripts for the SCSI chip are
27 * compiled with the script compiler written by Drew.
28 *
29 * This is a simple driver for the NCR53c710.  More complex drivers
30 * for this chip (e.g. 53c7xx.c) require that the scsi chip be able to
31 * do DMA block moves between memory and on-chip registers, which can
32 * be a problem if those registers are in the I/O address space.  There
33 * can also be problems on hardware where the registers are memory
34 * mapped, if the design is such that memory-to-memory transfers initiated
35 * by the scsi chip cannot access the chip registers.
36 *
37 * This driver is designed to avoid these problems and is intended to
38 * work with any Intel machines using 53c710 chips, including various
39 * Compaq and NCR machines.  It was initially written for the Tadpole
40 * TP34V VME board which is 68030 based.
41 *
42 * The driver supports boot-time parameters similar to
43 *	sim710=addr:0x9000,irq:15
44 * and insmod parameters similar to
45 *	sim710="addr:0x9000 irq:15"
46 *
47 * Multiple controllers can also be set up by command line, provided the
48 * addr: parameter is specified first for each controller.  e.g.
49 *      sim710="addr:0x9000 irq:15 addr:0x8000 irq:14"
50 *
51 * To seperate the different options, ' ', '+', and ',' can be used, except
52 * that ',' can not be used in module parameters.  ' ' can be a pain, because
53 * it needs to be quoted, which causes problems with some installers.
54 * The command line above is completely equivalent to
55 *      sim710="addr:0x9000+irq:15+addr:0x8000+irq:14"
56 *
57 * The complete list of options are:
58 *
59 * addr:0x9000		Specifies the base I/O port (or address) of the 53C710.
60 * irq:15		Specifies the IRQ number used by the 53c710.
61 * debug:0xffff		Generates lots of debug output.
62 * ignore:0x0a		Makes the driver ignore SCSI IDs 0 and 2.
63 * nodisc:0x70		Prevents disconnects from IDs 6, 5 and 4.
64 * noneg:0x10		Prevents SDTR negotiation on ID 4.
65 * disabled:1		Completely disables the driver. When present, overrides
66 *			all other options.
67 *
68 * The driver will auto-probe chip addresses and IRQs now, so typically no
69 * parameters are needed.  Auto-probing of addresses is disabled if any addr:
70 * parameters are specified.
71 *
72 * Current limitations:
73 *
74 * o  Async only
75 * o  Severely lacking in error recovery
76 * o  'debug:' should be per host really.
77 *
78 */
79
80#include <linux/config.h>
81#include <linux/module.h>
82
83#include <linux/version.h>
84#include <linux/kernel.h>
85#include <linux/types.h>
86#include <linux/string.h>
87#include <linux/ioport.h>
88#include <linux/delay.h>
89#include <linux/sched.h>
90#include <linux/proc_fs.h>
91#include <linux/init.h>
92#include <linux/mca.h>
93#include <linux/interrupt.h>
94#include <asm/dma.h>
95#include <asm/system.h>
96#include <linux/spinlock.h>
97#include <asm/io.h>
98#include <asm/pgtable.h>
99#include <asm/byteorder.h>
100#include <linux/blk.h>
101
102/* All targets are I/O mapped at the moment */
103#define IO_MAPPED
104
105#if defined(CONFIG_MCA)
106
107/*
108 * For each known microchannel card using the 53c710 we need a list
109 * of possible IRQ and IO settings, as well as their corresponding
110 * bit assignment in pos[].  This might get cumbersome if there
111 * are more than a few cards (I only know of 2 at this point).
112 */
113
114#define MCA_53C710_IDS { 0x01bb, 0x01ba, 0x004f }
115
116/* CARD ID 01BB and 01BA use the same pos values */
117
118#define MCA_01BB_IO_PORTS { 0x0000, 0x0000, 0x0800, 0x0C00, 0x1000, 0x1400, \
119			    0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, \
120			    0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00, \
121			    0x4000, 0x4400, 0x4800, 0x4C00, 0x5000  }
122
123#define MCA_01BB_IRQS { 3, 5, 11, 14 }
124
125/* CARD ID 004f */
126
127#define MCA_004F_IO_PORTS { 0x0000, 0x0200, 0x0300, 0x0400, 0x0500,  0x0600 }
128
129#define MCA_004F_IRQS { 5, 9, 14 }
130
131#endif
132
133#include "scsi.h"
134#include "hosts.h"
135#include "sim710.h"
136
137#include<linux/stat.h>
138
139#define DEBUG
140#undef DEBUG_LIMIT_INTS		/* Define to 10 to hang driver after 10 ints */
141
142/* Debug options available via the "debug:0x1234" parameter		*/
143
144#define DEB_NONE	0x0000	/* Nothing				*/
145#define DEB_HALT	0x0001	/* Detailed trace of chip halt funtion	*/
146#define DEB_REGS	0x0002	/* All chip register read/writes	*/
147#define DEB_SYNC	0x0004	/* Sync/async negotiation		*/
148#define DEB_PMM		0x0008	/* Phase mis-match handling		*/
149#define DEB_INTS	0x0010	/* General interrupt trace		*/
150#define DEB_TOUT	0x0020	/* Selection timeouts			*/
151#define DEB_RESUME	0x0040	/* Resume addresses for the script	*/
152#define DEB_CMND	0x0080	/* Commands and status returned		*/
153#define DEB_FIXUP	0x0100	/* Fixup of scsi addresses		*/
154#define DEB_DISC	0x0200	/* Disconnect/reselect handling		*/
155
156#define DEB_ANY		0xffff	/* Any and all debug options		*/
157
158#ifdef DEBUG
159#define DEB(m,x) if (sim710_debug & m) x
160int sim710_debug;
161#else
162#define DEB(m,x)
163#endif
164
165/* Redefine scsi_done to force renegotiation of (a)sync transfers
166 * following any failed command.
167 */
168
169#define SCSI_DONE(cmd)	{ \
170	DEB(DEB_CMND, printk("scsi%d: Complete %08x\n", \
171		host->host_no, cmd->result)); \
172	if (cmd->result) \
173	    hostdata->negotiate |= (1 << cmd->target); \
174	cmd->scsi_done(cmd); \
175    }
176
177#ifndef offsetof
178#define offsetof(t, m)      ((size_t) (&((t *)0)->m))
179#endif
180
181#define STATE_INITIALISED	0
182#define STATE_HALTED		1
183#define STATE_IDLE		2
184#define STATE_BUSY		3
185#define STATE_DISABLED		4
186
187#define MAXBOARDS 4	/* Increase this and the sizes of the
188			   arrays below, if you need more.. */
189
190#ifdef MODULE
191
192char *sim710;		/* command line passed by insmod */
193
194MODULE_AUTHOR("Richard Hirst");
195MODULE_DESCRIPTION("Simple NCR53C710 driver");
196MODULE_LICENSE("GPL");
197
198MODULE_PARM(sim710, "s");
199
200#endif
201
202static int sim710_errors;		/* Count of error interrupts */
203static int sim710_intrs;		/* Count of all interrupts */
204static int ignore_ids[MAXBOARDS];	/* Accept all SCSI IDs */
205static int opt_nodisc[MAXBOARDS];	/* Allow disconnect on all IDs */
206static int opt_noneg[MAXBOARDS];	/* Allow SDTR negotiation on all IDs */
207static int hostdata_order;		/* Encoded size of hostdata for free_pages() */
208static int no_of_boards;		/* Actual number of boards/chips */
209static unsigned int bases[MAXBOARDS];	/* Base addresses of chips */
210static unsigned int irq_vectors[MAXBOARDS]; /* IRQ vectors used by chips */
211
212/* The SCSI Script!!! */
213
214#include "sim710_d.h"
215
216/* Now define offsets in the DSA, as (A_dsa_xxx/4) */
217
218#define DSA_SELECT	(A_dsa_select/4)
219#define DSA_MSGOUT	(A_dsa_msgout/4)
220#define DSA_CMND	(A_dsa_cmnd/4)
221#define DSA_STATUS	(A_dsa_status/4)
222#define DSA_MSGIN	(A_dsa_msgin/4)
223#define DSA_DATAIN	(A_dsa_datain/4)
224#define DSA_DATAOUT	(A_dsa_dataout/4)
225#define DSA_SIZE	(A_dsa_size/4)
226
227#define MAX_SG		128	/* Scatter/Gather elements */
228
229#define MAX_MSGOUT	8
230#define MAX_MSGIN	8
231#define MAX_CMND	12
232#define MAX_STATUS	1
233
234struct sim710_hostdata{
235    int state;
236    Scsi_Cmnd * issue_queue;
237    Scsi_Cmnd * running;
238    int chip;
239    u8 negotiate;
240    u8 reselected_identify;
241    u8 msgin_buf[MAX_MSGIN];
242    u8 msg_reject;
243    u32 test1_src __attribute__ ((aligned (4)));
244    u32 test1_dst;
245
246    struct sim710_target {
247	Scsi_Cmnd *cur_cmd;
248	u32 resume_offset;
249	u32 data_in_jump;
250	u32 data_out_jump;
251	u32 dsa[DSA_SIZE];		/* SCSI Script DSA area */
252	u8  dsa_msgout[MAX_MSGOUT];
253	u8  dsa_msgin[MAX_MSGIN];
254	u8  dsa_cdb[MAX_CMND];
255	u8  dsa_status[MAX_STATUS];
256    } target[8];
257
258    u32 script[sizeof(SCRIPT)/4] __attribute__ ((aligned (4)));
259};
260
261
262/* Template to request asynchronous transfers */
263
264static const unsigned char async_message[] = {
265    EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */};
266
267
268static void sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs);
269static void do_sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs);
270static __inline__ void run_process_issue_queue(struct sim710_hostdata *);
271static void process_issue_queue (struct sim710_hostdata *, unsigned long flags);
272static int full_reset(struct Scsi_Host * host);
273
274
275/*
276 * Function : static void ncr_dump (struct Scsi_Host *host)
277 *
278 * Purpose :  Dump (possibly) useful info
279 *
280 * Inputs : host - pointer to this host adapter's structure
281 */
282
283static void
284ncr_dump (struct Scsi_Host *host)
285{
286    unsigned long flags;
287    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
288       host->hostdata[0];
289
290    save_flags(flags);
291    cli();
292    printk("scsi%d: Chip register contents:\n", host->host_no);
293    printk(" (script at virt %p, bus %lx)\n",
294           hostdata->script, virt_to_bus(hostdata->script));
295    printk(" 00  sien:  %02x  sdid:  %02x  scntl1:%02x  scntl0:%02x\n"
296	   " 04  socl:  %02x  sodl:  %02x  sxfer: %02x  scid:  %02x\n"
297	   " 08  sbcl:  %02x  sbdl:  %02x  sidl:  %02x  sfbr:  %02x\n"
298	   " 0C  sstat2:%02x  sstat1:%02x  sstat0:%02x  dstat: %02x\n"
299	   " 10  dsa:   %08x\n"
300	   " 14  ctest3:%02x  ctest2:%02x  ctest1:%02x  ctest0:%02x\n"
301	   " 18  ctest7:%02x  ctest6:%02x  ctest5:%02x  ctest4:%02x\n"
302	   " 1C  temp:  %08x\n"
303	   " 20  lcrc:  %02x  ctest8:%02x  istat: %02x  dfifo: %02x\n"
304	   " 24  dbc:   %08x  dnad:  %08x  dsp:   %08x\n"
305	   " 30  dsps:  %08x  scratch:%08x\n"
306	   " 38  dcntl: %02x  dwt:   %02x  dien:  %02x  dmode: %02x\n"
307	   " 3C  adder: %08x\n",
308	  NCR_read8(SIEN_REG), NCR_read8(SDID_REG), NCR_read8(SCNTL1_REG),
309	  NCR_read8(SCNTL0_REG), NCR_read8(SOCL_REG), NCR_read8(SODL_REG),
310	  NCR_read8(SXFER_REG), NCR_read8(SCID_REG), NCR_read8(SBCL_REG),
311	  NCR_read8(SBDL_REG), NCR_read8(SIDL_REG), NCR_read8(SFBR_REG),
312	  NCR_read8(SSTAT2_REG), NCR_read8(SSTAT1_REG), NCR_read8(SSTAT0_REG),
313	  NCR_read8(DSTAT_REG), NCR_read32(DSA_REG), NCR_read8(CTEST3_REG),
314	  NCR_read8(CTEST2_REG), NCR_read8(CTEST1_REG), NCR_read8(CTEST0_REG),
315	  NCR_read8(CTEST7_REG), NCR_read8(CTEST6_REG), NCR_read8(CTEST5_REG),
316	  NCR_read8(CTEST4_REG), NCR_read8(TEMP_REG), NCR_read8(LCRC_REG),
317	  NCR_read8(CTEST8_REG), NCR_read8(ISTAT_REG), NCR_read8(DFIFO_REG),
318	  NCR_read32(DBC_REG), NCR_read32(DNAD_REG), NCR_read32(DSP_REG),
319	  NCR_read32(DSPS_REG), NCR_read32(SCRATCH_REG), NCR_read8(DCNTL_REG),
320	  NCR_read8(DWT_REG), NCR_read8(DIEN_REG), NCR_read8(DMODE_REG),
321	  NCR_read32(ADDER_REG));
322
323    restore_flags(flags);
324}
325
326
327/*
328 * Function: int param_setup(char *str)
329 */
330
331__init int
332param_setup(char *str)
333{
334    char *cur = str;
335    char *p, *pc, *pv;
336    int val;
337    int c;
338
339    no_of_boards = 0;
340    while (no_of_boards < MAXBOARDS && cur != NULL &&
341		(pc = strchr(cur, ':')) != NULL) {
342	char *pe;
343
344	val = 0;
345	pv = pc;
346	c = *++pv;
347
348	val = (int) simple_strtoul(pv, &pe, 0);
349
350	if (!strncmp(cur, "addr:", 5)) {
351	    bases[no_of_boards++] = val;
352	}
353#ifdef DEBUG
354	else if (!strncmp(cur, "debug:", 6)) {
355	    sim710_debug = val;
356	}
357#endif
358	else if (no_of_boards == 0) {
359	    printk("sim710: Invalid parameters, addr: must come first\n");
360	    no_of_boards = -1;
361	    return 1;
362	}
363	else if	(!strncmp(cur, "irq:", 4))
364	    irq_vectors[no_of_boards-1] = val;
365	else if	(!strncmp(cur, "ignore:", 7))
366	    ignore_ids[no_of_boards-1] = val;
367	else if	(!strncmp(cur, "nodisc:", 7))
368	    opt_nodisc[no_of_boards-1] = val;
369	else if	(!strncmp(cur, "noneg:", 6))
370	    opt_noneg[no_of_boards-1] = val;
371	else if	(!strncmp(cur, "disabled:", 9)) {
372	    no_of_boards = -1;
373	    return 1;
374	}
375	else {
376	    printk("sim710: unexpected boot option '%.*s'\n", (int)(pc-cur+1), cur);
377	    no_of_boards = -1;
378	    return 1;
379	}
380
381	/* Allow ',', ' ', or '+' seperators.  Used to be ',' at boot and
382	 * ' ' for module load, some installers crap out on the space and
383	 * insmod doesn't like the comma.
384	 */
385       if ((p = strchr(cur, ',')) || (p = strchr(cur, ' ')) ||
386               (p = strchr(cur, '+')))
387           cur = p + 1;
388        else
389           break;
390    }
391    return 1;
392}
393
394#ifndef MODULE
395__setup("sim710=", param_setup);
396#endif
397
398
399/*
400 * Function: static const char *sbcl_to_phase (int sbcl)
401 */
402
403static const char *
404sbcl_to_phase (int sbcl) {
405    switch (sbcl & SBCL_PHASE_MASK) {
406    case SBCL_PHASE_DATAIN:
407	return "DATAIN";
408    case SBCL_PHASE_DATAOUT:
409	return "DATAOUT";
410    case SBCL_PHASE_MSGIN:
411	return "MSGIN";
412    case SBCL_PHASE_MSGOUT:
413	return "MSGOUT";
414    case SBCL_PHASE_CMDOUT:
415	return "CMDOUT";
416    case SBCL_PHASE_STATIN:
417	return "STATUSIN";
418    default:
419	return "unknown";
420    }
421}
422
423
424/*
425 * Function : static int ncr_halt (struct Scsi_Host *host)
426 *
427 * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
428 *
429 * Inputs : host - SCSI chip to halt
430 *
431 * Returns : 0 on success
432 */
433
434static int
435ncr_halt (struct Scsi_Host *host)
436{
437    unsigned long flags;
438    unsigned char istat, tmp;
439    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
440	host->hostdata[0];
441    int stage;
442    int timeout;
443    int res = 0;
444
445    save_flags(flags);
446    cli();
447    /* Stage 0 : eat all interrupts
448       Stage 1 : set ABORT
449       Stage 2 : eat all but abort interrupts
450       Stage 3 : eat all interrupts
451       We loop for 50000 times with a delay of 10us which should give us
452       about half a second.
453     */
454    for (stage = 0, timeout = 50000; timeout; timeout--) {
455	if (stage == 1) {
456	    DEB(DEB_HALT, printk("ncr_halt: writing ISTAT_ABRT\n"));
457	    NCR_write8(ISTAT_REG, ISTAT_ABRT);
458	    ++stage;
459	}
460	istat = NCR_read8 (ISTAT_REG);
461	if (istat & ISTAT_SIP) {
462	    DEB(DEB_HALT, printk("ncr_halt: got ISTAT_SIP, istat=%02x\n", istat));
463	    tmp = NCR_read8(SSTAT0_REG);
464	    DEB(DEB_HALT, printk("ncr_halt: got SSTAT0_REG=%02x\n", tmp));
465	} else if (istat & ISTAT_DIP) {
466	    DEB(DEB_HALT, printk("ncr_halt: got ISTAT_DIP, istat=%02x\n", istat));
467	    tmp = NCR_read8(DSTAT_REG);
468	    DEB(DEB_HALT, printk("ncr_halt: got DSTAT_REG=%02x\n", tmp));
469	    if (stage == 2) {
470		if (tmp & DSTAT_ABRT) {
471	    	    DEB(DEB_HALT, printk("ncr_halt: got DSTAT_ABRT, clearing istat\n"));
472		    NCR_write8(ISTAT_REG, 0);
473		    ++stage;
474		} else {
475		    res = 1;
476		    break;
477	    	}
478    	    }
479	}
480	if (!(istat & (ISTAT_SIP|ISTAT_DIP))) {
481	    if (stage == 0)
482	    	++stage;
483	    else if (stage == 3)
484		break;
485	}
486	udelay(10);
487    }
488    restore_flags(flags);
489
490    if (timeout == 0 || res) {
491	printk(KERN_ALERT "scsi%d: could not halt NCR chip\n", host->host_no);
492	return 1;
493    }
494    else {
495	hostdata->state = STATE_HALTED;
496	return 0;
497    }
498}
499
500/*
501 * Function : static void sim710_soft_reset (struct Scsi_Host *host)
502 *
503 * Purpose :  perform a soft reset of the NCR53c7xx chip
504 *
505 * Inputs : host - pointer to this host adapter's structure
506 *
507 * Preconditions : sim710_init must have been called for this
508 *      host.
509 *
510 */
511
512static void
513sim710_soft_reset (struct Scsi_Host *host)
514{
515    unsigned long flags;
516
517    save_flags(flags);
518    cli();
519    /*
520     * Do a soft reset of the chip so that everything is
521     * reinitialized to the power-on state.
522     *
523     * Basically follow the procedure outlined in the NCR53c700
524     * data manual under Chapter Six, How to Use, Steps Necessary to
525     * Start SCRIPTS, with the exception of actually starting the
526     * script and setting up the synchronous transfer gunk.
527     */
528
529
530    NCR_write8(SCNTL1_REG, SCNTL1_RST);		/* Reset the bus */
531    udelay(50);
532    NCR_write8(SCNTL1_REG, 0);
533
534    udelay(500);
535
536    NCR_write8(ISTAT_REG, ISTAT_10_SRST);	/* Reset the chip */
537    udelay(50);
538    NCR_write8(ISTAT_REG, 0);
539
540    mdelay(1000);				/* Let devices recover */
541
542    NCR_write32(SCRATCH_REG, 0);
543    NCR_write8(DCNTL_REG, DCNTL_10_COM | DCNTL_700_CF_3);
544    NCR_write8(CTEST7_REG, CTEST7_10_CDIS|CTEST7_STD);
545    NCR_write8(DMODE_REG, DMODE_10_BL_8 | DMODE_10_FC2);
546    NCR_write8(SCID_REG, 1 << host->this_id);
547    NCR_write8(SBCL_REG, 0);
548    NCR_write8(SXFER_REG, 0);
549    NCR_write8(SCNTL1_REG, SCNTL1_ESR_700);
550    NCR_write8(SCNTL0_REG, SCNTL0_EPC | SCNTL0_EPG_700 | SCNTL0_ARB1 |
551		SCNTL0_ARB2);
552
553    NCR_write8(DIEN_REG, DIEN_700_BF |
554		DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_700_OPC);
555
556    NCR_write8(SIEN_REG_700,
557	    SIEN_PAR | SIEN_700_STO | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
558
559    restore_flags(flags);
560}
561
562
563/*
564 * Function : static void sim710_driver_init (struct Scsi_Host *host)
565 *
566 * Purpose : Initialize internal structures, as required on startup, or
567 *	after a SCSI bus reset.
568 *
569 * Inputs : host - pointer to this host adapter's structure
570 */
571
572static void
573sim710_driver_init (struct Scsi_Host *host)
574{
575    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
576	host->hostdata[0];
577    int i;
578
579    hostdata->running = NULL;
580    memcpy (hostdata->script, SCRIPT, sizeof(SCRIPT));
581    for (i = 0; i < PATCHES; i++)
582	hostdata->script[LABELPATCHES[i]] += virt_to_bus(hostdata->script);
583    patch_abs_32 (hostdata->script, 0, reselected_identify,
584    	virt_to_bus((void *)&(hostdata->reselected_identify)));
585    patch_abs_32 (hostdata->script, 0, msgin_buf,
586    	virt_to_bus((void *)&(hostdata->msgin_buf[0])));
587    patch_abs_32 (hostdata->script, 0, msg_reject,
588	virt_to_bus((void *)&(hostdata->msg_reject)));
589    patch_abs_32 (hostdata->script, 0, test1_src,
590	virt_to_bus((void *)&(hostdata->test1_src)));
591    patch_abs_32 (hostdata->script, 0, test1_dst,
592	virt_to_bus((void *)&(hostdata->test1_dst)));
593    hostdata->state = STATE_INITIALISED;
594    hostdata->negotiate = 0xff;
595}
596
597
598/* Handle incoming Synchronous data transfer request.  If our negotiate
599 * flag is set then this is a response to our request, otherwise it is
600 * spurious request from the target.  Don't really expect target initiated
601 * SDTRs, because we always negotiate on the first command.  Could still
602 * get them though..
603 * The chip is currently paused with ACK asserted on the last byte of the
604 * SDTR.
605 * resa is the resume address if the message is in response to our outgoing
606 * SDTR.  Only possible on initial identify.
607 * resb is the resume address if the message exchange is initiated by the
608 * target.
609 */
610
611static u32
612handle_sdtr (struct Scsi_Host * host, Scsi_Cmnd * cmd, u32 resa, u32 resb)
613{
614    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0];
615    struct sim710_target *targdata = hostdata->target + cmd->target;
616    u32 resume_offset;
617
618    if (resa && hostdata->negotiate & (1 << cmd->target)) {
619	DEB(DEB_SYNC, printk("scsi%d: Response to host SDTR = %02x %02x\n",
620		host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4]));
621	/* We always issue an SDTR with the identify, so we must issue
622	 * the CDB next.
623	 */
624	resume_offset = resa;
625	hostdata->negotiate &= ~(1 << cmd->target);
626    }
627    else {
628	DEB(DEB_SYNC, printk("scsi%d: Target initiated SDTR = %02x %02x\n",
629		host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4]));
630	memcpy(targdata->dsa_msgout, async_message, sizeof(async_message));
631	targdata->dsa[DSA_MSGOUT] = sizeof(async_message);
632	/* I guess the target could do this anytime; we have to send our
633	 * response, and then continue (sending the CDB if not already done).
634	 */
635	resume_offset = resb;
636    }
637    return resume_offset;
638}
639
640
641/*
642 * Function : static int datapath_residual (Scsi_Host *host)
643 *
644 * Purpose : return residual data count of what's in the chip.
645 *
646 * Inputs : host - SCSI host
647 */
648
649static int
650datapath_residual (struct Scsi_Host *host) {
651    int count, synchronous, sstat;
652    unsigned int ddir;
653
654    count = ((NCR_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) -
655	(NCR_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK;
656    synchronous = NCR_read8 (SXFER_REG) & SXFER_MO_MASK;
657    ddir = NCR_read8 (CTEST0_REG_700) & CTEST0_700_DDIR;
658
659    if (ddir) {
660    /* Receive */
661	if (synchronous)
662	    count += (NCR_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
663	else
664	    if (NCR_read8 (SSTAT1_REG) & SSTAT1_ILF)
665		++count;
666    } else {
667    /* Send */
668	sstat = NCR_read8 (SSTAT1_REG);
669	if (sstat & SSTAT1_OLF)
670	    ++count;
671	if (synchronous && (sstat & SSTAT1_ORF))
672	    ++count;
673    }
674    return count;
675}
676
677
678static u32
679handle_idd (struct Scsi_Host * host, Scsi_Cmnd * cmd)
680{
681    struct sim710_hostdata *hostdata =
682		(struct sim710_hostdata *)host->hostdata[0];
683    struct sim710_target *targdata = hostdata->target + cmd->target;
684    u32 resume_offset = 0, index;
685
686    index = (u32)((u32 *)(bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script);
687
688    switch (index) {
689    case Ent_wait_disc_complete/4 + 2:
690	cmd->result = targdata->dsa_status[0];
691        SCSI_DONE(cmd);
692	targdata->cur_cmd = NULL;
693	resume_offset = Ent_reselect;
694	break;
695    case Ent_wait_disc2/4 + 2:
696	/* Disconnect after command - just wait for a reselect */
697	targdata->resume_offset = Ent_resume_msgin2a;
698	resume_offset = Ent_reselect;
699	break;
700    case Ent_wait_disc3/4 + 2:
701	/* Disconnect after the data phase */
702	targdata->resume_offset = Ent_resume_msgin3a;
703	resume_offset = Ent_reselect;
704	break;
705    case Ent_wait_disc1/4 + 2:
706	/* Disconnect before command - not expected */
707	targdata->resume_offset = Ent_resume_msgin1a;
708	resume_offset = Ent_reselect;
709	break;
710    default:
711	printk("scsi%d: Unexpected Illegal Instruction, script[%04x]\n",
712		host->host_no, index);
713	sim710_errors++;
714	/* resume_offset is zero, which will cause host reset */
715    }
716    return resume_offset;
717}
718
719
720/* Handle a phase mismatch.
721 */
722
723static u32
724handle_phase_mismatch (struct Scsi_Host * host, Scsi_Cmnd * cmd)
725{
726    struct sim710_hostdata *hostdata =
727		(struct sim710_hostdata *)host->hostdata[0];
728    struct sim710_target *targdata = hostdata->target + cmd->target;
729    u32 resume_offset = 0, index;
730    unsigned char sbcl;
731
732    sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
733    index = (u32)((u32 *)(bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script);
734
735    DEB(DEB_PMM, printk("scsi%d: Phase mismatch, phase %s (%x) at script[0x%x]\n",
736	host->host_no, sbcl_to_phase(sbcl), sbcl, index));
737    DEB(DEB_PMM, print_command(cmd->cmnd));
738
739    if (index == Ent_done_ident/4) {
740	/* Sending initial message out - probably rejecting our sync
741	 * negotiation request.
742	 */
743	NCR_write8(SOCL_REG, 0);	/* Negate ATN */
744	if (sbcl == SBCL_PHASE_MSGIN)
745	    resume_offset = Ent_resume_rej_ident;
746	else if (sbcl == SBCL_PHASE_CMDOUT) {
747	    /* Some old devices (SQ555) switch to cmdout after the first
748	     * byte of an identify message, regardless of whether we
749	     * have more bytes to send!
750	     */
751	    printk("scsi%d: Unexpected switch to CMDOUT during IDENTIFY\n",
752		host->host_no);
753	    resume_offset = Ent_resume_cmd;
754	}
755	else if (sbcl == SBCL_PHASE_STATIN) {
756	    /* Some devices do this on parity error, at least */
757	    printk("scsi%d: Unexpected switch to STATUSIN on initial message out\n",
758		host->host_no);
759	    resume_offset = Ent_end_data_trans;
760	}
761	else {
762	    printk("scsi%d: Unexpected phase change to %s on initial msgout\n",
763		host->host_no, sbcl_to_phase(sbcl));
764	    /* resume_offset is zero, which will cause a host reset */
765	}
766	hostdata->negotiate &= ~(1 << cmd->target);
767    }
768    else if (index > Ent_patch_input_data/4 &&
769		index < Ent_patch_output_data/4) {
770	/* DataIn transfer phase */
771	u32 sg_id, oaddr, olen, naddr, nlen;
772	int residual;
773
774	sg_id = (index - Ent_patch_input_data/4 - 4) / 2;
775	targdata->data_in_jump = hostdata->script[Ent_patch_input_data/4+1] =
776		virt_to_bus(hostdata->script + Ent_patch_input_data/4 + sg_id * 2 + 2);
777	olen  = targdata->dsa[DSA_DATAIN + sg_id * 2];
778	oaddr = targdata->dsa[DSA_DATAIN + sg_id * 2 + 1];
779	residual = datapath_residual (host);
780	if (residual)
781	    printk("scsi%d: Residual count %d on DataIn - NOT expected!!!",
782		host->host_no, residual);
783	naddr = NCR_read32(DNAD_REG) - residual;
784	nlen  = (NCR_read32(DBC_REG) & 0x00ffffff) + residual;
785	DEB(DEB_PMM, printk("scsi%d: DIN sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
786		host->host_no, sg_id, oaddr, olen, naddr, nlen, residual));
787	if (oaddr+olen != naddr+nlen) {
788	    printk("scsi%d: PMM DIN counts error: 0x%x + 0x%x != 0x%x + 0x%x",
789		host->host_no, oaddr, olen, naddr, nlen);
790	}
791	else {
792	    targdata->dsa[DSA_DATAIN + sg_id * 2]     = nlen;
793	    targdata->dsa[DSA_DATAIN + sg_id * 2 + 1] = naddr;
794	    resume_offset = Ent_resume_pmm;
795	}
796    }
797    else if (index > Ent_patch_output_data/4 &&
798		index <= Ent_end_data_trans/4) {
799	/* Dataout transfer phase */
800	u32 sg_id, oaddr, olen, naddr, nlen;
801	int residual;
802
803	sg_id = (index - Ent_patch_output_data/4 - 4) / 2;
804	targdata->data_out_jump = hostdata->script[Ent_patch_output_data/4+1] =
805		virt_to_bus(hostdata->script + Ent_patch_output_data/4 + sg_id * 2 + 2);
806	olen  = targdata->dsa[DSA_DATAOUT + sg_id * 2];
807	oaddr = targdata->dsa[DSA_DATAOUT + sg_id * 2 + 1];
808	residual = datapath_residual (host);
809	naddr = NCR_read32(DNAD_REG) - residual;
810	nlen  = (NCR_read32(DBC_REG) & 0x00ffffff) + residual;
811	DEB(DEB_PMM, printk("scsi%d: DOUT sg %d, old %08x/%08x, new %08x/%08x (%d)\n",
812		host->host_no, sg_id, oaddr, olen, naddr, nlen, residual));
813	if (oaddr+olen != naddr+nlen) {
814	    printk("scsi%d: PMM DOUT counts error: 0x%x + 0x%x != 0x%x + 0x%x",
815		host->host_no, oaddr, olen, naddr, nlen);
816	}
817	else {
818	    targdata->dsa[DSA_DATAOUT + sg_id * 2]     = nlen;
819	    targdata->dsa[DSA_DATAOUT + sg_id * 2 + 1] = naddr;
820	    resume_offset = Ent_resume_pmm;
821	}
822    }
823    else if (sbcl == SBCL_PHASE_STATIN) {
824	/* Change to Status In at some random point; probably wants to report a
825	 * parity error or similar.
826	 */
827	printk("scsi%d: Unexpected phase change to STATUSIN at index 0x%x\n",
828		host->host_no, index);
829	resume_offset = Ent_end_data_trans;
830    }
831    else {
832	printk("scsi%d: Unexpected phase change to %s at index 0x%x\n",
833		host->host_no, sbcl_to_phase(sbcl), index);
834	/* resume_offset is zero, which will cause a host reset */
835    }
836    /* Flush DMA FIFO */
837    NCR_write8 (CTEST8_REG, CTEST8_10_CLF);
838    while (NCR_read8 (CTEST8_REG) & CTEST8_10_CLF);
839
840    return resume_offset;
841}
842
843
844static u32
845handle_script_int(struct Scsi_Host * host, Scsi_Cmnd * cmd)
846{
847    struct sim710_hostdata *hostdata =
848		(struct sim710_hostdata *)host->hostdata[0];
849    struct sim710_target *targdata = hostdata->target + cmd->target;
850    u32 dsps, resume_offset = 0;
851    unsigned char sbcl;
852
853    dsps = NCR_read32(DSPS_REG);
854
855    switch (dsps) {
856    case A_int_cmd_complete:
857	cmd->result = targdata->dsa_status[0];
858        SCSI_DONE(cmd);
859	targdata->cur_cmd = NULL;
860	resume_offset = Ent_reselect;
861	break;
862    case A_int_msg_sdtr1:
863	resume_offset = handle_sdtr(host, cmd,
864		Ent_resume_msgin1a, Ent_resume_msgin1b);
865	break;
866    case A_int_msg_sdtr2:
867	resume_offset = handle_sdtr(host, cmd, 0, Ent_resume_msgin2b);
868	break;
869    case A_int_msg_sdtr3:
870	resume_offset = handle_sdtr(host, cmd, 0, Ent_resume_msgin3b);
871	break;
872    case A_int_disc1:
873	/* Disconnect before command - not expected */
874	targdata->resume_offset = Ent_resume_msgin1a;
875	resume_offset = Ent_reselect;
876	break;
877    case A_int_disc2:
878	/* Disconnect after command - just wait for a reselect */
879	targdata->resume_offset = Ent_resume_msgin2a;
880	resume_offset = Ent_reselect;
881	break;
882    case A_int_disc3:
883	/* Disconnect after the data phase */
884	targdata->resume_offset = Ent_resume_msgin3a;
885	resume_offset = Ent_reselect;
886	break;
887    case A_int_reselected:
888	hostdata->script[Ent_patch_output_data/4+1] = targdata->data_out_jump;
889	hostdata->script[Ent_patch_input_data/4+1] = targdata->data_in_jump;
890	NCR_write32(DSA_REG, virt_to_bus(targdata->dsa));
891	resume_offset = targdata->resume_offset;
892	break;
893    case A_int_data_bad_phase:
894	sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
895	printk("scsi%d: int_data_bad_phase, phase %s (%x)\n",
896		host->host_no, sbcl_to_phase(sbcl), sbcl);
897	break;
898    case A_int_bad_msg1:
899    case A_int_bad_msg2:
900    case A_int_bad_msg3:
901    case A_int_cmd_bad_phase:
902    case A_int_no_msgout1:
903    case A_int_no_msgout2:
904    case A_int_no_msgout3:
905    case A_int_not_cmd_complete:
906    case A_int_sel_no_ident:
907    case A_int_sel_not_cmd:
908    case A_int_status_not_msgin:
909    case A_int_resel_not_msgin:
910    case A_int_selected:
911    case A_int_not_rej:
912    default:
913	sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK;
914	printk("scsi%d: Unimplemented script interrupt: %08x, phase %s\n",
915		host->host_no, dsps, sbcl_to_phase(sbcl));
916	sim710_errors++;
917	/* resume_offset is zero, which will cause a host reset */
918    }
919    return resume_offset;
920}
921
922
923/* A quick wrapper for sim710_intr_handle to grab the spin lock */
924
925static void
926do_sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
927{
928    unsigned long flags;
929
930    spin_lock_irqsave(&io_request_lock, flags);
931    sim710_intr_handle(irq, dev_id, regs);
932    spin_unlock_irqrestore(&io_request_lock, flags);
933}
934
935
936/* A "high" level interrupt handler */
937
938static void
939sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
940{
941    struct Scsi_Host * host = (struct Scsi_Host *)dev_id;
942    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0];
943    Scsi_Cmnd * cmd;
944    unsigned char istat, dstat;
945    unsigned char sstat0;
946    u32 scratch, dsps, resume_offset = 0;
947
948    istat = NCR_read8(ISTAT_REG);
949    if (!(istat & (ISTAT_SIP|ISTAT_DIP)))
950	return;
951    else {
952	sim710_intrs++;
953	dsps = NCR_read32(DSPS_REG);
954	hostdata->state = STATE_HALTED;
955	sstat0 = dstat = 0;
956	scratch = NCR_read32(SCRATCH_REG);
957	if (istat & ISTAT_SIP) {
958	    sstat0 = NCR_read8(SSTAT0_REG);
959	}
960	if (istat & ISTAT_DIP) {
961	    udelay(10);		/* Some comment somewhere about 10cycles
962				 * between accesses to sstat0 and dstat ??? */
963	    dstat = NCR_read8(DSTAT_REG);
964	}
965	DEB(DEB_INTS, printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
966		"dstat %02x, dsp [%04x], scratch %02x\n",
967	    host->host_no, sim710_intrs, istat, sstat0, dstat,
968	    (u32 *)(bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script,
969	    scratch));
970	if (scratch & 0x100) {
971	    u8 *p = hostdata->msgin_buf;
972
973	    DEB(DEB_INTS, printk("  msgin_buf: %02x %02x %02x %02x\n",
974			p[0], p[1], p[2], p[3]));
975	}
976	if ((dstat & DSTAT_SIR) && dsps == A_int_reselected) {
977	    /* Reselected.  Identify the target from LCRC_REG, and
978	     * update current command.  If we were trying to select
979	     * a device, then that command needs to go back on the
980	     * issue_queue for later.
981	     */
982	    unsigned char lcrc = NCR_read8(LCRC_REG_10);
983	    int id = 0;
984
985	    if (!(lcrc & 0x7f)) {
986		printk("scsi%d: Reselected with LCRC = %02x\n",
987			host->host_no, lcrc);
988		cmd = NULL;
989	    }
990	    else {
991		while (!(lcrc & 1)) {
992		    id++;
993		    lcrc >>= 1;
994		}
995		DEB(DEB_DISC, printk("scsi%d: Reselected by ID %d\n",
996			host->host_no, id));
997		if (hostdata->running) {
998		    /* Clear SIGP */
999		    (void)NCR_read8(CTEST2_REG_700);
1000
1001		    DEB(DEB_DISC, printk("scsi%d: Select of %d interrupted "
1002				"by reselect from %d (%p)\n",
1003				host->host_no, hostdata->running->target,
1004				id, hostdata->target[id].cur_cmd));
1005		    cmd = hostdata->running;
1006		    hostdata->target[cmd->target].cur_cmd = NULL;
1007		    cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
1008		    hostdata->issue_queue = cmd;
1009		}
1010		cmd = hostdata->running = hostdata->target[id].cur_cmd;
1011	    }
1012	}
1013	else
1014	    cmd = hostdata->running;
1015
1016	if (!cmd) {
1017	    printk("scsi%d: No active command!\n", host->host_no);
1018	    printk("scsi%d: Int %d, istat %02x, sstat0 %02x "
1019		"dstat %02x, dsp [%04x], scratch %02x, dsps %08x\n",
1020		host->host_no, sim710_intrs, istat, sstat0, dstat,
1021		(u32 *)(bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script,
1022		NCR_read32(SCRATCH_REG), dsps);
1023	    /* resume_offset is zero, which will cause a host reset */
1024	}
1025	else if (sstat0 & SSTAT0_700_STO) {
1026	    DEB(DEB_TOUT, printk("scsi%d: Selection timeout\n", host->host_no));
1027	    cmd->result = DID_NO_CONNECT << 16;
1028	    SCSI_DONE(cmd);
1029	    hostdata->target[cmd->target].cur_cmd = NULL;
1030	    resume_offset = Ent_reselect;
1031	}
1032	else if (sstat0 & (SSTAT0_SGE|SSTAT0_UDC|SSTAT0_RST|SSTAT0_PAR)) {
1033	    printk("scsi%d: Serious error, sstat0 = %02x\n", host->host_no,
1034			    sstat0);
1035	    sim710_errors++;
1036	    /* resume_offset is zero, which will cause a host reset */
1037	}
1038	else if (dstat & (DSTAT_BF|DSTAT_ABRT|DSTAT_SSI|DSTAT_WTD)) {
1039	    printk("scsi%d: Serious error, dstat = %02x\n", host->host_no,
1040			    dstat);
1041	    sim710_errors++;
1042	    /* resume_offset is zero, which will cause a host reset */
1043	}
1044	else if (dstat & DSTAT_SIR)
1045	    resume_offset = handle_script_int(host, cmd);
1046	else if (sstat0 & SSTAT0_MA)
1047	    resume_offset = handle_phase_mismatch(host, cmd);
1048	else if (dstat & DSTAT_IID) {
1049	    /* This can be due to a quick reselect while doing a WAIT
1050	     * DISCONNECT.
1051	     */
1052	    resume_offset = handle_idd(host, cmd);
1053	}
1054	else {
1055	    sim710_errors++;
1056	    printk("scsi%d: Spurious interrupt!\n", host->host_no);
1057	    /* resume_offset is zero, which will cause a host reset */
1058	}
1059    }
1060
1061    if (resume_offset) {
1062	if (resume_offset == Ent_reselect) {
1063	    hostdata->running = NULL;
1064	    hostdata->state = STATE_IDLE;
1065	}
1066	else
1067	    hostdata->state = STATE_BUSY;
1068	DEB(DEB_RESUME, printk("scsi%d: Resuming at script[0x%x]\n",
1069		host->host_no, resume_offset/4));
1070#ifdef DEBUG_LIMIT_INTS
1071	if (sim710_intrs < DEBUG_LIMIT_INTS)
1072#endif
1073	{
1074	    NCR_write32(SCRATCH_REG, 0);
1075	    NCR_write32(DSP_REG, virt_to_bus(hostdata->script+resume_offset/4));
1076	}
1077	if (resume_offset == Ent_reselect)
1078	    run_process_issue_queue(hostdata);
1079    }
1080    else {
1081	printk("scsi%d: Failed to handle interrupt.  Failing commands "
1082		"and resetting SCSI bus and chip\n", host->host_no);
1083	mdelay(1000);		/* Give chance to read screen!! */
1084	full_reset(host);
1085    }
1086}
1087
1088
1089static void
1090run_command (struct sim710_hostdata *hostdata, Scsi_Cmnd *cmd)
1091{
1092    struct Scsi_Host *host = cmd->host;
1093    struct sim710_target *targdata = hostdata->target + cmd->target;
1094    int i, datain, dataout, sg_start;
1095    u32 *dip, *dop, dsa;
1096
1097    DEB(DEB_CMND, printk("scsi%d: id%d starting ", host->host_no,
1098		cmd->target));
1099    DEB(DEB_CMND, print_command(cmd->cmnd));
1100
1101    switch (cmd->cmnd[0]) {
1102    case INQUIRY:
1103    case MODE_SENSE:
1104    case READ_6:
1105    case READ_10:
1106    case READ_CAPACITY:
1107    case REQUEST_SENSE:
1108    case READ_BLOCK_LIMITS:
1109    case READ_TOC:
1110        datain = 1;
1111	dataout = 0;
1112        break;
1113    case MODE_SELECT:
1114    case WRITE_6:
1115    case WRITE_10:
1116        datain = 0;
1117        dataout = 1;
1118        break;
1119    case TEST_UNIT_READY:
1120    case ALLOW_MEDIUM_REMOVAL:
1121    case START_STOP:
1122        datain = dataout = 0;
1123        break;
1124    default:
1125        datain = dataout = 1;
1126    }
1127
1128    memcpy(targdata->dsa_cdb, cmd->cmnd, MAX_CMND);
1129
1130    targdata->dsa_msgout[0] =
1131		IDENTIFY((opt_nodisc[hostdata->chip] & (1<<cmd->target)) ? 0 : 1 ,0);
1132    if (hostdata->negotiate & (1 << cmd->target)) {
1133	if (opt_noneg[hostdata->chip] & (1 << cmd->target)) {
1134	    hostdata->negotiate ^= (1 << cmd->target);
1135	    targdata->dsa[DSA_MSGOUT] = 1;
1136	}
1137	else {
1138	    DEB(DEB_SYNC, printk("scsi%d: Negotiating async transfers "
1139		"for ID %d\n",
1140		host->host_no, cmd->target));
1141	    memcpy(targdata->dsa_msgout+1, async_message, sizeof(async_message));
1142	    targdata->dsa[DSA_MSGOUT] = sizeof(async_message) + 1;
1143	}
1144    }
1145    else
1146	targdata->dsa[DSA_MSGOUT] = 1;
1147
1148    targdata->dsa_msgin[0] = 0xff;
1149    targdata->dsa_status[0] = 0xff;
1150
1151    targdata->dsa[DSA_SELECT]		= (1 << cmd->target) << 16;
1152    targdata->dsa[DSA_MSGOUT+1]		= virt_to_bus(targdata->dsa_msgout);
1153    targdata->dsa[DSA_CMND]		= cmd->cmd_len;
1154    targdata->dsa[DSA_CMND+1]		= virt_to_bus(targdata->dsa_cdb);
1155    targdata->dsa[DSA_STATUS]		= 1;
1156    targdata->dsa[DSA_STATUS+1]		= virt_to_bus(targdata->dsa_status);
1157    targdata->dsa[DSA_MSGIN]		= 1;
1158    targdata->dsa[DSA_MSGIN+1]		= virt_to_bus(targdata->dsa_msgin);
1159
1160    sg_start = (MAX_SG - (cmd->use_sg ? cmd->use_sg : 1)) * 2;
1161    dip = targdata->dsa + DSA_DATAIN + sg_start;
1162    dop = targdata->dsa + DSA_DATAOUT + sg_start;
1163
1164    for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; i++) {
1165	u32 vbuf = cmd->use_sg ?
1166		(u32)(((struct scatterlist *)cmd->buffer)[i].address) :
1167		(u32)(cmd->request_buffer);
1168	u32 bbuf = virt_to_bus((void *)vbuf);
1169	u32 cnt = cmd->use_sg ?
1170		((struct scatterlist *)cmd->buffer)[i].length :
1171		cmd->request_bufflen;
1172
1173	if (datain) {
1174	    *dip++	= cnt;
1175	    *dip++	= bbuf;
1176	}
1177	if (dataout) {
1178	    *dop++	= cnt;
1179	    *dop++	= bbuf;
1180	}
1181    }
1182    targdata->data_out_jump = hostdata->script[Ent_patch_output_data/4+1] =
1183	virt_to_bus(hostdata->script + Ent_patch_output_data/4 + sg_start + 2);
1184    targdata->data_in_jump = hostdata->script[Ent_patch_input_data/4+1] =
1185	virt_to_bus(hostdata->script + Ent_patch_input_data/4 + sg_start + 2);
1186
1187    for (i = 0, dsa = virt_to_bus(targdata->dsa); i < 4; i++) {
1188	u32 v = hostdata->script[Ent_patch_new_dsa/4 + i * 2];
1189
1190	v &= ~0x0000ff00;
1191	v |= (dsa & 0xff) << 8;
1192	hostdata->script[Ent_patch_new_dsa/4 + i * 2] = v;
1193	dsa >>= 8;
1194    }
1195    hostdata->running = targdata->cur_cmd = cmd;
1196    hostdata->state = STATE_BUSY;
1197
1198    NCR_write8(ISTAT_REG, ISTAT_10_SIGP);
1199}
1200
1201
1202static volatile int process_issue_queue_running = 0;
1203
1204static __inline__ void
1205run_process_issue_queue(struct sim710_hostdata *hostdata)
1206{
1207    unsigned long flags;
1208    save_flags (flags);
1209    cli();
1210    if (!process_issue_queue_running) {
1211	process_issue_queue_running = 1;
1212	process_issue_queue(hostdata, flags);
1213	/*
1214	 * process_issue_queue_running is cleared in process_issue_queue
1215	 * once it can't do more work, and process_issue_queue exits with
1216	 * interrupts disabled.
1217	 */
1218    }
1219    restore_flags (flags);
1220}
1221
1222
1223/*
1224 * Function : process_issue_queue (hostdata, flags)
1225 *
1226 * Purpose : Start next command for any idle target.
1227 *
1228 * NOTE : process_issue_queue exits with interrupts *disabled*, so the
1229 *	caller must reenable them if it desires.
1230 *
1231 * NOTE : process_issue_queue should be called from both
1232 *	sim710_queue_command() and from the interrupt handler
1233 *	after command completion.
1234 */
1235
1236static void
1237process_issue_queue (struct sim710_hostdata *hostdata, unsigned long flags)
1238{
1239    Scsi_Cmnd *tmp, *prev;
1240    int done;
1241
1242    /*
1243     * We run (with interrupts disabled) until we're sure that none of
1244     * the host adapters have anything that can be done, at which point
1245     * we set process_issue_queue_running to 0 and exit.
1246     *
1247     * Interrupts are enabled before doing various other internal
1248     * instructions, after we've decided that we need to run through
1249     * the loop again.
1250     *
1251     */
1252
1253    do {
1254	cli(); /* Freeze request queues */
1255	done = 1;
1256	if (hostdata->issue_queue) {
1257	    if (hostdata->state == STATE_DISABLED) {
1258		tmp = (Scsi_Cmnd *) hostdata->issue_queue;
1259		hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
1260		tmp->result = (DID_BAD_TARGET << 16);
1261		tmp->scsi_done (tmp);
1262		done = 0;
1263	    }
1264	    else if (hostdata->state == STATE_IDLE) {
1265		for (tmp = hostdata->issue_queue, prev = NULL; tmp;
1266				prev = tmp, tmp = (Scsi_Cmnd *) tmp->SCp.ptr) {
1267		    if (hostdata->target[tmp->target].cur_cmd == NULL) {
1268			if (prev)
1269			    prev->SCp.ptr = tmp->SCp.ptr;
1270			else
1271			    hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
1272			tmp->SCp.ptr = NULL;
1273			run_command (hostdata, tmp);
1274			done = 0;
1275		    } /* if target/lun is not busy */
1276		} /* scan issue queue for work */
1277	    } /* host is idle */
1278	} /* if hostdata->issue_queue */
1279	if (!done)
1280	    restore_flags (flags);
1281    } while (!done);
1282    process_issue_queue_running = 0;
1283}
1284
1285
1286int
1287sim710_queuecommand(Scsi_Cmnd * cmd, void (*done)(Scsi_Cmnd *))
1288{
1289    struct Scsi_Host *host = cmd->host;
1290    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0];
1291    Scsi_Cmnd *tmp;
1292    unsigned long flags;
1293
1294    if (cmd->lun) {
1295	/* Silently ignore luns other than zero! */
1296	cmd->result = (DID_BAD_TARGET << 16);
1297	done(cmd);
1298	return 0;
1299    }
1300
1301    DEB(DEB_CMND, printk("scsi%d: id%d queuing ", host->host_no,
1302		cmd->target));
1303    DEB(DEB_CMND, print_command(cmd->cmnd));
1304
1305    cmd->scsi_done = done;
1306    cmd->host_scribble = NULL;
1307    cmd->SCp.ptr = NULL;
1308    cmd->SCp.buffer = NULL;
1309
1310    save_flags(flags);
1311    cli();
1312
1313    if (ignore_ids[hostdata->chip] & (1 << cmd->target)) {
1314	printk("scsi%d: ignoring target %d\n", host->host_no, cmd->target);
1315	cmd->result = (DID_BAD_TARGET << 16);
1316	done(cmd);
1317	restore_flags (flags);
1318	return 0;
1319    }
1320#ifdef DEBUG_LIMIT_INTS
1321    if (sim710_intrs > DEBUG_LIMIT_INTS) {
1322	cmd->result = (DID_BAD_TARGET << 16);
1323	done(cmd);
1324	restore_flags (flags);
1325	return 0;
1326    }
1327#endif
1328    if (cmd->use_sg > MAX_SG)
1329	panic ("cmd->use_sg = %d\n", cmd->use_sg);
1330
1331    if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
1332        cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
1333        hostdata->issue_queue = cmd;
1334    } else {
1335        for (tmp = hostdata->issue_queue; tmp->SCp.ptr;
1336                tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
1337        tmp->SCp.ptr = (unsigned char *) cmd;
1338    }
1339    restore_flags (flags);
1340    run_process_issue_queue(hostdata);
1341    return 0;
1342}
1343
1344
1345__init int
1346sim710_detect(Scsi_Host_Template * tpnt)
1347{
1348    unsigned char scsi_id;
1349    unsigned int base_addr;
1350    struct Scsi_Host * host = NULL;
1351    struct sim710_hostdata *hostdata;
1352    unsigned long timeout;
1353    unsigned long irq_mask;
1354    int requested_irq;
1355    int probed_irq;
1356    u32 dsps;
1357    int chips = 0;
1358    int limit;
1359    int indx;
1360    int revision;
1361    int size;
1362    volatile u8 tmp;
1363    struct Scsi_Host *our_hosts[MAXBOARDS+1];
1364
1365#ifdef MODULE
1366    if (sim710)
1367	param_setup(sim710);
1368#endif
1369
1370    if (no_of_boards < 0) {
1371	printk("sim710: NCR53C710 driver disabled\n");
1372	return 0;
1373    }
1374
1375#ifdef CONFIG_MCA
1376    /* If board details have been specified via boot/module parameters,
1377     * then don't bother probing.
1378     */
1379    if (no_of_boards == 0) {
1380	int slot;
1381	int pos[3];
1382	int mca_53c710_ids[] = MCA_53C710_IDS;
1383	int *id_to_check = mca_53c710_ids;
1384	static int io_004f_by_pos[] = MCA_004F_IO_PORTS;
1385	static int irq_004f_by_pos[] = MCA_004F_IRQS;
1386	static int io_01bb_by_pos[] = MCA_01BB_IO_PORTS;
1387	static int irq_01bb_by_pos[] = MCA_01BB_IRQS;
1388
1389	while ( *id_to_check && no_of_boards < MAXBOARDS) {
1390	    if (!MCA_bus)
1391		return 0;
1392
1393	    if ((slot = mca_find_adapter(*id_to_check, 0)) != MCA_NOTFOUND) {
1394
1395		pos[0] = mca_read_stored_pos(slot, 2);
1396		pos[1] = mca_read_stored_pos(slot, 3);
1397		pos[2] = mca_read_stored_pos(slot, 4);
1398
1399		/*
1400		 * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2]
1401		 *
1402		 *    000000  <disabled>   001010  0x2800
1403		 *    000001  <invalid>    001011  0x2C00
1404		 *    000010  0x0800       001100  0x3000
1405		 *    000011  0x0C00       001101  0x3400
1406		 *    000100  0x1000       001110  0x3800
1407		 *    000101  0x1400       001111  0x3C00
1408		 *    000110  0x1800       010000  0x4000
1409		 *    000111  0x1C00       010001  0x4400
1410		 *    001000  0x2000       010010  0x4800
1411		 *    001001  0x2400       010011  0x4C00
1412		 *                         010100  0x5000
1413		 *
1414		 * 00F4 port base by bits 3,2,1 in pos[0]
1415		 *
1416		 *    000  <disabled>      001    0x200
1417		 *    010  0x300           011    0x400
1418		 *    100  0x500           101    0x600
1419		 *
1420		 * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6:
1421		 *
1422		 *    00   3               10   11
1423		 *    01   5               11   14
1424		 *
1425		 * 00F4 IRQ specified by bits 6,5,4 in pos[0]
1426		 *
1427		 *    100   5              101    9
1428		 *    110   14
1429		 */
1430
1431		if ( *id_to_check == 0x01bb || *id_to_check == 0x01ba ) {
1432		    bases[no_of_boards] = io_01bb_by_pos[(pos[2] & 0xFC) >> 2];
1433		    irq_vectors[no_of_boards] =
1434				irq_01bb_by_pos[((pos[0] & 0xC0) >> 6)];
1435		    if (bases[no_of_boards] == 0x0000)
1436			printk("sim710: NCR53C710 Adapter ID 0x01bb is disabled.\n");
1437		    else {
1438			no_of_boards++;
1439			if ( *id_to_check == 0x01bb )
1440			    mca_set_adapter_name( slot,
1441				    "NCR 3360/3430 SCSI SubSystem" );
1442			else
1443			    mca_set_adapter_name(slot,
1444				    "NCR Dual SIOP SCSI Host Adapter Board");
1445		    }
1446		}
1447		else if ( *id_to_check == 0x004f ) {
1448		    bases[no_of_boards] = io_004f_by_pos[((pos[0] & 0x0E) >> 1)];
1449		    irq_vectors[no_of_boards] =
1450				irq_004f_by_pos[((pos[0] & 0x70) >> 4) - 4];
1451		    if (bases[no_of_boards] == 0x0000)
1452			printk("sim710: NCR53C710 Adapter ID 0x004f is disabled.\n");
1453		    else {
1454			no_of_boards++;
1455			mca_set_adapter_name(slot,
1456				"NCR 53c710 SCSI Host Adapter Board");
1457		    }
1458		}
1459	    }
1460	    id_to_check++;
1461	}
1462    }
1463#endif
1464
1465#ifdef CONFIG_EISA
1466    /* Auto probe, if no boards specified in boot parameters */
1467    if (no_of_boards == 0) {
1468	int io_addr;
1469	/* reverse probe, so my on-board controller at 0x9000 is always scsi0 */
1470	for (io_addr = 0x9000; no_of_boards < MAXBOARDS && io_addr >= 0x1000; io_addr -= 0x1000) {
1471	    if (request_region(io_addr, 0x40, "sim710") != NULL) {
1472		int id0 = inw(io_addr + 0xc80);
1473		int id1 = inw(io_addr + 0xc82);
1474		/* The on-board controller on my Proliant 2000 is 0x1044,
1475		 * my EISA card is 0x1144.
1476		 */
1477		if (id0 == 0x110e && (id1 == 0x1044 || id1 == 0x1144)) {
1478		    bases[no_of_boards] = io_addr;
1479		    no_of_boards++;
1480		}
1481		release_region(io_addr, 64);
1482	    }
1483	}
1484    }
1485#endif
1486    if (!no_of_boards) {
1487	printk("sim710: No NCR53C710 adapter found.\n");
1488	return 0;
1489    }
1490
1491    size = sizeof(struct sim710_hostdata);
1492    hostdata_order = 0;
1493    while (size > (PAGE_SIZE << hostdata_order))
1494	hostdata_order++;
1495    size = PAGE_SIZE << hostdata_order;
1496
1497    DEB(DEB_ANY, printk("sim710: hostdata %d bytes, size %d, order %d\n",
1498	sizeof(struct sim710_hostdata), size, hostdata_order));
1499
1500    tpnt->proc_name = "sim710";
1501
1502    memset(our_hosts, 0, sizeof(our_hosts));
1503    for (indx = 0; indx < no_of_boards; indx++) {
1504        unsigned long page = __get_free_pages(GFP_ATOMIC, hostdata_order);
1505        if(page == 0UL)
1506        {
1507	    printk(KERN_WARNING "sim710: out of memory registering board %d.\n", indx);
1508	    break;
1509        }
1510	host = scsi_register(tpnt, 4);
1511	if(host == NULL) {
1512	    free_pages(host->hostdata[0], hostdata_order);
1513	    break;
1514	}
1515	our_hosts[chips] = host;
1516	host->hostdata[0] = page;
1517	hostdata = (struct sim710_hostdata *)host->hostdata[0];
1518	memset(hostdata, 0, size);
1519	scsi_id = 7;
1520	base_addr = bases[indx];
1521	requested_irq = irq_vectors[indx];
1522	printk("scsi%d: Configuring Sim710 (SCSI-ID %d) at %x, IRQ %d\n",
1523			host->host_no, scsi_id, base_addr, requested_irq);
1524	DEB(DEB_ANY, printk("sim710: hostdata = %p (%d bytes), dsa0 = %p\n",
1525			hostdata, sizeof(struct sim710_hostdata),
1526			 hostdata->target[0].dsa));
1527	hostdata->chip = indx;
1528	host->irq = requested_irq;
1529	host->this_id = scsi_id;
1530	host->unique_id = base_addr;
1531	host->base = base_addr;
1532	hostdata->msg_reject = MESSAGE_REJECT;
1533
1534	if (ncr_halt(host)) {
1535	    free_pages(host->hostdata[0], hostdata_order);
1536	    scsi_unregister (host);
1537	    printk("scsi%d: Failed to initialise 53c710 at address %x\n",
1538			host->host_no, base_addr);
1539	    continue;
1540	}
1541	DEB(DEB_ANY,ncr_dump(host));
1542	revision = (NCR_read8(CTEST8_REG) & 0xF0) >> 4;
1543	printk("scsi%d: Revision 0x%x\n",host->host_no,revision);
1544	sim710_soft_reset(host);
1545
1546	sim710_driver_init(host);
1547
1548	request_region((u32)host->base, 64, "sim710");
1549	/* Now run test1 */
1550	hostdata->test1_src = 0x53c710aa;
1551	hostdata->test1_dst = 0x76543210;
1552	NCR_write32(DSPS_REG, 0x89abcdef);
1553	irq_mask = probe_irq_on();
1554	NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_test1/4));
1555	timeout = 5;
1556	while (hostdata->test1_dst != hostdata->test1_src && timeout--)
1557	    mdelay(100);
1558	tmp = NCR_read8(ISTAT_REG);
1559	tmp = NCR_read8(SSTAT0_REG);
1560	udelay(10);
1561	tmp = NCR_read8(DSTAT_REG);
1562	probed_irq = probe_irq_off(irq_mask);
1563	if (requested_irq == 0) {
1564	    if (probed_irq > 0) {
1565		printk("scsi%d: Chip is using IRQ %d\n", host->host_no,
1566			probed_irq);
1567		requested_irq = host->irq = probed_irq;
1568	    }
1569	    else {
1570		printk("scsi%d: Failed to probe for IRQ (returned %d)\n",
1571			host->host_no, probed_irq);
1572		ncr_halt(host);
1573		free_pages(host->hostdata[0], hostdata_order);
1574		scsi_unregister (host);
1575		release_region((u32)host->base, 64);
1576		continue;
1577	    }
1578	}
1579	else if (probed_irq > 0 && probed_irq != requested_irq)
1580	    printk("scsi%d: WARNING requested IRQ %d, but probed as %d\n",
1581			host->host_no, requested_irq, probed_irq);
1582	else if (probed_irq <= 0)
1583	    printk("scsi%d: WARNING IRQ probe failed, (returned %d)\n",
1584			host->host_no, probed_irq);
1585
1586	dsps = NCR_read32(DSPS_REG);
1587	if (hostdata->test1_dst != 0x53c710aa || dsps != A_int_test1) {
1588	    if (hostdata->test1_dst != 0x53c710aa)
1589		printk("scsi%d: test 1 FAILED: data: exp 0x53c710aa, got 0x%08x\n",
1590			host->host_no, hostdata->test1_dst);
1591	    if (dsps != A_int_test1)
1592		printk("scsi%d: test 1 FAILED: dsps: exp 0x%08x, got 0x%08x\n",
1593			host->host_no, A_int_test1, dsps);
1594	    ncr_dump(host);
1595	    ncr_halt(host);
1596	    free_pages(host->hostdata[0], hostdata_order);
1597	    scsi_unregister (host);
1598	    release_region((u32)host->base, 64);
1599	    continue;
1600	}
1601	printk("scsi%d: test 1 completed ok.\n", host->host_no);
1602
1603	NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_reselect/4));
1604	hostdata->state = STATE_IDLE;
1605	chips++;
1606    }
1607    /* OK, now run down our_hosts[] calling request_irq(... SA_SHIRQ ...).
1608     * Couldn't call request_irq earlier, as probing would have failed.
1609     */
1610    for (indx = 0, limit = chips; indx < limit; indx++) {
1611	host = our_hosts[indx];
1612	if (request_irq(host->irq, do_sim710_intr_handle,
1613                       SA_INTERRUPT | SA_SHIRQ, "sim710", host))
1614	{
1615	    printk("scsi%d : IRQ%d not free, detaching\n",
1616			host->host_no, host->irq);
1617	    ncr_halt(host);
1618	    free_pages(host->hostdata[0], hostdata_order);
1619	    scsi_unregister (host);
1620	    chips--;
1621	}
1622    }
1623
1624    return chips;
1625}
1626
1627int
1628sim710_abort(Scsi_Cmnd * cmd)
1629{
1630    struct Scsi_Host * host = cmd->host;
1631
1632    printk("scsi%d: Unable to abort command for target %d\n",
1633	   host->host_no, cmd->target);
1634    return FAILED;
1635}
1636
1637/*
1638 * This is a device reset.  Need to select and send a Bus Device Reset msg.
1639 */
1640
1641int
1642sim710_dev_reset(Scsi_Cmnd * SCpnt)
1643{
1644    struct Scsi_Host * host = SCpnt->host;
1645
1646    printk("scsi%d: Unable to send Bus Device Reset for target %d\n",
1647	   host->host_no, SCpnt->target);
1648    return FAILED;
1649}
1650
1651/*
1652 * This is bus reset.  We need to reset the bus and fail any active commands.
1653 */
1654
1655int
1656sim710_bus_reset(Scsi_Cmnd * SCpnt)
1657{
1658    struct Scsi_Host * host = SCpnt->host;
1659
1660    printk("scsi%d: Unable to do SCSI bus reset\n", host->host_no);
1661    return FAILED;
1662}
1663
1664static int
1665full_reset(struct Scsi_Host * host)
1666{
1667    struct sim710_hostdata *hostdata = (struct sim710_hostdata *)
1668	    host->hostdata[0];
1669    int target;
1670    Scsi_Cmnd *cmd;
1671    u32 istat, dstat = 0, sstat0 = 0, sstat1 = 0, dsp, dsps, scratch;
1672    unsigned long flags;
1673
1674    save_flags(flags);
1675    cli();
1676
1677    istat = NCR_read8(ISTAT_REG);
1678    if (istat & ISTAT_SIP) {
1679	sstat0 = NCR_read8(SSTAT0_REG);
1680	sstat1 = NCR_read8(SSTAT1_REG);
1681	udelay(10);
1682    }
1683    if (istat & ISTAT_DIP)
1684	dstat = NCR_read8(DSTAT_REG);
1685
1686    if (ncr_halt(host)) {
1687	restore_flags(flags);
1688	return FAILED;
1689    }
1690    restore_flags(flags);
1691    dsp = NCR_read32(DSP_REG);
1692    dsps = NCR_read32(DSPS_REG);
1693    scratch = NCR_read32(SCRATCH_REG);
1694    printk("scsi%d: istat = %02x, sstat0 = %02x, sstat1 = %02x, dstat = %02x\n",
1695		host->host_no, istat, sstat0, sstat1, dstat);
1696    printk("scsi%d: dsp = %08x (script[0x%04x]), dsps = %08x, scratch = %08x\n",
1697		host->host_no, dsp,
1698		((u32)bus_to_virt(dsp) - (u32)hostdata->script)/4, dsps, scratch);
1699
1700    for (target = 0; target < 7; target++) {
1701	if ((cmd = hostdata->target[target].cur_cmd)) {
1702	    printk("scsi%d: Failing command for ID%d\n",
1703			host->host_no, target);
1704	    cmd->result = DID_RESET << 16;
1705	    cmd->scsi_done(cmd);
1706	    hostdata->target[target].cur_cmd = NULL;
1707	}
1708    }
1709
1710    sim710_soft_reset(host);
1711    sim710_driver_init(host);
1712
1713    NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_reselect/4));
1714    hostdata->state = STATE_IDLE;
1715
1716    run_process_issue_queue(hostdata);
1717
1718    return SUCCESS;
1719}
1720
1721/*
1722 * This is host reset.  We need to reset the chip and the bus.
1723 */
1724
1725int
1726sim710_host_reset(Scsi_Cmnd * SCpnt)
1727{
1728    struct Scsi_Host * host = SCpnt->host;
1729
1730    printk("scsi%d: >>>>>>>>>>>> Host reset <<<<<<<<<<<<\n", host->host_no);
1731
1732    return full_reset(host);
1733}
1734
1735#ifdef MODULE
1736
1737int
1738sim710_release(struct Scsi_Host *host)
1739{
1740    ncr_halt(host);
1741    free_pages(host->hostdata[0], hostdata_order);
1742    free_irq(host->irq, host);
1743    release_region((u32)host->base, 64);
1744    return 1;
1745}
1746
1747#endif
1748
1749static Scsi_Host_Template driver_template = SIM710_SCSI;
1750
1751#include "scsi_module.c"
1752