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

Linux/Unix编程

开发平台:

Unix_Linux

  1.     void *real; /* Real address */
  2.     int size; /* Size of *tmp */
  3.     struct NCR53c7x0_cmd *tmp;
  4.     unsigned long flags;
  5.     if (hostdata->options & OPTION_DEBUG_ALLOCATION)
  6. printk ("scsi%d : num_cmds = %d, can_queue = %dn"
  7. "         target = %d, lun = %d, %sn",
  8.     host->host_no, hostdata->num_cmds, host->can_queue,
  9.     cmd->target, cmd->lun, (hostdata->cmd_allocated[cmd->target] &
  10. (1 << cmd->lun)) ? "already allocated" : "not allocated");
  11. /*
  12.  * If we have not yet reserved commands for this I_T_L nexus, and
  13.  * the device exists (as indicated by permanent Scsi_Cmnd structures
  14.  * being allocated under 1.3.x, or being outside of scan_scsis in
  15.  * 1.2.x), do so now.
  16.  */
  17.     if (!(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun)) &&
  18. cmd->device && cmd->device->has_cmdblocks) {
  19.       if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue)
  20.           hostdata->extra_allocate += host->cmd_per_lun;
  21.       hostdata->cmd_allocated[cmd->target] |= (1 << cmd->lun);
  22.     }
  23.     for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate, 
  24.      ++hostdata->num_cmds) {
  25.     /* historically, kmalloc has returned unaligned addresses; pad so we
  26.        have enough room to ROUNDUP */
  27. size = hostdata->max_cmd_size + sizeof (void *);
  28. #ifdef FORCE_DSA_ALIGNMENT
  29. /*
  30.  * 53c710 rev.0 doesn't have an add-with-carry instruction.
  31.  * Ensure we allocate enough memory to force alignment.
  32.  */
  33. size += 256;
  34. #endif
  35. /* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
  36.         if (size > 4096) {
  37.             printk (KERN_ERR "53c7xx: allocate_cmd size > 4Kn");
  38.     return NULL;
  39. }
  40.         real = (void *)get_free_page(GFP_ATOMIC);
  41.         if (real == 0)
  42.          return NULL;
  43.         memset(real, 0, 4096);
  44.         cache_push(virt_to_phys(real), 4096);
  45.         cache_clear(virt_to_phys(real), 4096);
  46.         kernel_set_cachemode(real, 4096, IOMAP_NOCACHE_SER);
  47. tmp = ROUNDUP(real, void *);
  48. #ifdef FORCE_DSA_ALIGNMENT
  49. {
  50.     if (((u32)tmp & 0xff) > CmdPageStart)
  51. tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
  52.     tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
  53. #if 0
  54.     printk ("scsi: size = %d, real = %p, tmp set to 0x%08xn",
  55. size, real, (u32)tmp);
  56. #endif
  57. }
  58. #endif
  59. tmp->real = real;
  60. tmp->size = size;
  61. tmp->free = ((void (*)(void *, int)) my_free_page);
  62. save_flags (flags);
  63. cli();
  64. tmp->next = hostdata->free;
  65. hostdata->free = tmp;
  66. restore_flags (flags);
  67.     }
  68.     save_flags(flags);
  69.     cli();
  70.     tmp = (struct NCR53c7x0_cmd *) hostdata->free;
  71.     if (tmp) {
  72. hostdata->free = tmp->next;
  73.     }
  74.     restore_flags(flags);
  75.     if (!tmp)
  76. printk ("scsi%d : can't allocate command for target %d lun %dn",
  77.     host->host_no, cmd->target, cmd->lun);
  78.     return tmp;
  79. }
  80. /*
  81.  * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) 
  82.  *
  83.  *
  84.  * Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the 
  85.  *  Scsi_Cmnd structure passed in cmd, including dsa and Linux field 
  86.  *  initialization, and dsa code relocation.
  87.  *
  88.  * Inputs : cmd - SCSI command
  89.  *
  90.  * Returns : NCR53c7x0_cmd structure corresponding to cmd,
  91.  * NULL on failure.
  92.  */
  93. static struct NCR53c7x0_cmd *
  94. create_cmd (Scsi_Cmnd *cmd) {
  95.     NCR53c7x0_local_declare();
  96.     struct Scsi_Host *host = cmd->host;
  97.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  98.         host->hostdata[0];
  99.     struct NCR53c7x0_cmd *tmp;  /* NCR53c7x0_cmd structure for this command */
  100.     int datain,   /* Number of instructions per phase */
  101. dataout;
  102.     int data_transfer_instructions, /* Count of dynamic instructions */
  103.      i; /* Counter */
  104.     u32 *cmd_datain, /* Address of datain/dataout code */
  105. *cmd_dataout; /* Incremented as we assemble */
  106. #ifdef notyet
  107.     unsigned char *msgptr; /* Current byte in select message */
  108.     int msglen; /* Length of whole select message */
  109. #endif
  110.     unsigned long flags;
  111.     u32 exp_select_indirect; /* Used in sanity check */
  112.     NCR53c7x0_local_setup(cmd->host);
  113.     if (!(tmp = allocate_cmd (cmd)))
  114. return NULL;
  115.     /*
  116.      * Copy CDB and initialised result fields from Scsi_Cmnd to NCR53c7x0_cmd.
  117.      * We do this because NCR53c7x0_cmd may have a special cache mode
  118.      * selected to cope with lack of bus snooping, etc.
  119.      */
  120.     memcpy(tmp->cmnd, cmd->cmnd, 12);
  121.     tmp->result = cmd->result;
  122.     /*
  123.      * Decide whether we need to generate commands for DATA IN,
  124.      * DATA OUT, neither, or both based on the SCSI command 
  125.      */
  126.     switch (cmd->cmnd[0]) {
  127.     /* These commands do DATA IN */
  128.     case INQUIRY:
  129.     case MODE_SENSE:
  130.     case READ_6:
  131.     case READ_10:
  132.     case READ_CAPACITY:
  133.     case REQUEST_SENSE:
  134.     case READ_BLOCK_LIMITS:
  135.     case READ_TOC:
  136. datain = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
  137.      dataout = 0;
  138. break;
  139.     /* These commands do DATA OUT */
  140.     case MODE_SELECT: 
  141.     case WRITE_6:
  142.     case WRITE_10:
  143. #if 0
  144. printk("scsi%d : command is ", host->host_no);
  145. print_command(cmd->cmnd);
  146. #endif
  147. #if 0
  148. printk ("scsi%d : %d scatter/gather segmentsn", host->host_no,
  149.     cmd->use_sg);
  150. #endif
  151.      datain = 0;
  152. dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
  153. #if 0
  154. hostdata->options |= OPTION_DEBUG_INTR;
  155. #endif
  156. break;
  157.     /* 
  158.      * These commands do no data transfer, we should force an
  159.      * interrupt if a data phase is attempted on them.
  160.      */
  161.     case TEST_UNIT_READY:
  162.     case ALLOW_MEDIUM_REMOVAL:
  163.     case START_STOP:
  164.      datain = dataout = 0;
  165. break;
  166.     /*
  167.      * We don't know about these commands, so generate code to handle
  168.      * both DATA IN and DATA OUT phases.  More efficient to identify them
  169.      * and add them to the above cases.
  170.      */
  171.     default:
  172. printk("scsi%d : datain+dataout for command ", host->host_no);
  173. print_command(cmd->cmnd);
  174. datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
  175.     }
  176.     /*
  177.      * New code : so that active pointers work correctly regardless
  178.      *  of where the saved data pointer is at, we want to immediately
  179.      *  enter the dynamic code after selection, and on a non-data
  180.      *  phase perform a CALL to the non-data phase handler, with
  181.      *  returns back to this address.
  182.      *
  183.      *  If a phase mismatch is encountered in the middle of a 
  184.      *  Block MOVE instruction, we want to _leave_ that instruction
  185.      * unchanged as the current case is, modify a temporary buffer,
  186.      * and point the active pointer (TEMP) at that.
  187.      *
  188.      *  Furthermore, we want to implement a saved data pointer, 
  189.      *  set by the SAVE_DATA_POINTERs message.
  190.      *
  191.      *  So, the data transfer segments will change to 
  192.      * CALL data_transfer, WHEN NOT data phase
  193.      * MOVE x, x, WHEN data phase
  194.      * ( repeat )
  195.      * JUMP other_transfer
  196.      */
  197.     data_transfer_instructions = datain + dataout;
  198.     /*
  199.      * When we perform a request sense, we overwrite various things,
  200.      * including the data transfer code.  Make sure we have enough
  201.      * space to do that.
  202.      */
  203.     if (data_transfer_instructions < 2)
  204.      data_transfer_instructions = 2;
  205.     /*
  206.      * The saved data pointer is set up so that a RESTORE POINTERS message 
  207.      * will start the data transfer over at the beginning.
  208.      */
  209.     tmp->saved_data_pointer = virt_to_bus (hostdata->script) + 
  210. hostdata->E_data_transfer;
  211.     /*
  212.      * Initialize Linux specific fields.
  213.      */
  214.     tmp->cmd = cmd;
  215.     tmp->next = NULL;
  216.     tmp->flags = 0;
  217.     tmp->dsa_next_addr = virt_to_bus(tmp->dsa) + hostdata->dsa_next - 
  218. hostdata->dsa_start;
  219.     tmp->dsa_addr = virt_to_bus(tmp->dsa) - hostdata->dsa_start;
  220.     /* 
  221.      * Calculate addresses of dynamic code to fill in DSA
  222.      */
  223.     tmp->data_transfer_start = tmp->dsa + (hostdata->dsa_end - 
  224.      hostdata->dsa_start) / sizeof(u32);
  225.     tmp->data_transfer_end = tmp->data_transfer_start + 
  226.      2 * data_transfer_instructions;
  227.     cmd_datain = datain ? tmp->data_transfer_start : NULL;
  228.     cmd_dataout = dataout ? (datain ? cmd_datain + 2 * datain : tmp->
  229.      data_transfer_start) : NULL;
  230.     /*
  231.      * Fill in the NCR53c7x0_cmd structure as follows
  232.      * dsa, with fixed up DSA code
  233.      * datain code
  234.      * dataout code
  235.      */
  236.     /* Copy template code into dsa and perform all necessary fixups */
  237.     if (hostdata->dsa_fixup)
  238.      hostdata->dsa_fixup(tmp);
  239.     patch_dsa_32(tmp->dsa, dsa_next, 0, 0);
  240.     /*
  241.      * XXX is this giving 53c710 access to the Scsi_Cmnd in some way?
  242.      * Do we need to change it for caching reasons?
  243.      */
  244.     patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd));
  245.     if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS) {
  246. exp_select_indirect = ((1 << cmd->target) << 16) |
  247. (hostdata->sync[cmd->target].sxfer_sanity << 8);
  248. if (hostdata->sync[cmd->target].select_indirect != 
  249. exp_select_indirect) {
  250.     printk ("scsi%d :  sanity check failed select_indirect=0x%xn",
  251. host->host_no, hostdata->sync[cmd->target].select_indirect);
  252.     FATAL(host);
  253. }
  254.     }
  255.     patch_dsa_32(tmp->dsa, dsa_select, 0,
  256. hostdata->sync[cmd->target].select_indirect);
  257.     /*
  258.      * Right now, we'll do the WIDE and SYNCHRONOUS negotiations on
  259.      * different commands; although it should be trivial to do them
  260.      * both at the same time.
  261.      */
  262.     if (hostdata->initiate_wdtr & (1 << cmd->target)) {
  263. memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
  264.     sizeof(wdtr_message));
  265.      patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message));
  266. save_flags(flags);
  267. cli();
  268. hostdata->initiate_wdtr &= ~(1 << cmd->target);
  269. restore_flags(flags);
  270.     } else if (hostdata->initiate_sdtr & (1 << cmd->target)) {
  271. memcpy ((void *) (tmp->select + 1), (void *) sdtr_message, 
  272.     sizeof(sdtr_message));
  273.      patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message));
  274. tmp->flags |= CMD_FLAG_SDTR;
  275. save_flags(flags);
  276. cli();
  277. hostdata->initiate_sdtr &= ~(1 << cmd->target);
  278. restore_flags(flags);
  279.     
  280.     }
  281. #if 1
  282.     else if (!(hostdata->talked_to & (1 << cmd->target)) && 
  283. !(hostdata->options & OPTION_NO_ASYNC)) {
  284. memcpy ((void *) (tmp->select + 1), (void *) async_message, 
  285.     sizeof(async_message));
  286.      patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(async_message));
  287. tmp->flags |= CMD_FLAG_SDTR;
  288.     } 
  289. #endif
  290.     else 
  291.      patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
  292.     hostdata->talked_to |= (1 << cmd->target);
  293.     tmp->select[0] = (hostdata->options & OPTION_DISCONNECT) ? 
  294. IDENTIFY (1, cmd->lun) : IDENTIFY (0, cmd->lun);
  295.     patch_dsa_32(tmp->dsa, dsa_msgout, 1, virt_to_bus(tmp->select));
  296.     patch_dsa_32(tmp->dsa, dsa_cmdout, 0, cmd->cmd_len);
  297.     patch_dsa_32(tmp->dsa, dsa_cmdout, 1, virt_to_bus(tmp->cmnd));
  298.     patch_dsa_32(tmp->dsa, dsa_dataout, 0, cmd_dataout ? 
  299.          virt_to_bus (cmd_dataout)
  300. : virt_to_bus (hostdata->script) + hostdata->E_other_transfer);
  301.     patch_dsa_32(tmp->dsa, dsa_datain, 0, cmd_datain ? 
  302.          virt_to_bus (cmd_datain) 
  303. : virt_to_bus (hostdata->script) + hostdata->E_other_transfer);
  304.     /* 
  305.      * XXX - need to make endian aware, should use separate variables
  306.      * for both status and message bytes.
  307.      */
  308.     patch_dsa_32(tmp->dsa, dsa_msgin, 0, 1);
  309. /* 
  310.  * FIXME : these only works for little endian.  We probably want to 
  311.  *  provide message and status fields in the NCR53c7x0_cmd 
  312.  * structure, and assign them to cmd->result when we're done.
  313.  */
  314. #ifdef BIG_ENDIAN
  315.     patch_dsa_32(tmp->dsa, dsa_msgin, 1, virt_to_bus(&tmp->result) + 2);
  316.     patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
  317.     patch_dsa_32(tmp->dsa, dsa_status, 1, virt_to_bus(&tmp->result) + 3);
  318. #else
  319.     patch_dsa_32(tmp->dsa, dsa_msgin, 1, virt_to_bus(&tmp->result) + 1);
  320.     patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
  321.     patch_dsa_32(tmp->dsa, dsa_status, 1, virt_to_bus(&tmp->result));
  322. #endif
  323.     patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
  324.     patch_dsa_32(tmp->dsa, dsa_msgout_other, 1, 
  325. virt_to_bus(&(hostdata->NCR53c7xx_msg_nop)));
  326.     
  327.     /*
  328.      * Generate code for zero or more of the DATA IN, DATA OUT phases 
  329.      * in the format 
  330.      *
  331.      * CALL data_transfer, WHEN NOT phase
  332.      * MOVE first buffer length, first buffer address, WHEN phase
  333.      * ...
  334.      * MOVE last buffer length, last buffer address, WHEN phase
  335.      * JUMP other_transfer
  336.      */
  337. /* 
  338.  * See if we're getting to data transfer by generating an unconditional 
  339.  * interrupt.
  340.  */
  341. #if 0
  342.     if (datain) {
  343. cmd_datain[0] = 0x98080000;
  344. cmd_datain[1] = 0x03ffd00d;
  345. cmd_datain += 2;
  346.     }
  347. #endif
  348. /* 
  349.  * XXX - I'm undecided whether all of this nonsense is faster
  350.  * in the long run, or whether I should just go and implement a loop
  351.  * on the NCR chip using table indirect mode?
  352.  *
  353.  * In any case, this is how it _must_ be done for 53c700/700-66 chips,
  354.  * so this stays even when we come up with something better.
  355.  *
  356.  * When we're limited to 1 simultaneous command, no overlapping processing,
  357.  * we're seeing 630K/sec, with 7% CPU usage on a slow Syquest 45M
  358.  * drive.
  359.  *
  360.  * Not bad, not good. We'll see.
  361.  */
  362.     tmp->bounce.len = 0; /* Assume aligned buffer */
  363.     for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, 
  364. cmd_dataout += 4, ++i) {
  365. u32 vbuf = cmd->use_sg ? 
  366.     (u32)(((struct scatterlist *)cmd->buffer)[i].address) :
  367.     (u32)(cmd->request_buffer);
  368. u32 bbuf = virt_to_bus((void *)vbuf);
  369. u32 count = cmd->use_sg ?
  370.     ((struct scatterlist *)cmd->buffer)[i].length :
  371.     cmd->request_bufflen;
  372. /*
  373.  * If we have buffers which are not aligned with 16 byte cache
  374.  * lines, then we just hope nothing accesses the other parts of
  375.  * those cache lines while the transfer is in progress.  That would
  376.  * fill the cache, and subsequent reads of the dma data would pick
  377.  * up the wrong thing.
  378.  * XXX We need a bounce buffer to handle that correctly.
  379.  */
  380. if (((bbuf & 15) || (count & 15)) && (datain || dataout))
  381. {
  382.     /* Bounce buffer needed */
  383.     if (cmd->use_sg)
  384. printk ("53c7xx: Non-aligned buffer with use_sgn");
  385.     else if (datain && dataout)
  386.                 printk ("53c7xx: Non-aligned buffer with datain && dataoutn");
  387.             else if (count > 256)
  388. printk ("53c7xx: Non-aligned transfer > 256 bytesn");
  389.     else
  390.     {
  391.     if (datain)
  392.     {
  393. tmp->bounce.len = count;
  394. tmp->bounce.addr = vbuf;
  395. bbuf = virt_to_bus(tmp->bounce.buf);
  396. tmp->bounce.buf[0] = 0xff;
  397. tmp->bounce.buf[1] = 0xfe;
  398. tmp->bounce.buf[2] = 0xfd;
  399. tmp->bounce.buf[3] = 0xfc;
  400.          }
  401.          if (dataout)
  402.          {
  403. memcpy ((void *)tmp->bounce.buf, (void *)vbuf, count);
  404. bbuf = virt_to_bus(tmp->bounce.buf);
  405.     }
  406.     }
  407. }
  408. if (datain) {
  409.             cache_clear(virt_to_phys((void *)vbuf), count);
  410.     /* CALL other_in, WHEN NOT DATA_IN */  
  411.     cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | 
  412. DCMD_TCI_IO) << 24) | 
  413. DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
  414.     cmd_datain[1] = virt_to_bus (hostdata->script) + 
  415. hostdata->E_other_in;
  416.     /* MOVE count, buf, WHEN DATA_IN */
  417.     cmd_datain[2] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | DCMD_BMI_IO) 
  418.           << 24) | count;
  419.     cmd_datain[3] = bbuf;
  420. #if 0
  421.     print_insn (host, cmd_datain, "dynamic ", 1);
  422.     print_insn (host, cmd_datain + 2, "dynamic ", 1);
  423. #endif
  424. }
  425. if (dataout) {
  426.             cache_push(virt_to_phys((void *)vbuf), count);
  427.     /* CALL other_out, WHEN NOT DATA_OUT */
  428.     cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL) << 24) | 
  429. DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
  430.     cmd_dataout[1] = virt_to_bus(hostdata->script) + 
  431.           hostdata->E_other_out;
  432.     /* MOVE count, buf, WHEN DATA+OUT */
  433.     cmd_dataout[2] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I) << 24) 
  434. | count;
  435.     cmd_dataout[3] = bbuf;
  436. #if 0
  437.     print_insn (host, cmd_dataout, "dynamic ", 1);
  438.     print_insn (host, cmd_dataout + 2, "dynamic ", 1);
  439. #endif
  440. }
  441.     }
  442.     /*
  443.      * Install JUMP instructions after the data transfer routines to return
  444.      * control to the do_other_transfer routines.
  445.      */
  446.   
  447.     
  448.     if (datain) {
  449. cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
  450.          DBC_TCI_TRUE;
  451. cmd_datain[1] = virt_to_bus(hostdata->script) + 
  452.          hostdata->E_other_transfer;
  453. #if 0
  454. print_insn (host, cmd_datain, "dynamic jump ", 1);
  455. #endif
  456. cmd_datain += 2; 
  457.     }
  458. #if 0
  459.     if (datain) {
  460. cmd_datain[0] = 0x98080000;
  461. cmd_datain[1] = 0x03ffdeed;
  462. cmd_datain += 2;
  463.     }
  464. #endif
  465.     if (dataout) {
  466. cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
  467.          DBC_TCI_TRUE;
  468. cmd_dataout[1] = virt_to_bus(hostdata->script) + 
  469.          hostdata->E_other_transfer;
  470. #if 0
  471. print_insn (host, cmd_dataout, "dynamic jump ", 1);
  472. #endif
  473. cmd_dataout += 2;
  474.     }
  475.     return tmp;
  476. }
  477. /*
  478.  * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd,
  479.  *      void (*done)(Scsi_Cmnd *))
  480.  *
  481.  * Purpose :  enqueues a SCSI command
  482.  *
  483.  * Inputs : cmd - SCSI command, done - function called on completion, with
  484.  *      a pointer to the command descriptor.
  485.  *
  486.  * Returns : 0
  487.  *
  488.  * Side effects :
  489.  *      cmd is added to the per instance driver issue_queue, with major
  490.  *      twiddling done to the host specific fields of cmd.  If the
  491.  *      process_issue_queue coroutine isn't running, it is restarted.
  492.  * 
  493.  * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to 
  494.  * hold our own data, and pervert the ptr field of the SCp field
  495.  * to create a linked list.
  496.  */
  497. int
  498. NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
  499.     struct Scsi_Host *host = cmd->host;
  500.     struct NCR53c7x0_hostdata *hostdata = 
  501. (struct NCR53c7x0_hostdata *) host->hostdata[0];
  502.     unsigned long flags;
  503.     Scsi_Cmnd *tmp;
  504.     cmd->scsi_done = done;
  505.     cmd->host_scribble = NULL;
  506.     cmd->SCp.ptr = NULL;
  507.     cmd->SCp.buffer = NULL;
  508. #ifdef VALID_IDS
  509.     /* Ignore commands on invalid IDs */
  510.     if (!hostdata->valid_ids[cmd->target]) {
  511.         printk("scsi%d : ignoring target %d lun %dn", host->host_no,
  512.             cmd->target, cmd->lun);
  513.         cmd->result = (DID_BAD_TARGET << 16);
  514.         done(cmd);
  515.         return 0;
  516.     }
  517. #endif
  518.     save_flags(flags);
  519.     cli();
  520.     if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY)) 
  521. || ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
  522.     !(hostdata->debug_lun_limit[cmd->target] & (1 << cmd->lun))) 
  523. #ifdef LINUX_1_2
  524. || cmd->target > 7
  525. #else
  526. || cmd->target > host->max_id
  527. #endif
  528. || cmd->target == host->this_id
  529. || hostdata->state == STATE_DISABLED) {
  530. printk("scsi%d : disabled or bad target %d lun %dn", host->host_no,
  531.     cmd->target, cmd->lun);
  532. cmd->result = (DID_BAD_TARGET << 16);
  533. done(cmd);
  534. restore_flags (flags);
  535. return 0;
  536.     }
  537.     if ((hostdata->options & OPTION_DEBUG_NCOMMANDS_LIMIT) &&
  538. (hostdata->debug_count_limit == 0)) {
  539. printk("scsi%d : maximum commands exceededn", host->host_no);
  540. cmd->result = (DID_BAD_TARGET << 16);
  541. done(cmd);
  542. restore_flags (flags);
  543. return 0;
  544.     }
  545.     if (hostdata->options & OPTION_DEBUG_READ_ONLY) {
  546. switch (cmd->cmnd[0]) {
  547. case WRITE_6:
  548. case WRITE_10:
  549.     printk("scsi%d : WRITE attempted with NO_WRITE debugging flag setn",
  550. host->host_no);
  551.     cmd->result = (DID_BAD_TARGET << 16);
  552.     done(cmd);
  553.     restore_flags (flags);
  554.     return 0;
  555. }
  556.     }
  557.     if ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
  558.     hostdata->debug_count_limit != -1) 
  559. --hostdata->debug_count_limit;
  560.     cmd->result = 0xffff; /* The NCR will overwrite message
  561.        and status with valid data */
  562.     cmd->host_scribble = (unsigned char *) tmp = create_cmd (cmd);
  563.     /*
  564.      * REQUEST SENSE commands are inserted at the head of the queue 
  565.      * so that we do not clear the contingent allegiance condition
  566.      * they may be looking at.
  567.      */
  568.     if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
  569. cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
  570. hostdata->issue_queue = cmd;
  571.     } else {
  572. for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr; 
  573. tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
  574. tmp->SCp.ptr = (unsigned char *) cmd;
  575.     }
  576.     restore_flags (flags);
  577.     run_process_issue_queue();
  578.     return 0;
  579. }
  580. /*
  581.  * Function : void to_schedule_list (struct Scsi_Host *host,
  582.  *  struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd)
  583.  *
  584.  * Purpose : takes a SCSI command which was just removed from the 
  585.  * issue queue, and deals with it by inserting it in the first
  586.  * free slot in the schedule list or by terminating it immediately.
  587.  *
  588.  * Inputs : 
  589.  * host - SCSI host adapter; hostdata - hostdata structure for 
  590.  * this adapter; cmd - a pointer to the command; should have 
  591.  * the host_scribble field initialized to point to a valid 
  592.  *
  593.  * Side effects : 
  594.  *      cmd is added to the per instance schedule list, with minor 
  595.  *      twiddling done to the host specific fields of cmd.
  596.  *
  597.  */
  598. static __inline__ void
  599. to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
  600.     struct NCR53c7x0_cmd *cmd) {
  601.     NCR53c7x0_local_declare();
  602.     Scsi_Cmnd *tmp = cmd->cmd;
  603.     unsigned long flags;
  604.     /* dsa start is negative, so subtraction is used */
  605.     volatile u32 *ncrcurrent;
  606.     int i;
  607.     NCR53c7x0_local_setup(host);
  608. #if 0
  609.     printk("scsi%d : new dsa is 0x%lx (virt 0x%p)n", host->host_no, 
  610. virt_to_bus(hostdata->dsa), hostdata->dsa);
  611. #endif
  612.     save_flags(flags);
  613.     cli();
  614.     
  615.     /* 
  616.      * Work around race condition : if an interrupt fired and we 
  617.      * got disabled forget about this command.
  618.      */
  619.     if (hostdata->state == STATE_DISABLED) {
  620. printk("scsi%d : driver disabledn", host->host_no);
  621. tmp->result = (DID_BAD_TARGET << 16);
  622. cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
  623. hostdata->free = cmd;
  624. tmp->scsi_done(tmp);
  625. restore_flags (flags);
  626. return;
  627.     }
  628.     for (i = host->can_queue, ncrcurrent = hostdata->schedule; 
  629. i > 0  && ncrcurrent[0] != hostdata->NOP_insn;
  630. --i, ncrcurrent += 2 /* JUMP instructions are two words */);
  631.     if (i > 0) {
  632. ++hostdata->busy[tmp->target][tmp->lun];
  633. cmd->next = hostdata->running_list;
  634. hostdata->running_list = cmd;
  635. /* Restore this instruction to a NOP once the command starts */
  636. cmd->dsa [(hostdata->dsa_jump_dest - hostdata->dsa_start) / 
  637.     sizeof(u32)] = (u32) virt_to_bus ((void *)ncrcurrent);
  638. /* Replace the current jump operand.  */
  639. ncrcurrent[1] =
  640.     virt_to_bus ((void *) cmd->dsa) + hostdata->E_dsa_code_begin -
  641.     hostdata->E_dsa_code_template;
  642. /* Replace the NOP instruction with a JUMP */
  643. ncrcurrent[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) |
  644.     DBC_TCI_TRUE;
  645.     }  else {
  646. printk ("scsi%d: no free slotn", host->host_no);
  647. disable(host);
  648. tmp->result = (DID_ERROR << 16);
  649. cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
  650. hostdata->free = cmd;
  651. tmp->scsi_done(tmp);
  652. restore_flags (flags);
  653. return;
  654.     }
  655.     /* 
  656.      * If the NCR chip is in an idle state, start it running the scheduler
  657.      * immediately.  Otherwise, signal the chip to jump to schedule as 
  658.      * soon as it is idle.
  659.      */
  660.     if (hostdata->idle) {
  661. hostdata->idle = 0;
  662. hostdata->state = STATE_RUNNING;
  663. NCR53c7x0_write32 (DSP_REG,  virt_to_bus ((void *)hostdata->schedule));
  664. if (hostdata->options & OPTION_DEBUG_TRACE)
  665.     NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl |
  666. DCNTL_SSM | DCNTL_STD);
  667.     } else {
  668. NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP);
  669.     }
  670.     restore_flags(flags);
  671. }
  672. /*
  673.  * Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata 
  674.  * *hostdata, Scsi_Cmnd *cmd)
  675.  *
  676.  * Purpose : decide if we can pass the given SCSI command on to the 
  677.  * device in question or not.
  678.  *  
  679.  * Returns : non-zero when we're busy, 0 when we aren't.
  680.  */
  681. static __inline__ int
  682. busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata, 
  683.     Scsi_Cmnd *cmd) {
  684.     /* FIXME : in the future, this needs to accommodate SCSI-II tagged
  685.        queuing, and we may be able to play with fairness here a bit.
  686.      */
  687.     return hostdata->busy[cmd->target][cmd->lun];
  688. }
  689. /*
  690.  * Function : process_issue_queue (void)
  691.  *
  692.  * Purpose : transfer commands from the issue queue to NCR start queue 
  693.  * of each NCR53c7/8xx in the system, avoiding kernel stack 
  694.  * overflows when the scsi_done() function is invoked recursively.
  695.  * 
  696.  * NOTE : process_issue_queue exits with interrupts *disabled*, so the 
  697.  * caller must reenable them if it desires.
  698.  * 
  699.  * NOTE : process_issue_queue should be called from both 
  700.  * NCR53c7x0_queue_command() and from the interrupt handler 
  701.  * after command completion in case NCR53c7x0_queue_command()
  702.  *  isn't invoked again but we've freed up resources that are
  703.  * needed.
  704.  */
  705. static void 
  706. process_issue_queue (unsigned long flags) {
  707.     Scsi_Cmnd *tmp, *prev;
  708.     struct Scsi_Host *host;
  709.     struct NCR53c7x0_hostdata *hostdata;
  710.     int done;
  711.     /*
  712.      * We run (with interrupts disabled) until we're sure that none of 
  713.      * the host adapters have anything that can be done, at which point 
  714.      * we set process_issue_queue_running to 0 and exit.
  715.      *
  716.      * Interrupts are enabled before doing various other internal 
  717.      * instructions, after we've decided that we need to run through
  718.      * the loop again.
  719.      *
  720.      */
  721.     do {
  722. cli(); /* Freeze request queues */
  723. done = 1;
  724. for (host = first_host; host && host->hostt == the_template;
  725.     host = host->next) {
  726.     hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
  727.     cli();
  728.     if (hostdata->issue_queue) {
  729.      if (hostdata->state == STATE_DISABLED) {
  730.     tmp = (Scsi_Cmnd *) hostdata->issue_queue;
  731.     hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
  732.     tmp->result = (DID_BAD_TARGET << 16);
  733.     if (tmp->host_scribble) {
  734. ((struct NCR53c7x0_cmd *)tmp->host_scribble)->next = 
  735.     hostdata->free;
  736. hostdata->free = 
  737.     (struct NCR53c7x0_cmd *)tmp->host_scribble;
  738. tmp->host_scribble = NULL;
  739.     }
  740.     tmp->scsi_done (tmp);
  741.     done = 0;
  742. } else 
  743.     for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, 
  744. prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) 
  745. tmp->SCp.ptr) 
  746. if (!tmp->host_scribble || 
  747.     !busyp (host, hostdata, tmp)) {
  748. if (prev)
  749.     prev->SCp.ptr = tmp->SCp.ptr;
  750. else
  751.     hostdata->issue_queue = (Scsi_Cmnd *) 
  752. tmp->SCp.ptr;
  753.     tmp->SCp.ptr = NULL;
  754.     if (tmp->host_scribble) {
  755. if (hostdata->options & OPTION_DEBUG_QUEUES) 
  756.     printk ("scsi%d : moving command for target %d lun %d to start listn",
  757. host->host_no, tmp->target, tmp->lun);
  758.      to_schedule_list (host, hostdata, 
  759.     (struct NCR53c7x0_cmd *)
  760.     tmp->host_scribble);
  761.     } else {
  762. if (((tmp->result & 0xff) == 0xff) ||
  763.          ((tmp->result & 0xff00) == 0xff00)) {
  764.     printk ("scsi%d : danger Will Robinson!n",
  765. host->host_no);
  766.     tmp->result = DID_ERROR << 16;
  767.     disable (host);
  768. }
  769. tmp->scsi_done(tmp);
  770.     }
  771.     done = 0;
  772. } /* if target/lun is not busy */
  773.     } /* if hostdata->issue_queue */
  774.     if (!done)
  775. restore_flags (flags);
  776.      } /* for host */
  777.     } while (!done);
  778.     process_issue_queue_running = 0;
  779. }
  780. /*
  781.  * Function : static void intr_scsi (struct Scsi_Host *host, 
  782.  *  struct NCR53c7x0_cmd *cmd)
  783.  *
  784.  * Purpose : handle all SCSI interrupts, indicated by the setting 
  785.  *  of the SIP bit in the ISTAT register.
  786.  *
  787.  * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
  788.  *  may be NULL.
  789.  */
  790. static void 
  791. intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
  792.     NCR53c7x0_local_declare();
  793.     struct NCR53c7x0_hostdata *hostdata = 
  794.      (struct NCR53c7x0_hostdata *) host->hostdata[0];
  795.     unsigned char sstat0_sist0, sist1,  /* Registers */
  796.     fatal;  /* Did a fatal interrupt 
  797.    occur ? */
  798.    
  799.     NCR53c7x0_local_setup(host);
  800.     fatal = 0;
  801.     sstat0_sist0 = NCR53c7x0_read8(SSTAT0_REG);
  802.     sist1 = 0;
  803.     if (hostdata->options & OPTION_DEBUG_INTR) 
  804. printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0xn", host->host_no,
  805.     sstat0_sist0, sist1);
  806.     /* 250ms selection timeout */
  807.     if (sstat0_sist0 & SSTAT0_700_STO) {
  808. fatal = 1;
  809. if (hostdata->options & OPTION_DEBUG_INTR) {
  810.     printk ("scsi%d : Selection Timeoutn", host->host_no);
  811.          if (cmd) {
  812.           printk("scsi%d : target %d, lun %d, command ",
  813.               host->host_no, cmd->cmd->target, cmd->cmd->lun);
  814.           print_command (cmd->cmd->cmnd);
  815. printk("scsi%d : dsp = 0x%x (virt 0x%p)n", host->host_no,
  816.     NCR53c7x0_read32(DSP_REG),
  817.     bus_to_virt(NCR53c7x0_read32(DSP_REG)));
  818.          } else {
  819.           printk("scsi%d : no commandn", host->host_no);
  820.          }
  821.      }
  822. /*
  823.  * XXX - question : how do we want to handle the Illegal Instruction
  824.  *  interrupt, which may occur before or after the Selection Timeout
  825.  *  interrupt?
  826.  */
  827. if (1) {
  828.     hostdata->idle = 1;
  829.     hostdata->expecting_sto = 0;
  830.     if (hostdata->test_running) {
  831. hostdata->test_running = 0;
  832. hostdata->test_completed = 3;
  833.     } else if (cmd) {
  834. abnormal_finished(cmd, DID_BAD_TARGET << 16);
  835.     }
  836. #if 0     
  837.     hostdata->intrs = 0;
  838. #endif
  839. }
  840.     } 
  841. /*
  842.  * FIXME : in theory, we can also get a UDC when a STO occurs.
  843.  */
  844.     if (sstat0_sist0 & SSTAT0_UDC) {
  845. fatal = 1;
  846. if (cmd) {
  847.     printk("scsi%d : target %d lun %d unexpected disconnectn",
  848. host->host_no, cmd->cmd->target, cmd->cmd->lun);
  849.     print_lots (host);
  850.     abnormal_finished(cmd, DID_ERROR << 16);
  851. } else 
  852.      printk("scsi%d : unexpected disconnect (no command)n",
  853. host->host_no);
  854. hostdata->dsp = (u32 *) hostdata->schedule;
  855. hostdata->dsp_changed = 1;
  856.     }
  857.     /* SCSI PARITY error */
  858.     if (sstat0_sist0 & SSTAT0_PAR) {
  859. fatal = 1;
  860. if (cmd && cmd->cmd) {
  861.     printk("scsi%d : target %d lun %d parity error.n",
  862. host->host_no, cmd->cmd->target, cmd->cmd->lun);
  863.     abnormal_finished (cmd, DID_PARITY << 16); 
  864. } else
  865.     printk("scsi%d : parity errorn", host->host_no);
  866. /* Should send message out, parity error */
  867. /* XXX - Reduce synchronous transfer rate! */
  868. hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
  869.          sizeof(u32);
  870. hostdata->dsp_changed = 1; 
  871.     /* SCSI GROSS error */
  872.     } 
  873.     if (sstat0_sist0 & SSTAT0_SGE) {
  874. fatal = 1;
  875. printk("scsi%d : gross error, saved2_dsa = 0x%xn", host->host_no,
  876. (unsigned int)hostdata->saved2_dsa);
  877. print_lots (host);
  878. /* 
  879.          * A SCSI gross error may occur when we have 
  880.  *
  881.  * - A synchronous offset which causes the SCSI FIFO to be overwritten.
  882.  *
  883.  * - A REQ which causes the maximum synchronous offset programmed in 
  884.  *  the SXFER register to be exceeded.
  885.  *
  886.  * - A phase change with an outstanding synchronous offset.
  887.  *
  888.  * - Residual data in the synchronous data FIFO, with a transfer
  889.  * other than a synchronous receive is started.$#
  890.  */
  891. /* XXX Should deduce synchronous transfer rate! */
  892. hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
  893.          sizeof(u32);
  894. hostdata->dsp_changed = 1;
  895.     /* Phase mismatch */
  896.     } 
  897.     if (sstat0_sist0 & SSTAT0_MA) {
  898. fatal = 1;
  899. if (hostdata->options & OPTION_DEBUG_INTR)
  900.     printk ("scsi%d : SSTAT0_MAn", host->host_no);
  901. intr_phase_mismatch (host, cmd);
  902.     }
  903. #if 0
  904.     if (sstat0_sist0 & SIST0_800_RSL) 
  905. printk ("scsi%d : Oh no Mr. Bill!n", host->host_no);
  906. #endif
  907.     
  908. /*
  909.  * If a fatal SCSI interrupt occurs, we must insure that the DMA and
  910.  * SCSI FIFOs were flushed.
  911.  */
  912.     if (fatal) {
  913. if (!hostdata->dstat_valid) {
  914.     hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
  915.     hostdata->dstat_valid = 1;
  916. }
  917. if (!(hostdata->dstat & DSTAT_DFE)) {
  918.   printk ("scsi%d : DMA FIFO not emptyn", host->host_no);
  919.   /*
  920.    * Really need to check this code for 710  RGH.
  921.    * Havn't seen any problems, but maybe we should FLUSH before
  922.    * clearing sometimes.
  923.    */
  924.           NCR53c7x0_write8 (CTEST8_REG, CTEST8_10_CLF);
  925.           while (NCR53c7x0_read8 (CTEST8_REG) & CTEST8_10_CLF)
  926. ;
  927.   hostdata->dstat |= DSTAT_DFE;
  928.      }
  929.     }
  930. }
  931. #ifdef CYCLIC_TRACE
  932. /*
  933.  * The following implements a cyclic log of instructions executed, if you turn
  934.  * TRACE on.  It will also print the log for you.  Very useful when debugging
  935.  * 53c710 support, possibly not really needed any more.
  936.  */
  937. u32 insn_log[4096];
  938. u32 insn_log_index = 0;
  939. void log1 (u32 i)
  940. {
  941. insn_log[insn_log_index++] = i;
  942. if (insn_log_index == 4096)
  943. insn_log_index = 0;
  944. }
  945. void log_insn (u32 *ip)
  946. {
  947. log1 ((u32)ip);
  948. log1 (*ip);
  949. log1 (*(ip+1));
  950. if (((*ip >> 24) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI)
  951. log1 (*(ip+2));
  952. }
  953. void dump_log(void)
  954. {
  955. int cnt = 0;
  956. int i = insn_log_index;
  957. int size;
  958. struct Scsi_Host *host = first_host;
  959. while (cnt < 4096) {
  960. printk ("%08x (+%6x): ", insn_log[i], (insn_log[i] - (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4);
  961. if (++i == 4096)
  962. i = 0;
  963. cnt++;
  964. if (((insn_log[i]  >> 24) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI) 
  965. size = 3;
  966. else
  967. size = 2;
  968. while (size--) {
  969. printk ("%08x ", insn_log[i]);
  970. if (++i == 4096)
  971. i = 0;
  972. cnt++;
  973. }
  974. printk ("n");
  975. }
  976. }
  977. #endif
  978. /*
  979.  * Function : static void NCR53c7x0_intfly (struct Scsi_Host *host)
  980.  *
  981.  * Purpose : Scan command queue for specified host, looking for completed
  982.  *           commands.
  983.  * 
  984.  * Inputs : Scsi_Host pointer.
  985.  *
  986.  *  This is called from the interrupt handler, when a simulated INTFLY
  987.  *  interrupt occurs.
  988.  */
  989. static void
  990. NCR53c7x0_intfly (struct Scsi_Host *host)
  991. {
  992.     NCR53c7x0_local_declare();
  993.     struct NCR53c7x0_hostdata *hostdata; /* host->hostdata[0] */
  994.     struct NCR53c7x0_cmd *cmd, /* command which halted */
  995. **cmd_prev_ptr;
  996.     unsigned long flags;
  997.     char search_found = 0; /* Got at least one ? */
  998.     hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
  999.     NCR53c7x0_local_setup(host);
  1000.     if (hostdata->options & OPTION_DEBUG_INTR)
  1001.     printk ("scsi%d : INTFLYn", host->host_no); 
  1002.     /*
  1003.     * Traverse our list of running commands, and look
  1004.     * for those with valid (non-0xff ff) status and message
  1005.     * bytes encoded in the result which signify command
  1006.     * completion.
  1007.     */
  1008.     save_flags(flags);
  1009.     cli();
  1010. restart:
  1011.     for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)&(hostdata->running_list),
  1012. cmd = (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
  1013. cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next), 
  1014.      cmd = (struct NCR53c7x0_cmd *) cmd->next)
  1015.     {
  1016. Scsi_Cmnd *tmp;
  1017. if (!cmd) {
  1018.     printk("scsi%d : very weird.n", host->host_no);
  1019.     break;
  1020. }
  1021. if (!(tmp = cmd->cmd)) {
  1022.     printk("scsi%d : weird.  NCR53c7x0_cmd has no Scsi_Cmndn",
  1023.     host->host_no);
  1024.     continue;
  1025. }
  1026. /* Copy the result over now; may not be complete,
  1027.  * but subsequent tests may as well be done on
  1028.  * cached memory.
  1029.  */
  1030. tmp->result = cmd->result;
  1031. if (((tmp->result & 0xff) == 0xff) ||
  1032.     ((tmp->result & 0xff00) == 0xff00))
  1033.     continue;
  1034. search_found = 1;
  1035. if (cmd->bounce.len)
  1036.     memcpy ((void *)cmd->bounce.addr,
  1037. (void *)cmd->bounce.buf, cmd->bounce.len);
  1038. /* Important - remove from list _before_ done is called */
  1039. if (cmd_prev_ptr)
  1040.     *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
  1041. --hostdata->busy[tmp->target][tmp->lun];
  1042. cmd->next = hostdata->free;
  1043. hostdata->free = cmd;
  1044. tmp->host_scribble = NULL;
  1045. if (hostdata->options & OPTION_DEBUG_INTR) {
  1046.     printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ", 
  1047.   host->host_no, tmp->pid, tmp->target, tmp->lun, tmp->result);
  1048.     print_command (tmp->cmnd);
  1049. }
  1050. tmp->scsi_done(tmp);
  1051. goto restart;
  1052.     }
  1053.     restore_flags(flags);
  1054.     if (!search_found)  {
  1055. printk ("scsi%d : WARNING : INTFLY with no completed commands.n",
  1056.     host->host_no);
  1057.     } else {
  1058. run_process_issue_queue();
  1059.     }
  1060.     return;
  1061. }
  1062. /*
  1063.  * Function : static void NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs)
  1064.  *
  1065.  * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing
  1066.  * the same IRQ line.  
  1067.  * 
  1068.  * Inputs : Since we're using the SA_INTERRUPT interrupt handler
  1069.  * semantics, irq indicates the interrupt which invoked 
  1070.  * this handler.  
  1071.  *
  1072.  * On the 710 we simualte an INTFLY with a script interrupt, and the
  1073.  * script interrupt handler will call back to this function.
  1074.  */
  1075. static void 
  1076. NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) {
  1077.     NCR53c7x0_local_declare();
  1078.     struct Scsi_Host *host; /* Host we are looking at */
  1079.     unsigned char istat;  /* Values of interrupt regs */
  1080.     struct NCR53c7x0_hostdata *hostdata; /* host->hostdata[0] */
  1081.     struct NCR53c7x0_cmd *cmd; /* command which halted */
  1082.     u32 *dsa; /* DSA */
  1083. #ifdef NCR_DEBUG
  1084.     char buf[80]; /* Debugging sprintf buffer */
  1085.     size_t buflen; /* Length of same */
  1086. #endif
  1087.     host     = (struct Scsi_Host *)dev_id;
  1088.     hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
  1089.     NCR53c7x0_local_setup(host);
  1090.     /*
  1091.      * Only read istat once per loop, since reading it again will unstack
  1092.      * interrupts
  1093.      */
  1094.     while ((istat = NCR53c7x0_read8(hostdata->istat)) & (ISTAT_SIP|ISTAT_DIP)) {
  1095. hostdata->dsp_changed = 0;
  1096. hostdata->dstat_valid = 0;
  1097.      hostdata->state = STATE_HALTED;
  1098. if (NCR53c7x0_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) 
  1099.     printk ("scsi%d : SCSI FIFO not emptyn", host->host_no);
  1100. /*
  1101.  * NCR53c700 and NCR53c700-66 change the current SCSI
  1102.  * process, hostdata->ncrcurrent, in the Linux driver so
  1103.  * cmd = hostdata->ncrcurrent.
  1104.  *
  1105.  * With other chips, we must look through the commands
  1106.  * executing and find the command structure which 
  1107.  * corresponds to the DSA register.
  1108.  */
  1109. if (hostdata->options & OPTION_700) {
  1110.     cmd = (struct NCR53c7x0_cmd *) hostdata->ncrcurrent;
  1111. } else {
  1112.     dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
  1113.     for (cmd = (struct NCR53c7x0_cmd *) hostdata->running_list;
  1114. cmd && (dsa + (hostdata->dsa_start / sizeof(u32))) != cmd->dsa;
  1115.     cmd = (struct NCR53c7x0_cmd *)(cmd->next))
  1116. ;
  1117. }
  1118. if (hostdata->options & OPTION_DEBUG_INTR) {
  1119.     if (cmd) {
  1120. printk("scsi%d : interrupt for pid %lu, id %d, lun %d ", 
  1121.     host->host_no, cmd->cmd->pid, (int) cmd->cmd->target,
  1122.     (int) cmd->cmd->lun);
  1123. print_command (cmd->cmd->cmnd);
  1124.     } else {
  1125. printk("scsi%d : no active commandn", host->host_no);
  1126.     }
  1127. }
  1128. if (istat & ISTAT_SIP) {
  1129.     if (hostdata->options & OPTION_DEBUG_INTR) 
  1130. printk ("scsi%d : ISTAT_SIPn", host->host_no);
  1131.     intr_scsi (host, cmd);
  1132. }
  1133. if (istat & ISTAT_DIP) {
  1134.     if (hostdata->options & OPTION_DEBUG_INTR) 
  1135. printk ("scsi%d : ISTAT_DIPn", host->host_no);
  1136.     intr_dma (host, cmd);
  1137. }
  1138. if (!hostdata->dstat_valid) {
  1139.     hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
  1140.     hostdata->dstat_valid = 1;
  1141. }
  1142. if (!(hostdata->dstat & DSTAT_DFE)) {
  1143.     printk ("scsi%d : DMA FIFO not emptyn", host->host_no);
  1144.     /* Really need to check this out for 710 RGH */
  1145.     NCR53c7x0_write8 (CTEST8_REG, CTEST8_10_CLF);
  1146.     while (NCR53c7x0_read8 (CTEST8_REG) & CTEST8_10_CLF)
  1147. ;
  1148.     hostdata->dstat |= DSTAT_DFE;
  1149. }
  1150. if (!hostdata->idle && hostdata->state == STATE_HALTED) {
  1151.     if (!hostdata->dsp_changed)
  1152. hostdata->dsp = (u32 *)bus_to_virt(NCR53c7x0_read32(DSP_REG));
  1153. #if 0
  1154.     printk("scsi%d : new dsp is 0x%lx (virt 0x%p)n",
  1155. host->host_no,  virt_to_bus(hostdata->dsp), hostdata->dsp);
  1156. #endif
  1157.     hostdata->state = STATE_RUNNING;
  1158.     NCR53c7x0_write32 (DSP_REG, virt_to_bus(hostdata->dsp));
  1159.     if (hostdata->options & OPTION_DEBUG_TRACE) {
  1160. #ifdef CYCLIC_TRACE
  1161. log_insn (hostdata->dsp);
  1162. #else
  1163.      print_insn (host, hostdata->dsp, "t ", 1);
  1164. #endif
  1165. NCR53c7x0_write8 (DCNTL_REG,
  1166. hostdata->saved_dcntl | DCNTL_SSM | DCNTL_STD);
  1167.     }
  1168. }
  1169.     }
  1170. }
  1171. /* 
  1172.  * Function : static int abort_connected (struct Scsi_Host *host)
  1173.  *
  1174.  * Purpose : Assuming that the NCR SCSI processor is currently 
  1175.  *  halted, break the currently established nexus.  Clean
  1176.  * up of the NCR53c7x0_cmd and Scsi_Cmnd structures should
  1177.  * be done on receipt of the abort interrupt.
  1178.  *
  1179.  * Inputs : host - SCSI host
  1180.  *
  1181.  */
  1182. static int 
  1183. abort_connected (struct Scsi_Host *host) {
  1184. #ifdef NEW_ABORT
  1185.     NCR53c7x0_local_declare();
  1186. #endif
  1187.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  1188. host->hostdata[0];
  1189. /* FIXME : this probably should change for production kernels; at the 
  1190.    least, counter should move to a per-host structure. */
  1191.     static int counter = 5;
  1192. #ifdef NEW_ABORT
  1193.     int sstat, phase, offset;
  1194.     u32 *script;
  1195.     NCR53c7x0_local_setup(host);
  1196. #endif
  1197.     if (--counter <= 0) {
  1198. disable(host);
  1199. return 0;
  1200.     }
  1201.     printk ("scsi%d : DANGER : abort_connected() called n",
  1202. host->host_no);
  1203. #ifdef NEW_ABORT
  1204. /*
  1205.  * New strategy : Rather than using a generic abort routine,
  1206.  * we'll specifically try to source or sink the appropriate
  1207.  * amount of data for the phase we're currently in (taking into 
  1208.  * account the current synchronous offset) 
  1209.  */
  1210.     sstat = (NCR53c8x0_read8 (SSTAT2_REG);
  1211.     offset = OFFSET (sstat & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
  1212.     phase = sstat & SSTAT2_PHASE_MASK;
  1213. /*
  1214.  * SET ATN
  1215.  * MOVE source_or_sink, WHEN CURRENT PHASE 
  1216.  * < repeat for each outstanding byte >
  1217.  * JUMP send_abort_message
  1218.  */
  1219.     script = hostdata->abort_script = kmalloc (
  1220. 8  /* instruction size */ * (
  1221.     1 /* set ATN */ +
  1222.     (!offset ? 1 : offset) /* One transfer per outstanding byte */ +
  1223.     1 /* send abort message */),
  1224. GFP_ATOMIC);
  1225. #else /* def NEW_ABORT */
  1226.     hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
  1227.     sizeof(u32);
  1228. #endif /* def NEW_ABORT */
  1229.     hostdata->dsp_changed = 1;
  1230. /* XXX - need to flag the command as aborted after the abort_connected
  1231.    code runs 
  1232.  */
  1233.     return 0;
  1234. }
  1235. /*
  1236.  * Function : static int datapath_residual (Scsi_Host *host)
  1237.  *
  1238.  * Purpose : return residual data count of what's in the chip.
  1239.  *
  1240.  * Inputs : host - SCSI host
  1241.  */
  1242. static int
  1243. datapath_residual (struct Scsi_Host *host) {
  1244.     NCR53c7x0_local_declare();
  1245.     int count, synchronous, sstat;
  1246.     unsigned int ddir;
  1247.     NCR53c7x0_local_setup(host);
  1248.     /* COMPAT : the 700 and 700-66 need to use DFIFO_00_BO_MASK */
  1249.     count = ((NCR53c7x0_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) -
  1250. (NCR53c7x0_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK;
  1251.     synchronous = NCR53c7x0_read8 (SXFER_REG) & SXFER_MO_MASK;
  1252.     /* COMPAT : DDIR is elsewhere on non-'8xx chips. */
  1253.     ddir = NCR53c7x0_read8 (CTEST0_REG_700) & CTEST0_700_DDIR;
  1254.     if (ddir) {
  1255.     /* Receive */
  1256. if (synchronous) 
  1257.     count += (NCR53c7x0_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
  1258. else
  1259.     if (NCR53c7x0_read8 (SSTAT1_REG) & SSTAT1_ILF)
  1260. ++count;
  1261.     } else {
  1262.     /* Send */
  1263. sstat = NCR53c7x0_read8 (SSTAT1_REG);
  1264. if (sstat & SSTAT1_OLF)
  1265.     ++count;
  1266. if (synchronous && (sstat & SSTAT1_ORF))
  1267.     ++count;
  1268.     }
  1269.     return count;
  1270. }
  1271. /* 
  1272.  * Function : static const char * sbcl_to_phase (int sbcl)_
  1273.  *
  1274.  * Purpose : Convert SBCL register to user-parsable phase representation
  1275.  *
  1276.  * Inputs : sbcl - value of sbcl register
  1277.  */
  1278. static const char *
  1279. sbcl_to_phase (int sbcl) {
  1280.     switch (sbcl & SBCL_PHASE_MASK) {
  1281.     case SBCL_PHASE_DATAIN:
  1282. return "DATAIN";
  1283.     case SBCL_PHASE_DATAOUT:
  1284. return "DATAOUT";
  1285.     case SBCL_PHASE_MSGIN:
  1286. return "MSGIN";
  1287.     case SBCL_PHASE_MSGOUT:
  1288. return "MSGOUT";
  1289.     case SBCL_PHASE_CMDOUT:
  1290. return "CMDOUT";
  1291.     case SBCL_PHASE_STATIN:
  1292. return "STATUSIN";
  1293.     default:
  1294. return "unknown";
  1295.     }
  1296. }
  1297. /* 
  1298.  * Function : static const char * sstat2_to_phase (int sstat)_
  1299.  *
  1300.  * Purpose : Convert SSTAT2 register to user-parsable phase representation
  1301.  *
  1302.  * Inputs : sstat - value of sstat register
  1303.  */
  1304. static const char *
  1305. sstat2_to_phase (int sstat) {
  1306.     switch (sstat & SSTAT2_PHASE_MASK) {
  1307.     case SSTAT2_PHASE_DATAIN:
  1308. return "DATAIN";
  1309.     case SSTAT2_PHASE_DATAOUT:
  1310. return "DATAOUT";
  1311.     case SSTAT2_PHASE_MSGIN:
  1312. return "MSGIN";
  1313.     case SSTAT2_PHASE_MSGOUT:
  1314. return "MSGOUT";
  1315.     case SSTAT2_PHASE_CMDOUT:
  1316. return "CMDOUT";
  1317.     case SSTAT2_PHASE_STATIN:
  1318. return "STATUSIN";
  1319.     default:
  1320. return "unknown";
  1321.     }
  1322. }
  1323. /* 
  1324.  * Function : static void intr_phase_mismatch (struct Scsi_Host *host, 
  1325.  * struct NCR53c7x0_cmd *cmd)
  1326.  *
  1327.  * Purpose : Handle phase mismatch interrupts
  1328.  *
  1329.  * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
  1330.  *  may be NULL.
  1331.  *
  1332.  * Side effects : The abort_connected() routine is called or the NCR chip 
  1333.  * is restarted, jumping to the command_complete entry point, or 
  1334.  * patching the address and transfer count of the current instruction 
  1335.  * and calling the msg_in entry point as appropriate.
  1336.  */
  1337. static void 
  1338. intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
  1339.     NCR53c7x0_local_declare();
  1340.     u32 dbc_dcmd, *dsp, *dsp_next;
  1341.     unsigned char dcmd, sbcl;
  1342.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  1343.      host->hostdata[0];
  1344.     int residual;
  1345.     enum {ACTION_ABORT, ACTION_ABORT_PRINT, ACTION_CONTINUE} action = 
  1346. ACTION_ABORT_PRINT;
  1347.     const char *where = NULL;
  1348.     NCR53c7x0_local_setup(host);
  1349.     /*
  1350.      * Corrective action is based on where in the SCSI SCRIPT(tm) the error 
  1351.      * occurred, as well as which SCSI phase we are currently in.
  1352.      */
  1353.     dsp_next = bus_to_virt(NCR53c7x0_read32(DSP_REG));
  1354.     /* 
  1355.      * Fetch the current instruction, and remove the operands for easier 
  1356.      * interpretation.
  1357.      */
  1358.     dbc_dcmd = NCR53c7x0_read32(DBC_REG);
  1359.     dcmd = (dbc_dcmd & 0xff000000) >> 24;
  1360.     /*
  1361.      * Like other processors, the NCR adjusts the instruction pointer before
  1362.      * instruction decode.  Set the DSP address back to what it should
  1363.      * be for this instruction based on its size (2 or 3 32 bit words).
  1364.      */
  1365.     dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
  1366.     /*
  1367.      * Read new SCSI phase from the SBCL lines.  Since all of our code uses 
  1368.      * a WHEN conditional instead of an IF conditional, we don't need to 
  1369.      * wait for a new REQ.
  1370.      */
  1371.     sbcl = NCR53c7x0_read8(SBCL_REG) & SBCL_PHASE_MASK;
  1372.     if (!cmd) {
  1373. action = ACTION_ABORT_PRINT;
  1374. where = "no current command";
  1375.     /*
  1376.      * The way my SCSI SCRIPTS(tm) are architected, recoverable phase
  1377.      * mismatches should only occur where we're doing a multi-byte  
  1378.      * BMI instruction.  Specifically, this means 
  1379.      *
  1380.      *  - select messages (a SCSI-I target may ignore additional messages
  1381.      *  after the IDENTIFY; any target may reject a SDTR or WDTR)
  1382.      *
  1383.      *  - command out (targets may send a message to signal an error 
  1384.      *  condition, or go into STATUSIN after they've decided 
  1385.      * they don't like the command.
  1386.      *
  1387.      * - reply_message (targets may reject a multi-byte message in the 
  1388.      * middle)
  1389.      *
  1390.      *  - data transfer routines (command completion with buffer space
  1391.      * left, disconnect message, or error message)
  1392.      */
  1393.     } else if (((dsp >= cmd->data_transfer_start && 
  1394. dsp < cmd->data_transfer_end)) || dsp == (cmd->residual + 2)) {
  1395. if ((dcmd & (DCMD_TYPE_MASK|DCMD_BMI_OP_MASK|DCMD_BMI_INDIRECT|
  1396. DCMD_BMI_MSG|DCMD_BMI_CD)) == (DCMD_TYPE_BMI|
  1397. DCMD_BMI_OP_MOVE_I)) {
  1398.     residual = datapath_residual (host);
  1399.     if (hostdata->options & OPTION_DEBUG_DISCONNECT)
  1400.      printk ("scsi%d : handling residual transfer (+ %d bytes from DMA FIFO)n", 
  1401.     host->host_no, residual);
  1402.     /*
  1403.      * The first instruction is a CALL to the alternate handler for 
  1404.      * this data transfer phase, so we can do calls to 
  1405.      * munge_msg_restart as we would if control were passed 
  1406.      * from normal dynamic code.
  1407.      */
  1408.     if (dsp != cmd->residual + 2) {
  1409. cmd->residual[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
  1410. ((dcmd & DCMD_BMI_IO) ? DCMD_TCI_IO : 0)) << 24) | 
  1411.     DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
  1412. cmd->residual[1] = virt_to_bus(hostdata->script)
  1413.     + ((dcmd & DCMD_BMI_IO)
  1414.        ? hostdata->E_other_in : hostdata->E_other_out);
  1415.     }
  1416.     /*
  1417.      * The second instruction is the a data transfer block
  1418.      * move instruction, reflecting the pointer and count at the 
  1419.      * time of the phase mismatch.
  1420.      */
  1421.     cmd->residual[2] = dbc_dcmd + residual;
  1422.     cmd->residual[3] = NCR53c7x0_read32(DNAD_REG) - residual;
  1423.     /*
  1424.      * The third and final instruction is a jump to the instruction
  1425.      * which follows the instruction which had to be 'split'
  1426.      */
  1427.     if (dsp != cmd->residual + 2) {
  1428. cmd->residual[4] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) 
  1429.     << 24) | DBC_TCI_TRUE;
  1430. cmd->residual[5] = virt_to_bus(dsp_next);
  1431.     }
  1432.     /*
  1433.      * For the sake of simplicity, transfer control to the 
  1434.      * conditional CALL at the start of the residual buffer.
  1435.      */
  1436.     hostdata->dsp = cmd->residual;
  1437.     hostdata->dsp_changed = 1;
  1438.     action = ACTION_CONTINUE;
  1439. } else {
  1440.     where = "non-BMI dynamic DSA code";
  1441.     action = ACTION_ABORT_PRINT;
  1442. }
  1443.     } else if (dsp == (hostdata->script + hostdata->E_select_msgout / 4 + 2)) {
  1444. /* RGH 290697:  Added +2 above, to compensate for the script
  1445.  * instruction which disables the selection timer. */
  1446. /* Release ATN */
  1447. NCR53c7x0_write8 (SOCL_REG, 0);
  1448. switch (sbcl) {
  1449.     /* 
  1450.      * Some devices (SQ555 come to mind) grab the IDENTIFY message
  1451.      * sent on selection, and decide to go into COMMAND OUT phase
  1452.      * rather than accepting the rest of the messages or rejecting
  1453.      * them.  Handle these devices gracefully.
  1454.      */
  1455. case SBCL_PHASE_CMDOUT:
  1456.     hostdata->dsp = dsp + 2 /* two _words_ */;
  1457.     hostdata->dsp_changed = 1;
  1458.     printk ("scsi%d : target %d ignored SDTR and went into COMMAND OUTn", 
  1459. host->host_no, cmd->cmd->target);
  1460.     cmd->flags &= ~CMD_FLAG_SDTR;
  1461.     action = ACTION_CONTINUE;
  1462.     break;
  1463. case SBCL_PHASE_MSGIN:
  1464.     hostdata->dsp = hostdata->script + hostdata->E_msg_in / 
  1465. sizeof(u32);
  1466.     hostdata->dsp_changed = 1;
  1467.     action = ACTION_CONTINUE;
  1468.     break;
  1469. default:
  1470.     where="select message out";
  1471.     action = ACTION_ABORT_PRINT;
  1472. }
  1473.     /*
  1474.      * Some SCSI devices will interpret a command as they read the bytes
  1475.      * off the SCSI bus, and may decide that the command is Bogus before 
  1476.      * they've read the entire command off the bus.
  1477.      */
  1478.     } else if (dsp == hostdata->script + hostdata->E_cmdout_cmdout / sizeof 
  1479. (u32)) {
  1480. hostdata->dsp = hostdata->script + hostdata->E_data_transfer /
  1481.     sizeof (u32);
  1482. hostdata->dsp_changed = 1;
  1483. action = ACTION_CONTINUE;
  1484.     /* FIXME : we need to handle message reject, etc. within msg_respond. */
  1485. #ifdef notyet
  1486.     } else if (dsp == hostdata->script + hostdata->E_reply_message) {
  1487. switch (sbcl) {
  1488.     /* Any other phase mismatches abort the currently executing command.  */
  1489. #endif
  1490.     } else {
  1491. where = "unknown location";
  1492. action = ACTION_ABORT_PRINT;
  1493.     }
  1494.     /* Flush DMA FIFO */
  1495.     if (!hostdata->dstat_valid) {
  1496. hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
  1497. hostdata->dstat_valid = 1;
  1498.     }
  1499.     if (!(hostdata->dstat & DSTAT_DFE)) {
  1500.       /* Really need to check this out for 710 RGH */
  1501.       NCR53c7x0_write8 (CTEST8_REG, CTEST8_10_CLF);
  1502.       while (NCR53c7x0_read8 (CTEST8_REG) & CTEST8_10_CLF);
  1503.       hostdata->dstat |= DSTAT_DFE;
  1504.     }
  1505.     switch (action) {
  1506.     case ACTION_ABORT_PRINT:
  1507. printk("scsi%d : %s : unexpected phase %s.n",
  1508.      host->host_no, where ? where : "unknown location", 
  1509.      sbcl_to_phase(sbcl));
  1510. print_lots (host);
  1511.     /* Fall through to ACTION_ABORT */
  1512.     case ACTION_ABORT:
  1513. abort_connected (host);
  1514. break;
  1515.     case ACTION_CONTINUE:
  1516. break;
  1517.     }
  1518. #if 0
  1519.     if (hostdata->dsp_changed) {
  1520. printk("scsi%d: new dsp 0x%pn", host->host_no, hostdata->dsp);
  1521. print_insn (host, hostdata->dsp, "", 1);
  1522.     }
  1523. #endif
  1524. }
  1525. /*
  1526.  * Function : static void intr_bf (struct Scsi_Host *host, 
  1527.  *  struct NCR53c7x0_cmd *cmd)
  1528.  *
  1529.  * Purpose : handle BUS FAULT interrupts 
  1530.  *
  1531.  * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
  1532.  *  may be NULL.
  1533.  */
  1534. static void
  1535. intr_bf (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
  1536.     NCR53c7x0_local_declare();
  1537.     u32 *dsp,
  1538. *next_dsp, /* Current dsp */
  1539.      *dsa,
  1540. dbc_dcmd; /* DCMD (high eight bits) + DBC */
  1541.     char *reason = NULL;
  1542.     /* Default behavior is for a silent error, with a retry until we've
  1543.        exhausted retries. */
  1544.     enum {MAYBE, ALWAYS, NEVER} retry = MAYBE;
  1545.     int report = 0;
  1546.     NCR53c7x0_local_setup(host);
  1547.     dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
  1548.     next_dsp = bus_to_virt (NCR53c7x0_read32(DSP_REG));
  1549.     dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
  1550. /* FIXME - check chip type  */
  1551.     dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
  1552.     /*
  1553.      * Bus faults can be caused by either a Bad Address or 
  1554.      * Target Abort. We should check the Received Target Abort
  1555.      * bit of the PCI status register and Master Abort Bit.
  1556.      *
  1557.      *  - Master Abort bit indicates that no device claimed
  1558.      * the address with DEVSEL within five clocks
  1559.      *
  1560.      * - Target Abort bit indicates that a target claimed it,
  1561.      * but changed its mind once it saw the byte enables.
  1562.      *
  1563.      */
  1564.     /* 53c710, not PCI system */
  1565.     report = 1;
  1566.     reason = "Unknown";
  1567. #ifndef notyet
  1568.     report = 1;
  1569. #endif
  1570.     if (report && reason)
  1571.     {
  1572. printk(KERN_ALERT "scsi%d : BUS FAULT reason = %sn",
  1573.      host->host_no, reason ? reason : "unknown");
  1574. print_lots (host);
  1575.     }
  1576. #ifndef notyet
  1577.     retry = NEVER;
  1578. #endif
  1579.     /* 
  1580.      * TODO : we should attempt to recover from any spurious bus 
  1581.      * faults.  After X retries, we should figure that things are 
  1582.      * sufficiently wedged, and call NCR53c7xx_reset.
  1583.      *
  1584.      * This code should only get executed once we've decided that we 
  1585.      * cannot retry.
  1586.      */
  1587.     if (retry == NEVER) {
  1588.      printk(KERN_ALERT "          mail richard@sleepie.demon.co.ukn");
  1589.      FATAL (host);
  1590.     }
  1591. }
  1592. /*
  1593.  * Function : static void intr_dma (struct Scsi_Host *host, 
  1594.  *  struct NCR53c7x0_cmd *cmd)
  1595.  *
  1596.  * Purpose : handle all DMA interrupts, indicated by the setting 
  1597.  *  of the DIP bit in the ISTAT register.
  1598.  *
  1599.  * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
  1600.  *  may be NULL.
  1601.  */
  1602. static void 
  1603. intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
  1604.     NCR53c7x0_local_declare();
  1605.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  1606. host->hostdata[0];
  1607.     unsigned char dstat; /* DSTAT */
  1608.     u32 *dsp,
  1609. *next_dsp, /* Current dsp */
  1610.      *dsa,
  1611. dbc_dcmd; /* DCMD (high eight bits) + DBC */
  1612.     int tmp;
  1613.     unsigned long flags;
  1614.     NCR53c7x0_local_setup(host);
  1615.     if (!hostdata->dstat_valid) {
  1616. hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
  1617. hostdata->dstat_valid = 1;
  1618.     }
  1619.     
  1620.     dstat = hostdata->dstat;
  1621.     
  1622.     if (hostdata->options & OPTION_DEBUG_INTR)
  1623. printk("scsi%d : DSTAT=0x%xn", host->host_no, (int) dstat);
  1624.     dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
  1625.     next_dsp = bus_to_virt(NCR53c7x0_read32(DSP_REG));
  1626.     dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
  1627. /* XXX - check chip type */
  1628.     dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
  1629.     /*
  1630.      * DSTAT_ABRT is the aborted interrupt.  This is set whenever the 
  1631.      * SCSI chip is aborted.  
  1632.      * 
  1633.      * With NCR53c700 and NCR53c700-66 style chips, we should only 
  1634.      * get this when the chip is currently running the accept 
  1635.      * reselect/select code and we have set the abort bit in the 
  1636.      * ISTAT register.
  1637.      *
  1638.      */
  1639.     
  1640.     if (dstat & DSTAT_ABRT) {
  1641. #if 0
  1642. /* XXX - add code here to deal with normal abort */
  1643. if ((hostdata->options & OPTION_700) && (hostdata->state ==
  1644.     STATE_ABORTING)) {
  1645. } else 
  1646. #endif
  1647. {
  1648.     printk(KERN_ALERT "scsi%d : unexpected abort interrupt atn" 
  1649.    "         ", host->host_no);
  1650.     print_insn (host, dsp, KERN_ALERT "s ", 1);
  1651.     FATAL (host);
  1652. }
  1653.     }
  1654.     /*
  1655.      * DSTAT_SSI is the single step interrupt.  Should be generated 
  1656.      * whenever we have single stepped or are tracing.
  1657.      */
  1658.     if (dstat & DSTAT_SSI) {
  1659. if (hostdata->options & OPTION_DEBUG_TRACE) {
  1660.     /* Don't print instr. until we write DSP at end of intr function */
  1661. } else if (hostdata->options & OPTION_DEBUG_SINGLE) {
  1662.     print_insn (host, dsp, "s ", 0);
  1663.     save_flags(flags);
  1664.     cli();
  1665. /* XXX - should we do this, or can we get away with writing dsp? */
  1666.     NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) & 
  1667.           ~DCNTL_SSM) | DCNTL_STD);
  1668.     restore_flags(flags);
  1669. } else {
  1670.     printk(KERN_ALERT "scsi%d : unexpected single step interrupt atn"
  1671.    "         ", host->host_no);
  1672.     print_insn (host, dsp, KERN_ALERT "", 1);
  1673.     printk(KERN_ALERT "         mail drew@PoohSticks.ORGn");
  1674.          FATAL (host);
  1675.      }
  1676.     }
  1677.     /*
  1678.      * DSTAT_IID / DSTAT_OPC (same bit, same meaning, only the name 
  1679.      * is different) is generated whenever an illegal instruction is 
  1680.      * encountered.  
  1681.      * 
  1682.      * XXX - we may want to emulate INTFLY here, so we can use 
  1683.      *    the same SCSI SCRIPT (tm) for NCR53c710 through NCR53c810  
  1684.      *   chips.
  1685.      */
  1686.     if (dstat & DSTAT_OPC) {
  1687.     /* 
  1688.      * Ascertain if this IID interrupts occurred before or after a STO 
  1689.      * interrupt.  Since the interrupt handling code now leaves 
  1690.      * DSP unmodified until _after_ all stacked interrupts have been
  1691.      * processed, reading the DSP returns the original DSP register.
  1692.      * This means that if dsp lies between the select code, and 
  1693.      * message out following the selection code (where the IID interrupt
  1694.      * would have to have occurred by due to the implicit wait for REQ),
  1695.      * we have an IID interrupt resulting from a STO condition and 
  1696.      * can ignore it.
  1697.      */
  1698. if (((dsp >= (hostdata->script + hostdata->E_select / sizeof(u32))) &&
  1699.     (dsp <= (hostdata->script + hostdata->E_select_msgout / 
  1700.          sizeof(u32) + 8))) || (hostdata->test_running == 2)) {
  1701.     if (hostdata->options & OPTION_DEBUG_INTR) 
  1702. printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STOn",
  1703.     host->host_no);
  1704.     if (hostdata->expecting_iid) {
  1705. hostdata->expecting_iid = 0;
  1706. hostdata->idle = 1;
  1707. if (hostdata->test_running == 2) {
  1708.     hostdata->test_running = 0;
  1709.     hostdata->test_completed = 3;
  1710. } else if (cmd) 
  1711. abnormal_finished (cmd, DID_BAD_TARGET << 16);
  1712.     } else {
  1713. hostdata->expecting_sto = 1;
  1714.     }
  1715.     /*
  1716.      * We can't guarantee we'll be able to execute the WAIT DISCONNECT
  1717.      * instruction within the 3.4us of bus free and arbitration delay
  1718.      * that a target can RESELECT in and assert REQ after we've dropped
  1719.      * ACK.  If this happens, we'll get an illegal instruction interrupt.
  1720.      * Doing away with the WAIT DISCONNECT instructions broke everything,
  1721.      * so instead I'll settle for moving one WAIT DISCONNECT a few 
  1722.      * instructions closer to the CLEAR ACK before it to minimize the
  1723.      * chances of this happening, and handle it if it occurs anyway.
  1724.      *
  1725.      * Simply continue with what we were doing, and control should
  1726.      * be transferred to the schedule routine which will ultimately
  1727.      * pass control onto the reselection or selection (not yet)
  1728.      * code.
  1729.      */
  1730. } else if (dbc_dcmd == 0x48000000 && (NCR53c7x0_read8 (SBCL_REG) &
  1731.     SBCL_REQ)) {
  1732.     if (!(hostdata->options & OPTION_NO_PRINT_RACE))
  1733.     {
  1734. printk("scsi%d: REQ before WAIT DISCONNECT IIDn", 
  1735.     host->host_no);
  1736. hostdata->options |= OPTION_NO_PRINT_RACE;
  1737.     }
  1738. } else {
  1739.     printk(KERN_ALERT "scsi%d : illegal instructionn", host->host_no);
  1740.     print_lots (host);
  1741.     printk(KERN_ALERT "         mail Richard@sleepie.demon.co.uk with ALLn"
  1742.               "         boot messages and diagnostic outputn");
  1743.          FATAL (host);
  1744. }
  1745.     }
  1746.     /* 
  1747.      * DSTAT_BF are bus fault errors.  DSTAT_800_BF is valid for 710 also.
  1748.      */
  1749.     
  1750.     if (dstat & DSTAT_800_BF) {
  1751. intr_bf (host, cmd);
  1752.     }
  1753.     /* 
  1754.      * DSTAT_SIR interrupts are generated by the execution of 
  1755.      * the INT instruction.  Since the exact values available 
  1756.      * are determined entirely by the SCSI script running, 
  1757.      * and are local to a particular script, a unique handler
  1758.      * is called for each script.
  1759.      */
  1760.     if (dstat & DSTAT_SIR) {
  1761. if (hostdata->options & OPTION_DEBUG_INTR)
  1762.     printk ("scsi%d : DSTAT_SIRn", host->host_no);
  1763. switch ((tmp = hostdata->dstat_sir_intr (host, cmd))) {
  1764. case SPECIFIC_INT_NOTHING:
  1765. case SPECIFIC_INT_RESTART:
  1766.     break;
  1767. case SPECIFIC_INT_ABORT:
  1768.     abort_connected(host);
  1769.     break;
  1770. case SPECIFIC_INT_PANIC:
  1771.     printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
  1772.     print_insn (host, dsp, KERN_ALERT "", 1);
  1773.     printk(KERN_ALERT "          dstat_sir_intr() returned SPECIFIC_INT_PANICn");
  1774.          FATAL (host);
  1775.     break;
  1776. case SPECIFIC_INT_BREAK:
  1777.     intr_break (host, cmd);
  1778.     break;
  1779. default:
  1780.     printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
  1781.     print_insn (host, dsp, KERN_ALERT "", 1);
  1782.     printk(KERN_ALERT"          dstat_sir_intr() returned unknown value %dn", 
  1783. tmp);
  1784.          FATAL (host);
  1785. }
  1786.     } 
  1787. }
  1788. /*
  1789.  * Function : static int print_insn (struct Scsi_Host *host, 
  1790.  *  u32 *insn, int kernel)
  1791.  *
  1792.  * Purpose : print numeric representation of the instruction pointed
  1793.  *  to by insn to the debugging or kernel message buffer
  1794.  * as appropriate.  
  1795.  *
  1796.  *  If desired, a user level program can interpret this 
  1797.  *  information.
  1798.  *
  1799.  * Inputs : host, insn - host, pointer to instruction, prefix - 
  1800.  * string to prepend, kernel - use printk instead of debugging buffer.
  1801.  *
  1802.  * Returns : size, in u32s, of instruction printed.
  1803.  */
  1804. /*
  1805.  * FIXME: should change kernel parameter so that it takes an ENUM
  1806.  *  specifying severity - either KERN_ALERT or KERN_PANIC so
  1807.  * all panic messages are output with the same severity.
  1808.  */
  1809. static int 
  1810. print_insn (struct Scsi_Host *host, const u32 *insn, 
  1811.     const char *prefix, int kernel) {
  1812.     char buf[160],  /* Temporary buffer and pointer.  ICKY 
  1813.    arbitrary length.  */
  1814. *tmp;
  1815.     unsigned char dcmd; /* dcmd register for *insn */
  1816.     int size;
  1817.     /* 
  1818.      * Check to see if the instruction pointer is not bogus before 
  1819.      * indirecting through it; avoiding red-zone at start of 
  1820.      * memory.
  1821.      *
  1822.      * FIXME: icky magic needs to happen here on non-intel boxes which
  1823.      * don't have kernel memory mapped in like this.  Might be reasonable
  1824.      * to use vverify()?
  1825.      */
  1826.     if (virt_to_phys((void *)insn) < PAGE_SIZE || 
  1827. virt_to_phys((void *)(insn + 8)) > virt_to_phys(high_memory) ||
  1828. ((((dcmd = (insn[0] >> 24) & 0xff) & DCMD_TYPE_MMI) == DCMD_TYPE_MMI) &&
  1829. virt_to_phys((void *)(insn + 12)) > virt_to_phys(high_memory))) {
  1830. size = 0;
  1831. sprintf (buf, "%s%p: address out of rangen",
  1832.     prefix, insn);
  1833.     } else {
  1834. /* 
  1835.  * FIXME : (void *) cast in virt_to_bus should be unnecessary, because
  1836.  *  it should take const void * as argument.
  1837.  */
  1838. #if !defined(CONFIG_MVME16x) && !defined(CONFIG_BVME6000)
  1839. sprintf(buf, "%s0x%lx (virt 0x%p) : 0x%08x 0x%08x (virt 0x%p)", 
  1840.     (prefix ? prefix : ""), virt_to_bus((void *) insn), insn,  
  1841.     insn[0], insn[1], bus_to_virt (insn[1]));
  1842. #else
  1843. /* Remove virtual addresses to reduce output, as they are the same */
  1844. sprintf(buf, "%s0x%x (+%x) : 0x%08x 0x%08x", 
  1845.     (prefix ? prefix : ""), (u32)insn, ((u32)insn -
  1846. (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4, 
  1847.     insn[0], insn[1]);
  1848. #endif
  1849. tmp = buf + strlen(buf);
  1850. if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI)  {
  1851. #if !defined(CONFIG_MVME16x) && !defined(CONFIG_BVME6000)
  1852.     sprintf (tmp, " 0x%08x (virt 0x%p)n", insn[2], 
  1853. bus_to_virt(insn[2]));
  1854. #else
  1855.     /* Remove virtual addr to reduce output, as it is the same */
  1856.     sprintf (tmp, " 0x%08xn", insn[2]);
  1857. #endif
  1858.     size = 3;
  1859. } else {
  1860.     sprintf (tmp, "n");
  1861.     size = 2;
  1862. }
  1863.     }
  1864.     if (kernel) 
  1865. printk ("%s", buf);
  1866. #ifdef NCR_DEBUG
  1867.     else {
  1868. size_t len = strlen(buf);
  1869. debugger_kernel_write(host, buf, len);
  1870.     }
  1871. #endif
  1872.     return size;
  1873. }
  1874. /*
  1875.  * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd)
  1876.  * 
  1877.  * Purpose : Abort an errant SCSI command, doing all necessary
  1878.  * cleanup of the issue_queue, running_list, shared Linux/NCR
  1879.  * dsa issue and reconnect queues.
  1880.  *
  1881.  * Inputs : cmd - command to abort, code - entire result field
  1882.  *
  1883.  * Returns : 0 on success, -1 on failure.
  1884.  */
  1885. int 
  1886. NCR53c7xx_abort (Scsi_Cmnd *cmd) {
  1887.     NCR53c7x0_local_declare();
  1888.     struct Scsi_Host *host = cmd->host;
  1889.     struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *) 
  1890. host->hostdata[0] : NULL;
  1891.     unsigned long flags;
  1892.     struct NCR53c7x0_cmd *curr, **prev;
  1893.     Scsi_Cmnd *me, **last;
  1894. #if 0
  1895.     static long cache_pid = -1;
  1896. #endif
  1897.     if (!host) {
  1898. printk ("Bogus SCSI command pid %ld; no host structuren",
  1899.     cmd->pid);
  1900. return SCSI_ABORT_ERROR;
  1901.     } else if (!hostdata) {
  1902. printk ("Bogus SCSI host %d; no hostdatan", host->host_no);
  1903. return SCSI_ABORT_ERROR;
  1904.     }
  1905.     NCR53c7x0_local_setup(host);
  1906. /*
  1907.  * CHECK : I don't think that reading ISTAT will unstack any interrupts,
  1908.  * since we need to write the INTF bit to clear it, and SCSI/DMA
  1909.  *  interrupts don't clear until we read SSTAT/SIST and DSTAT registers.
  1910.  *
  1911.  * See that this is the case.  Appears to be correct on the 710, at least.
  1912.  *
  1913.  * I suspect that several of our failures may be coming from a new fatal
  1914.  * interrupt (possibly due to a phase mismatch) happening after we've left
  1915.  * the interrupt handler, but before the PIC has had the interrupt condition
  1916.  * cleared.
  1917.  */
  1918.     if (NCR53c7x0_read8(hostdata->istat) & (ISTAT_DIP|ISTAT_SIP)) {
  1919. printk ("scsi%d : dropped interrupt for command %ldn", host->host_no,
  1920.     cmd->pid);
  1921. NCR53c7x0_intr (host->irq, NULL, NULL);
  1922. return SCSI_ABORT_BUSY;
  1923.     }
  1924.     save_flags(flags);
  1925.     cli();
  1926. #if 0
  1927.     if (cache_pid == cmd->pid) 
  1928. panic ("scsi%d : bloody fetus %dn", host->host_no, cmd->pid);
  1929.     else
  1930. cache_pid = cmd->pid;
  1931. #endif
  1932. /*
  1933.  * The command could be hiding in the issue_queue.  This would be very
  1934.  * nice, as commands can't be moved from the high level driver's issue queue 
  1935.  * into the shared queue until an interrupt routine is serviced, and this
  1936.  * moving is atomic.  
  1937.  *
  1938.  * If this is the case, we don't have to worry about anything - we simply
  1939.  * pull the command out of the old queue, and call it aborted.
  1940.  */
  1941.     for (me = (Scsi_Cmnd *) hostdata->issue_queue, 
  1942.          last = (Scsi_Cmnd **) &(hostdata->issue_queue);
  1943.  me && me != cmd;  last = (Scsi_Cmnd **)&(me->SCp.ptr), 
  1944.  me = (Scsi_Cmnd *)me->SCp.ptr);
  1945.     if (me) {
  1946. *last = (Scsi_Cmnd *) me->SCp.ptr;
  1947. if (me->host_scribble) {
  1948.     ((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free;
  1949.     hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble;
  1950.     me->host_scribble = NULL;
  1951. }
  1952. cmd->result = DID_ABORT << 16;
  1953. cmd->scsi_done(cmd);
  1954. printk ("scsi%d : found command %ld in Linux issue queuen", 
  1955.     host->host_no, me->pid);
  1956. restore_flags(flags);
  1957.      run_process_issue_queue();
  1958. return SCSI_ABORT_SUCCESS;
  1959.     }
  1960. /* 
  1961.  * That failing, the command could be in our list of already executing 
  1962.  * commands.  If this is the case, drastic measures are called for.  
  1963.  */ 
  1964.     for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list, 
  1965.       prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
  1966.  curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **) 
  1967.          &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
  1968.     if (curr) {
  1969. if ((curr->result & 0xff) != 0xff && (curr->result & 0xff00) != 0xff00) {
  1970.             cmd->result = curr->result;
  1971.     if (prev)
  1972. *prev = (struct NCR53c7x0_cmd *) curr->next;
  1973.     curr->next = (struct NCR53c7x0_cmd *) hostdata->free;
  1974.     cmd->host_scribble = NULL;
  1975.     hostdata->free = curr;
  1976.     cmd->scsi_done(cmd);
  1977. printk ("scsi%d : found finished command %ld in running listn", 
  1978.     host->host_no, cmd->pid);
  1979.     restore_flags(flags);
  1980.     return SCSI_ABORT_NOT_RUNNING;
  1981. } else {
  1982.     printk ("scsi%d : DANGER : command running, can not abort.n",
  1983. cmd->host->host_no);
  1984.     restore_flags(flags);
  1985.     return SCSI_ABORT_BUSY;
  1986. }
  1987.     }
  1988. /* 
  1989.  * And if we couldn't find it in any of our queues, it must have been 
  1990.  * a dropped interrupt.
  1991.  */
  1992.     curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
  1993.     if (curr) {
  1994. curr->next = hostdata->free;
  1995. hostdata->free = curr;
  1996. cmd->host_scribble = NULL;
  1997.     }
  1998.     if (curr == NULL || ((curr->result & 0xff00) == 0xff00) ||
  1999. ((curr->result & 0xff) == 0xff)) {
  2000. printk ("scsi%d : did this command ever run?n", host->host_no);
  2001.     cmd->result = DID_ABORT << 16;
  2002.     } else {
  2003. printk ("scsi%d : probably lost INTFLY, normal completionn", 
  2004.     host->host_no);
  2005.         cmd->result = curr->result;
  2006. /* 
  2007.  * FIXME : We need to add an additional flag which indicates if a 
  2008.  * command was ever counted as BUSY, so if we end up here we can
  2009.  * decrement the busy count if and only if it is necessary.
  2010.  */
  2011.         --hostdata->busy[cmd->target][cmd->lun];
  2012.     }
  2013.     restore_flags(flags);
  2014.     cmd->scsi_done(cmd);
  2015. /* 
  2016.  * We need to run process_issue_queue since termination of this command 
  2017.  * may allow another queued command to execute first? 
  2018.  */
  2019.     return SCSI_ABORT_NOT_RUNNING;
  2020. }
  2021. /*
  2022.  * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd) 
  2023.  * 
  2024.  * Purpose : perform a hard reset of the SCSI bus and NCR
  2025.  *  chip.
  2026.  *
  2027.  * Inputs : cmd - command which caused the SCSI RESET
  2028.  *
  2029.  * Returns : 0 on success.
  2030.  */
  2031.  
  2032. int 
  2033. NCR53c7xx_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) {
  2034.     NCR53c7x0_local_declare();
  2035.     unsigned long flags;
  2036.     int found = 0;
  2037.     struct NCR53c7x0_cmd * c;
  2038.     Scsi_Cmnd *tmp;
  2039.     /*
  2040.      * When we call scsi_done(), it's going to wake up anything sleeping on the
  2041.      * resources which were in use by the aborted commands, and we'll start to 
  2042.      * get new commands.
  2043.      *
  2044.      * We can't let this happen until after we've re-initialized the driver
  2045.      * structures, and can't reinitialize those structures until after we've 
  2046.      * dealt with their contents.
  2047.      *
  2048.      * So, we need to find all of the commands which were running, stick
  2049.      * them on a linked list of completed commands (we'll use the host_scribble
  2050.      * pointer), do our reinitialization, and then call the done function for
  2051.      * each command.  
  2052.      */
  2053.     Scsi_Cmnd *nuke_list = NULL;
  2054.     struct Scsi_Host *host = cmd->host;
  2055.     struct NCR53c7x0_hostdata *hostdata = 
  2056.      (struct NCR53c7x0_hostdata *) host->hostdata[0];
  2057.     NCR53c7x0_local_setup(host);
  2058.     save_flags(flags);
  2059.     cli();
  2060.     ncr_halt (host);
  2061.     print_lots (host);
  2062.     dump_events (host, 30);
  2063.     ncr_scsi_reset (host);
  2064.     for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */,
  2065. 0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer)
  2066. if (tmp == cmd) {
  2067.     found = 1;
  2068.     break;
  2069. }
  2070.     
  2071.     /* 
  2072.      * If we didn't find the command which caused this reset in our running
  2073.      * list, then we've lost it.  See that it terminates normally anyway.
  2074.      */
  2075.     if (!found) {
  2076.      c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
  2077.      if (c) {
  2078.     cmd->host_scribble = NULL;
  2079.          c->next = hostdata->free;
  2080.          hostdata->free = c;
  2081.      } else
  2082.     printk ("scsi%d: lost command %ldn", host->host_no, cmd->pid);
  2083. cmd->SCp.buffer = (struct scatterlist *) nuke_list;
  2084. nuke_list = cmd;
  2085.     }
  2086.     NCR53c7x0_driver_init (host);
  2087.     hostdata->soft_reset (host);
  2088.     if (hostdata->resets == 0) 
  2089. disable(host);
  2090.     else if (hostdata->resets != -1)
  2091. --hostdata->resets;
  2092.     restore_flags(flags);
  2093.     for (; nuke_list; nuke_list = tmp) {
  2094. tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
  2095.      nuke_list->result = DID_RESET << 16;
  2096. nuke_list->scsi_done (nuke_list);
  2097.     }
  2098.     restore_flags(flags);
  2099.     return SCSI_RESET_SUCCESS;
  2100. }
  2101. /*
  2102.  * The NCR SDMS bios follows Annex A of the SCSI-CAM draft, and 
  2103.  * therefore shares the scsicam_bios_param function.
  2104.  */
  2105. /*
  2106.  * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn)
  2107.  *
  2108.  * Purpose : convert instructions stored at NCR pointer into data 
  2109.  * pointer offset.
  2110.  * 
  2111.  * Inputs : cmd - SCSI command; insn - pointer to instruction.  Either current
  2112.  * DSP, or saved data pointer.
  2113.  *
  2114.  * Returns : offset on success, -1 on failure.
  2115.  */
  2116. static int 
  2117. insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
  2118.     struct NCR53c7x0_hostdata *hostdata = 
  2119. (struct NCR53c7x0_hostdata *) cmd->host->hostdata[0];
  2120.     struct NCR53c7x0_cmd *ncmd = 
  2121. (struct NCR53c7x0_cmd *) cmd->host_scribble;
  2122.     int offset = 0, buffers;
  2123.     struct scatterlist *segment;
  2124.     char *ptr;
  2125.     int found = 0;
  2126. /*
  2127.  * With the current code implementation, if the insn is inside dynamically 
  2128.  * generated code, the data pointer will be the instruction preceding 
  2129.  * the next transfer segment.
  2130.  */
  2131.     if (!check_address ((unsigned long) ncmd, sizeof (struct NCR53c7x0_cmd)) &&
  2132. ((insn >= ncmd->data_transfer_start &&  
  2133.          insn < ncmd->data_transfer_end) ||
  2134.      (insn >= ncmd->residual &&
  2135.          insn < (ncmd->residual + 
  2136.           sizeof(ncmd->residual))))) {
  2137.     ptr = bus_to_virt(insn[3]);
  2138.     if ((buffers = cmd->use_sg)) {
  2139.           for (offset = 0, 
  2140.       segment = (struct scatterlist *) cmd->buffer;
  2141.                buffers && !((found = ((ptr >= segment->address) && 
  2142.                    (ptr < (segment->address + segment->length)))));
  2143.                --buffers, offset += segment->length, ++segment)
  2144. #if 0
  2145.     printk("scsi%d: comparing 0x%p to 0x%pn", 
  2146. cmd->host->host_no, saved, segment->address);
  2147. #else
  2148.     ;
  2149. #endif
  2150.               offset += ptr - segment->address;
  2151.          } else {
  2152. found = 1;
  2153.           offset = ptr - (char *) (cmd->request_buffer);
  2154.          }
  2155.     } else if ((insn >= hostdata->script + 
  2156. hostdata->E_data_transfer / sizeof(u32)) &&
  2157.        (insn <= hostdata->script +
  2158. hostdata->E_end_data_transfer / sizeof(u32))) {
  2159.      found = 1;
  2160. offset = 0;
  2161.     }
  2162.     return found ? offset : -1;
  2163. }
  2164. /*
  2165.  * Function : void print_progress (Scsi_Cmnd *cmd) 
  2166.  * 
  2167.  * Purpose : print the current location of the saved data pointer
  2168.  *
  2169.  * Inputs : cmd - command we are interested in
  2170.  *
  2171.  */
  2172. static void 
  2173. print_progress (Scsi_Cmnd *cmd) {
  2174.     NCR53c7x0_local_declare();
  2175.     struct NCR53c7x0_cmd *ncmd = 
  2176. (struct NCR53c7x0_cmd *) cmd->host_scribble;
  2177.     int offset, i;
  2178.     char *where;
  2179.     u32 *ptr;
  2180.     NCR53c7x0_local_setup (cmd->host);
  2181.     if (check_address ((unsigned long) ncmd,sizeof (struct NCR53c7x0_cmd)) == 0)
  2182.     {
  2183. printk("nNCR53c7x0_cmd fields:n");
  2184. printk("  bounce.len=0x%x, addr=0x%0x, buf[]=0x%02x %02x %02x %02xn",
  2185.     ncmd->bounce.len, ncmd->bounce.addr, ncmd->bounce.buf[0],
  2186.     ncmd->bounce.buf[1], ncmd->bounce.buf[2], ncmd->bounce.buf[3]);
  2187. printk("  result=%04x, cdb[0]=0x%02xn", ncmd->result, ncmd->cmnd[0]);
  2188.     }
  2189.     for (i = 0; i < 2; ++i) {
  2190. if (check_address ((unsigned long) ncmd, 
  2191.     sizeof (struct NCR53c7x0_cmd)) == -1) 
  2192.     continue;
  2193. if (!i) {
  2194.     where = "saved";
  2195.     ptr = bus_to_virt(ncmd->saved_data_pointer);
  2196. } else {
  2197.     where = "active";
  2198.     ptr = bus_to_virt (NCR53c7x0_read32 (DSP_REG) -
  2199. NCR53c7x0_insn_size (NCR53c7x0_read8 (DCMD_REG)) *
  2200. sizeof(u32));
  2201. offset = insn_to_offset (cmd, ptr);
  2202. if (offset != -1) 
  2203.     printk ("scsi%d : %s data pointer at offset %dn",
  2204. cmd->host->host_no, where, offset);
  2205. else {
  2206.     int size;
  2207.     printk ("scsi%d : can't determine %s data pointer offsetn",
  2208. cmd->host->host_no, where);
  2209.     if (ncmd) {
  2210. size = print_insn (cmd->host, 
  2211.     bus_to_virt(ncmd->saved_data_pointer), "", 1);
  2212. print_insn (cmd->host, 
  2213.     bus_to_virt(ncmd->saved_data_pointer) + size * sizeof(u32),
  2214.     "", 1);
  2215.     }
  2216. }
  2217.     }
  2218. }
  2219. static void 
  2220. print_dsa (struct Scsi_Host *host, u32 *dsa, const char *prefix) {
  2221.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  2222. host->hostdata[0];
  2223.     int i, len;
  2224.     char *ptr;
  2225.     Scsi_Cmnd *cmd;
  2226.     if (check_address ((unsigned long) dsa, hostdata->dsa_end - 
  2227. hostdata->dsa_start) == -1) {
  2228. printk("scsi%d : bad dsa virt 0x%pn", host->host_no, dsa);
  2229. return;
  2230.     }
  2231.     printk("%sscsi%d : dsa at phys 0x%lx (virt 0x%p)n"
  2232.     "        + %d : dsa_msgout length = %u, data = 0x%x (virt 0x%p)n" ,
  2233.          prefix ? prefix : "",
  2234.          host->host_no,  virt_to_bus (dsa), dsa, hostdata->dsa_msgout,
  2235.          dsa[hostdata->dsa_msgout / sizeof(u32)],
  2236.     dsa[hostdata->dsa_msgout / sizeof(u32) + 1],
  2237.     bus_to_virt (dsa[hostdata->dsa_msgout / sizeof(u32) + 1]));
  2238.     /* 
  2239.      * Only print messages if they're sane in length so we don't
  2240.      * blow the kernel printk buffer on something which won't buy us
  2241.      * anything.
  2242.      */
  2243.     if (dsa[hostdata->dsa_msgout / sizeof(u32)] < 
  2244.     sizeof (hostdata->free->select)) 
  2245. for (i = dsa[hostdata->dsa_msgout / sizeof(u32)],
  2246.     ptr = bus_to_virt (dsa[hostdata->dsa_msgout / sizeof(u32) + 1]); 
  2247.     i > 0 && !check_address ((unsigned long) ptr, 1);
  2248.     ptr += len, i -= len) {
  2249.     printk("               ");
  2250.     len = print_msg (ptr);
  2251.     printk("n");
  2252.     if (!len)
  2253. break;
  2254. }
  2255.     printk("        + %d : select_indirect = 0x%xn",
  2256. hostdata->dsa_select, dsa[hostdata->dsa_select / sizeof(u32)]);
  2257.     cmd = (Scsi_Cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
  2258.     printk("        + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd,
  2259.    (u32) virt_to_bus(cmd));
  2260.     /* XXX Maybe we should access cmd->host_scribble->result here. RGH */
  2261.     if (cmd) {
  2262. printk("               result = 0x%x, target = %d, lun = %d, cmd = ",
  2263.     cmd->result, cmd->target, cmd->lun);
  2264. print_command(cmd->cmnd);
  2265.     } else
  2266. printk("n");
  2267.     printk("        + %d : dsa_next = 0x%xn", hostdata->dsa_next,
  2268. dsa[hostdata->dsa_next / sizeof(u32)]);
  2269.     if (cmd) { 
  2270. printk("scsi%d target %d : sxfer_sanity = 0x%x, scntl3_sanity = 0x%xn"
  2271.        "                   script : ",
  2272.     host->host_no, cmd->target,
  2273.     hostdata->sync[cmd->target].sxfer_sanity,
  2274.     hostdata->sync[cmd->target].scntl3_sanity);
  2275. for (i = 0; i < (sizeof(hostdata->sync[cmd->target].script) / 4); ++i)
  2276.     printk ("0x%x ", hostdata->sync[cmd->target].script[i]);
  2277. printk ("n");
  2278.      print_progress (cmd);
  2279.     }
  2280. }
  2281. /*
  2282.  * Function : void print_queues (Scsi_Host *host) 
  2283.  * 
  2284.  * Purpose : print the contents of the NCR issue and reconnect queues
  2285.  *
  2286.  * Inputs : host - SCSI host we are interested in
  2287.  *
  2288.  */
  2289. static void 
  2290. print_queues (struct Scsi_Host *host) {
  2291.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  2292. host->hostdata[0];
  2293.     u32 *dsa, *next_dsa;
  2294.     volatile u32 *ncrcurrent;
  2295.     int left;
  2296.     Scsi_Cmnd *cmd, *next_cmd;
  2297.     unsigned long flags;
  2298.     printk ("scsi%d : issue queuen", host->host_no);
  2299.     for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue; 
  2300.     left >= 0 && cmd; 
  2301.     cmd = next_cmd) {
  2302. next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr;
  2303. save_flags(flags);
  2304. cli();
  2305. if (cmd->host_scribble) {
  2306.     if (check_address ((unsigned long) (cmd->host_scribble), 
  2307. sizeof (cmd->host_scribble)) == -1)
  2308. printk ("scsi%d: scsi pid %ld bad pointer to NCR53c7x0_cmdn",
  2309.     host->host_no, cmd->pid);
  2310.     /* print_dsa does sanity check on address, no need to check */
  2311.     else
  2312.      print_dsa (host, ((struct NCR53c7x0_cmd *) cmd->host_scribble)
  2313.     -> dsa, "");
  2314. } else 
  2315.     printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmdn",
  2316. host->host_no, cmd->pid, cmd->target, cmd->lun);
  2317. restore_flags(flags);
  2318.     }
  2319.     if (left <= 0) {
  2320. printk ("scsi%d : loop detected in issue queuen",
  2321.     host->host_no);
  2322.     }
  2323.     /*
  2324.      * Traverse the NCR reconnect and start DSA structures, printing out 
  2325.      * each element until we hit the end or detect a loop.  Currently,
  2326.      * the reconnect structure is a linked list; and the start structure
  2327.      * is an array.  Eventually, the reconnect structure will become a 
  2328.      * list as well, since this simplifies the code.
  2329.      */
  2330.     printk ("scsi%d : schedule dsa array :n", host->host_no);
  2331.     for (left = host->can_queue, ncrcurrent = hostdata->schedule;
  2332.     left > 0; ncrcurrent += 2, --left)
  2333. if (ncrcurrent[0] != hostdata->NOP_insn) 
  2334. /* FIXME : convert pointer to dsa_begin to pointer to dsa. */
  2335.     print_dsa (host, bus_to_virt (ncrcurrent[1] - 
  2336. (hostdata->E_dsa_code_begin - 
  2337. hostdata->E_dsa_code_template)), "");
  2338.     printk ("scsi%d : end schedule dsa arrayn", host->host_no);
  2339.     
  2340.     printk ("scsi%d : reconnect_dsa_head :n", host->host_no);
  2341.     
  2342.     for (left = host->can_queue, 
  2343. dsa = bus_to_virt (hostdata->reconnect_dsa_head);
  2344. left >= 0 && dsa; 
  2345. dsa = next_dsa) {
  2346. save_flags (flags);
  2347. cli();
  2348. if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) {
  2349.     printk ("scsi%d: bad DSA pointer 0x%p", host->host_no,
  2350. dsa);
  2351.     next_dsa = NULL;
  2352. }
  2353. else 
  2354. {
  2355.     next_dsa = bus_to_virt(dsa[hostdata->dsa_next / sizeof(u32)]);
  2356.     print_dsa (host, dsa, "");
  2357. }
  2358. restore_flags(flags);
  2359.     }
  2360.     printk ("scsi%d : end reconnect_dsa_headn", host->host_no);
  2361.     if (left < 0)
  2362. printk("scsi%d: possible loop in ncr reconnect listn",
  2363.     host->host_no);
  2364. }
  2365. static void
  2366. print_lots (struct Scsi_Host *host) {
  2367.     NCR53c7x0_local_declare();
  2368.     struct NCR53c7x0_hostdata *hostdata = 
  2369. (struct NCR53c7x0_hostdata *) host->hostdata[0];
  2370.     u32 *dsp_next, *dsp, *dsa, dbc_dcmd;
  2371.     unsigned char dcmd, sbcl;
  2372.     int i, size;
  2373.     NCR53c7x0_local_setup(host);
  2374.     if ((dsp_next = bus_to_virt(NCR53c7x0_read32 (DSP_REG)))) {
  2375.      dbc_dcmd = NCR53c7x0_read32(DBC_REG);
  2376.      dcmd = (dbc_dcmd & 0xff000000) >> 24;
  2377.      dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
  2378. dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
  2379. sbcl = NCR53c7x0_read8 (SBCL_REG);
  2380.     
  2381. /*
  2382.  * For the 53c710, the following will report value 0 for SCNTL3
  2383.  * and STEST0 - we don't have these registers.
  2384.  */
  2385.      printk ("scsi%d : DCMD|DBC=0x%x, DNAD=0x%x (virt 0x%p)n"
  2386. "         DSA=0x%lx (virt 0x%p)n"
  2387.         "         DSPS=0x%x, TEMP=0x%x (virt 0x%p), DMODE=0x%xn"
  2388. "         SXFER=0x%x, SCNTL3=0x%xn"
  2389. "         %s%s%sphase=%s, %d bytes in SCSI FIFOn"
  2390. "         SCRATCH=0x%x, saved2_dsa=0x%0lxn",
  2391.     host->host_no, dbc_dcmd, NCR53c7x0_read32(DNAD_REG),
  2392. bus_to_virt(NCR53c7x0_read32(DNAD_REG)),
  2393.     virt_to_bus(dsa), dsa,
  2394.     NCR53c7x0_read32(DSPS_REG), NCR53c7x0_read32(TEMP_REG), 
  2395.     bus_to_virt (NCR53c7x0_read32(TEMP_REG)),
  2396.     (int) NCR53c7x0_read8(hostdata->dmode),
  2397.     (int) NCR53c7x0_read8(SXFER_REG), 
  2398.     ((hostdata->chip / 100) == 8) ?
  2399. (int) NCR53c7x0_read8(SCNTL3_REG_800) : 0,
  2400.     (sbcl & SBCL_BSY) ? "BSY " : "",
  2401.     (sbcl & SBCL_SEL) ? "SEL " : "",
  2402.     (sbcl & SBCL_REQ) ? "REQ " : "",
  2403.     sstat2_to_phase(NCR53c7x0_read8 (((hostdata->chip / 100) == 8) ?
  2404.      SSTAT1_REG : SSTAT2_REG)),
  2405.     (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ? 
  2406. SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT,
  2407.     ((hostdata->chip / 100) == 8) ? NCR53c7x0_read8 (STEST0_REG_800) :
  2408. NCR53c7x0_read32(SCRATCHA_REG_800),
  2409.     hostdata->saved2_dsa);
  2410. printk ("scsi%d : DSP 0x%lx (virt 0x%p) ->n", host->host_no, 
  2411.     virt_to_bus(dsp), dsp);
  2412.      for (i = 6; i > 0; --i, dsp += size)
  2413.     size = print_insn (host, dsp, "", 1);
  2414. if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON)  {
  2415.     if ((hostdata->chip / 100) == 8)
  2416.         printk ("scsi%d : connected (SDID=0x%x, SSID=0x%x)n",
  2417.     host->host_no, NCR53c7x0_read8 (SDID_REG_800),
  2418.     NCR53c7x0_read8 (SSID_REG_800));
  2419.     else
  2420. printk ("scsi%d : connected (SDID=0x%x)n",
  2421.     host->host_no, NCR53c7x0_read8 (SDID_REG_700));
  2422.     print_dsa (host, dsa, "");
  2423. }
  2424. #if 1
  2425. print_queues (host);
  2426. #endif
  2427.     }
  2428. }
  2429. /*
  2430.  * Function : static int shutdown (struct Scsi_Host *host)
  2431.  * 
  2432.  * Purpose : does a clean (we hope) shutdown of the NCR SCSI 
  2433.  * chip.  Use prior to dumping core, unloading the NCR driver,
  2434.  * 
  2435.  * Returns : 0 on success
  2436.  */
  2437. static int 
  2438. shutdown (struct Scsi_Host *host) {
  2439.     NCR53c7x0_local_declare();
  2440.     unsigned long flags;
  2441.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  2442. host->hostdata[0];
  2443.     NCR53c7x0_local_setup(host);
  2444.     save_flags (flags);
  2445.     cli();
  2446. /* Get in a state where we can reset the SCSI bus */
  2447.     ncr_halt (host);
  2448.     ncr_scsi_reset (host);
  2449.     hostdata->soft_reset(host);
  2450.     disable (host);
  2451.     restore_flags (flags);
  2452.     return 0;
  2453. }
  2454. /*
  2455.  * Function : void ncr_scsi_reset (struct Scsi_Host *host)
  2456.  *
  2457.  * Purpose : reset the SCSI bus.
  2458.  */
  2459. static void 
  2460. ncr_scsi_reset (struct Scsi_Host *host) {
  2461.     NCR53c7x0_local_declare();
  2462.     unsigned long flags;
  2463.     NCR53c7x0_local_setup(host);
  2464.     save_flags (flags);
  2465.     cli();
  2466.     NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
  2467.     udelay(25); /* Minimum amount of time to assert RST */
  2468.     NCR53c7x0_write8(SCNTL1_REG, 0);
  2469.     restore_flags (flags);
  2470. }
  2471. /* 
  2472.  * Function : void hard_reset (struct Scsi_Host *host)
  2473.  *
  2474.  */
  2475. static void 
  2476. hard_reset (struct Scsi_Host *host) {
  2477.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  2478. host->hostdata[0];
  2479.     unsigned long flags;
  2480.     save_flags (flags);
  2481.     cli();
  2482.     ncr_scsi_reset(host);
  2483.     NCR53c7x0_driver_init (host);
  2484.     if (hostdata->soft_reset)
  2485. hostdata->soft_reset (host);
  2486.     restore_flags(flags);
  2487. }
  2488. /*
  2489.  * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host,
  2490.  * int free, int issue)
  2491.  *
  2492.  * Purpose : return a linked list (using the SCp.buffer field as next,
  2493.  * so we don't perturb hostdata.  We don't use a field of the 
  2494.  * NCR53c7x0_cmd structure since we may not have allocated one 
  2495.  * for the command causing the reset.) of Scsi_Cmnd structures that 
  2496.  *   had propogated below the Linux issue queue level.  If free is set, 
  2497.  * free the NCR53c7x0_cmd structures which are associated with 
  2498.  * the Scsi_Cmnd structures, and clean up any internal 
  2499.  * NCR lists that the commands were on.  If issue is set,
  2500.  * also return commands in the issue queue.
  2501.  *
  2502.  * Returns : linked list of commands
  2503.  *
  2504.  * NOTE : the caller should insure that the NCR chip is halted
  2505.  * if the free flag is set. 
  2506.  */
  2507. static Scsi_Cmnd *
  2508. return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
  2509.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  2510. host->hostdata[0];
  2511.     struct NCR53c7x0_cmd *c;
  2512.     int i;
  2513.     u32 *ncrcurrent;
  2514.     Scsi_Cmnd *list = NULL, *tmp;
  2515.     for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c; 
  2516.      c = (struct NCR53c7x0_cmd *) c->next)  {
  2517. if (c->cmd->SCp.buffer) {
  2518.     printk ("scsi%d : loop detected in running list!n", host->host_no);
  2519.     break;
  2520. } else {
  2521.     printk ("Duh? Bad things happening in the NCR drivern");
  2522.     break;
  2523. }
  2524. c->cmd->SCp.buffer = (struct scatterlist *) list;
  2525. list = c->cmd;
  2526. if (free) {
  2527.          c->next = hostdata->free;
  2528.          hostdata->free = c;
  2529. }
  2530.     }
  2531.     if (free) { 
  2532. for (i = 0, ncrcurrent = (u32 *) hostdata->schedule; 
  2533.     i < host->can_queue; ++i, ncrcurrent += 2) {
  2534.     ncrcurrent[0] = hostdata->NOP_insn;
  2535.     ncrcurrent[1] = 0xdeadbeef;
  2536. }
  2537. hostdata->ncrcurrent = NULL;
  2538.     }
  2539.     if (issue) {
  2540. for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) {
  2541.     if (tmp->SCp.buffer) {
  2542. printk ("scsi%d : loop detected in issue queue!n", 
  2543. host->host_no);
  2544. break;
  2545.     }
  2546.     tmp->SCp.buffer = (struct scatterlist *) list;
  2547.     list = tmp;
  2548. }
  2549. if (free)
  2550.     hostdata->issue_queue = NULL;
  2551.     }
  2552.     return list;
  2553. }
  2554. /* 
  2555.  * Function : static int disable (struct Scsi_Host *host)
  2556.  *
  2557.  * Purpose : disables the given NCR host, causing all commands
  2558.  *  to return a driver error.  Call this so we can unload the
  2559.  *  module during development and try again.  Eventually, 
  2560.  *  we should be able to find clean workarounds for these
  2561.  *  problems.
  2562.  *
  2563.  * Inputs : host - hostadapter to twiddle
  2564.  *
  2565.  * Returns : 0 on success.
  2566.  */
  2567. static int 
  2568. disable (struct Scsi_Host *host) {
  2569.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  2570. host->hostdata[0];
  2571.     unsigned long flags;
  2572.     Scsi_Cmnd *nuke_list, *tmp;
  2573.     save_flags(flags);
  2574.     cli();
  2575.     if (hostdata->state != STATE_HALTED)
  2576. ncr_halt (host);
  2577.     nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */);
  2578.     hard_reset (host);
  2579.     hostdata->state = STATE_DISABLED;
  2580.     restore_flags(flags);
  2581.     printk ("scsi%d : nuking commandsn", host->host_no);
  2582.     for (; nuke_list; nuke_list = tmp) {
  2583.     tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
  2584.     nuke_list->result = DID_ERROR << 16;
  2585.     nuke_list->scsi_done(nuke_list);
  2586.     }
  2587.     printk ("scsi%d : done. n", host->host_no);
  2588.     printk (KERN_ALERT "scsi%d : disabled.  Unload and reloadn",
  2589.      host->host_no);
  2590.     return 0;
  2591. }
  2592. /*
  2593.  * Function : static int ncr_halt (struct Scsi_Host *host)
  2594.  * 
  2595.  * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
  2596.  *
  2597.  * Inputs : host - SCSI chip to halt
  2598.  *
  2599.  * Returns : 0 on success
  2600.  */
  2601. static int 
  2602. ncr_halt (struct Scsi_Host *host) {
  2603.     NCR53c7x0_local_declare();
  2604.     unsigned long flags;
  2605.     unsigned char istat, tmp;
  2606.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  2607. host->hostdata[0];
  2608.     int stage;
  2609.     NCR53c7x0_local_setup(host);
  2610.     save_flags(flags);
  2611.     cli();
  2612.     /* Stage 0 : eat all interrupts
  2613.        Stage 1 : set ABORT
  2614.        Stage 2 : eat all but abort interrupts
  2615.        Stage 3 : eat all interrupts
  2616.      */
  2617.     for (stage = 0;;) {
  2618. if (stage == 1) {
  2619.     NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT);
  2620.     ++stage;
  2621. }
  2622. istat = NCR53c7x0_read8 (hostdata->istat);
  2623. if (istat & ISTAT_SIP) {
  2624.     tmp = NCR53c7x0_read8(SSTAT0_REG);
  2625. } else if (istat & ISTAT_DIP) {
  2626.     tmp = NCR53c7x0_read8(DSTAT_REG);
  2627.     if (stage == 2) {
  2628. if (tmp & DSTAT_ABRT) {
  2629.     NCR53c7x0_write8(hostdata->istat, 0);
  2630.     ++stage;
  2631. } else {
  2632.     printk(KERN_ALERT "scsi%d : could not halt NCR chipn", 
  2633. host->host_no);
  2634.     disable (host);
  2635.      }
  2636.          }
  2637. }
  2638. if (!(istat & (ISTAT_SIP|ISTAT_DIP))) {
  2639.     if (stage == 0)
  2640.      ++stage;
  2641.     else if (stage == 3)
  2642. break;
  2643. }
  2644.     }
  2645.     hostdata->state = STATE_HALTED;
  2646.     restore_flags(flags);
  2647. #if 0
  2648.     print_lots (host);
  2649. #endif
  2650.     return 0;
  2651. }
  2652. /* 
  2653.  * Function: event_name (int event)
  2654.  * 
  2655.  * Purpose: map event enum into user-readable strings.
  2656.  */
  2657. static const char *
  2658. event_name (int event) {
  2659.     switch (event) {
  2660.     case EVENT_NONE: return "none";
  2661.     case EVENT_ISSUE_QUEUE: return "to issue queue";
  2662.     case EVENT_START_QUEUE: return "to start queue";
  2663.     case EVENT_SELECT: return "selected";
  2664.     case EVENT_DISCONNECT: return "disconnected";
  2665.     case EVENT_RESELECT: return "reselected";
  2666.     case EVENT_COMPLETE: return "completed";
  2667.     case EVENT_IDLE: return "idle";
  2668.     case EVENT_SELECT_FAILED: return "select failed";
  2669.     case EVENT_BEFORE_SELECT: return "before select";
  2670.     case EVENT_RESELECT_FAILED: return "reselect failed";
  2671.     default: return "unknown";
  2672.     }
  2673. }
  2674. /*
  2675.  * Function : void dump_events (struct Scsi_Host *host, count)
  2676.  *
  2677.  * Purpose : print last count events which have occurred.
  2678.  */ 
  2679. static void
  2680. dump_events (struct Scsi_Host *host, int count) {
  2681.     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
  2682. host->hostdata[0];
  2683.     struct NCR53c7x0_event event;
  2684.     int i;
  2685.     unsigned long flags;
  2686.     if (hostdata->events) {
  2687. if (count > hostdata->event_size)
  2688.     count = hostdata->event_size;
  2689. for (i = hostdata->event_index; count > 0; 
  2690.     i = (i ? i - 1 : hostdata->event_size -1), --count) {
  2691.     save_flags(flags);
  2692. /*
  2693.  * By copying the event we're currently examining with interrupts
  2694.  * disabled, we can do multiple printk(), etc. operations and 
  2695.  * still be guaranteed that they're happening on the same 
  2696.  * event structure.
  2697.  */
  2698.     cli();
  2699. #if 0
  2700.     event = hostdata->events[i];
  2701. #else
  2702.     memcpy ((void *) &event, (void *) &(hostdata->events[i]),
  2703. sizeof(event));
  2704. #endif
  2705.     restore_flags(flags);
  2706.     printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %dn",
  2707. host->host_no, event_name (event.event), count,
  2708. (long) event.time.tv_sec, (long) event.time.tv_usec,
  2709. event.target, event.lun);
  2710.     if (event.dsa) 
  2711. printk ("         event for dsa 0x%lx (virt 0x%p)n", 
  2712.     virt_to_bus(event.dsa), event.dsa);
  2713.     if (event.pid != -1) {
  2714. printk ("         event for pid %ld ", event.pid);
  2715. print_command (event.cmnd);
  2716.     }
  2717. }
  2718.     }
  2719. }
  2720. /*
  2721.  * Function: check_address
  2722.  *
  2723.  * Purpose: Check to see if a possibly corrupt pointer will fault the 
  2724.  * kernel.
  2725.  *
  2726.  * Inputs: addr - address; size - size of area
  2727.  *
  2728.  * Returns: 0 if area is OK, -1 on error.
  2729.  *
  2730.  * NOTES: should be implemented in terms of vverify on kernels 
  2731.  * that have it.
  2732.  */
  2733. static int 
  2734. check_address (unsigned long addr, int size) {
  2735.     return (virt_to_phys((void *)addr) < PAGE_SIZE || virt_to_phys((void *)(addr + size)) > virt_to_phys(high_memory) ?  -1 : 0);
  2736. }
  2737. #ifdef MODULE
  2738. int 
  2739. NCR53c7x0_release(struct Scsi_Host *host) {
  2740.     struct NCR53c7x0_hostdata *hostdata = 
  2741. (struct NCR53c7x0_hostdata *) host->hostdata[0];
  2742.     struct NCR53c7x0_cmd *cmd, *tmp;
  2743.     shutdown (host);
  2744.     if (host->irq != IRQ_NONE)
  2745. {
  2746.     int irq_count;
  2747.     struct Scsi_Host *tmp;
  2748.     for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
  2749. if (tmp->hostt == the_template && tmp->irq == host->irq)
  2750.     ++irq_count;
  2751.     if (irq_count == 1)
  2752. free_irq(host->irq, NULL);
  2753. }
  2754.     if (host->dma_channel != DMA_NONE)
  2755. free_dma(host->dma_channel);
  2756.     if (host->io_port)
  2757. release_region(host->io_port, host->n_io_port);
  2758.     
  2759.     for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp, 
  2760. --hostdata->num_cmds) {
  2761. tmp = (struct NCR53c7x0_cmd *) cmd->next;
  2762.     /* 
  2763.      * If we're going to loop, try to stop it to get a more accurate
  2764.      * count of the leaked commands.
  2765.      */
  2766. cmd->next = NULL;
  2767. if (cmd->free)
  2768.     cmd->free ((void *) cmd->real, cmd->size);
  2769.     }
  2770.     if (hostdata->num_cmds)
  2771. printk ("scsi%d : leaked %d NCR53c7x0_cmd structuresn",
  2772.     host->host_no, hostdata->num_cmds);
  2773.     if (hostdata->events) 
  2774. vfree ((void *)hostdata->events);
  2775.     /* XXX This assumes default cache mode to be IOMAP_FULL_CACHING, which
  2776.      * XXX may be invalid (CONFIG_060_WRITETHROUGH)
  2777.      */
  2778.     kernel_set_cachemode((u32)hostdata, 8192, IOMAP_FULL_CACHING);
  2779.     free_pages ((u32)hostdata, 1);
  2780.     return 1;
  2781. }
  2782. #endif /* def MODULE */