sim710.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:52k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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