linux/drivers/scsi/tmscsim.c
<<
>>
Prefs
   1/************************************************************************
   2 *      FILE NAME : TMSCSIM.C                                           *
   3 *           BY   : C.L. Huang,  ching@tekram.com.tw                    *
   4 *      Description: Device Driver for Tekram DC-390(T) PCI SCSI        *
   5 *                   Bus Master Host Adapter                            *
   6 * (C)Copyright 1995-1996 Tekram Technology Co., Ltd.                   *
   7 ************************************************************************
   8 * (C) Copyright: put under GNU GPL in 10/96                            *
   9 *                              (see Documentation/scsi/tmscsim.txt)    *
  10 ************************************************************************
  11 * $Id: tmscsim.c,v 2.60.2.30 2000/12/20 01:07:12 garloff Exp $         *
  12 *      Enhancements and bugfixes by                                    *
  13 *      Kurt Garloff <kurt@garloff.de>  <garloff@suse.de>               *
  14 ************************************************************************
  15 *      HISTORY:                                                        *
  16 *                                                                      *
  17 *      REV#    DATE    NAME    DESCRIPTION                             *
  18 *      1.00  96/04/24  CLH     First release                           *
  19 *      1.01  96/06/12  CLH     Fixed bug of Media Change for Removable *
  20 *                              Device, scan all LUN. Support Pre2.0.10 *
  21 *      1.02  96/06/18  CLH     Fixed bug of Command timeout ...        *
  22 *      1.03  96/09/25  KG      Added tmscsim_proc_info()               *
  23 *      1.04  96/10/11  CLH     Updating for support KV 2.0.x           *
  24 *      1.05  96/10/18  KG      Fixed bug in DC390_abort(null ptr deref)*
  25 *      1.06  96/10/25  KG      Fixed module support                    *
  26 *      1.07  96/11/09  KG      Fixed tmscsim_proc_info()               *
  27 *      1.08  96/11/18  KG      Fixed null ptr in DC390_Disconnect()    *
  28 *      1.09  96/11/30  KG      Added register the allocated IO space   *
  29 *      1.10  96/12/05  CLH     Modified tmscsim_proc_info(), and reset *
  30 *                              pending interrupt in DC390_detect()     *
  31 *      1.11  97/02/05  KG/CLH  Fixeds problem with partitions greater  *
  32 *                              than 1GB                                *
  33 *      1.12  98/02/15  MJ      Rewritten PCI probing                   *
  34 *      1.13  98/04/08  KG      Support for non DC390, __initfunc decls,*
  35 *                              changed max devs from 10 to 16          *
  36 *      1.14a 98/05/05  KG      Dynamic DCB allocation, add-single-dev  *
  37 *                              for LUNs if LUN_SCAN (BIOS) not set     *
  38 *                              runtime config using /proc interface    *
  39 *      1.14b 98/05/06  KG      eliminated cli (); sti (); spinlocks    *
  40 *      1.14c 98/05/07  KG      2.0.x compatibility                     *
  41 *      1.20a 98/05/07  KG      changed names of funcs to be consistent *
  42 *                              DC390_ (entry points), dc390_ (internal)*
  43 *                              reworked locking                        *
  44 *      1.20b 98/05/12  KG      bugs: version, kfree, _ctmp             *
  45 *                              debug output                            *
  46 *      1.20c 98/05/12  KG      bugs: kfree, parsing, EEpromDefaults    *
  47 *      1.20d 98/05/14  KG      bugs: list linkage, clear flag after    *
  48 *                              reset on startup, code cleanup          *
  49 *      1.20e 98/05/15  KG      spinlock comments, name space cleanup   *
  50 *                              pLastDCB now part of ACB structure      *
  51 *                              added stats, timeout for 2.1, TagQ bug  *
  52 *                              RESET and INQUIRY interface commands    *
  53 *      1.20f 98/05/18  KG      spinlocks fixes, max_lun fix, free DCBs *
  54 *                              for missing LUNs, pending int           *
  55 *      1.20g 98/05/19  KG      Clean up: Avoid short                   *
  56 *      1.20h 98/05/21  KG      Remove AdaptSCSIID, max_lun ...         *
  57 *      1.20i 98/05/21  KG      Aiiie: Bug with TagQMask                *
  58 *      1.20j 98/05/24  KG      Handle STAT_BUSY, handle pACB->pLinkDCB *
  59 *                              == 0 in remove_dev and DoingSRB_Done    *
  60 *      1.20k 98/05/25  KG      DMA_INT (experimental)                  *
  61 *      1.20l 98/05/27  KG      remove DMA_INT; DMA_IDLE cmds added;    *
  62 *      1.20m 98/06/10  KG      glitch configurable; made some global   *
  63 *                              vars part of ACB; use DC390_readX       *
  64 *      1.20n 98/06/11  KG      startup params                          *
  65 *      1.20o 98/06/15  KG      added TagMaxNum to boot/module params   *
  66 *                              Device Nr -> Idx, TagMaxNum power of 2  *
  67 *      1.20p 98/06/17  KG      Docu updates. Reset depends on settings *
  68 *                              pci_set_master added; 2.0.xx: pcibios_* *
  69 *                              used instead of MechNum things ...      *
  70 *      1.20q 98/06/23  KG      Changed defaults. Added debug code for  *
  71 *                              removable media and fixed it. TagMaxNum *
  72 *                              fixed for DC390. Locking: ACB, DRV for  *
  73 *                              better IRQ sharing. Spelling: Queueing  *
  74 *                              Parsing and glitch_cfg changes. Display *
  75 *                              real SyncSpeed value. Made DisConn      *
  76 *                              functional (!)                          *
  77 *      1.20r 98/06/30  KG      Debug macros, allow disabling DsCn, set *
  78 *                              BIT4 in CtrlR4, EN_PAGE_INT, 2.0 module *
  79 *                              param -1 fixed.                         *
  80 *      1.20s 98/08/20  KG      Debug info on abort(), try to check PCI,*
  81 *                              phys_to_bus instead of phys_to_virt,    *
  82 *                              fixed sel. process, fixed locking,      *
  83 *                              added MODULE_XXX infos, changed IRQ     *
  84 *                              request flags, disable DMA_INT          *
  85 *      1.20t 98/09/07  KG      TagQ report fixed; Write Erase DMA Stat;*
  86 *                              initfunc -> __init; better abort;       *
  87 *                              Timeout for XFER_DONE & BLAST_COMPLETE; *
  88 *                              Allow up to 33 commands being processed *
  89 *      2.0a  98/10/14  KG      Max Cmnds back to 17. DMA_Stat clearing *
  90 *                              all flags. Clear within while() loops   *
  91 *                              in DataIn_0/Out_0. Null ptr in dumpinfo *
  92 *                              for pSRB==0. Better locking during init.*
  93 *                              bios_param() now respects part. table.  *
  94 *      2.0b  98/10/24  KG      Docu fixes. Timeout Msg in DMA Blast.   *
  95 *                              Disallow illegal idx in INQUIRY/REMOVE  *
  96 *      2.0c  98/11/19  KG      Cleaned up detect/init for SMP boxes,   *
  97 *                              Write Erase DMA (1.20t) caused problems *
  98 *      2.0d  98/12/25  KG      Christmas release ;-) Message handling  *
  99 *                              completely reworked. Handle target ini- *
 100 *                              tiated SDTR correctly.                  *
 101 *      2.0d1 99/01/25  KG      Try to handle RESTORE_PTR               *
 102 *      2.0d2 99/02/08  KG      Check for failure of kmalloc, correct   *
 103 *                              inclusion of scsicam.h, DelayReset      *
 104 *      2.0d3 99/05/31  KG      DRIVER_OK -> DID_OK, DID_NO_CONNECT,    *
 105 *                              detect Target mode and warn.            *
 106 *                              pcmd->result handling cleaned up.       *
 107 *      2.0d4 99/06/01  KG      Cleaned selection process. Found bug    *
 108 *                              which prevented more than 16 tags. Now: *
 109 *                              24. SDTR cleanup. Cleaner multi-LUN     *
 110 *                              handling. Don't modify ControlRegs/FIFO *
 111 *                              when connected.                         *
 112 *      2.0d5 99/06/01  KG      Clear DevID, Fix INQUIRY after cfg chg. *
 113 *      2.0d6 99/06/02  KG      Added ADD special command to allow cfg. *
 114 *                              before detection. Reset SYNC_NEGO_DONE  *
 115 *                              after a bus reset.                      *
 116 *      2.0d7 99/06/03  KG      Fixed bugs wrt add,remove commands      *
 117 *      2.0d8 99/06/04  KG      Removed copying of cmnd into CmdBlock.  *
 118 *                              Fixed Oops in _release().               *
 119 *      2.0d9 99/06/06  KG      Also tag queue INQUIRY, T_U_R, ...      *
 120 *                              Allow arb. no. of Tagged Cmnds. Max 32  *
 121 *      2.0d1099/06/20  KG      TagMaxNo changes now honoured! Queueing *
 122 *                              clearified (renamed ..) TagMask handling*
 123 *                              cleaned.                                *
 124 *      2.0d1199/06/28  KG      cmd->result now identical to 2.0d2      *
 125 *      2.0d1299/07/04  KG      Changed order of processing in IRQ      *
 126 *      2.0d1399/07/05  KG      Don't update DCB fields if removed      *
 127 *      2.0d1499/07/05  KG      remove_dev: Move kfree() to the end     *
 128 *      2.0d1599/07/12  KG      use_new_eh_code: 0, ULONG -> UINT where *
 129 *                              appropriate                             *
 130 *      2.0d1699/07/13  KG      Reenable StartSCSI interrupt, Retry msg *
 131 *      2.0d1799/07/15  KG      Remove debug msg. Disable recfg. when   *
 132 *                              there are queued cmnds                  *
 133 *      2.0d1899/07/18  KG      Selection timeout: Don't requeue        *
 134 *      2.0d1999/07/18  KG      Abort: Only call scsi_done if dequeued  *
 135 *      2.0d2099/07/19  KG      Rst_Detect: DoingSRB_Done               *
 136 *      2.0d2199/08/15  KG      dev_id for request/free_irq, cmnd[0] for*
 137 *                              RETRY, SRBdone does DID_ABORT for the   *
 138 *                              cmd passed by DC390_reset()             *
 139 *      2.0d2299/08/25  KG      dev_id fixed. can_queue: 42             *
 140 *      2.0d2399/08/25  KG      Removed some debugging code. dev_id     *
 141 *                              now is set to pACB. Use u8,u16,u32.     *
 142 *      2.0d2499/11/14  KG      Unreg. I/O if failed IRQ alloc. Call    *
 143 *                              done () w/ DID_BAD_TARGET in case of    *
 144 *                              missing DCB. We are old EH!!            *
 145 *      2.0d2500/01/15  KG      2.3.3x compat from Andreas Schultz      *
 146 *                              set unique_id. Disable RETRY message.   *
 147 *      2.0d2600/01/29  KG      Go to new EH.                           *
 148 *      2.0d2700/01/31  KG      ... but maintain 2.0 compat.            *
 149 *                              and fix DCB freeing                     *
 150 *      2.0d2800/02/14  KG      Queue statistics fixed, dump special cmd*
 151 *                              Waiting_Timer for failed StartSCSI      *
 152 *                              New EH: Don't return cmnds to ML on RST *
 153 *                              Use old EH (don't have new EH fns yet)  *
 154 *                              Reset: Unlock, but refuse to queue      *
 155 *                              2.3 __setup function                    *
 156 *      2.0e  00/05/22  KG      Return residual for 2.3                 *
 157 *      2.0e1 00/05/25  KG      Compile fixes for 2.3.99                *
 158 *      2.0e2 00/05/27  KG      Jeff Garzik's pci_enable_device()       *
 159 *      2.0e3 00/09/29  KG      Some 2.4 changes. Don't try Sync Nego   *
 160 *                              before INQUIRY has reported ability.    *
 161 *                              Recognise INQUIRY as scanning command.  *
 162 *      2.0e4 00/10/13  KG      Allow compilation into 2.4 kernel       *
 163 *      2.0e5 00/11/17  KG      Store Inq.flags in DCB                  *
 164 *      2.0e6 00/11/22  KG      2.4 init function (Thx to O.Schumann)   *
 165 *                              2.4 PCI device table (Thx to A.Richter) *
 166 *      2.0e7 00/11/28  KG      Allow overriding of BIOS settings       *
 167 *      2.0f  00/12/20  KG      Handle failed INQUIRYs during scan      *
 168 *      2.1a  03/11/29  GL, KG  Initial fixing for 2.6. Convert to      *
 169 *                              use the current PCI-mapping API, update *
 170 *                              command-queuing.                        *
 171 *      2.1b  04/04/13  GL      Fix for 64-bit platforms                *
 172 *      2.1b1 04/01/31  GL      (applied 05.04) Remove internal         *
 173 *                              command-queuing.                        *
 174 *      2.1b2 04/02/01  CH      (applied 05.04) Fix error-handling      *
 175 *      2.1c  04/05/23  GL      Update to use the new pci_driver API,   *
 176 *                              some scsi EH updates, more cleanup.     *
 177 *      2.1d  04/05/27  GL      Moved setting of scan_devices to        *
 178 *                              slave_alloc/_configure/_destroy, as     *
 179 *                              suggested by CH.                        *
 180 ***********************************************************************/
 181
 182/* DEBUG options */
 183//#define DC390_DEBUG0
 184//#define DC390_DEBUG1
 185//#define DC390_DCBDEBUG
 186//#define DC390_PARSEDEBUG
 187//#define DC390_REMOVABLEDEBUG
 188//#define DC390_LOCKDEBUG
 189
 190//#define NOP do{}while(0)
 191#define C_NOP
 192
 193/* Debug definitions */
 194#ifdef DC390_DEBUG0
 195# define DEBUG0(x) x
 196#else
 197# define DEBUG0(x) C_NOP
 198#endif
 199#ifdef DC390_DEBUG1
 200# define DEBUG1(x) x
 201#else
 202# define DEBUG1(x) C_NOP
 203#endif
 204#ifdef DC390_DCBDEBUG
 205# define DCBDEBUG(x) x
 206#else
 207# define DCBDEBUG(x) C_NOP
 208#endif
 209#ifdef DC390_PARSEDEBUG
 210# define PARSEDEBUG(x) x
 211#else
 212# define PARSEDEBUG(x) C_NOP
 213#endif
 214#ifdef DC390_REMOVABLEDEBUG
 215# define REMOVABLEDEBUG(x) x
 216#else
 217# define REMOVABLEDEBUG(x) C_NOP
 218#endif
 219#define DCBDEBUG1(x) C_NOP
 220
 221#include <linux/module.h>
 222#include <linux/delay.h>
 223#include <linux/signal.h>
 224#include <linux/sched.h>
 225#include <linux/errno.h>
 226#include <linux/kernel.h>
 227#include <linux/ioport.h>
 228#include <linux/pci.h>
 229#include <linux/proc_fs.h>
 230#include <linux/string.h>
 231#include <linux/mm.h>
 232#include <linux/blkdev.h>
 233#include <linux/timer.h>
 234#include <linux/interrupt.h>
 235#include <linux/init.h>
 236#include <linux/spinlock.h>
 237#include <asm/io.h>
 238
 239#include <scsi/scsi.h>
 240#include <scsi/scsi_cmnd.h>
 241#include <scsi/scsi_device.h>
 242#include <scsi/scsi_host.h>
 243#include <scsi/scsicam.h>
 244#include <scsi/scsi_tcq.h>
 245
 246
 247#define DC390_BANNER "Tekram DC390/AM53C974"
 248#define DC390_VERSION "2.1d 2004-05-27"
 249
 250#define PCI_DEVICE_ID_AMD53C974         PCI_DEVICE_ID_AMD_SCSI
 251
 252#include "tmscsim.h"
 253
 254
 255static void dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 256static void dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 257static void dc390_Command_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 258static void dc390_Status_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 259static void dc390_MsgOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 260static void dc390_MsgIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 261static void dc390_DataOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 262static void dc390_DataInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 263static void dc390_CommandPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 264static void dc390_StatusPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 265static void dc390_MsgOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 266static void dc390_MsgInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 267static void dc390_Nop_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 268static void dc390_Nop_1( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 269
 270static void dc390_SetXferRate( struct dc390_acb* pACB, struct dc390_dcb* pDCB );
 271static void dc390_Disconnect( struct dc390_acb* pACB );
 272static void dc390_Reselect( struct dc390_acb* pACB );
 273static void dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB );
 274static void dc390_ScsiRstDetect( struct dc390_acb* pACB );
 275static void dc390_EnableMsgOut_Abort(struct dc390_acb*, struct dc390_srb*);
 276static void dc390_dumpinfo(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB);
 277static void dc390_ResetDevParam(struct dc390_acb* pACB);
 278
 279static u32      dc390_laststatus = 0;
 280static u8       dc390_adapterCnt = 0;
 281
 282static int disable_clustering;
 283module_param(disable_clustering, int, S_IRUGO);
 284MODULE_PARM_DESC(disable_clustering, "If you experience problems with your devices, try setting to 1");
 285
 286/* Startup values, to be overriden on the commandline */
 287static int tmscsim[] = {-2, -2, -2, -2, -2, -2};
 288
 289module_param_array(tmscsim, int, NULL, 0);
 290MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)");
 291MODULE_AUTHOR("C.L. Huang / Kurt Garloff");
 292MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");
 293MODULE_LICENSE("GPL");
 294MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
 295
 296static void *dc390_phase0[]={
 297       dc390_DataOut_0,
 298       dc390_DataIn_0,
 299       dc390_Command_0,
 300       dc390_Status_0,
 301       dc390_Nop_0,
 302       dc390_Nop_0,
 303       dc390_MsgOut_0,
 304       dc390_MsgIn_0,
 305       dc390_Nop_1
 306       };
 307
 308static void *dc390_phase1[]={
 309       dc390_DataOutPhase,
 310       dc390_DataInPhase,
 311       dc390_CommandPhase,
 312       dc390_StatusPhase,
 313       dc390_Nop_0,
 314       dc390_Nop_0,
 315       dc390_MsgOutPhase,
 316       dc390_MsgInPhase,
 317       dc390_Nop_1
 318       };
 319
 320#ifdef DC390_DEBUG1
 321static char* dc390_p0_str[] = {
 322       "dc390_DataOut_0",
 323       "dc390_DataIn_0",
 324       "dc390_Command_0",
 325       "dc390_Status_0",
 326       "dc390_Nop_0",
 327       "dc390_Nop_0",
 328       "dc390_MsgOut_0",
 329       "dc390_MsgIn_0",
 330       "dc390_Nop_1"
 331       };
 332     
 333static char* dc390_p1_str[] = {
 334       "dc390_DataOutPhase",
 335       "dc390_DataInPhase",
 336       "dc390_CommandPhase",
 337       "dc390_StatusPhase",
 338       "dc390_Nop_0",
 339       "dc390_Nop_0",
 340       "dc390_MsgOutPhase",
 341       "dc390_MsgInPhase",
 342       "dc390_Nop_1"
 343       };
 344#endif   
 345
 346static u8  dc390_eepromBuf[MAX_ADAPTER_NUM][EE_LEN];
 347static u8  dc390_clock_period1[] = {4, 5, 6, 7, 8, 10, 13, 20};
 348static u8  dc390_clock_speed[] = {100,80,67,57,50, 40, 31, 20};
 349
 350/***********************************************************************
 351 * Functions for the management of the internal structures 
 352 * (DCBs, SRBs, Queueing)
 353 *
 354 **********************************************************************/
 355static struct dc390_dcb __inline__ *dc390_findDCB ( struct dc390_acb* pACB, u8 id, u8 lun)
 356{
 357   struct dc390_dcb* pDCB = pACB->pLinkDCB; if (!pDCB) return NULL;
 358   while (pDCB->TargetID != id || pDCB->TargetLUN != lun)
 359     {
 360        pDCB = pDCB->pNextDCB;
 361        if (pDCB == pACB->pLinkDCB)
 362             return NULL;
 363     }
 364   DCBDEBUG1( printk (KERN_DEBUG "DCB %p (%02x,%02x) found.\n", \
 365                      pDCB, pDCB->TargetID, pDCB->TargetLUN));
 366   return pDCB;
 367}
 368
 369/* Insert SRB oin top of free list */
 370static __inline__ void dc390_Free_insert (struct dc390_acb* pACB, struct dc390_srb* pSRB)
 371{
 372    DEBUG0(printk ("DC390: Free SRB %p\n", pSRB));
 373    pSRB->pNextSRB = pACB->pFreeSRB;
 374    pACB->pFreeSRB = pSRB;
 375}
 376
 377static __inline__ void dc390_Going_append (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
 378{
 379    pDCB->GoingSRBCnt++;
 380    DEBUG0(printk("DC390: Append SRB %p to Going\n", pSRB));
 381    /* Append to the list of Going commands */
 382    if( pDCB->pGoingSRB )
 383        pDCB->pGoingLast->pNextSRB = pSRB;
 384    else
 385        pDCB->pGoingSRB = pSRB;
 386
 387    pDCB->pGoingLast = pSRB;
 388    /* No next one in sent list */
 389    pSRB->pNextSRB = NULL;
 390}
 391
 392static __inline__ void dc390_Going_remove (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
 393{
 394        DEBUG0(printk("DC390: Remove SRB %p from Going\n", pSRB));
 395   if (pSRB == pDCB->pGoingSRB)
 396        pDCB->pGoingSRB = pSRB->pNextSRB;
 397   else
 398     {
 399        struct dc390_srb* psrb = pDCB->pGoingSRB;
 400        while (psrb && psrb->pNextSRB != pSRB)
 401          psrb = psrb->pNextSRB;
 402        if (!psrb) 
 403          { printk (KERN_ERR "DC390: Remove non-ex. SRB %p from Going!\n", pSRB); return; }
 404        psrb->pNextSRB = pSRB->pNextSRB;
 405        if (pSRB == pDCB->pGoingLast)
 406          pDCB->pGoingLast = psrb;
 407     }
 408   pDCB->GoingSRBCnt--;
 409}
 410
 411static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
 412{
 413        memset(sg, 0, sizeof(struct scatterlist));
 414        sg->page        = virt_to_page(addr);
 415        sg->length      = length;
 416        sg->offset      = (unsigned long)addr & ~PAGE_MASK;
 417        return sg;
 418}
 419
 420/* Create pci mapping */
 421static int dc390_pci_map (struct dc390_srb* pSRB)
 422{
 423        int error = 0;
 424        struct scsi_cmnd *pcmd = pSRB->pcmd;
 425        struct pci_dev *pdev = pSRB->pSRBDCB->pDCBACB->pdev;
 426        dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp));
 427
 428        /* Map sense buffer */
 429        if (pSRB->SRBFlag & AUTO_REQSENSE) {
 430                pSRB->pSegmentList      = dc390_sg_build_single(&pSRB->Segmentx, pcmd->sense_buffer, sizeof(pcmd->sense_buffer));
 431                pSRB->SGcount           = pci_map_sg(pdev, pSRB->pSegmentList, 1,
 432                                                     DMA_FROM_DEVICE);
 433                cmdp->saved_dma_handle  = sg_dma_address(pSRB->pSegmentList);
 434
 435                /* TODO: error handling */
 436                if (pSRB->SGcount != 1)
 437                        error = 1;
 438                DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle));
 439        /* Map SG list */
 440        } else if (pcmd->use_sg) {
 441                pSRB->pSegmentList      = (struct scatterlist *) pcmd->request_buffer;
 442                pSRB->SGcount           = pci_map_sg(pdev, pSRB->pSegmentList, pcmd->use_sg,
 443                                                     pcmd->sc_data_direction);
 444                /* TODO: error handling */
 445                if (!pSRB->SGcount)
 446                        error = 1;
 447                DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\
 448                              __FUNCTION__, pcmd->request_buffer, pSRB->SGcount, pcmd->use_sg));
 449        /* Map single segment */
 450        } else if (pcmd->request_buffer && pcmd->request_bufflen) {
 451                pSRB->pSegmentList      = dc390_sg_build_single(&pSRB->Segmentx, pcmd->request_buffer, pcmd->request_bufflen);
 452                pSRB->SGcount           = pci_map_sg(pdev, pSRB->pSegmentList, 1,
 453                                                     pcmd->sc_data_direction);
 454                cmdp->saved_dma_handle  = sg_dma_address(pSRB->pSegmentList);
 455
 456                /* TODO: error handling */
 457                if (pSRB->SGcount != 1)
 458                        error = 1;
 459                DEBUG1(printk("%s(): Mapped request buffer %p at %x\n", __FUNCTION__, pcmd->request_buffer, cmdp->saved_dma_handle));
 460        /* No mapping !? */     
 461        } else
 462                pSRB->SGcount = 0;
 463
 464        return error;
 465}
 466
 467/* Remove pci mapping */
 468static void dc390_pci_unmap (struct dc390_srb* pSRB)
 469{
 470        struct scsi_cmnd *pcmd = pSRB->pcmd;
 471        struct pci_dev *pdev = pSRB->pSRBDCB->pDCBACB->pdev;
 472        DEBUG1(dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp)));
 473
 474        if (pSRB->SRBFlag) {
 475                pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE);
 476                DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle));
 477        } else if (pcmd->use_sg) {
 478                pci_unmap_sg(pdev, pcmd->request_buffer, pcmd->use_sg, pcmd->sc_data_direction);
 479                DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", __FUNCTION__, pcmd->request_buffer, pcmd->use_sg));
 480        } else if (pcmd->request_buffer && pcmd->request_bufflen) {
 481                pci_unmap_sg(pdev, &pSRB->Segmentx, 1, pcmd->sc_data_direction);
 482                DEBUG1(printk("%s(): Unmapped request buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle));
 483        }
 484}
 485
 486static void __inline__
 487dc390_freetag (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
 488{
 489        if (pSRB->TagNumber != SCSI_NO_TAG) {
 490                pDCB->TagMask &= ~(1 << pSRB->TagNumber);   /* free tag mask */
 491                pSRB->TagNumber = SCSI_NO_TAG;
 492        }
 493}
 494
 495
 496static int
 497dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB )
 498{
 499    struct scsi_cmnd *scmd = pSRB->pcmd;
 500    struct scsi_device *sdev = scmd->device;
 501    u8 cmd, disc_allowed, try_sync_nego;
 502    char tag[2];
 503
 504    pSRB->ScsiPhase = SCSI_NOP0;
 505
 506    if (pACB->Connected)
 507    {
 508        // Should not happen normally
 509        printk (KERN_WARNING "DC390: Can't select when connected! (%08x,%02x)\n",
 510                pSRB->SRBState, pSRB->SRBFlag);
 511        pSRB->SRBState = SRB_READY;
 512        pACB->SelConn++;
 513        return 1;
 514    }
 515    if (time_before (jiffies, pACB->pScsiHost->last_reset))
 516    {
 517        DEBUG0(printk ("DC390: We were just reset and don't accept commands yet!\n"));
 518        return 1;
 519    }
 520    /* KG: Moved pci mapping here */
 521    dc390_pci_map(pSRB);
 522    /* TODO: error handling */
 523    DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
 524    DC390_write8 (Sync_Period, pDCB->SyncPeriod);
 525    DC390_write8 (Sync_Offset, pDCB->SyncOffset);
 526    DC390_write8 (CtrlReg1, pDCB->CtrlR1);
 527    DC390_write8 (CtrlReg3, pDCB->CtrlR3);
 528    DC390_write8 (CtrlReg4, pDCB->CtrlR4);
 529    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);             /* Flush FIFO */
 530    DEBUG1(printk (KERN_INFO "DC390: Start SCSI command: %02x (Sync:%02x)\n",\
 531            scmd->cmnd[0], pDCB->SyncMode));
 532
 533    /* Don't disconnect on AUTO_REQSENSE, cause it might be an
 534     * Contingent Allegiance Condition (6.6), where no tags should be used.
 535     * All other have to be allowed to disconnect to prevent Incorrect 
 536     * Initiator Connection (6.8.2/6.5.2) */
 537    /* Changed KG, 99/06/06 */
 538    if (! (pSRB->SRBFlag & AUTO_REQSENSE))
 539        disc_allowed = pDCB->DevMode & EN_DISCONNECT_;
 540    else
 541        disc_allowed = 0;
 542
 543    if ((pDCB->SyncMode & SYNC_ENABLE) && pDCB->TargetLUN == 0 && sdev->sdtr &&
 544        (((scmd->cmnd[0] == REQUEST_SENSE || (pSRB->SRBFlag & AUTO_REQSENSE)) &&
 545          !(pDCB->SyncMode & SYNC_NEGO_DONE)) || scmd->cmnd[0] == INQUIRY))
 546      try_sync_nego = 1;
 547    else
 548      try_sync_nego = 0;
 549
 550    pSRB->MsgCnt = 0;
 551    cmd = SEL_W_ATN;
 552    DC390_write8 (ScsiFifo, IDENTIFY(disc_allowed, pDCB->TargetLUN));
 553    /* Change 99/05/31: Don't use tags when not disconnecting (BUSY) */
 554    if ((pDCB->SyncMode & EN_TAG_QUEUEING) && disc_allowed && scsi_populate_tag_msg(scmd, tag)) {
 555        DC390_write8(ScsiFifo, tag[0]);
 556        pDCB->TagMask |= 1 << tag[1];
 557        pSRB->TagNumber = tag[1];
 558        DC390_write8(ScsiFifo, tag[1]);
 559        DEBUG1(printk(KERN_INFO "DC390: Select w/DisCn for Cmd %li (SRB %p), block tag %02x\n", scmd->pid, pSRB, tag[1]));
 560        cmd = SEL_W_ATN3;
 561    } else {
 562        /* No TagQ */
 563//no_tag:
 564        DEBUG1(printk(KERN_INFO "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", disc_allowed ? "" : "o", scmd->pid, pSRB));
 565    }
 566
 567    pSRB->SRBState = SRB_START_;
 568
 569    if (try_sync_nego)
 570      { 
 571        u8 Sync_Off = pDCB->SyncOffset;
 572        DEBUG0(printk (KERN_INFO "DC390: NEW Sync Nego code triggered (%i %i)\n", pDCB->TargetID, pDCB->TargetLUN));
 573        pSRB->MsgOutBuf[0] = EXTENDED_MESSAGE;
 574        pSRB->MsgOutBuf[1] = 3;
 575        pSRB->MsgOutBuf[2] = EXTENDED_SDTR;
 576        pSRB->MsgOutBuf[3] = pDCB->NegoPeriod;
 577        if (!(Sync_Off & 0x0f)) Sync_Off = SYNC_NEGO_OFFSET;
 578        pSRB->MsgOutBuf[4] = Sync_Off;
 579        pSRB->MsgCnt = 5;
 580        //pSRB->SRBState = SRB_MSGOUT_;
 581        pSRB->SRBState |= DO_SYNC_NEGO;
 582        cmd = SEL_W_ATN_STOP;
 583      }
 584
 585    /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
 586    if (cmd != SEL_W_ATN_STOP)
 587      {
 588        if( pSRB->SRBFlag & AUTO_REQSENSE )
 589          {
 590            DC390_write8 (ScsiFifo, REQUEST_SENSE);
 591            DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
 592            DC390_write8 (ScsiFifo, 0);
 593            DC390_write8 (ScsiFifo, 0);
 594            DC390_write8 (ScsiFifo, sizeof(scmd->sense_buffer));
 595            DC390_write8 (ScsiFifo, 0);
 596            DEBUG1(printk (KERN_DEBUG "DC390: AutoReqSense !\n"));
 597          }
 598        else    /* write cmnd to bus */ 
 599          {
 600            u8 *ptr; u8 i;
 601            ptr = (u8 *)scmd->cmnd;
 602            for (i = 0; i < scmd->cmd_len; i++)
 603              DC390_write8 (ScsiFifo, *(ptr++));
 604          }
 605      }
 606    DEBUG0(if (pACB->pActiveDCB)        \
 607           printk (KERN_WARNING "DC390: ActiveDCB != 0\n"));
 608    DEBUG0(if (pDCB->pActiveSRB)        \
 609           printk (KERN_WARNING "DC390: ActiveSRB != 0\n"));
 610    //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
 611    if (DC390_read8 (Scsi_Status) & INTERRUPT)
 612    {
 613        dc390_freetag (pDCB, pSRB);
 614        DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)\n",
 615                scmd->pid, scmd->device->id, scmd->device->lun));
 616        pSRB->SRBState = SRB_READY;
 617        //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
 618        pACB->SelLost++;
 619        return 1;
 620    }
 621    DC390_write8 (ScsiCmd, cmd);
 622    pACB->pActiveDCB = pDCB;
 623    pDCB->pActiveSRB = pSRB;
 624    pACB->Connected = 1;
 625    pSRB->ScsiPhase = SCSI_NOP1;
 626    return 0;
 627}
 628
 629//#define DMA_INT EN_DMA_INT /*| EN_PAGE_INT*/
 630#define DMA_INT 0
 631
 632#if DMA_INT
 633/* This is similar to AM53C974.c ... */
 634static u8 
 635dc390_dma_intr (struct dc390_acb* pACB)
 636{
 637  struct dc390_srb* pSRB;
 638  u8 dstate;
 639  DEBUG0(u16 pstate; struct pci_dev *pdev = pACB->pdev);
 640  
 641  DEBUG0(pci_read_config_word(pdev, PCI_STATUS, &pstate));
 642  DEBUG0(if (pstate & (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY))\
 643        { printk(KERN_WARNING "DC390: PCI state = %04x!\n", pstate); \
 644          pci_write_config_word(pdev, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));});
 645
 646  dstate = DC390_read8 (DMA_Status); 
 647
 648  if (! pACB->pActiveDCB || ! pACB->pActiveDCB->pActiveSRB) return dstate;
 649  else pSRB  = pACB->pActiveDCB->pActiveSRB;
 650  
 651  if (dstate & (DMA_XFER_ABORT | DMA_XFER_ERROR | POWER_DOWN | PCI_MS_ABORT))
 652    {
 653        printk (KERN_ERR "DC390: DMA error (%02x)!\n", dstate);
 654        return dstate;
 655    }
 656  if (dstate & DMA_XFER_DONE)
 657    {
 658        u32 residual, xferCnt; int ctr = 6000000;
 659        if (! (DC390_read8 (DMA_Cmd) & READ_DIRECTION))
 660          {
 661            do
 662              {
 663                DEBUG1(printk (KERN_DEBUG "DC390: read residual bytes ... \n"));
 664                dstate = DC390_read8 (DMA_Status);
 665                residual = DC390_read8 (CtcReg_Low) | DC390_read8 (CtcReg_Mid) << 8 |
 666                  DC390_read8 (CtcReg_High) << 16;
 667                residual += DC390_read8 (Current_Fifo) & 0x1f;
 668              } while (residual && ! (dstate & SCSI_INTERRUPT) && --ctr);
 669            if (!ctr) printk (KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
 670            /* residual =  ... */
 671          }
 672        else
 673            residual = 0;
 674        
 675        /* ??? */
 676        
 677        xferCnt = pSRB->SGToBeXferLen - residual;
 678        pSRB->SGBusAddr += xferCnt;
 679        pSRB->TotalXferredLen += xferCnt;
 680        pSRB->SGToBeXferLen = residual;
 681# ifdef DC390_DEBUG0
 682        printk (KERN_INFO "DC390: DMA: residual = %i, xfer = %i\n", 
 683                (unsigned int)residual, (unsigned int)xferCnt);
 684# endif
 685        
 686        DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
 687    }
 688  dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
 689  return dstate;
 690}
 691#endif
 692
 693
 694static void __inline__
 695dc390_InvalidCmd(struct dc390_acb* pACB)
 696{
 697        if (pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_ | SRB_MSGOUT))
 698                DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
 699}
 700
 701
 702static irqreturn_t __inline__
 703DC390_Interrupt(void *dev_id)
 704{
 705    struct dc390_acb *pACB = dev_id;
 706    struct dc390_dcb *pDCB;
 707    struct dc390_srb *pSRB;
 708    u8  sstatus=0;
 709    u8  phase;
 710    void   (*stateV)( struct dc390_acb*, struct dc390_srb*, u8 *);
 711    u8  istate, istatus;
 712#if DMA_INT
 713    u8  dstatus;
 714#endif
 715
 716    sstatus = DC390_read8 (Scsi_Status);
 717    if( !(sstatus & INTERRUPT) )
 718        return IRQ_NONE;
 719
 720    DEBUG1(printk (KERN_DEBUG "sstatus=%02x,", sstatus));
 721
 722#if DMA_INT
 723    spin_lock_irq(pACB->pScsiHost->host_lock);
 724    dstatus = dc390_dma_intr (pACB);
 725    spin_unlock_irq(pACB->pScsiHost->host_lock);
 726
 727    DEBUG1(printk (KERN_DEBUG "dstatus=%02x,", dstatus));
 728    if (! (dstatus & SCSI_INTERRUPT))
 729      {
 730        DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n"));
 731        return IRQ_NONE;
 732      }
 733#else
 734    //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
 735    //dstatus = DC390_read8 (DMA_Status);
 736    //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
 737#endif
 738
 739    spin_lock_irq(pACB->pScsiHost->host_lock);
 740
 741    istate = DC390_read8 (Intern_State);
 742    istatus = DC390_read8 (INT_Status); /* This clears Scsi_Status, Intern_State and INT_Status ! */
 743
 744    DEBUG1(printk (KERN_INFO "Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus));
 745    dc390_laststatus &= ~0x00ffffff;
 746    dc390_laststatus |= /* dstatus<<24 | */ sstatus<<16 | istate<<8 | istatus;
 747
 748    if (sstatus & ILLEGAL_OP_ERR)
 749    {
 750        printk ("DC390: Illegal Operation detected (%08x)!\n", dc390_laststatus);
 751        dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
 752    }
 753        
 754    else if (istatus &  INVALID_CMD)
 755    {
 756        printk ("DC390: Invalid Command detected (%08x)!\n", dc390_laststatus);
 757        dc390_InvalidCmd( pACB );
 758        goto unlock;
 759    }
 760
 761    if (istatus &  SCSI_RESET)
 762    {
 763        dc390_ScsiRstDetect( pACB );
 764        goto unlock;
 765    }
 766
 767    if (istatus &  DISCONNECTED)
 768    {
 769        dc390_Disconnect( pACB );
 770        goto unlock;
 771    }
 772
 773    if (istatus &  RESELECTED)
 774    {
 775        dc390_Reselect( pACB );
 776        goto unlock;
 777    }
 778
 779    else if (istatus & (SELECTED | SEL_ATTENTION))
 780    {
 781        printk (KERN_ERR "DC390: Target mode not supported!\n");
 782        goto unlock;
 783    }
 784
 785    if (istatus & (SUCCESSFUL_OP|SERVICE_REQUEST) )
 786    {
 787        pDCB = pACB->pActiveDCB;
 788        if (!pDCB)
 789        {
 790                printk (KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
 791                goto unlock;
 792        }
 793        pSRB = pDCB->pActiveSRB;
 794        if( pDCB->DCBFlag & ABORT_DEV_ )
 795          dc390_EnableMsgOut_Abort (pACB, pSRB);
 796
 797        phase = pSRB->ScsiPhase;
 798        DEBUG1(printk (KERN_INFO "DC390: [%i]%s(0) (%02x)\n", phase, dc390_p0_str[phase], sstatus));
 799        stateV = (void *) dc390_phase0[phase];
 800        ( *stateV )( pACB, pSRB, &sstatus );
 801
 802        pSRB->ScsiPhase = sstatus & 7;
 803        phase = (u8) sstatus & 7;
 804        DEBUG1(printk (KERN_INFO "DC390: [%i]%s(1) (%02x)\n", phase, dc390_p1_str[phase], sstatus));
 805        stateV = (void *) dc390_phase1[phase];
 806        ( *stateV )( pACB, pSRB, &sstatus );
 807    }
 808
 809 unlock:
 810    spin_unlock_irq(pACB->pScsiHost->host_lock);
 811    return IRQ_HANDLED;
 812}
 813
 814static irqreturn_t do_DC390_Interrupt(int irq, void *dev_id)
 815{
 816    irqreturn_t ret;
 817    DEBUG1(printk (KERN_INFO "DC390: Irq (%i) caught: ", irq));
 818    /* Locking is done in DC390_Interrupt */
 819    ret = DC390_Interrupt(dev_id);
 820    DEBUG1(printk (".. IRQ returned\n"));
 821    return ret;
 822}
 823
 824static void
 825dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
 826{
 827    u8   sstatus;
 828    struct scatterlist *psgl;
 829    u32    ResidCnt, xferCnt;
 830    u8   dstate = 0;
 831
 832    sstatus = *psstatus;
 833
 834    if( !(pSRB->SRBState & SRB_XFERPAD) )
 835    {
 836        if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR) )
 837            pSRB->SRBStatus |= PARITY_ERROR;
 838
 839        if( sstatus & COUNT_2_ZERO )
 840        {
 841            unsigned long timeout = jiffies + HZ;
 842
 843            /* Function called from the ISR with the host_lock held and interrupts disabled */
 844            if (pSRB->SGToBeXferLen)
 845                while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE)) {
 846                    spin_unlock_irq(pACB->pScsiHost->host_lock);
 847                    udelay(50);
 848                    spin_lock_irq(pACB->pScsiHost->host_lock);
 849                }
 850            if (!time_before(jiffies, timeout))
 851                printk (KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n",
 852                        DC390_read32 (DMA_Wk_ByteCntr));
 853            dc390_laststatus &= ~0xff000000;
 854            dc390_laststatus |= dstate << 24;
 855            pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
 856            pSRB->SGIndex++;
 857            if( pSRB->SGIndex < pSRB->SGcount )
 858            {
 859                pSRB->pSegmentList++;
 860                psgl = pSRB->pSegmentList;
 861
 862                pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
 863                pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
 864            }
 865            else
 866                pSRB->SGToBeXferLen = 0;
 867        }
 868        else
 869        {
 870            ResidCnt  = (u32) DC390_read8 (Current_Fifo) & 0x1f;
 871            ResidCnt |= (u32) DC390_read8 (CtcReg_High) << 16;
 872            ResidCnt |= (u32) DC390_read8 (CtcReg_Mid) << 8; 
 873            ResidCnt += (u32) DC390_read8 (CtcReg_Low);
 874
 875            xferCnt = pSRB->SGToBeXferLen - ResidCnt;
 876            pSRB->SGBusAddr += xferCnt;
 877            pSRB->TotalXferredLen += xferCnt;
 878            pSRB->SGToBeXferLen = ResidCnt;
 879        }
 880    }
 881    if ((*psstatus & 7) != SCSI_DATA_OUT)
 882    {
 883            DC390_write8 (DMA_Cmd, WRITE_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
 884            DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
 885    }       
 886}
 887
 888static void
 889dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
 890{
 891    u8   sstatus, residual, bval;
 892    struct scatterlist *psgl;
 893    u32    ResidCnt, i;
 894    unsigned long   xferCnt;
 895    u8      *ptr;
 896
 897    sstatus = *psstatus;
 898
 899    if( !(pSRB->SRBState & SRB_XFERPAD) )
 900    {
 901        if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR))
 902            pSRB->SRBStatus |= PARITY_ERROR;
 903
 904        if( sstatus & COUNT_2_ZERO )
 905        {
 906            int dstate = 0;
 907            unsigned long timeout = jiffies + HZ;
 908
 909            /* Function called from the ISR with the host_lock held and interrupts disabled */
 910            if (pSRB->SGToBeXferLen)
 911                while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE)) {
 912                    spin_unlock_irq(pACB->pScsiHost->host_lock);
 913                    udelay(50);
 914                    spin_lock_irq(pACB->pScsiHost->host_lock);
 915                }
 916            if (!time_before(jiffies, timeout)) {
 917                printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n",
 918                        DC390_read32 (DMA_Wk_ByteCntr));
 919                printk (KERN_CRIT "DC390: DataIn_0: DMA State: %i\n", dstate);
 920            }
 921            dc390_laststatus &= ~0xff000000;
 922            dc390_laststatus |= dstate << 24;
 923            DEBUG1(ResidCnt = ((unsigned long) DC390_read8 (CtcReg_High) << 16) \
 924                + ((unsigned long) DC390_read8 (CtcReg_Mid) << 8)               \
 925                + ((unsigned long) DC390_read8 (CtcReg_Low)));
 926            DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%i,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen));
 927
 928            DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
 929
 930            pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
 931            pSRB->SGIndex++;
 932            if( pSRB->SGIndex < pSRB->SGcount )
 933            {
 934                pSRB->pSegmentList++;
 935                psgl = pSRB->pSegmentList;
 936
 937                pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
 938                pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
 939            }
 940            else
 941                pSRB->SGToBeXferLen = 0;
 942        }
 943        else    /* phase changed */
 944        {
 945            residual = 0;
 946            bval = DC390_read8 (Current_Fifo);
 947            while( bval & 0x1f )
 948            {
 949                DEBUG1(printk (KERN_DEBUG "Check for residuals,"));
 950                if( (bval & 0x1f) == 1 )
 951                {
 952                    for(i=0; i < 0x100; i++)
 953                    {
 954                        bval = DC390_read8 (Current_Fifo);
 955                        if( !(bval & 0x1f) )
 956                            goto din_1;
 957                        else if( i == 0x0ff )
 958                        {
 959                            residual = 1;   /* ;1 residual byte */
 960                            goto din_1;
 961                        }
 962                    }
 963                }
 964                else
 965                    bval = DC390_read8 (Current_Fifo);
 966            }
 967din_1:
 968            DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_BLAST_CMD);
 969            for (i = 0xa000; i; i--)
 970            {
 971                bval = DC390_read8 (DMA_Status);
 972                if (bval & BLAST_COMPLETE)
 973                    break;
 974            }
 975            /* It seems a DMA Blast abort isn't that bad ... */
 976            if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n");
 977            //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
 978            dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24;
 979
 980            DEBUG1(printk (KERN_DEBUG "Blast: Read %i times DMA_Status %02x", 0xa000-i, bval));
 981            ResidCnt = (u32) DC390_read8 (CtcReg_High);
 982            ResidCnt <<= 8;
 983            ResidCnt |= (u32) DC390_read8 (CtcReg_Mid);
 984            ResidCnt <<= 8;
 985            ResidCnt |= (u32) DC390_read8 (CtcReg_Low);
 986
 987            xferCnt = pSRB->SGToBeXferLen - ResidCnt;
 988            pSRB->SGBusAddr += xferCnt;
 989            pSRB->TotalXferredLen += xferCnt;
 990            pSRB->SGToBeXferLen = ResidCnt;
 991
 992            if( residual )
 993            {
 994                static int feedback_requested;
 995                bval = DC390_read8 (ScsiFifo);      /* get one residual byte */
 996
 997                if (!feedback_requested) {
 998                        feedback_requested = 1;
 999                        printk(KERN_WARNING "%s: Please, contact <linux-scsi@vger.kernel.org> "
1000                               "to help improve support for your system.\n", __FILE__);
1001                }
1002
1003                ptr = (u8 *) bus_to_virt( pSRB->SGBusAddr );
1004                *ptr = bval;
1005                pSRB->SGBusAddr++; xferCnt++;
1006                pSRB->TotalXferredLen++;
1007                pSRB->SGToBeXferLen--;
1008            }
1009            DEBUG1(printk (KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %li\n", xferCnt,\
1010                           pSRB->TotalXferredLen, pSRB->SGToBeXferLen));
1011
1012        }
1013    }
1014    if ((*psstatus & 7) != SCSI_DATA_IN)
1015    {
1016            DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1017            DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
1018    }
1019}
1020
1021static void
1022dc390_Command_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1023{
1024}
1025
1026static void
1027dc390_Status_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1028{
1029
1030    pSRB->TargetStatus = DC390_read8 (ScsiFifo);
1031    //udelay (1);
1032    pSRB->EndMessage = DC390_read8 (ScsiFifo);  /* get message */
1033
1034    *psstatus = SCSI_NOP0;
1035    pSRB->SRBState = SRB_COMPLETED;
1036    DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
1037}
1038
1039static void
1040dc390_MsgOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1041{
1042    if( pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT) )
1043        *psstatus = SCSI_NOP0;
1044    //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1045}
1046
1047
1048static void __inline__
1049dc390_reprog (struct dc390_acb* pACB, struct dc390_dcb* pDCB)
1050{
1051  DC390_write8 (Sync_Period, pDCB->SyncPeriod);
1052  DC390_write8 (Sync_Offset, pDCB->SyncOffset);
1053  DC390_write8 (CtrlReg3, pDCB->CtrlR3);
1054  DC390_write8 (CtrlReg4, pDCB->CtrlR4);
1055  dc390_SetXferRate (pACB, pDCB);
1056}
1057
1058
1059#ifdef DC390_DEBUG0
1060static void
1061dc390_printMsg (u8 *MsgBuf, u8 len)
1062{
1063  int i;
1064  printk (" %02x", MsgBuf[0]);
1065  for (i = 1; i < len; i++)
1066    printk (" %02x", MsgBuf[i]);
1067  printk ("\n");
1068}
1069#endif
1070
1071#define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
1072
1073/* reject_msg */
1074static void __inline__
1075dc390_MsgIn_reject (struct dc390_acb* pACB, struct dc390_srb* pSRB)
1076{
1077  pSRB->MsgOutBuf[0] = MESSAGE_REJECT;
1078  pSRB->MsgCnt = 1;
1079  DC390_ENABLE_MSGOUT;
1080  DEBUG0 (printk (KERN_INFO "DC390: Reject message\n"));
1081}
1082
1083/* abort command */
1084static void
1085dc390_EnableMsgOut_Abort ( struct dc390_acb* pACB, struct dc390_srb* pSRB )
1086{
1087    pSRB->MsgOutBuf[0] = ABORT; 
1088    pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
1089    pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
1090}
1091
1092static struct dc390_srb*
1093dc390_MsgIn_QTag (struct dc390_acb* pACB, struct dc390_dcb* pDCB, s8 tag)
1094{
1095  struct dc390_srb* pSRB = pDCB->pGoingSRB;
1096
1097  if (pSRB)
1098    {
1099        struct scsi_cmnd *scmd = scsi_find_tag(pSRB->pcmd->device, tag);
1100        pSRB = (struct dc390_srb *)scmd->host_scribble;
1101
1102        if (pDCB->DCBFlag & ABORT_DEV_)
1103        {
1104          pSRB->SRBState = SRB_ABORT_SENT;
1105          dc390_EnableMsgOut_Abort( pACB, pSRB );
1106        }
1107
1108        if (!(pSRB->SRBState & SRB_DISCONNECT))
1109                goto mingx0;
1110
1111        pDCB->pActiveSRB = pSRB;
1112        pSRB->SRBState = SRB_DATA_XFER;
1113    }
1114  else
1115    {
1116    mingx0:
1117      pSRB = pACB->pTmpSRB;
1118      pSRB->SRBState = SRB_UNEXPECT_RESEL;
1119      pDCB->pActiveSRB = pSRB;
1120      pSRB->MsgOutBuf[0] = ABORT_TAG;
1121      pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
1122    }
1123  return pSRB;
1124}
1125
1126
1127/* set async transfer mode */
1128static void 
1129dc390_MsgIn_set_async (struct dc390_acb* pACB, struct dc390_srb* pSRB)
1130{
1131  struct dc390_dcb* pDCB = pSRB->pSRBDCB;
1132  if (!(pSRB->SRBState & DO_SYNC_NEGO)) 
1133    printk (KERN_INFO "DC390: Target %i initiates Non-Sync?\n", pDCB->TargetID);
1134  pSRB->SRBState &= ~DO_SYNC_NEGO;
1135  pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);
1136  pDCB->SyncPeriod = 0;
1137  pDCB->SyncOffset = 0;
1138  //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
1139  pDCB->CtrlR3 = FAST_CLK;      /* fast clock / normal scsi */
1140  pDCB->CtrlR4 &= 0x3f;
1141  pDCB->CtrlR4 |= pACB->glitch_cfg;     /* glitch eater */
1142  dc390_reprog (pACB, pDCB);
1143}
1144
1145/* set sync transfer mode */
1146static void
1147dc390_MsgIn_set_sync (struct dc390_acb* pACB, struct dc390_srb* pSRB)
1148{
1149  u8 bval;
1150  u16 wval, wval1;
1151  struct dc390_dcb* pDCB = pSRB->pSRBDCB;
1152  u8 oldsyncperiod = pDCB->SyncPeriod;
1153  u8 oldsyncoffset = pDCB->SyncOffset;
1154  
1155  if (!(pSRB->SRBState & DO_SYNC_NEGO))
1156    {
1157      printk (KERN_INFO "DC390: Target %i initiates Sync: %ins %i ... answer ...\n", 
1158              pDCB->TargetID, pSRB->MsgInBuf[3]<<2, pSRB->MsgInBuf[4]);
1159
1160      /* reject */
1161      //dc390_MsgIn_reject (pACB, pSRB);
1162      //return dc390_MsgIn_set_async (pACB, pSRB);
1163
1164      /* Reply with corrected SDTR Message */
1165      if (pSRB->MsgInBuf[4] > 15)
1166        { 
1167          printk (KERN_INFO "DC390: Lower Sync Offset to 15\n");
1168          pSRB->MsgInBuf[4] = 15;
1169        }
1170      if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod)
1171        {
1172          printk (KERN_INFO "DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
1173          pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
1174        }
1175      memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
1176      pSRB->MsgCnt = 5;
1177      DC390_ENABLE_MSGOUT;
1178    }
1179
1180  pSRB->SRBState &= ~DO_SYNC_NEGO;
1181  pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
1182  pDCB->SyncOffset &= 0x0f0;
1183  pDCB->SyncOffset |= pSRB->MsgInBuf[4];
1184  pDCB->NegoPeriod = pSRB->MsgInBuf[3];
1185
1186  wval = (u16) pSRB->MsgInBuf[3];
1187  wval = wval << 2; wval -= 3; wval1 = wval / 25;       /* compute speed */
1188  if( (wval1 * 25) != wval) wval1++;
1189  bval = FAST_CLK+FAST_SCSI;    /* fast clock / fast scsi */
1190
1191  pDCB->CtrlR4 &= 0x3f;         /* Glitch eater: 12ns less than normal */
1192  if (pACB->glitch_cfg != NS_TO_GLITCH(0))
1193    pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1));
1194  else
1195    pDCB->CtrlR4 |= NS_TO_GLITCH(0);
1196  if (wval1 < 4) pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */
1197
1198  if (wval1 >= 8)
1199    {
1200      wval1--;  /* Timing computation differs by 1 from FAST_SCSI */
1201      bval = FAST_CLK;          /* fast clock / normal scsi */
1202      pDCB->CtrlR4 |= pACB->glitch_cfg;         /* glitch eater */
1203    }
1204
1205  pDCB->CtrlR3 = bval;
1206  pDCB->SyncPeriod = (u8)wval1;
1207  
1208  if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->TargetLUN == 0)
1209    {
1210      if (! (bval & FAST_SCSI)) wval1++;
1211      printk (KERN_INFO "DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->TargetID, 
1212              40/wval1, ((40%wval1)*10+wval1/2)/wval1, pDCB->SyncOffset & 0x0f);
1213    }
1214  
1215  dc390_reprog (pACB, pDCB);
1216}
1217
1218
1219/* handle RESTORE_PTR */
1220/* I presume, this command is already mapped, so, have to remap. */
1221static void 
1222dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB)
1223{
1224    struct scsi_cmnd *pcmd = pSRB->pcmd;
1225    struct scatterlist *psgl;
1226    pSRB->TotalXferredLen = 0;
1227    pSRB->SGIndex = 0;
1228    if (pcmd->use_sg) {
1229        pSRB->pSegmentList = (struct scatterlist *)pcmd->request_buffer;
1230        psgl = pSRB->pSegmentList;
1231        //dc390_pci_sync(pSRB);
1232
1233        while (pSRB->TotalXferredLen + (unsigned long) sg_dma_len(psgl) < pSRB->Saved_Ptr)
1234        {
1235            pSRB->TotalXferredLen += (unsigned long) sg_dma_len(psgl);
1236            pSRB->SGIndex++;
1237            if( pSRB->SGIndex < pSRB->SGcount )
1238            {
1239                pSRB->pSegmentList++;
1240                psgl = pSRB->pSegmentList;
1241                pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
1242                pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
1243            }
1244            else
1245                pSRB->SGToBeXferLen = 0;
1246        }
1247        pSRB->SGToBeXferLen -= (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
1248        pSRB->SGBusAddr += (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
1249        printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n",
1250                pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr);
1251
1252    } else if(pcmd->request_buffer) {
1253        //dc390_pci_sync(pSRB);
1254
1255        sg_dma_len(&pSRB->Segmentx) = pcmd->request_bufflen - pSRB->Saved_Ptr;
1256        pSRB->SGcount = 1;
1257        pSRB->pSegmentList = (struct scatterlist *) &pSRB->Segmentx;
1258    } else {
1259         pSRB->SGcount = 0;
1260         printk (KERN_INFO "DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n");
1261    }
1262
1263  pSRB->TotalXferredLen = pSRB->Saved_Ptr;
1264}
1265
1266
1267/* According to the docs, the AM53C974 reads the message and 
1268 * generates a Successful Operation IRQ before asserting ACK for
1269 * the last byte (how does it know whether it's the last ?) */
1270/* The old code handled it in another way, indicating, that on
1271 * every message byte an IRQ is generated and every byte has to
1272 * be manually ACKed. Hmmm ?  (KG, 98/11/28) */
1273/* The old implementation was correct. Sigh! */
1274
1275/* Check if the message is complete */
1276static u8 __inline__
1277dc390_MsgIn_complete (u8 *msgbuf, u32 len)
1278{ 
1279  if (*msgbuf == EXTENDED_MESSAGE)
1280  {
1281        if (len < 2) return 0;
1282        if (len < msgbuf[1] + 2) return 0;
1283  }
1284  else if (*msgbuf >= 0x20 && *msgbuf <= 0x2f) // two byte messages
1285        if (len < 2) return 0;
1286  return 1;
1287}
1288
1289
1290
1291/* read and eval received messages */
1292static void
1293dc390_MsgIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1294{
1295    struct dc390_dcb*   pDCB = pACB->pActiveDCB;
1296
1297    /* Read the msg */
1298
1299    pSRB->MsgInBuf[pACB->MsgLen++] = DC390_read8 (ScsiFifo);
1300    //pSRB->SRBState = 0;
1301
1302    /* Msg complete ? */
1303    if (dc390_MsgIn_complete (pSRB->MsgInBuf, pACB->MsgLen))
1304      {
1305        DEBUG0 (printk (KERN_INFO "DC390: MsgIn:"); dc390_printMsg (pSRB->MsgInBuf, pACB->MsgLen));
1306        /* Now eval the msg */
1307        switch (pSRB->MsgInBuf[0]) 
1308          {
1309          case DISCONNECT: 
1310            pSRB->SRBState = SRB_DISCONNECT; break;
1311            
1312          case SIMPLE_QUEUE_TAG:
1313          case HEAD_OF_QUEUE_TAG:
1314          case ORDERED_QUEUE_TAG:
1315            pSRB = dc390_MsgIn_QTag (pACB, pDCB, pSRB->MsgInBuf[1]);
1316            break;
1317            
1318          case MESSAGE_REJECT: 
1319            DC390_write8 (ScsiCmd, RESET_ATN_CMD);
1320            pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
1321            if( pSRB->SRBState & DO_SYNC_NEGO)
1322              dc390_MsgIn_set_async (pACB, pSRB);
1323            break;
1324            
1325          case EXTENDED_MESSAGE:
1326            /* reject every extended msg but SDTR */
1327            if (pSRB->MsgInBuf[1] != 3 || pSRB->MsgInBuf[2] != EXTENDED_SDTR)
1328              dc390_MsgIn_reject (pACB, pSRB);
1329            else
1330              {
1331                if (pSRB->MsgInBuf[3] == 0 || pSRB->MsgInBuf[4] == 0)
1332                  dc390_MsgIn_set_async (pACB, pSRB);
1333                else
1334                  dc390_MsgIn_set_sync (pACB, pSRB);
1335              }
1336            
1337            // nothing has to be done
1338          case COMMAND_COMPLETE: break;
1339            
1340            // SAVE POINTER may be ignored as we have the struct dc390_srb* associated with the
1341            // scsi command. Thanks, Gerard, for pointing it out.
1342          case SAVE_POINTERS: 
1343            pSRB->Saved_Ptr = pSRB->TotalXferredLen;
1344            break;
1345            // The device might want to restart transfer with a RESTORE
1346          case RESTORE_POINTERS:
1347            DEBUG0(printk ("DC390: RESTORE POINTER message received ... try to handle\n"));
1348            dc390_restore_ptr (pACB, pSRB);
1349            break;
1350
1351            // reject unknown messages
1352          default: dc390_MsgIn_reject (pACB, pSRB);
1353          }
1354        
1355        /* Clear counter and MsgIn state */
1356        pSRB->SRBState &= ~SRB_MSGIN;
1357        pACB->MsgLen = 0;
1358      }
1359
1360    *psstatus = SCSI_NOP0;
1361    DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
1362    //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1363}
1364
1365
1366static void
1367dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir)
1368{
1369    struct scatterlist *psgl;
1370    unsigned long  lval;
1371    struct dc390_dcb*   pDCB = pACB->pActiveDCB;
1372
1373    if (pSRB == pACB->pTmpSRB)
1374    {
1375        if (pDCB)
1376                printk(KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (%02i-%i)\n", pDCB->TargetID, pDCB->TargetLUN);
1377        else
1378                printk(KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (DCB 0!)\n");
1379
1380        /* Try to recover - some broken disks react badly to tagged INQUIRY */
1381        if (pDCB && pACB->scan_devices && pDCB->GoingSRBCnt == 1) {
1382                pSRB = pDCB->pGoingSRB;
1383                pDCB->pActiveSRB = pSRB;
1384        } else {
1385                pSRB->pSRBDCB = pDCB;
1386                dc390_EnableMsgOut_Abort(pACB, pSRB);
1387                if (pDCB)
1388                        pDCB->DCBFlag |= ABORT_DEV;
1389                return;
1390        }
1391    }
1392
1393    if( pSRB->SGIndex < pSRB->SGcount )
1394    {
1395        DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir /* | DMA_INT */);
1396        if( !pSRB->SGToBeXferLen )
1397        {
1398            psgl = pSRB->pSegmentList;
1399            pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
1400            pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
1401            DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment."));
1402        }
1403        lval = pSRB->SGToBeXferLen;
1404        DEBUG1(printk (KERN_DEBUG " DC390: Start transfer: %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr));
1405        DC390_write8 (CtcReg_Low, (u8) lval);
1406        lval >>= 8;
1407        DC390_write8 (CtcReg_Mid, (u8) lval);
1408        lval >>= 8;
1409        DC390_write8 (CtcReg_High, (u8) lval);
1410
1411        DC390_write32 (DMA_XferCnt, pSRB->SGToBeXferLen);
1412        DC390_write32 (DMA_XferAddr, pSRB->SGBusAddr);
1413
1414        //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); /* | DMA_INT; */
1415        pSRB->SRBState = SRB_DATA_XFER;
1416
1417        DC390_write8 (ScsiCmd, DMA_COMMAND+INFO_XFER_CMD);
1418
1419        DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
1420        //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT));
1421        //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status)));
1422        //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT));
1423    }
1424    else    /* xfer pad */
1425    {
1426        if( pSRB->SGcount )
1427        {
1428            pSRB->AdaptStatus = H_OVER_UNDER_RUN;
1429            pSRB->SRBStatus |= OVER_RUN;
1430            DEBUG0(printk (KERN_WARNING " DC390: Overrun -"));
1431        }
1432        DEBUG0(printk (KERN_WARNING " Clear transfer pad \n"));
1433        DC390_write8 (CtcReg_Low, 0);
1434        DC390_write8 (CtcReg_Mid, 0);
1435        DC390_write8 (CtcReg_High, 0);
1436
1437        pSRB->SRBState |= SRB_XFERPAD;
1438        DC390_write8 (ScsiCmd, DMA_COMMAND+XFER_PAD_BYTE);
1439/*
1440        DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT;
1441        DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
1442*/
1443    }
1444}
1445
1446
1447static void
1448dc390_DataOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1449{
1450    dc390_DataIO_Comm (pACB, pSRB, WRITE_DIRECTION);
1451}
1452
1453static void
1454dc390_DataInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1455{
1456    dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
1457}
1458
1459static void
1460dc390_CommandPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1461{
1462    struct dc390_dcb*   pDCB;
1463    u8  i, cnt;
1464    u8     *ptr;
1465
1466    DC390_write8 (ScsiCmd, RESET_ATN_CMD);
1467    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1468    if( !(pSRB->SRBFlag & AUTO_REQSENSE) )
1469    {
1470        cnt = (u8) pSRB->pcmd->cmd_len;
1471        ptr = (u8 *) pSRB->pcmd->cmnd;
1472        for(i=0; i < cnt; i++)
1473            DC390_write8 (ScsiFifo, *(ptr++));
1474    }
1475    else
1476    {
1477        DC390_write8 (ScsiFifo, REQUEST_SENSE);
1478        pDCB = pACB->pActiveDCB;
1479        DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
1480        DC390_write8 (ScsiFifo, 0);
1481        DC390_write8 (ScsiFifo, 0);
1482        DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
1483        DC390_write8 (ScsiFifo, 0);
1484        DEBUG0(printk(KERN_DEBUG "DC390: AutoReqSense (CmndPhase)!\n"));
1485    }
1486    pSRB->SRBState = SRB_COMMAND;
1487    DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1488}
1489
1490static void
1491dc390_StatusPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1492{
1493    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1494    pSRB->SRBState = SRB_STATUS;
1495    DC390_write8 (ScsiCmd, INITIATOR_CMD_CMPLTE);
1496    //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1497}
1498
1499static void
1500dc390_MsgOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1501{
1502    u8   bval, i, cnt;
1503    u8     *ptr;
1504    struct dc390_dcb*    pDCB;
1505
1506    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1507    pDCB = pACB->pActiveDCB;
1508    if( !(pSRB->SRBState & SRB_MSGOUT) )
1509    {
1510        cnt = pSRB->MsgCnt;
1511        if( cnt )
1512        {
1513            ptr = (u8 *) pSRB->MsgOutBuf;
1514            for(i=0; i < cnt; i++)
1515                DC390_write8 (ScsiFifo, *(ptr++));
1516            pSRB->MsgCnt = 0;
1517            if( (pDCB->DCBFlag & ABORT_DEV_) &&
1518                (pSRB->MsgOutBuf[0] == ABORT) )
1519                pSRB->SRBState = SRB_ABORT_SENT;
1520        }
1521        else
1522        {
1523            bval = ABORT;       /* ??? MSG_NOP */
1524            if( (pSRB->pcmd->cmnd[0] == INQUIRY ) ||
1525                (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) ||
1526                (pSRB->SRBFlag & AUTO_REQSENSE) )
1527            {
1528                if( pDCB->SyncMode & SYNC_ENABLE )
1529                    goto  mop1;
1530            }
1531            DC390_write8 (ScsiFifo, bval);
1532        }
1533        DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1534    }
1535    else
1536    {
1537mop1:
1538        printk (KERN_ERR "DC390: OLD Sync Nego code triggered! (%i %i)\n", pDCB->TargetID, pDCB->TargetLUN);
1539        DC390_write8 (ScsiFifo, EXTENDED_MESSAGE);
1540        DC390_write8 (ScsiFifo, 3);     /*    ;length of extended msg */
1541        DC390_write8 (ScsiFifo, EXTENDED_SDTR); /*    ; sync nego */
1542        DC390_write8 (ScsiFifo, pDCB->NegoPeriod);
1543        if (pDCB->SyncOffset & 0x0f)
1544                    DC390_write8 (ScsiFifo, pDCB->SyncOffset);
1545        else
1546                    DC390_write8 (ScsiFifo, SYNC_NEGO_OFFSET);              
1547        pSRB->SRBState |= DO_SYNC_NEGO;
1548        DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1549    }
1550}
1551
1552static void
1553dc390_MsgInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1554{
1555    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1556    if( !(pSRB->SRBState & SRB_MSGIN) )
1557    {
1558        pSRB->SRBState &= ~SRB_DISCONNECT;
1559        pSRB->SRBState |= SRB_MSGIN;
1560    }
1561    DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1562    //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1563}
1564
1565static void
1566dc390_Nop_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1567{
1568}
1569
1570static void
1571dc390_Nop_1( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1572{
1573}
1574
1575
1576static void
1577dc390_SetXferRate( struct dc390_acb* pACB, struct dc390_dcb* pDCB )
1578{
1579    u8  bval, i, cnt;
1580    struct dc390_dcb*   ptr;
1581
1582    if( !(pDCB->TargetLUN) )
1583    {
1584        if( !pACB->scan_devices )
1585        {
1586            ptr = pACB->pLinkDCB;
1587            cnt = pACB->DCBCnt;
1588            bval = pDCB->TargetID;
1589            for(i=0; i<cnt; i++)
1590            {
1591                if( ptr->TargetID == bval )
1592                {
1593                    ptr->SyncPeriod = pDCB->SyncPeriod;
1594                    ptr->SyncOffset = pDCB->SyncOffset;
1595                    ptr->CtrlR3 = pDCB->CtrlR3;
1596                    ptr->CtrlR4 = pDCB->CtrlR4;
1597                    ptr->SyncMode = pDCB->SyncMode;
1598                }
1599                ptr = ptr->pNextDCB;
1600            }
1601        }
1602    }
1603    return;
1604}
1605
1606
1607static void
1608dc390_Disconnect( struct dc390_acb* pACB )
1609{
1610    struct dc390_dcb *pDCB;
1611    struct dc390_srb *pSRB, *psrb;
1612    u8  i, cnt;
1613
1614    DEBUG0(printk(KERN_INFO "DISC,"));
1615
1616    if (!pACB->Connected) printk(KERN_ERR "DC390: Disconnect not-connected bus?\n");
1617    pACB->Connected = 0;
1618    pDCB = pACB->pActiveDCB;
1619    if (!pDCB)
1620     {
1621        DEBUG0(printk(KERN_ERR "ACB:%p->ActiveDCB:%p IOPort:%04x IRQ:%02x !\n",\
1622               pACB, pDCB, pACB->IOPortBase, pACB->IRQLevel));
1623        mdelay(400);
1624        DC390_read8 (INT_Status);       /* Reset Pending INT */
1625        DC390_write8 (ScsiCmd, EN_SEL_RESEL);
1626        return;
1627     }
1628    DC390_write8 (ScsiCmd, EN_SEL_RESEL);
1629    pSRB = pDCB->pActiveSRB;
1630    pACB->pActiveDCB = NULL;
1631    pSRB->ScsiPhase = SCSI_NOP0;
1632    if( pSRB->SRBState & SRB_UNEXPECT_RESEL )
1633        pSRB->SRBState = 0;
1634    else if( pSRB->SRBState & SRB_ABORT_SENT )
1635    {
1636        pDCB->TagMask = 0;
1637        pDCB->DCBFlag = 0;
1638        cnt = pDCB->GoingSRBCnt;
1639        pDCB->GoingSRBCnt = 0;
1640        pSRB = pDCB->pGoingSRB;
1641        for( i=0; i < cnt; i++)
1642        {
1643            psrb = pSRB->pNextSRB;
1644            dc390_Free_insert (pACB, pSRB);
1645            pSRB = psrb;
1646        }
1647        pDCB->pGoingSRB = NULL;
1648    }
1649    else
1650    {
1651        if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||
1652           !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) )
1653        {       /* Selection time out */
1654                pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
1655                goto  disc1;
1656        }
1657        else if (!(pSRB->SRBState & SRB_DISCONNECT) && (pSRB->SRBState & SRB_COMPLETED))
1658        {
1659disc1:
1660            dc390_freetag (pDCB, pSRB);
1661            pDCB->pActiveSRB = NULL;
1662            pSRB->SRBState = SRB_FREE;
1663            dc390_SRBdone( pACB, pDCB, pSRB);
1664        }
1665    }
1666    pACB->MsgLen = 0;
1667}
1668
1669
1670static void
1671dc390_Reselect( struct dc390_acb* pACB )
1672{
1673    struct dc390_dcb*   pDCB;
1674    struct dc390_srb*   pSRB;
1675    u8  id, lun;
1676
1677    DEBUG0(printk(KERN_INFO "RSEL,"));
1678    pACB->Connected = 1;
1679    pDCB = pACB->pActiveDCB;
1680    if( pDCB )
1681    {   /* Arbitration lost but Reselection won */
1682        DEBUG0(printk ("DC390: (ActiveDCB != 0: Arb. lost but resel. won)!\n"));
1683        pSRB = pDCB->pActiveSRB;
1684        if( !( pACB->scan_devices ) )
1685        {
1686            struct scsi_cmnd *pcmd = pSRB->pcmd;
1687            pcmd->resid = pcmd->request_bufflen;
1688            SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
1689            dc390_Going_remove(pDCB, pSRB);
1690            dc390_Free_insert(pACB, pSRB);
1691            pcmd->scsi_done (pcmd);
1692            DEBUG0(printk(KERN_DEBUG"DC390: Return SRB %p to free\n", pSRB));
1693        }
1694    }
1695    /* Get ID */
1696    lun = DC390_read8 (ScsiFifo);
1697    DEBUG0(printk ("Dev %02x,", lun));
1698    if (!(lun & (1 << pACB->pScsiHost->this_id)))
1699      printk (KERN_ERR "DC390: Reselection must select host adapter: %02x!\n", lun);
1700    else
1701      lun ^= 1 << pACB->pScsiHost->this_id; /* Mask AdapterID */
1702    id = 0; while (lun >>= 1) id++;
1703    /* Get LUN */
1704    lun = DC390_read8 (ScsiFifo);
1705    if (!(lun & IDENTIFY_BASE)) printk (KERN_ERR "DC390: Resel: Expect identify message!\n");
1706    lun &= 7;
1707    DEBUG0(printk ("(%02i-%i),", id, lun));
1708    pDCB = dc390_findDCB (pACB, id, lun);
1709    if (!pDCB)
1710    {
1711        printk (KERN_ERR "DC390: Reselect from non existing device (%02i-%i)\n",
1712                    id, lun);
1713        return;
1714    }
1715    pACB->pActiveDCB = pDCB;
1716    /* TagQ: We expect a message soon, so never mind the exact SRB */
1717    if( pDCB->SyncMode & EN_TAG_QUEUEING )
1718    {
1719        pSRB = pACB->pTmpSRB;
1720        pDCB->pActiveSRB = pSRB;
1721    }
1722    else
1723    {
1724        pSRB = pDCB->pActiveSRB;
1725        if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) )
1726        {
1727            pSRB= pACB->pTmpSRB;
1728            pSRB->SRBState = SRB_UNEXPECT_RESEL;
1729            printk (KERN_ERR "DC390: Reselect without outstanding cmnd (%02i-%i)\n",
1730                    id, lun);
1731            pDCB->pActiveSRB = pSRB;
1732            dc390_EnableMsgOut_Abort ( pACB, pSRB );
1733        }
1734        else
1735        {
1736            if( pDCB->DCBFlag & ABORT_DEV_ )
1737            {
1738                pSRB->SRBState = SRB_ABORT_SENT;
1739                printk (KERN_INFO "DC390: Reselect: Abort (%02i-%i)\n",
1740                        id, lun);
1741                dc390_EnableMsgOut_Abort( pACB, pSRB );
1742            }
1743            else
1744                pSRB->SRBState = SRB_DATA_XFER;
1745        }
1746    }
1747
1748    DEBUG1(printk (KERN_DEBUG "Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber));
1749    pSRB->ScsiPhase = SCSI_NOP0;
1750    DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
1751    DC390_write8 (Sync_Period, pDCB->SyncPeriod);
1752    DC390_write8 (Sync_Offset, pDCB->SyncOffset);
1753    DC390_write8 (CtrlReg1, pDCB->CtrlR1);
1754    DC390_write8 (CtrlReg3, pDCB->CtrlR3);
1755    DC390_write8 (CtrlReg4, pDCB->CtrlR4);      /* ; Glitch eater */
1756    DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);   /* ;to release the /ACK signal */
1757}
1758
1759static int __inline__
1760dc390_RequestSense(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
1761{
1762        struct scsi_cmnd *pcmd;
1763
1764        pcmd = pSRB->pcmd;
1765
1766        REMOVABLEDEBUG(printk(KERN_INFO "DC390: RequestSense(Cmd %02x, Id %02x, LUN %02x)\n",\
1767                              pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN));
1768
1769        pSRB->SRBFlag |= AUTO_REQSENSE;
1770        pSRB->SavedSGCount = pcmd->use_sg;
1771        pSRB->SavedTotXLen = pSRB->TotalXferredLen;
1772        pSRB->AdaptStatus = 0;
1773        pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */
1774
1775        /* We are called from SRBdone, original PCI mapping has been removed
1776         * already, new one is set up from StartSCSI */
1777        pSRB->SGIndex = 0;
1778
1779        pSRB->TotalXferredLen = 0;
1780        pSRB->SGToBeXferLen = 0;
1781        return dc390_StartSCSI(pACB, pDCB, pSRB);
1782}
1783
1784
1785static void
1786dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB )
1787{
1788    u8 status;
1789    struct scsi_cmnd *pcmd;
1790
1791    pcmd = pSRB->pcmd;
1792    /* KG: Moved pci_unmap here */
1793    dc390_pci_unmap(pSRB);
1794
1795    status = pSRB->TargetStatus;
1796
1797    DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\
1798                pSRB, pcmd->pid));
1799    if(pSRB->SRBFlag & AUTO_REQSENSE)
1800    {   /* Last command was a Request Sense */
1801        pSRB->SRBFlag &= ~AUTO_REQSENSE;
1802        pSRB->AdaptStatus = 0;
1803        pSRB->TargetStatus = CHECK_CONDITION << 1;
1804
1805        //pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status);
1806        if (status == (CHECK_CONDITION << 1))
1807            pcmd->result = MK_RES_LNX(0, DID_BAD_TARGET, 0, /*CHECK_CONDITION*/0);
1808        else /* Retry */
1809        {
1810            if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */)
1811            {
1812                /* Don't retry on TEST_UNIT_READY */
1813                pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
1814                REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],\
1815                       (u32) pcmd->result, (u32) pSRB->TotalXferredLen));
1816            } else {
1817                SET_RES_DRV(pcmd->result, DRIVER_SENSE);
1818                pcmd->use_sg = pSRB->SavedSGCount;
1819                //pSRB->ScsiCmdLen       = (u8) (pSRB->Segment1[0] >> 8);
1820                DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
1821                pSRB->TotalXferredLen = 0;
1822                SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
1823            }
1824        }
1825        goto cmd_done;
1826    }
1827    if( status )
1828    {
1829        if( status_byte(status) == CHECK_CONDITION )
1830        {
1831            if (dc390_RequestSense(pACB, pDCB, pSRB)) {
1832                SET_RES_DID(pcmd->result, DID_ERROR);
1833                goto cmd_done;
1834            }
1835            return;
1836        }
1837        else if( status_byte(status) == QUEUE_FULL )
1838        {
1839            scsi_track_queue_full(pcmd->device, pDCB->GoingSRBCnt - 1);
1840            pcmd->use_sg = pSRB->SavedSGCount;
1841            DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
1842            pSRB->TotalXferredLen = 0;
1843            SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
1844        }
1845        else if(status == SCSI_STAT_SEL_TIMEOUT)
1846        {
1847            pSRB->AdaptStatus = H_SEL_TIMEOUT;
1848            pSRB->TargetStatus = 0;
1849            pcmd->result = MK_RES(0,DID_NO_CONNECT,0,0);
1850            /* Devices are removed below ... */
1851        }
1852        else if (status_byte(status) == BUSY && 
1853                 (pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) &&
1854                 pACB->scan_devices)
1855        {
1856            pSRB->AdaptStatus = 0;
1857            pSRB->TargetStatus = status;
1858            pcmd->result = MK_RES(0,0,pSRB->EndMessage,/*status*/0);
1859        }
1860        else
1861        {   /* Another error */
1862            pSRB->TotalXferredLen = 0;
1863            SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
1864            goto cmd_done;
1865        }
1866    }
1867    else
1868    {   /*  Target status == 0 */
1869        status = pSRB->AdaptStatus;
1870        if(status & H_OVER_UNDER_RUN)
1871        {
1872            pSRB->TargetStatus = 0;
1873            SET_RES_DID(pcmd->result,DID_OK);
1874            SET_RES_MSG(pcmd->result,pSRB->EndMessage);
1875        }
1876        else if( pSRB->SRBStatus & PARITY_ERROR)
1877        {
1878            //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0);
1879            SET_RES_DID(pcmd->result,DID_PARITY);
1880            SET_RES_MSG(pcmd->result,pSRB->EndMessage);
1881        }
1882        else                   /* No error */
1883        {
1884            pSRB->AdaptStatus = 0;
1885            pSRB->TargetStatus = 0;
1886            SET_RES_DID(pcmd->result,DID_OK);
1887        }
1888    }
1889
1890cmd_done:
1891    pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
1892
1893    dc390_Going_remove (pDCB, pSRB);
1894    /* Add to free list */
1895    dc390_Free_insert (pACB, pSRB);
1896
1897    DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->pid));
1898    pcmd->scsi_done (pcmd);
1899
1900    return;
1901}
1902
1903
1904/* Remove all SRBs from Going list and inform midlevel */
1905static void
1906dc390_DoingSRB_Done(struct dc390_acb* pACB, struct scsi_cmnd *cmd)
1907{
1908    struct dc390_dcb *pDCB, *pdcb;
1909    struct dc390_srb *psrb, *psrb2;
1910    int i;
1911    struct scsi_cmnd *pcmd;
1912
1913    pDCB = pACB->pLinkDCB;
1914    pdcb = pDCB;
1915    if (! pdcb) return;
1916    do
1917    {
1918        psrb = pdcb->pGoingSRB;
1919        for (i = 0; i < pdcb->GoingSRBCnt; i++)
1920        {
1921            psrb2 = psrb->pNextSRB;
1922            pcmd = psrb->pcmd;
1923            dc390_Free_insert (pACB, psrb);
1924            psrb  = psrb2;
1925        }
1926        pdcb->GoingSRBCnt = 0;
1927        pdcb->pGoingSRB = NULL;
1928        pdcb->TagMask = 0;
1929        pdcb = pdcb->pNextDCB;
1930    } while( pdcb != pDCB );
1931}
1932
1933
1934static void
1935dc390_ResetSCSIBus( struct dc390_acb* pACB )
1936{
1937    //DC390_write8 (ScsiCmd, RST_DEVICE_CMD);
1938    //udelay (250);
1939    //DC390_write8 (ScsiCmd, NOP_CMD);
1940
1941    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1942    DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1943    DC390_write8 (ScsiCmd, RST_SCSI_BUS_CMD);
1944    pACB->Connected = 0;
1945
1946    return;
1947}
1948
1949static void
1950dc390_ScsiRstDetect( struct dc390_acb* pACB )
1951{
1952    printk ("DC390: Rst_Detect: laststat = %08x\n", dc390_laststatus);
1953    //DEBUG0(printk(KERN_INFO "RST_DETECT,"));
1954
1955    DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1956    /* Unlock before ? */
1957    /* delay half a second */
1958    udelay (1000);
1959    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1960    pACB->pScsiHost->last_reset = jiffies + 5*HZ/2
1961                    + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
1962    pACB->Connected = 0;
1963
1964    if( pACB->ACBFlag & RESET_DEV )
1965        pACB->ACBFlag |= RESET_DONE;
1966    else
1967    {   /* Reset was issued by sb else */
1968        pACB->ACBFlag |= RESET_DETECT;
1969
1970        dc390_ResetDevParam( pACB );
1971        dc390_DoingSRB_Done( pACB, NULL);
1972        //dc390_RecoverSRB( pACB );
1973        pACB->pActiveDCB = NULL;
1974        pACB->ACBFlag = 0;
1975    }
1976    return;
1977}
1978
1979static int DC390_queuecommand(struct scsi_cmnd *cmd,
1980                void (*done)(struct scsi_cmnd *))
1981{
1982        struct scsi_device *sdev = cmd->device;
1983        struct dc390_acb *acb = (struct dc390_acb *)sdev->host->hostdata;
1984        struct dc390_dcb *dcb = sdev->hostdata;
1985        struct dc390_srb *srb;
1986
1987        if (sdev->queue_depth <= dcb->GoingSRBCnt)
1988                goto device_busy;
1989        if (acb->pActiveDCB)
1990                goto host_busy;
1991        if (acb->ACBFlag & (RESET_DETECT|RESET_DONE|RESET_DEV))
1992                goto host_busy;
1993
1994        srb = acb->pFreeSRB;
1995        if (unlikely(srb == NULL))
1996                goto host_busy;
1997
1998        cmd->scsi_done = done;
1999        cmd->result = 0;
2000        acb->Cmds++;
2001
2002        acb->pFreeSRB = srb->pNextSRB;
2003        srb->pNextSRB = NULL;
2004
2005        srb->pSRBDCB = dcb;
2006        srb->pcmd = cmd;
2007        cmd->host_scribble = (char *)srb;
2008    
2009        srb->SGIndex = 0;
2010        srb->AdaptStatus = 0;
2011        srb->TargetStatus = 0;
2012        srb->MsgCnt = 0;
2013
2014        srb->SRBStatus = 0;
2015        srb->SRBFlag = 0;
2016        srb->SRBState = 0;
2017        srb->TotalXferredLen = 0;
2018        srb->SGBusAddr = 0;
2019        srb->SGToBeXferLen = 0;
2020        srb->ScsiPhase = 0;
2021        srb->EndMessage = 0;
2022        srb->TagNumber = SCSI_NO_TAG;
2023
2024        if (dc390_StartSCSI(acb, dcb, srb)) {
2025                dc390_Free_insert(acb, srb);
2026                goto host_busy;
2027        }
2028
2029        dc390_Going_append(dcb, srb);
2030
2031        return 0;
2032
2033 host_busy:
2034        return SCSI_MLQUEUE_HOST_BUSY;
2035
2036 device_busy:
2037        return SCSI_MLQUEUE_DEVICE_BUSY;
2038}
2039
2040static void dc390_dumpinfo (struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
2041{
2042    struct pci_dev *pdev;
2043    u16 pstat;
2044
2045    if (!pDCB) pDCB = pACB->pActiveDCB;
2046    if (!pSRB && pDCB) pSRB = pDCB->pActiveSRB;
2047
2048    if (pSRB) 
2049    {
2050        printk ("DC390: SRB: Xferred %08lx, Remain %08lx, State %08x, Phase %02x\n",
2051                pSRB->TotalXferredLen, pSRB->SGToBeXferLen, pSRB->SRBState,
2052                pSRB->ScsiPhase);
2053        printk ("DC390: AdpaterStatus: %02x, SRB Status %02x\n", pSRB->AdaptStatus, pSRB->SRBStatus);
2054    }
2055    printk ("DC390: Status of last IRQ (DMA/SC/Int/IRQ): %08x\n", dc390_laststatus);
2056    printk ("DC390: Register dump: SCSI block:\n");
2057    printk ("DC390: XferCnt  Cmd Stat IntS IRQS FFIS Ctl1 Ctl2 Ctl3 Ctl4\n");
2058    printk ("DC390:  %06x   %02x   %02x   %02x",
2059            DC390_read8(CtcReg_Low) + (DC390_read8(CtcReg_Mid) << 8) + (DC390_read8(CtcReg_High) << 16),
2060            DC390_read8(ScsiCmd), DC390_read8(Scsi_Status), DC390_read8(Intern_State));
2061    printk ("   %02x   %02x   %02x   %02x   %02x   %02x\n",
2062            DC390_read8(INT_Status), DC390_read8(Current_Fifo), DC390_read8(CtrlReg1),
2063            DC390_read8(CtrlReg2), DC390_read8(CtrlReg3), DC390_read8(CtrlReg4));
2064    DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
2065    if (DC390_read8(Current_Fifo) & 0x1f)
2066      {
2067        printk ("DC390: FIFO:");
2068        while (DC390_read8(Current_Fifo) & 0x1f) printk (" %02x", DC390_read8(ScsiFifo));
2069        printk ("\n");
2070      }
2071    printk ("DC390: Register dump: DMA engine:\n");
2072    printk ("DC390: Cmd   STrCnt    SBusA    WrkBC    WrkAC Stat SBusCtrl\n");
2073    printk ("DC390:  %02x %08x %08x %08x %08x   %02x %08x\n",
2074            DC390_read8(DMA_Cmd), DC390_read32(DMA_XferCnt), DC390_read32(DMA_XferAddr),
2075            DC390_read32(DMA_Wk_ByteCntr), DC390_read32(DMA_Wk_AddrCntr),
2076            DC390_read8(DMA_Status), DC390_read32(DMA_ScsiBusCtrl));
2077    DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
2078
2079    pdev = pACB->pdev;
2080    pci_read_config_word(pdev, PCI_STATUS, &pstat);
2081    printk ("DC390: Register dump: PCI Status: %04x\n", pstat);
2082    printk ("DC390: In case of driver trouble read Documentation/scsi/tmscsim.txt\n");
2083}
2084
2085
2086static int DC390_abort(struct scsi_cmnd *cmd)
2087{
2088        struct dc390_acb *pACB = (struct dc390_acb*) cmd->device->host->hostdata;
2089        struct dc390_dcb *pDCB = (struct dc390_dcb*) cmd->device->hostdata;
2090
2091        scmd_printk(KERN_WARNING, cmd,
2092                "DC390: Abort command (pid %li)\n", cmd->pid);
2093
2094        /* abort() is too stupid for already sent commands at the moment. 
2095         * If it's called we are in trouble anyway, so let's dump some info 
2096         * into the syslog at least. (KG, 98/08/20,99/06/20) */
2097        dc390_dumpinfo(pACB, pDCB, NULL);
2098
2099        pDCB->DCBFlag |= ABORT_DEV_;
2100        printk(KERN_INFO "DC390: Aborted pid %li\n", cmd->pid);
2101
2102        return FAILED;
2103}
2104
2105
2106static void dc390_ResetDevParam( struct dc390_acb* pACB )
2107{
2108    struct dc390_dcb *pDCB, *pdcb;
2109
2110    pDCB = pACB->pLinkDCB;
2111    if (! pDCB) return;
2112    pdcb = pDCB;
2113    do
2114    {
2115        pDCB->SyncMode &= ~SYNC_NEGO_DONE;
2116        pDCB->SyncPeriod = 0;
2117        pDCB->SyncOffset = 0;
2118        pDCB->TagMask = 0;
2119        pDCB->CtrlR3 = FAST_CLK;
2120        pDCB->CtrlR4 &= NEGATE_REQACKDATA | CTRL4_RESERVED | NEGATE_REQACK;
2121        pDCB->CtrlR4 |= pACB->glitch_cfg;
2122        pDCB = pDCB->pNextDCB;
2123    }
2124    while( pdcb != pDCB );
2125    pACB->ACBFlag &= ~(RESET_DEV | RESET_DONE | RESET_DETECT);
2126
2127}
2128
2129static int DC390_bus_reset (struct scsi_cmnd *cmd)
2130{
2131        struct dc390_acb*    pACB = (struct dc390_acb*) cmd->device->host->hostdata;
2132        u8   bval;
2133
2134        spin_lock_irq(cmd->device->host->host_lock);
2135
2136        bval = DC390_read8(CtrlReg1) | DIS_INT_ON_SCSI_RST;
2137        DC390_write8(CtrlReg1, bval);   /* disable IRQ on bus reset */
2138
2139        pACB->ACBFlag |= RESET_DEV;
2140        dc390_ResetSCSIBus(pACB);
2141
2142        dc390_ResetDevParam(pACB);
2143        mdelay(1);
2144        pACB->pScsiHost->last_reset = jiffies + 3*HZ/2 
2145                + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
2146    
2147        DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
2148        DC390_read8(INT_Status);                /* Reset Pending INT */
2149
2150        dc390_DoingSRB_Done(pACB, cmd);
2151
2152        pACB->pActiveDCB = NULL;
2153        pACB->ACBFlag = 0;
2154
2155        bval = DC390_read8(CtrlReg1) & ~DIS_INT_ON_SCSI_RST;
2156        DC390_write8(CtrlReg1, bval);   /* re-enable interrupt */
2157
2158        spin_unlock_irq(cmd->device->host->host_lock);
2159
2160        return SUCCESS;
2161}
2162
2163/**
2164 * dc390_slave_alloc - Called by the scsi mid layer to tell us about a new
2165 * scsi device that we need to deal with.
2166 *
2167 * @scsi_device: The new scsi device that we need to handle.
2168 */
2169static int dc390_slave_alloc(struct scsi_device *scsi_device)
2170{
2171        struct dc390_acb *pACB = (struct dc390_acb*) scsi_device->host->hostdata;
2172        struct dc390_dcb *pDCB, *pDCB2 = NULL;
2173        uint id = scsi_device->id;
2174        uint lun = scsi_device->lun;
2175
2176        pDCB = kmalloc(sizeof(struct dc390_dcb), GFP_KERNEL);
2177        if (!pDCB)
2178                return -ENOMEM;
2179        memset(pDCB, 0, sizeof(struct dc390_dcb));
2180
2181        if (!pACB->DCBCnt++) {
2182                pACB->pLinkDCB = pDCB;
2183                pACB->pDCBRunRobin = pDCB;
2184        } else {
2185                pACB->pLastDCB->pNextDCB = pDCB;
2186        }
2187   
2188        pDCB->pNextDCB = pACB->pLinkDCB;
2189        pACB->pLastDCB = pDCB;
2190
2191        pDCB->pDCBACB = pACB;
2192        pDCB->TargetID = id;
2193        pDCB->TargetLUN = lun;
2194
2195        /*
2196         * Some values are for all LUNs: Copy them 
2197         * In a clean way: We would have an own structure for a SCSI-ID 
2198         */
2199        if (lun && (pDCB2 = dc390_findDCB(pACB, id, 0))) {
2200                pDCB->DevMode = pDCB2->DevMode;
2201                pDCB->SyncMode = pDCB2->SyncMode & SYNC_NEGO_DONE;
2202                pDCB->SyncPeriod = pDCB2->SyncPeriod;
2203                pDCB->SyncOffset = pDCB2->SyncOffset;
2204                pDCB->NegoPeriod = pDCB2->NegoPeriod;
2205      
2206                pDCB->CtrlR3 = pDCB2->CtrlR3;
2207                pDCB->CtrlR4 = pDCB2->CtrlR4;
2208        } else {
2209                u8 index = pACB->AdapterIndex;
2210                PEEprom prom = (PEEprom) &dc390_eepromBuf[index][id << 2];
2211
2212                pDCB->DevMode = prom->EE_MODE1;
2213                pDCB->NegoPeriod =
2214                        (dc390_clock_period1[prom->EE_SPEED] * 25) >> 2;
2215                pDCB->CtrlR3 = FAST_CLK;
2216                pDCB->CtrlR4 = pACB->glitch_cfg | CTRL4_RESERVED;
2217                if (dc390_eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION)
2218                        pDCB->CtrlR4 |= NEGATE_REQACKDATA | NEGATE_REQACK;
2219        }
2220
2221        if (pDCB->DevMode & SYNC_NEGO_)
2222                pDCB->SyncMode |= SYNC_ENABLE;
2223        else {
2224                pDCB->SyncMode = 0;
2225                pDCB->SyncOffset &= ~0x0f;
2226        }
2227
2228        pDCB->CtrlR1 = pACB->pScsiHost->this_id;
2229        if (pDCB->DevMode & PARITY_CHK_)
2230                pDCB->CtrlR1 |= PARITY_ERR_REPO;
2231
2232        pACB->scan_devices = 1;
2233        scsi_device->hostdata = pDCB;
2234        return 0;
2235}
2236
2237/**
2238 * dc390_slave_destroy - Called by the scsi mid layer to tell us about a
2239 * device that is going away.
2240 *
2241 * @scsi_device: The scsi device that we need to remove.
2242 */
2243static void dc390_slave_destroy(struct scsi_device *scsi_device)
2244{
2245        struct dc390_acb* pACB = (struct dc390_acb*) scsi_device->host->hostdata;
2246        struct dc390_dcb* pDCB = (struct dc390_dcb*) scsi_device->hostdata;
2247        struct dc390_dcb* pPrevDCB = pACB->pLinkDCB;
2248
2249        pACB->scan_devices = 0;
2250
2251        BUG_ON(pDCB->GoingSRBCnt > 1);
2252        
2253        if (pDCB == pACB->pLinkDCB) {
2254                if (pACB->pLastDCB == pDCB) {
2255                        pDCB->pNextDCB = NULL;
2256                        pACB->pLastDCB = NULL;
2257                }
2258                pACB->pLinkDCB = pDCB->pNextDCB;
2259        } else {
2260                while (pPrevDCB->pNextDCB != pDCB)
2261                        pPrevDCB = pPrevDCB->pNextDCB;
2262                pPrevDCB->pNextDCB = pDCB->pNextDCB;
2263                if (pDCB == pACB->pLastDCB)
2264                        pACB->pLastDCB = pPrevDCB;
2265        }
2266
2267        if (pDCB == pACB->pActiveDCB)
2268                pACB->pActiveDCB = NULL;
2269        if (pDCB == pACB->pLinkDCB)
2270                pACB->pLinkDCB = pDCB->pNextDCB;
2271        if (pDCB == pACB->pDCBRunRobin)
2272                pACB->pDCBRunRobin = pDCB->pNextDCB;
2273        kfree(pDCB); 
2274        
2275        pACB->DCBCnt--;
2276}
2277
2278static int dc390_slave_configure(struct scsi_device *sdev)
2279{
2280        struct dc390_acb *acb = (struct dc390_acb *)sdev->host->hostdata;
2281        struct dc390_dcb *dcb = (struct dc390_dcb *)sdev->hostdata;
2282
2283        acb->scan_devices = 0;
2284        if (sdev->tagged_supported && (dcb->DevMode & TAG_QUEUEING_)) {
2285                dcb->SyncMode |= EN_TAG_QUEUEING;
2286                scsi_activate_tcq(sdev, acb->TagMaxNum);
2287        }
2288
2289        return 0;
2290}
2291
2292static struct scsi_host_template driver_template = {
2293        .module                 = THIS_MODULE,
2294        .proc_name              = "tmscsim", 
2295        .name                   = DC390_BANNER " V" DC390_VERSION,
2296        .slave_alloc            = dc390_slave_alloc,
2297        .slave_configure        = dc390_slave_configure,
2298        .slave_destroy          = dc390_slave_destroy,
2299        .queuecommand           = DC390_queuecommand,
2300        .eh_abort_handler       = DC390_abort,
2301        .eh_bus_reset_handler   = DC390_bus_reset,
2302        .can_queue              = 1,
2303        .this_id                = 7,
2304        .sg_tablesize           = SG_ALL,
2305        .cmd_per_lun            = 1,
2306        .use_clustering         = ENABLE_CLUSTERING,
2307        .max_sectors            = 0x4000, /* 8MiB = 16 * 1024 * 512 */
2308};
2309
2310/***********************************************************************
2311 * Functions for access to DC390 EEPROM
2312 * and some to emulate it
2313 *
2314 **********************************************************************/
2315
2316static void __devinit dc390_eeprom_prepare_read(struct pci_dev *pdev, u8 cmd)
2317{
2318        u8 carryFlag = 1, j = 0x80, bval;
2319        int i;
2320
2321        for (i = 0; i < 9; i++) {
2322                if (carryFlag) {
2323                        pci_write_config_byte(pdev, 0x80, 0x40);
2324                        bval = 0xc0;
2325                } else
2326                        bval = 0x80;
2327
2328                udelay(160);
2329                pci_write_config_byte(pdev, 0x80, bval);
2330                udelay(160);
2331                pci_write_config_byte(pdev, 0x80, 0);
2332                udelay(160);
2333
2334                carryFlag = (cmd & j) ? 1 : 0;
2335                j >>= 1;
2336        }
2337}
2338
2339static u16 __devinit dc390_eeprom_get_data(struct pci_dev *pdev)
2340{
2341        int i;
2342        u16 wval = 0;
2343        u8 bval;
2344
2345        for (i = 0; i < 16; i++) {
2346                wval <<= 1;
2347
2348                pci_write_config_byte(pdev, 0x80, 0x80);
2349                udelay(160);
2350                pci_write_config_byte(pdev, 0x80, 0x40);
2351                udelay(160);
2352                pci_read_config_byte(pdev, 0x00, &bval);
2353
2354                if (bval == 0x22)
2355                        wval |= 1;
2356        }
2357
2358        return wval;
2359}
2360
2361static void __devinit dc390_read_eeprom(struct pci_dev *pdev, u16 *ptr)
2362{
2363        u8 cmd = EEPROM_READ, i;
2364
2365        for (i = 0; i < 0x40; i++) {
2366                pci_write_config_byte(pdev, 0xc0, 0);
2367                udelay(160);
2368
2369                dc390_eeprom_prepare_read(pdev, cmd++);
2370                *ptr++ = dc390_eeprom_get_data(pdev);
2371
2372                pci_write_config_byte(pdev, 0x80, 0);
2373                pci_write_config_byte(pdev, 0x80, 0);
2374                udelay(160);
2375        }
2376}
2377
2378/* Override EEprom values with explicitly set values */
2379static void __devinit dc390_eeprom_override(u8 index)
2380{
2381        u8 *ptr = (u8 *) dc390_eepromBuf[index], id;
2382
2383        /* Adapter Settings */
2384        if (tmscsim[0] != -2)
2385                ptr[EE_ADAPT_SCSI_ID] = (u8)tmscsim[0]; /* Adapter ID */
2386        if (tmscsim[3] != -2)
2387                ptr[EE_MODE2] = (u8)tmscsim[3];
2388        if (tmscsim[5] != -2)
2389                ptr[EE_DELAY] = tmscsim[5];             /* Reset delay */
2390        if (tmscsim[4] != -2)
2391                ptr[EE_TAG_CMD_NUM] = (u8)tmscsim[4];   /* Tagged Cmds */
2392
2393        /* Device Settings */
2394        for (id = 0; id < MAX_SCSI_ID; id++) {
2395                if (tmscsim[2] != -2)
2396                        ptr[id << 2] = (u8)tmscsim[2];          /* EE_MODE1 */
2397                if (tmscsim[1] != -2)
2398                        ptr[(id << 2) + 1] = (u8)tmscsim[1];    /* EE_Speed */
2399        }
2400}
2401
2402static int __devinitdata tmscsim_def[] = {
2403        7,
2404        0 /* 10MHz */,
2405        PARITY_CHK_ | SEND_START_ | EN_DISCONNECT_ | SYNC_NEGO_ | TAG_QUEUEING_,
2406        MORE2_DRV | GREATER_1G | RST_SCSI_BUS | ACTIVE_NEGATION | LUN_CHECK,
2407        3 /* 16 Tags per LUN */,
2408        1 /* s delay after Reset */,
2409};
2410
2411/* Copy defaults over set values where missing */
2412static void __devinit dc390_fill_with_defaults (void)
2413{
2414        int i;
2415
2416        for (i = 0; i < 6; i++) {
2417                if (tmscsim[i] < 0 || tmscsim[i] > 255)
2418                        tmscsim[i] = tmscsim_def[i];
2419        }
2420
2421        /* Sanity checks */
2422        if (tmscsim[0] > 7)
2423                tmscsim[0] = 7;
2424        if (tmscsim[1] > 7)
2425                tmscsim[1] = 4;
2426        if (tmscsim[4] > 5)
2427                tmscsim[4] = 4;
2428        if (tmscsim[5] > 180)
2429                tmscsim[5] = 180;
2430}
2431
2432static void __devinit dc390_check_eeprom(struct pci_dev *pdev, u8 index)
2433{
2434        u8 interpd[] = {1, 3, 5, 10, 16, 30, 60, 120};
2435        u8 EEbuf[128];
2436        u16 *ptr = (u16 *)EEbuf, wval = 0;
2437        int i;
2438
2439        dc390_read_eeprom(pdev, ptr);
2440        memcpy(dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID);
2441        memcpy(&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID], 
2442               &EEbuf[REAL_EE_ADAPT_SCSI_ID], EE_LEN - EE_ADAPT_SCSI_ID);
2443
2444        dc390_eepromBuf[index][EE_DELAY] = interpd[dc390_eepromBuf[index][EE_DELAY]];
2445
2446        for (i = 0; i < 0x40; i++, ptr++)
2447                wval += *ptr;
2448
2449        /* no Tekram EEprom found */
2450        if (wval != 0x1234) {
2451                int speed;
2452
2453                printk(KERN_INFO "DC390_init: No EEPROM found! Trying default settings ...\n");
2454
2455                /*
2456                 * XXX(hch): bogus, because we might have tekram and
2457                 *           non-tekram hbas in a single machine.
2458                 */
2459                dc390_fill_with_defaults();
2460
2461                speed = dc390_clock_speed[tmscsim[1]];
2462                printk(KERN_INFO "DC390: Used defaults: AdaptID=%i, SpeedIdx=%i (%i.%i MHz), "
2463                       "DevMode=0x%02x, AdaptMode=0x%02x, TaggedCmnds=%i (%i), DelayReset=%is\n", 
2464                       tmscsim[0], tmscsim[1], speed / 10, speed % 10,
2465                       (u8)tmscsim[2], (u8)tmscsim[3], tmscsim[4], 2 << (tmscsim[4]), tmscsim[5]);
2466        }
2467}
2468
2469static void __devinit dc390_init_hw(struct dc390_acb *pACB, u8 index)
2470{
2471        struct Scsi_Host *shost = pACB->pScsiHost;
2472        u8 dstate;
2473
2474        /* Disable SCSI bus reset interrupt */
2475        DC390_write8(CtrlReg1, DIS_INT_ON_SCSI_RST | shost->this_id);
2476
2477        if (pACB->Gmode2 & RST_SCSI_BUS) {
2478                dc390_ResetSCSIBus(pACB);
2479                udelay(1000);
2480                shost->last_reset = jiffies + HZ/2 +
2481                        HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
2482        }
2483
2484        pACB->ACBFlag = 0;
2485
2486        /* Reset Pending INT */
2487        DC390_read8(INT_Status);
2488        
2489        /* 250ms selection timeout */
2490        DC390_write8(Scsi_TimeOut, SEL_TIMEOUT);
2491        
2492        /* Conversion factor = 0 , 40MHz clock */
2493        DC390_write8(Clk_Factor, CLK_FREQ_40MHZ);
2494        
2495        /* NOP cmd - clear command register */
2496        DC390_write8(ScsiCmd, NOP_CMD);
2497        
2498        /* Enable Feature and SCSI-2 */
2499        DC390_write8(CtrlReg2, EN_FEATURE+EN_SCSI2_CMD);
2500        
2501        /* Fast clock */
2502        DC390_write8(CtrlReg3, FAST_CLK);
2503
2504        /* Negation */
2505        DC390_write8(CtrlReg4, pACB->glitch_cfg | /* glitch eater */
2506                (dc390_eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION) ?
2507                 NEGATE_REQACKDATA : 0);
2508        
2509        /* Clear Transfer Count High: ID */
2510        DC390_write8(CtcReg_High, 0);
2511        DC390_write8(DMA_Cmd, DMA_IDLE_CMD);
2512        DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
2513        DC390_write32(DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
2514
2515        dstate = DC390_read8(DMA_Status);
2516        DC390_write8(DMA_Status, dstate);
2517}
2518
2519static int __devinit dc390_probe_one(struct pci_dev *pdev,
2520                                    const struct pci_device_id *id)
2521{
2522        struct dc390_acb *pACB;
2523        struct Scsi_Host *shost;
2524        unsigned long io_port;
2525        int error = -ENODEV, i;
2526
2527        if (pci_enable_device(pdev))
2528                goto out;
2529
2530        pci_set_master(pdev);
2531
2532        error = -ENOMEM;
2533        if (disable_clustering)
2534                driver_template.use_clustering = DISABLE_CLUSTERING;
2535        shost = scsi_host_alloc(&driver_template, sizeof(struct dc390_acb));
2536        if (!shost)
2537                goto out_disable_device;
2538
2539        pACB = (struct dc390_acb *)shost->hostdata;
2540        memset(pACB, 0, sizeof(struct dc390_acb));
2541
2542        dc390_check_eeprom(pdev, dc390_adapterCnt);
2543        dc390_eeprom_override(dc390_adapterCnt);
2544
2545        io_port = pci_resource_start(pdev, 0);
2546
2547        shost->this_id = dc390_eepromBuf[dc390_adapterCnt][EE_ADAPT_SCSI_ID];
2548        shost->io_port = io_port;
2549        shost->n_io_port = 0x80;
2550        shost->irq = pdev->irq;
2551        shost->base = io_port;
2552        shost->unique_id = io_port;
2553        shost->last_reset = jiffies;
2554        
2555        pACB->pScsiHost = shost;
2556        pACB->IOPortBase = (u16) io_port;
2557        pACB->IRQLevel = pdev->irq;
2558        
2559        shost->max_id = 8;
2560
2561        if (shost->max_id - 1 ==
2562            dc390_eepromBuf[dc390_adapterCnt][EE_ADAPT_SCSI_ID])
2563                shost->max_id--;
2564
2565        if (dc390_eepromBuf[dc390_adapterCnt][EE_MODE2] & LUN_CHECK)
2566                shost->max_lun = 8;
2567        else
2568                shost->max_lun = 1;
2569
2570        pACB->pFreeSRB = pACB->SRB_array;
2571        pACB->SRBCount = MAX_SRB_CNT;
2572        pACB->AdapterIndex = dc390_adapterCnt;
2573        pACB->TagMaxNum =
2574                2 << dc390_eepromBuf[dc390_adapterCnt][EE_TAG_CMD_NUM];
2575        pACB->Gmode2 = dc390_eepromBuf[dc390_adapterCnt][EE_MODE2];
2576
2577        for (i = 0; i < pACB->SRBCount-1; i++)
2578                pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
2579        pACB->SRB_array[pACB->SRBCount-1].pNextSRB = NULL;
2580        pACB->pTmpSRB = &pACB->TmpSRB;
2581
2582        pACB->sel_timeout = SEL_TIMEOUT;
2583        pACB->glitch_cfg = EATER_25NS;
2584        pACB->pdev = pdev;
2585
2586        if (!request_region(io_port, shost->n_io_port, "tmscsim")) {
2587                printk(KERN_ERR "DC390: register IO ports error!\n");
2588                goto out_host_put;
2589        }
2590
2591        /* Reset Pending INT */
2592        DC390_read8_(INT_Status, io_port);
2593
2594        if (request_irq(pdev->irq, do_DC390_Interrupt, IRQF_SHARED,
2595                                "tmscsim", pACB)) {
2596                printk(KERN_ERR "DC390: register IRQ error!\n");
2597                goto out_release_region;
2598        }
2599
2600        dc390_init_hw(pACB, dc390_adapterCnt);
2601        
2602        dc390_adapterCnt++;
2603
2604        pci_set_drvdata(pdev, shost);
2605
2606        error = scsi_add_host(shost, &pdev->dev);
2607        if (error)
2608                goto out_free_irq;
2609        scsi_scan_host(shost);
2610        return 0;
2611
2612 out_free_irq:
2613        free_irq(pdev->irq, pACB);
2614 out_release_region:
2615        release_region(io_port, shost->n_io_port);
2616 out_host_put:
2617        scsi_host_put(shost);
2618 out_disable_device:
2619        pci_disable_device(pdev);
2620 out:
2621        return error;
2622}
2623
2624/**
2625 * dc390_remove_one - Called to remove a single instance of the adapter.
2626 *
2627 * @dev: The PCI device to remove.
2628 */
2629static void __devexit dc390_remove_one(struct pci_dev *dev)
2630{
2631        struct Scsi_Host *scsi_host = pci_get_drvdata(dev);
2632        unsigned long iflags;
2633        struct dc390_acb* pACB = (struct dc390_acb*) scsi_host->hostdata;
2634        u8 bval;
2635
2636        scsi_remove_host(scsi_host);
2637
2638        spin_lock_irqsave(scsi_host->host_lock, iflags);
2639        pACB->ACBFlag = RESET_DEV;
2640        bval = DC390_read8(CtrlReg1) | DIS_INT_ON_SCSI_RST;
2641        DC390_write8 (CtrlReg1, bval);  /* disable interrupt */
2642        if (pACB->Gmode2 & RST_SCSI_BUS)
2643                dc390_ResetSCSIBus(pACB);
2644        spin_unlock_irqrestore(scsi_host->host_lock, iflags);
2645
2646        free_irq(scsi_host->irq, pACB);
2647        release_region(scsi_host->io_port, scsi_host->n_io_port);
2648
2649        pci_disable_device(dev);
2650        scsi_host_put(scsi_host);
2651        pci_set_drvdata(dev, NULL);
2652}
2653
2654static struct pci_device_id tmscsim_pci_tbl[] = {
2655        { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD53C974,
2656                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
2657        { }
2658};
2659MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl);
2660
2661static struct pci_driver dc390_driver = {
2662        .name           = "tmscsim",
2663        .id_table       = tmscsim_pci_tbl,
2664        .probe          = dc390_probe_one,
2665        .remove         = __devexit_p(dc390_remove_one),
2666};
2667
2668static int __init dc390_module_init(void)
2669{
2670        if (!disable_clustering)
2671                printk(KERN_INFO "DC390: clustering now enabled by default. If you get problems load\n"
2672                       "\twith \"disable_clustering=1\" and report to maintainers\n");
2673
2674        if (tmscsim[0] == -1 || tmscsim[0] > 15) {
2675                tmscsim[0] = 7;
2676                tmscsim[1] = 4;
2677                tmscsim[2] = PARITY_CHK_ | TAG_QUEUEING_;
2678                tmscsim[3] = MORE2_DRV | GREATER_1G | RST_SCSI_BUS | ACTIVE_NEGATION;
2679                tmscsim[4] = 2;
2680                tmscsim[5] = 10;
2681                printk (KERN_INFO "DC390: Using safe settings.\n");
2682        }
2683
2684        return pci_module_init(&dc390_driver);
2685}
2686
2687static void __exit dc390_module_exit(void)
2688{
2689        pci_unregister_driver(&dc390_driver);
2690}
2691
2692module_init(dc390_module_init);
2693module_exit(dc390_module_exit);
2694
2695#ifndef MODULE
2696static int __init dc390_setup (char *str)
2697{       
2698        int ints[8],i, im;
2699
2700        get_options(str, ARRAY_SIZE(ints), ints);
2701        im = ints[0];
2702
2703        if (im > 6) {
2704                printk (KERN_NOTICE "DC390: ignore extra params!\n");
2705                im = 6;
2706        }
2707
2708        for (i = 0; i < im; i++)
2709                tmscsim[i] = ints[i+1];
2710        /* dc390_checkparams (); */
2711        return 1;
2712}
2713
2714__setup("tmscsim=", dc390_setup);
2715#endif
2716
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.