File: /usr/src/linux/drivers/scsi/scsiiom.c

1     /***********************************************************************
2      *	FILE NAME : SCSIIOM.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      ***********************************************************************/
7     /* $Id: scsiiom.c,v 2.55.2.17 2000/12/20 00:39:37 garloff Exp $ */
8     
9     static void __inline__
10     dc390_freetag (PDCB pDCB, PSRB pSRB)
11     {
12     	if (pSRB->TagNumber < 255) {
13     		pDCB->TagMask &= ~(1 << pSRB->TagNumber);   /* free tag mask */
14     		pSRB->TagNumber = 255;
15     	}
16     };
17     
18     
19     UCHAR
20     dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
21     {
22         UCHAR cmd; UCHAR  disc_allowed, try_sync_nego;
23     
24         pSRB->ScsiPhase = SCSI_NOP0;
25     
26         if (pACB->Connected)
27         {
28     	// Should not happen normally
29     	printk (KERN_WARNING "DC390: Can't select when connected! (%08x,%02x)\n",
30     		pSRB->SRBState, pSRB->SRBFlag);
31     	pSRB->SRBState = SRB_READY;
32     	pACB->SelConn++;
33     	return 1;
34         }
35         if (time_before (jiffies, pACB->pScsiHost->last_reset))
36         {
37     	DEBUG0(printk ("DC390: We were just reset and don't accept commands yet!\n");)
38     	return 1;
39         }
40         DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
41         DC390_write8 (Sync_Period, pDCB->SyncPeriod);
42         DC390_write8 (Sync_Offset, pDCB->SyncOffset);
43         DC390_write8 (CtrlReg1, pDCB->CtrlR1);
44         DC390_write8 (CtrlReg3, pDCB->CtrlR3);
45         DC390_write8 (CtrlReg4, pDCB->CtrlR4);
46         DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);		/* Flush FIFO */
47         DEBUG1(printk (KERN_INFO "DC390: Start SCSI command: %02x (Sync:%02x)\n",
48     	    pSRB->pcmd->cmnd[0], pDCB->SyncMode);)
49         disc_allowed = pDCB->DevMode & EN_DISCONNECT_; try_sync_nego = 0;
50         /* Don't disconnect on AUTO_REQSENSE, cause it might be an
51          * Contingent Allegiance Condition (6.6), where no tags should be used.
52          * All other have to be allowed to disconnect to prevent Incorrect 
53          * Initiator Connection (6.8.2/6.5.2) */
54         /* Changed KG, 99/06/06 */
55         if( /*(((pSRB->pcmd->cmnd[0] == INQUIRY) || (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) ||
56     	 * (pSRB->pcmd->cmnd[0] == TEST_UNIT_READY)) && pACB->scan_devices)
57     		||*/ (pSRB->SRBFlag & AUTO_REQSENSE) ) 
58           disc_allowed = 0;
59         if ( (pDCB->SyncMode & SYNC_ENABLE) && (pDCB->TargetLUN == 0) && (pDCB->Inquiry7 & 0x10) &&
60     	( ( ( (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) || (pSRB->SRBFlag & AUTO_REQSENSE) )
61     	  && !(pDCB->SyncMode & SYNC_NEGO_DONE) ) || (pSRB->pcmd->cmnd[0] == INQUIRY) ) )
62           try_sync_nego = 1;
63     
64         pSRB->MsgCnt = 0; cmd = SEL_W_ATN;
65         DC390_write8 (ScsiFifo, IDENTIFY(disc_allowed, pDCB->TargetLUN));
66         /* Change 99/05/31: Don't use tags when not disconnecting (BUSY) */
67         if ((pDCB->SyncMode & EN_TAG_QUEUEING) && disc_allowed)
68           {
69     	UCHAR tag_no = 0;
70     	while ((1 << tag_no) & pDCB->TagMask) tag_no++;
71     	if (tag_no >= sizeof (pDCB->TagMask)*8 || tag_no >= pDCB->MaxCommand) { 
72     		printk (KERN_WARNING "DC390: Out of tags for Dev. %02x %02x\n", pDCB->TargetID, pDCB->TargetLUN); 
73     		return 1;
74     		//goto no_tag;
75     	};
76     	DC390_write8 (ScsiFifo, SIMPLE_QUEUE_TAG);
77     	pDCB->TagMask |= (1 << tag_no); pSRB->TagNumber = tag_no;
78     	DC390_write8 (ScsiFifo, tag_no);
79     	DEBUG1(printk (KERN_DEBUG "DC390: Select w/DisCn for Cmd %li (SRB %p), Using Tag %02x\n", pSRB->pcmd->pid, pSRB, tag_no);)
80     	cmd = SEL_W_ATN3;
81           }
82         else	/* No TagQ */
83           {
84     //      no_tag:
85     	DEBUG1(printk (KERN_DEBUG "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", (disc_allowed?"":"o"), pSRB->pcmd->pid, pSRB);) 
86           };
87     
88         pSRB->SRBState = SRB_START_;
89     
90         if (try_sync_nego)
91           { 
92     	UCHAR Sync_Off = pDCB->SyncOffset;
93             DEBUG0(printk (KERN_INFO "DC390: NEW Sync Nego code triggered (%i %i)\n", pDCB->TargetID, pDCB->TargetLUN);)
94     	pSRB->MsgOutBuf[0] = EXTENDED_MESSAGE;
95     	pSRB->MsgOutBuf[1] = 3;
96     	pSRB->MsgOutBuf[2] = EXTENDED_SDTR;
97     	pSRB->MsgOutBuf[3] = pDCB->NegoPeriod;
98     	if (!(Sync_Off & 0x0f)) Sync_Off = SYNC_NEGO_OFFSET;
99     	pSRB->MsgOutBuf[4] = Sync_Off;
100     	pSRB->MsgCnt = 5;
101     	//pSRB->SRBState = SRB_MSGOUT_;
102     	pSRB->SRBState |= DO_SYNC_NEGO;
103     	cmd = SEL_W_ATN_STOP;
104           };
105     
106         /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
107         if (cmd != SEL_W_ATN_STOP)
108           {
109     	if( pSRB->SRBFlag & AUTO_REQSENSE )
110     	  {
111     	    DC390_write8 (ScsiFifo, REQUEST_SENSE);
112     	    DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
113     	    DC390_write8 (ScsiFifo, 0);
114     	    DC390_write8 (ScsiFifo, 0);
115     	    DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
116     	    DC390_write8 (ScsiFifo, 0);
117     	    DEBUG1(printk (KERN_DEBUG "DC390: AutoReqSense !\n");)
118     	  }
119     	else	/* write cmnd to bus */ 
120     	  {
121     	    PUCHAR ptr; UCHAR i;
122     	    ptr = (PUCHAR) pSRB->pcmd->cmnd;
123     	    for (i=0; i<pSRB->pcmd->cmd_len; i++)
124     	      DC390_write8 (ScsiFifo, *(ptr++));
125     	  };
126           }
127         DEBUG0(if (pACB->pActiveDCB)	
128     	   printk (KERN_WARNING "DC390: ActiveDCB != 0\n");)
129         DEBUG0(if (pDCB->pActiveSRB)	
130     	   printk (KERN_WARNING "DC390: ActiveSRB != 0\n");)
131         //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
132         if (DC390_read8 (Scsi_Status) & INTERRUPT)
133         {
134     	dc390_freetag (pDCB, pSRB);
135     	DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)\n",
136     		pSRB->pcmd->pid, pSRB->pcmd->target, pSRB->pcmd->lun);)
137     	pSRB->SRBState = SRB_READY;
138     	//DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
139     	pACB->SelLost++;
140     	return 1;
141         };
142         DC390_write8 (ScsiCmd, cmd);
143         pACB->pActiveDCB = pDCB; pDCB->pActiveSRB = pSRB;
144         pACB->Connected = 1;
145         pSRB->ScsiPhase = SCSI_NOP1;
146         return 0;
147     }
148     
149     //#define DMA_INT EN_DMA_INT /*| EN_PAGE_INT*/
150     #define DMA_INT 0
151     
152     #if DMA_INT
153     /* This is similar to AM53C974.c ... */
154     static UCHAR 
155     dc390_dma_intr (PACB pACB)
156     {
157       PSRB pSRB;
158       UCHAR dstate;
159       DEBUG0(USHORT pstate;PDEVDECL1;)
160       
161       DEBUG0(PDEVSET1;)
162       DEBUG0(PCI_READ_CONFIG_WORD (PDEV, PCI_STATUS, &pstate);)
163       DEBUG0(if (pstate & (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY))
164     	{ printk(KERN_WARNING "DC390: PCI state = %04x!\n", pstate); 
165     	  PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));};)
166     
167       dstate = DC390_read8 (DMA_Status); 
168     
169       if (! pACB->pActiveDCB || ! pACB->pActiveDCB->pActiveSRB) return dstate;
170       else pSRB  = pACB->pActiveDCB->pActiveSRB;
171       
172       if (dstate & (DMA_XFER_ABORT | DMA_XFER_ERROR | POWER_DOWN | PCI_MS_ABORT))
173         {
174     	printk (KERN_ERR "DC390: DMA error (%02x)!\n", dstate);
175     	return dstate;
176         };
177       if (dstate & DMA_XFER_DONE)
178         {
179     	UINT residual, xferCnt; int ctr = 6000000;
180     	if (! (DC390_read8 (DMA_Cmd) & READ_DIRECTION))
181     	  {
182     	    do
183     	      {
184     		DEBUG1(printk (KERN_DEBUG "DC390: read residual bytes ... \n");)
185     		dstate = DC390_read8 (DMA_Status);
186     		residual = DC390_read8 (CtcReg_Low) | DC390_read8 (CtcReg_Mid) << 8 |
187     		  DC390_read8 (CtcReg_High) << 16;
188     		residual += DC390_read8 (Current_Fifo) & 0x1f;
189     	      } while (residual && ! (dstate & SCSI_INTERRUPT) && --ctr);
190     	    if (!ctr) printk (KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
191     	    /* residual =  ... */
192     	  }
193     	else
194     	    residual = 0;
195     	
196     	/* ??? */
197     	
198     	xferCnt = pSRB->SGToBeXferLen - residual;
199     	pSRB->SGBusAddr += xferCnt;
200     	pSRB->TotalXferredLen += xferCnt;
201     	pSRB->SGToBeXferLen = residual;
202     # ifdef DC390_DEBUG0
203     	printk (KERN_INFO "DC390: DMA: residual = %i, xfer = %i\n", 
204     		(unsigned int)residual, (unsigned int)xferCnt);
205     # endif
206     	
207     	DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
208         }
209       dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
210       return dstate;
211     };
212     #endif
213     
214     void __inline__
215     DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
216     {
217         PACB   pACB, pACB2;
218         PDCB   pDCB;
219         PSRB   pSRB;
220         UCHAR  sstatus=0;
221         UCHAR  phase;
222         void   (*stateV)( PACB, PSRB, PUCHAR );
223         UCHAR  istate, istatus;
224     #if DMA_INT
225         UCHAR  dstatus;
226     #endif
227         DC390_AFLAGS DC390_IFLAGS //DC390_DFLAGS
228     
229         pACB = (PACB)dev_id;
230         for (pACB2 = dc390_pACB_start; (pACB2 && pACB2 != pACB); pACB2 = pACB2->pNextACB);
231         if (!pACB2)
232         {
233     	printk ("DC390: IRQ called with foreign dev_id %p!\n", pACB);
234     	return;
235         }
236         
237         //DC390_LOCK_DRV;
238     
239         sstatus = DC390_read8 (Scsi_Status);
240         if( !(sstatus & INTERRUPT) )
241     	{ /*DC390_UNLOCK_DRV;*/ return; };
242     
243         DEBUG1(printk (KERN_DEBUG "sstatus=%02x,", sstatus);)
244     
245     #if DMA_INT
246         DC390_LOCK_IO;
247         DC390_LOCK_ACB;
248         dstatus = dc390_dma_intr (pACB);
249         DC390_UNLOCK_ACB;
250         DC390_UNLOCK_IO;
251     
252         DEBUG1(printk (KERN_DEBUG "dstatus=%02x,", dstatus);)
253         if (! (dstatus & SCSI_INTERRUPT))
254           {
255     	DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n");)
256     	//DC390_UNLOCK_DRV;
257     	return;
258           };
259     #else
260         //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
261         //dstatus = DC390_read8 (DMA_Status);
262         //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
263     #endif
264     
265         DC390_LOCK_IO;
266         DC390_LOCK_ACB;
267         //DC390_UNLOCK_DRV_NI; /* Allow _other_ CPUs to process IRQ (useful for shared IRQs) */
268     
269         istate = DC390_read8 (Intern_State);
270         istatus = DC390_read8 (INT_Status); /* This clears Scsi_Status, Intern_State and INT_Status ! */
271     
272         DEBUG1(printk (KERN_INFO "Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus);)
273         dc390_laststatus &= ~0x00ffffff;
274         dc390_laststatus |= /* dstatus<<24 | */ sstatus<<16 | istate<<8 | istatus;
275     
276         if (sstatus & ILLEGAL_OP_ERR)
277         {
278     	printk ("DC390: Illegal Operation detected (%08x)!\n", dc390_laststatus);
279     	dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
280         }
281     	
282         else if (istatus &  INVALID_CMD)
283         {
284     	printk ("DC390: Invalid Command detected (%08x)!\n", dc390_laststatus);
285     	dc390_InvalidCmd( pACB );
286     	goto unlock;
287         }
288     
289         if (istatus &  SCSI_RESET)
290         {
291     	dc390_ScsiRstDetect( pACB );
292     	goto unlock;
293         }
294     
295         if (istatus &  DISCONNECTED)
296         {
297     	dc390_Disconnect( pACB );
298     	goto unlock;
299         }
300     
301         if (istatus &  RESELECTED)
302         {
303     	dc390_Reselect( pACB );
304     	goto unlock;
305         }
306     
307         else if (istatus & (SELECTED | SEL_ATTENTION))
308         {
309     	printk (KERN_ERR "DC390: Target mode not supported!\n");
310     	goto unlock;
311         }
312     
313         if (istatus & (SUCCESSFUL_OP|SERVICE_REQUEST) )
314         {
315     	pDCB = pACB->pActiveDCB;
316     	if (!pDCB)
317     	{
318     		printk (KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
319     		goto unlock;
320     	};
321     	pSRB = pDCB->pActiveSRB;
322     	if( pDCB->DCBFlag & ABORT_DEV_ )
323     	  dc390_EnableMsgOut_Abort (pACB, pSRB);
324     
325     	phase = pSRB->ScsiPhase;
326     	DEBUG1(printk (KERN_INFO "DC390: [%i]%s(0) (%02x)\n", phase, dc390_p0_str[phase], sstatus);)
327     	stateV = (void *) dc390_phase0[phase];
328     	( *stateV )( pACB, pSRB, &sstatus );
329     
330     	pSRB->ScsiPhase = sstatus & 7;
331     	phase = (UCHAR) sstatus & 7;
332     	DEBUG1(printk (KERN_INFO "DC390: [%i]%s(1) (%02x)\n", phase, dc390_p1_str[phase], sstatus);)
333     	stateV = (void *) dc390_phase1[phase];
334     	( *stateV )( pACB, pSRB, &sstatus );
335     	goto unlock;
336         }
337     
338      unlock:
339         //DC390_LOCK_DRV_NI;
340         DC390_UNLOCK_ACB;
341         DC390_UNLOCK_IO;
342         //DC390_UNLOCK_DRV; /* Restore initial flags */
343     }
344     
345     void
346     do_DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
347     {
348         DEBUG1(printk (KERN_INFO "DC390: Irq (%i) caught: ", irq);)
349         /* Locking is done in DC390_Interrupt */
350         DC390_Interrupt(irq, dev_id, regs);
351         DEBUG1(printk (".. IRQ returned\n");)
352     }
353     
354     void
355     dc390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
356     {
357         UCHAR   sstatus;
358         PSGL    psgl;
359         UINT    ResidCnt, xferCnt;
360         UCHAR   dstate = 0;
361     
362         sstatus = *psstatus;
363     
364         if( !(pSRB->SRBState & SRB_XFERPAD) )
365         {
366     	if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR) )
367     	    pSRB->SRBStatus |= PARITY_ERROR;
368     
369     	if( sstatus & COUNT_2_ZERO )
370     	{
371     	    int ctr = 6000000; /* only try for about a second */
372     	    while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen );
373     	    if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
374     	    dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
375     	    pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
376     	    pSRB->SGIndex++;
377     	    if( pSRB->SGIndex < pSRB->SGcount )
378     	    {
379     		pSRB->pSegmentList++;
380     		psgl = pSRB->pSegmentList;
381     
382     		pSRB->SGBusAddr = virt_to_bus( psgl->address );
383     		pSRB->SGToBeXferLen = (ULONG) psgl->length;
384     	    }
385     	    else
386     		pSRB->SGToBeXferLen = 0;
387     	}
388     	else
389     	{
390     	    ResidCnt  = (UINT) DC390_read8 (Current_Fifo) & 0x1f;
391     	    ResidCnt |= (UINT) DC390_read8 (CtcReg_High) << 16;
392     	    ResidCnt |= (UINT) DC390_read8 (CtcReg_Mid) << 8; 
393     	    ResidCnt += (UINT) DC390_read8 (CtcReg_Low);
394     
395     	    xferCnt = pSRB->SGToBeXferLen - ResidCnt;
396     	    pSRB->SGBusAddr += xferCnt;
397     	    pSRB->TotalXferredLen += xferCnt;
398     	    pSRB->SGToBeXferLen = ResidCnt;
399     	}
400         }
401         if ((*psstatus & 7) != SCSI_DATA_OUT)
402         {
403     	    DC390_write8 (DMA_Cmd, WRITE_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
404     	    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
405         }	    
406     }
407     
408     void
409     dc390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
410     {
411         UCHAR   sstatus, residual, bval;
412         PSGL    psgl;
413         UINT    ResidCnt, i;
414         ULONG   xferCnt;
415         PUCHAR  ptr;
416     
417         sstatus = *psstatus;
418     
419         if( !(pSRB->SRBState & SRB_XFERPAD) )
420         {
421     	if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR))
422     	    pSRB->SRBStatus |= PARITY_ERROR;
423     
424     	if( sstatus & COUNT_2_ZERO )
425     	{
426     	    int ctr = 6000000; /* only try for about a second */
427     	    int dstate = 0;
428     	    while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen );
429     	    if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
430     	    if (!ctr) printk (KERN_CRIT "DC390: DataIn_0: DMA State: %i\n", dstate);
431     	    dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
432     	    DEBUG1(ResidCnt = ((ULONG) DC390_read8 (CtcReg_High) << 16)	
433     		+ ((ULONG) DC390_read8 (CtcReg_Mid) << 8)		
434     		+ ((ULONG) DC390_read8 (CtcReg_Low));)
435     	    DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%i,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen);)
436     
437     	    DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
438     
439     	    pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
440     	    pSRB->SGIndex++;
441     	    if( pSRB->SGIndex < pSRB->SGcount )
442     	    {
443     		pSRB->pSegmentList++;
444     		psgl = pSRB->pSegmentList;
445     
446     		pSRB->SGBusAddr = virt_to_bus( psgl->address );
447     		pSRB->SGToBeXferLen = (ULONG) psgl->length;
448     	    }
449     	    else
450     		pSRB->SGToBeXferLen = 0;
451     	}
452     	else	/* phase changed */
453     	{
454     	    residual = 0;
455     	    bval = DC390_read8 (Current_Fifo);
456     	    while( bval & 0x1f )
457     	    {
458     		DEBUG1(printk (KERN_DEBUG "Check for residuals,");)
459     		if( (bval & 0x1f) == 1 )
460     		{
461     		    for(i=0; i < 0x100; i++)
462     		    {
463     			bval = DC390_read8 (Current_Fifo);
464     			if( !(bval & 0x1f) )
465     			    goto din_1;
466     			else if( i == 0x0ff )
467     			{
468     			    residual = 1;   /* ;1 residual byte */
469     			    goto din_1;
470     			}
471     		    }
472     		}
473     		else
474     		    bval = DC390_read8 (Current_Fifo);
475     	    }
476     din_1:
477     	    DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_BLAST_CMD);
478     	    for (i = 0xa000; i; i--)
479     	    {
480     		bval = DC390_read8 (DMA_Status);
481     		if (bval & BLAST_COMPLETE)
482     		    break;
483     	    }
484     	    /* It seems a DMA Blast abort isn't that bad ... */
485     	    if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n");
486     	    //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
487     	    dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24;
488     
489     	    DEBUG1(printk (KERN_DEBUG "Blast: Read %i times DMA_Status %02x", 0xa000-i, bval);)
490     	    ResidCnt = (UINT) DC390_read8 (CtcReg_High);
491     	    ResidCnt <<= 8;
492     	    ResidCnt |= (UINT) DC390_read8 (CtcReg_Mid);
493     	    ResidCnt <<= 8;
494     	    ResidCnt |= (UINT) DC390_read8 (CtcReg_Low);
495     
496     	    xferCnt = pSRB->SGToBeXferLen - ResidCnt;
497     	    pSRB->SGBusAddr += xferCnt;
498     	    pSRB->TotalXferredLen += xferCnt;
499     	    pSRB->SGToBeXferLen = ResidCnt;
500     
501     	    if( residual )
502     	    {
503     		bval = DC390_read8 (ScsiFifo);	    /* get one residual byte */
504     		ptr = (PUCHAR) bus_to_virt( pSRB->SGBusAddr );
505     		*ptr = bval;
506     		pSRB->SGBusAddr++; xferCnt++;
507     		pSRB->TotalXferredLen++;
508     		pSRB->SGToBeXferLen--;
509     	    }
510     	    DEBUG1(printk (KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %li\n", xferCnt,
511     			   pSRB->TotalXferredLen, pSRB->SGToBeXferLen);)
512     
513     	}
514         }
515         if ((*psstatus & 7) != SCSI_DATA_IN)
516         {
517     	    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
518     	    DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
519         }	    
520     }
521     
522     static void
523     dc390_Command_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
524     {
525     }
526     
527     static void
528     dc390_Status_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
529     {
530     
531         pSRB->TargetStatus = DC390_read8 (ScsiFifo);
532         //udelay (1);
533         pSRB->EndMessage = DC390_read8 (ScsiFifo);	/* get message */
534     
535         *psstatus = SCSI_NOP0;
536         pSRB->SRBState = SRB_COMPLETED;
537         DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
538     }
539     
540     static void
541     dc390_MsgOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
542     {
543         if( pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT) )
544     	*psstatus = SCSI_NOP0;
545         //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
546     }
547     
548     
549     static void __inline__
550     dc390_reprog (PACB pACB, PDCB pDCB)
551     {
552       DC390_write8 (Sync_Period, pDCB->SyncPeriod);
553       DC390_write8 (Sync_Offset, pDCB->SyncOffset);
554       DC390_write8 (CtrlReg3, pDCB->CtrlR3);
555       DC390_write8 (CtrlReg4, pDCB->CtrlR4);
556       dc390_SetXferRate (pACB, pDCB);
557     };
558     
559     
560     #ifdef DC390_DEBUG0
561     static void
562     dc390_printMsg (UCHAR *MsgBuf, UCHAR len)
563     {
564       int i;
565       printk (" %02x", MsgBuf[0]);
566       for (i = 1; i < len; i++)
567         printk (" %02x", MsgBuf[i]);
568       printk ("\n");
569     };
570     #endif
571     
572     #define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
573     
574     /* reject_msg */
575     static void __inline__
576     dc390_MsgIn_reject (PACB pACB, PSRB pSRB)
577     {
578       pSRB->MsgOutBuf[0] = MESSAGE_REJECT;
579       pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
580       DEBUG0 (printk (KERN_INFO "DC390: Reject message\n");)
581     }
582     
583     /* abort command */
584     static void __inline__
585     dc390_EnableMsgOut_Abort ( PACB pACB, PSRB pSRB )
586     {
587         pSRB->MsgOutBuf[0] = ABORT; 
588         pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
589         pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
590     }
591     
592     static PSRB
593     dc390_MsgIn_QTag (PACB pACB, PDCB pDCB, UCHAR tag)
594     {
595       PSRB lastSRB = pDCB->pGoingLast;
596       PSRB pSRB = pDCB->pGoingSRB;
597     
598       if (pSRB)
599         {
600           for( ;pSRB ; )
601     	{
602     	  if (pSRB->TagNumber == tag) break;
603     	  if (pSRB == lastSRB) goto mingx0;
604     	  pSRB = pSRB->pNextSRB;
605     	}
606     
607           if( pDCB->DCBFlag & ABORT_DEV_ )
608     	{
609     	  pSRB->SRBState = SRB_ABORT_SENT;
610     	  dc390_EnableMsgOut_Abort( pACB, pSRB );
611     	}
612     
613           if( !(pSRB->SRBState & SRB_DISCONNECT) )
614     	goto  mingx0;
615     
616           pDCB->pActiveSRB = pSRB;
617           pSRB->SRBState = SRB_DATA_XFER;
618         }
619       else
620         {
621         mingx0:
622           pSRB = pACB->pTmpSRB;
623           pSRB->SRBState = SRB_UNEXPECT_RESEL;
624           pDCB->pActiveSRB = pSRB;
625           pSRB->MsgOutBuf[0] = ABORT_TAG;
626           pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
627         }
628       return pSRB;
629     }
630     
631     
632     /* set async transfer mode */
633     static void 
634     dc390_MsgIn_set_async (PACB pACB, PSRB pSRB)
635     {
636       PDCB pDCB = pSRB->pSRBDCB;
637       if (!(pSRB->SRBState & DO_SYNC_NEGO)) 
638         printk (KERN_INFO "DC390: Target %i initiates Non-Sync?\n", pDCB->TargetID);
639       pSRB->SRBState &= ~DO_SYNC_NEGO;
640       pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);
641       pDCB->SyncPeriod = 0;
642       pDCB->SyncOffset = 0;
643       //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
644       pDCB->CtrlR3 = FAST_CLK;	/* fast clock / normal scsi */
645       pDCB->CtrlR4 &= 0x3f;
646       pDCB->CtrlR4 |= pACB->glitch_cfg;	/* glitch eater */
647       dc390_reprog (pACB, pDCB);
648     }
649     
650     /* set sync transfer mode */
651     static void
652     dc390_MsgIn_set_sync (PACB pACB, PSRB pSRB)
653     {
654       UCHAR bval;
655       USHORT wval, wval1;
656       PDCB pDCB = pSRB->pSRBDCB;
657       UCHAR oldsyncperiod = pDCB->SyncPeriod;
658       UCHAR oldsyncoffset = pDCB->SyncOffset;
659       
660       if (!(pSRB->SRBState & DO_SYNC_NEGO))
661         {
662           printk (KERN_INFO "DC390: Target %i initiates Sync: %ins %i ... answer ...\n", 
663     	      pDCB->TargetID, pSRB->MsgInBuf[3]<<2, pSRB->MsgInBuf[4]);
664     
665           /* reject */
666           //dc390_MsgIn_reject (pACB, pSRB);
667           //return dc390_MsgIn_set_async (pACB, pSRB);
668     
669           /* Reply with corrected SDTR Message */
670           if (pSRB->MsgInBuf[4] > 15)
671     	{ 
672     	  printk (KERN_INFO "DC390: Lower Sync Offset to 15\n");
673     	  pSRB->MsgInBuf[4] = 15;
674     	}
675           if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod)
676     	{
677     	  printk (KERN_INFO "DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
678     	  pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
679     	};
680           memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
681           pSRB->MsgCnt = 5;
682           DC390_ENABLE_MSGOUT;
683         };
684     
685       pSRB->SRBState &= ~DO_SYNC_NEGO;
686       pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
687       pDCB->SyncOffset &= 0x0f0;
688       pDCB->SyncOffset |= pSRB->MsgInBuf[4];
689       pDCB->NegoPeriod = pSRB->MsgInBuf[3];
690     
691       wval = (USHORT) pSRB->MsgInBuf[3];
692       wval = wval << 2; wval -= 3; wval1 = wval / 25;	/* compute speed */
693       if( (wval1 * 25) != wval) wval1++;
694       bval = FAST_CLK+FAST_SCSI;	/* fast clock / fast scsi */
695     
696       pDCB->CtrlR4 &= 0x3f;		/* Glitch eater: 12ns less than normal */
697       if (pACB->glitch_cfg != NS_TO_GLITCH(0))
698         pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1));
699       else
700         pDCB->CtrlR4 |= NS_TO_GLITCH(0);
701       if (wval1 < 4) pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */
702     
703       if (wval1 >= 8)
704         {
705           wval1--;	/* Timing computation differs by 1 from FAST_SCSI */
706           bval = FAST_CLK;		/* fast clock / normal scsi */
707           pDCB->CtrlR4 |= pACB->glitch_cfg; 	/* glitch eater */
708         }
709     
710       pDCB->CtrlR3 = bval;
711       pDCB->SyncPeriod = (UCHAR)wval1;
712       
713       if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->TargetLUN == 0)
714         {
715           if (! (bval & FAST_SCSI)) wval1++;
716           printk (KERN_INFO "DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->TargetID, 
717     	      40/wval1, ((40%wval1)*10+wval1/2)/wval1, pDCB->SyncOffset & 0x0f);
718         }
719       
720       dc390_reprog (pACB, pDCB);
721     };
722     
723     
724     /* handle RESTORE_PTR */
725     static void 
726     dc390_restore_ptr (PACB pACB, PSRB pSRB)
727     {
728       PSGL psgl;
729       pSRB->TotalXferredLen = 0;
730       pSRB->SGIndex = 0;
731       if( pSRB->pcmd->use_sg )
732         {
733           pSRB->SGcount = (UCHAR) pSRB->pcmd->use_sg;
734           pSRB->pSegmentList = (PSGL) pSRB->pcmd->request_buffer;
735           psgl = pSRB->pSegmentList;
736           while (pSRB->TotalXferredLen + (ULONG) psgl->length < pSRB->Saved_Ptr)
737     	{
738     	  pSRB->TotalXferredLen += (ULONG) psgl->length;
739     	  pSRB->SGIndex++;
740     	  if( pSRB->SGIndex < pSRB->SGcount )
741     	    {
742     	      pSRB->pSegmentList++;
743     	      psgl = pSRB->pSegmentList;
744     	      
745     	      pSRB->SGBusAddr = virt_to_bus( psgl->address );
746     	      pSRB->SGToBeXferLen = (ULONG) psgl->length;
747     	    }
748     	  else
749     	    pSRB->SGToBeXferLen = 0;
750     	}
751           pSRB->SGToBeXferLen -= (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
752           pSRB->SGBusAddr += (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
753           printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n", pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr);
754         }
755         else if( pSRB->pcmd->request_buffer )
756         {
757     	pSRB->SGcount = 1;
758     	pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
759     	pSRB->Segmentx.address = (PUCHAR) pSRB->pcmd->request_buffer + pSRB->Saved_Ptr;
760     	pSRB->Segmentx.length = pSRB->pcmd->request_bufflen - pSRB->Saved_Ptr;
761     	printk (KERN_INFO "DC390: Pointer restored. Total %li, Bus %p\n",
762     		pSRB->Saved_Ptr, pSRB->Segmentx.address);
763         }
764          else
765            {
766     	 pSRB->SGcount = 0;
767     	 printk (KERN_INFO "DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n");
768            };
769     
770       pSRB->TotalXferredLen = pSRB->Saved_Ptr;
771     };
772     
773     
774     /* According to the docs, the AM53C974 reads the message and 
775      * generates a Succesful Operation IRQ before asserting ACK for
776      * the last byte (how does it know whether it's the last ?) */
777     /* The old code handled it in another way, indicating, that on
778      * every message byte an IRQ is generated and every byte has to
779      * be manually ACKed. Hmmm ?  (KG, 98/11/28) */
780     /* The old implementation was correct. Sigh! */
781     
782     /* Check if the message is complete */
783     static UCHAR __inline__
784     dc390_MsgIn_complete (UCHAR *msgbuf, UINT len)
785     { 
786       if (*msgbuf == EXTENDED_MESSAGE)
787       {
788     	if (len < 2) return 0;
789     	if (len < msgbuf[1] + 2) return 0;
790       }
791       else if (*msgbuf >= 0x20 && *msgbuf <= 0x2f) // two byte messages
792     	if (len < 2) return 0;
793       return 1;
794     }
795     
796     
797     
798     /* read and eval received messages */
799     void
800     dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
801     {
802         PDCB   pDCB = pACB->pActiveDCB;
803     
804         /* Read the msg */
805     
806         pSRB->MsgInBuf[pACB->MsgLen++] = DC390_read8 (ScsiFifo);
807         //pSRB->SRBState = 0;
808     
809         /* Msg complete ? */
810         if (dc390_MsgIn_complete (pSRB->MsgInBuf, pACB->MsgLen))
811           {
812     	DEBUG0 (printk (KERN_INFO "DC390: MsgIn:"); dc390_printMsg (pSRB->MsgInBuf, pACB->MsgLen);)
813     	/* Now eval the msg */
814     	switch (pSRB->MsgInBuf[0]) 
815     	  {
816     	  case DISCONNECT: 
817     	    pSRB->SRBState = SRB_DISCONNECT; break;
818     	    
819     	  case SIMPLE_QUEUE_TAG:
820     	  case HEAD_OF_QUEUE_TAG:
821     	  case ORDERED_QUEUE_TAG:
822     	    pSRB = dc390_MsgIn_QTag (pACB, pDCB, pSRB->MsgInBuf[1]);
823     	    break;
824     	    
825     	  case MESSAGE_REJECT: 
826     	    DC390_write8 (ScsiCmd, RESET_ATN_CMD);
827     	    pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
828     	    if( pSRB->SRBState & DO_SYNC_NEGO)
829     	      dc390_MsgIn_set_async (pACB, pSRB);
830     	    break;
831     	    
832     	  case EXTENDED_MESSAGE:
833     	    /* reject every extended msg but SDTR */
834     	    if (pSRB->MsgInBuf[1] != 3 || pSRB->MsgInBuf[2] != EXTENDED_SDTR)
835     	      dc390_MsgIn_reject (pACB, pSRB);
836     	    else
837     	      {
838     		if (pSRB->MsgInBuf[3] == 0 || pSRB->MsgInBuf[4] == 0)
839     		  dc390_MsgIn_set_async (pACB, pSRB);
840     		else
841     		  dc390_MsgIn_set_sync (pACB, pSRB);
842     	      };
843     	    
844     	    // nothing has to be done
845     	  case COMMAND_COMPLETE: break;
846     	    
847     	    // SAVE POINTER may be ignored as we have the PSRB associated with the
848     	    // scsi command. Thanks, Gerard, for pointing it out.
849     	  case SAVE_POINTERS: 
850     	    pSRB->Saved_Ptr = pSRB->TotalXferredLen;
851     	    break;
852     	    // The device might want to restart transfer with a RESTORE
853     	  case RESTORE_POINTERS:
854     	    DEBUG0(printk ("DC390: RESTORE POINTER message received ... try to handle\n");)
855     	    dc390_restore_ptr (pACB, pSRB);
856     	    break;
857     
858     	    // reject unknown messages
859     	  default: dc390_MsgIn_reject (pACB, pSRB);
860     	  }
861     	
862     	/* Clear counter and MsgIn state */
863     	pSRB->SRBState &= ~SRB_MSGIN;
864     	pACB->MsgLen = 0;
865           };
866     
867         *psstatus = SCSI_NOP0;
868         DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
869         //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
870     }
871     
872     
873     void
874     dc390_DataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir)
875     {
876         PSGL   psgl;
877         ULONG  lval;
878         PDCB   pDCB = pACB->pActiveDCB;
879     
880         if (pSRB == pACB->pTmpSRB)
881         {
882     	if (pDCB) printk (KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (%02i-%i)\n",
883     			  pDCB->TargetID, pDCB->TargetLUN);
884     	else printk (KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (DCB 0!)\n");
885     	dc390_EnableMsgOut_Abort (pACB, pSRB);
886     	if (pDCB) pDCB->DCBFlag |= ABORT_DEV;
887     	return;
888         }
889     
890         if( pSRB->SGIndex < pSRB->SGcount )
891         {
892     	DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir /* | DMA_INT */);
893     	if( !pSRB->SGToBeXferLen )
894     	{
895     	    psgl = pSRB->pSegmentList;
896     	    pSRB->SGBusAddr = virt_to_bus( psgl->address );
897     	    pSRB->SGToBeXferLen = (ULONG) psgl->length;
898     	    DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment.");)
899     	}
900     	lval = pSRB->SGToBeXferLen;
901     	DEBUG1(printk (KERN_DEBUG " DC390: Start transfer: %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr);)
902     	DC390_write8 (CtcReg_Low, (UCHAR) lval);
903     	lval >>= 8;
904     	DC390_write8 (CtcReg_Mid, (UCHAR) lval);
905     	lval >>= 8;
906     	DC390_write8 (CtcReg_High, (UCHAR) lval);
907     
908     	DC390_write32 (DMA_XferCnt, pSRB->SGToBeXferLen);
909     	DC390_write32 (DMA_XferAddr, pSRB->SGBusAddr);
910     
911     	//DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); /* | DMA_INT; */
912     	pSRB->SRBState = SRB_DATA_XFER;
913     
914     	DC390_write8 (ScsiCmd, DMA_COMMAND+INFO_XFER_CMD);
915     
916     	DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
917     	//DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);)
918     	//DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status));)
919     	//DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);)
920         }
921         else    /* xfer pad */
922         {
923     	if( pSRB->SGcount )
924     	{
925     	    pSRB->AdaptStatus = H_OVER_UNDER_RUN;
926     	    pSRB->SRBStatus |= OVER_RUN;
927     	    DEBUG0(printk (KERN_WARNING " DC390: Overrun -");)
928     	}
929     	DEBUG0(printk (KERN_WARNING " Clear transfer pad \n");)
930     	DC390_write8 (CtcReg_Low, 0);
931     	DC390_write8 (CtcReg_Mid, 0);
932     	DC390_write8 (CtcReg_High, 0);
933     
934     	pSRB->SRBState |= SRB_XFERPAD;
935     	DC390_write8 (ScsiCmd, DMA_COMMAND+XFER_PAD_BYTE);
936     /*
937     	DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT;
938     	DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
939     */
940         }
941     }
942     
943     
944     static void
945     dc390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
946     {
947         dc390_DataIO_Comm (pACB, pSRB, WRITE_DIRECTION);
948     }
949     
950     static void
951     dc390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
952     {
953         dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
954     }
955     
956     void
957     dc390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
958     {
959         PDCB   pDCB;
960         UCHAR  i, cnt;
961         PUCHAR ptr;
962     
963         DC390_write8 (ScsiCmd, RESET_ATN_CMD);
964         DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
965         if( !(pSRB->SRBFlag & AUTO_REQSENSE) )
966         {
967     	cnt = (UCHAR) pSRB->pcmd->cmd_len;
968     	ptr = (PUCHAR) pSRB->pcmd->cmnd;
969     	for(i=0; i < cnt; i++)
970     	    DC390_write8 (ScsiFifo, *(ptr++));
971         }
972         else
973         {
974     	UCHAR bval = 0;
975     	DC390_write8 (ScsiFifo, REQUEST_SENSE);
976     	pDCB = pACB->pActiveDCB;
977     	DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
978     	DC390_write8 (ScsiFifo, bval);
979     	DC390_write8 (ScsiFifo, bval);
980     	DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
981     	DC390_write8 (ScsiFifo, bval);
982     	DEBUG0(printk(KERN_DEBUG "DC390: AutoReqSense (CmndPhase)!\n");)
983         }
984         pSRB->SRBState = SRB_COMMAND;
985         DC390_write8 (ScsiCmd, INFO_XFER_CMD);
986     }
987     
988     static void
989     dc390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
990     {
991         DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
992         pSRB->SRBState = SRB_STATUS;
993         DC390_write8 (ScsiCmd, INITIATOR_CMD_CMPLTE);
994         //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
995     }
996     
997     void
998     dc390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
999     {
1000         UCHAR   bval, i, cnt;
1001         PUCHAR  ptr;
1002         PDCB    pDCB;
1003     
1004         DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1005         pDCB = pACB->pActiveDCB;
1006         if( !(pSRB->SRBState & SRB_MSGOUT) )
1007         {
1008     	cnt = pSRB->MsgCnt;
1009     	if( cnt )
1010     	{
1011     	    ptr = (PUCHAR) pSRB->MsgOutBuf;
1012     	    for(i=0; i < cnt; i++)
1013     		DC390_write8 (ScsiFifo, *(ptr++));
1014     	    pSRB->MsgCnt = 0;
1015     	    if( (pDCB->DCBFlag & ABORT_DEV_) &&
1016     		(pSRB->MsgOutBuf[0] == ABORT) )
1017     		pSRB->SRBState = SRB_ABORT_SENT;
1018     	}
1019     	else
1020     	{
1021     	    bval = ABORT;	/* ??? MSG_NOP */
1022     	    if( (pSRB->pcmd->cmnd[0] == INQUIRY ) ||
1023     		(pSRB->pcmd->cmnd[0] == REQUEST_SENSE) ||
1024     		(pSRB->SRBFlag & AUTO_REQSENSE) )
1025     	    {
1026     		if( pDCB->SyncMode & SYNC_ENABLE )
1027     		    goto  mop1;
1028     	    }
1029     	    DC390_write8 (ScsiFifo, bval);
1030     	}
1031     	DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1032         }
1033         else
1034         {
1035     mop1:
1036             printk (KERN_ERR "DC390: OLD Sync Nego code triggered! (%i %i)\n", pDCB->TargetID, pDCB->TargetLUN);
1037     	DC390_write8 (ScsiFifo, EXTENDED_MESSAGE);
1038     	DC390_write8 (ScsiFifo, 3);	/*    ;length of extended msg */
1039     	DC390_write8 (ScsiFifo, EXTENDED_SDTR);	/*    ; sync nego */
1040     	DC390_write8 (ScsiFifo, pDCB->NegoPeriod);
1041     	if (pDCB->SyncOffset & 0x0f)
1042     		    DC390_write8 (ScsiFifo, pDCB->SyncOffset);
1043     	else
1044     		    DC390_write8 (ScsiFifo, SYNC_NEGO_OFFSET);		    
1045     	pSRB->SRBState |= DO_SYNC_NEGO;
1046     	DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1047         }
1048     }
1049     
1050     static void
1051     dc390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
1052     {
1053         DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1054         if( !(pSRB->SRBState & SRB_MSGIN) )
1055         {
1056     	pSRB->SRBState &= ~SRB_DISCONNECT;
1057     	pSRB->SRBState |= SRB_MSGIN;
1058         }
1059         DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1060         //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1061     }
1062     
1063     static void
1064     dc390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
1065     {
1066     }
1067     
1068     static void
1069     dc390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus)
1070     {
1071     }
1072     
1073     
1074     static void
1075     dc390_SetXferRate( PACB pACB, PDCB pDCB )
1076     {
1077         UCHAR  bval, i, cnt;
1078         PDCB   ptr;
1079     
1080         if( !(pDCB->TargetLUN) )
1081         {
1082     	if( !pACB->scan_devices )
1083     	{
1084     	    ptr = pACB->pLinkDCB;
1085     	    cnt = pACB->DCBCnt;
1086     	    bval = pDCB->TargetID;
1087     	    for(i=0; i<cnt; i++)
1088     	    {
1089     		if( ptr->TargetID == bval )
1090     		{
1091     		    ptr->SyncPeriod = pDCB->SyncPeriod;
1092     		    ptr->SyncOffset = pDCB->SyncOffset;
1093     		    ptr->CtrlR3 = pDCB->CtrlR3;
1094     		    ptr->CtrlR4 = pDCB->CtrlR4;
1095     		    ptr->SyncMode = pDCB->SyncMode;
1096     		}
1097     		ptr = ptr->pNextDCB;
1098     	    }
1099     	}
1100         }
1101         return;
1102     }
1103     
1104     
1105     void
1106     dc390_Disconnect( PACB pACB )
1107     {
1108         PDCB   pDCB;
1109         PSRB   pSRB, psrb;
1110         UCHAR  i, cnt;
1111     
1112         DEBUG0(printk(KERN_INFO "DISC,");)
1113     
1114         if (!pACB->Connected) printk(KERN_ERR "DC390: Disconnect not-connected bus?\n");
1115         pACB->Connected = 0;
1116         pDCB = pACB->pActiveDCB;
1117         if (!pDCB)
1118          {
1119     	int j = 400;
1120     	DEBUG0(printk(KERN_ERR "ACB:%p->ActiveDCB:%p IOPort:%04x IRQ:%02x !\n",
1121     	       pACB, pDCB, pACB->IOPortBase, pACB->IRQLevel);)
1122     	while (--j) udelay (1000);
1123     	DC390_read8 (INT_Status);	/* Reset Pending INT */
1124     	DC390_write8 (ScsiCmd, EN_SEL_RESEL);
1125     	return;
1126          }
1127         DC390_write8 (ScsiCmd, EN_SEL_RESEL);
1128         pSRB = pDCB->pActiveSRB;
1129         pACB->pActiveDCB = 0;
1130         pSRB->ScsiPhase = SCSI_NOP0;
1131         if( pSRB->SRBState & SRB_UNEXPECT_RESEL )
1132         {
1133     	pSRB->SRBState = 0;
1134     	dc390_Waiting_process ( pACB );
1135         }
1136         else if( pSRB->SRBState & SRB_ABORT_SENT )
1137         {
1138     	pDCB->TagMask = 0;
1139     	pDCB->DCBFlag = 0;
1140     	cnt = pDCB->GoingSRBCnt;
1141     	pDCB->GoingSRBCnt = 0;
1142     	pSRB = pDCB->pGoingSRB;
1143     	for( i=0; i < cnt; i++)
1144     	{
1145     	    psrb = pSRB->pNextSRB;
1146     	    dc390_Free_insert (pACB, pSRB);
1147     	    pSRB = psrb;
1148     	}
1149     	pDCB->pGoingSRB = 0;
1150     	dc390_Query_to_Waiting (pACB);
1151     	dc390_Waiting_process (pACB);
1152         }
1153         else
1154         {
1155     	if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||
1156     	   !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) )
1157     	{	/* Selection time out */
1158     	    if( !(1/*pACB->scan_devices*/) )
1159     	    {
1160     		pSRB->SRBState = SRB_READY;
1161     		dc390_freetag (pDCB, pSRB);
1162     		dc390_Going_to_Waiting (pDCB, pSRB);
1163     		dc390_waiting_timer (pACB, HZ/5);
1164     	    }
1165     	    else
1166     	    {
1167     		pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
1168     		goto  disc1;
1169     	    }
1170     	}
1171     	else if( pSRB->SRBState & SRB_DISCONNECT )
1172     	{
1173     	    dc390_Waiting_process ( pACB );
1174     	}
1175     	else if( pSRB->SRBState & SRB_COMPLETED )
1176     	{
1177     disc1:
1178     	    dc390_freetag (pDCB, pSRB);
1179     	    pDCB->pActiveSRB = 0;
1180     	    pSRB->SRBState = SRB_FREE;
1181     	    dc390_SRBdone( pACB, pDCB, pSRB);
1182     	}
1183         }
1184         pACB->MsgLen = 0;
1185     }
1186     
1187     
1188     void
1189     dc390_Reselect( PACB pACB )
1190     {
1191         PDCB   pDCB;
1192         PSRB   pSRB;
1193         UCHAR  id, lun;
1194     
1195         DEBUG0(printk(KERN_INFO "RSEL,");)
1196         pACB->Connected = 1;
1197         pDCB = pACB->pActiveDCB;
1198         if( pDCB )
1199         {	/* Arbitration lost but Reselection won */
1200     	DEBUG0(printk ("DC390: (ActiveDCB != 0: Arb. lost but resel. won)!\n");)
1201     	pSRB = pDCB->pActiveSRB;
1202     	if( !( pACB->scan_devices ) )
1203     	{
1204     	    pSRB->SRBState = SRB_READY;
1205     	    dc390_freetag (pDCB, pSRB);
1206     	    dc390_Going_to_Waiting ( pDCB, pSRB);
1207     	    dc390_waiting_timer (pACB, HZ/5);
1208     	}
1209         }
1210         /* Get ID */
1211         lun = DC390_read8 (ScsiFifo);
1212         DEBUG0(printk ("Dev %02x,", lun);)
1213         if (!(lun & (1 << pACB->pScsiHost->this_id)))
1214           printk (KERN_ERR "DC390: Reselection must select host adapter: %02x!\n", lun);
1215         else
1216           lun ^= 1 << pACB->pScsiHost->this_id; /* Mask AdapterID */
1217         id = 0; while (lun >>= 1) id++;
1218         /* Get LUN */
1219         lun = DC390_read8 (ScsiFifo);
1220         if (!(lun & IDENTIFY_BASE)) printk (KERN_ERR "DC390: Resel: Expect identify message!\n");
1221         lun &= 7;
1222         DEBUG0(printk ("(%02i-%i),", id, lun);)
1223         pDCB = dc390_findDCB (pACB, id, lun);
1224         if (!pDCB)
1225         {
1226     	printk (KERN_ERR "DC390: Reselect from non existing device (%02i-%i)\n",
1227     		    id, lun);
1228     	return;
1229         }
1230         pACB->pActiveDCB = pDCB;
1231         /* TagQ: We expect a message soon, so never mind the exact SRB */
1232         if( pDCB->SyncMode & EN_TAG_QUEUEING )
1233         {
1234     	pSRB = pACB->pTmpSRB;
1235     	pDCB->pActiveSRB = pSRB;
1236         }
1237         else
1238         {
1239     	pSRB = pDCB->pActiveSRB;
1240     	if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) )
1241     	{
1242     	    pSRB= pACB->pTmpSRB;
1243     	    pSRB->SRBState = SRB_UNEXPECT_RESEL;
1244     	    printk (KERN_ERR "DC390: Reselect without outstanding cmnd (%02i-%i)\n",
1245     		    id, lun);
1246     	    pDCB->pActiveSRB = pSRB;
1247     	    dc390_EnableMsgOut_Abort ( pACB, pSRB );
1248     	}
1249     	else
1250     	{
1251     	    if( pDCB->DCBFlag & ABORT_DEV_ )
1252     	    {
1253     		pSRB->SRBState = SRB_ABORT_SENT;
1254     		printk (KERN_INFO "DC390: Reselect: Abort (%02i-%i)\n",
1255     			id, lun);
1256     		dc390_EnableMsgOut_Abort( pACB, pSRB );
1257     	    }
1258     	    else
1259     		pSRB->SRBState = SRB_DATA_XFER;
1260     	}
1261         }
1262     
1263         DEBUG1(printk (KERN_DEBUG "Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber);)
1264         pSRB->ScsiPhase = SCSI_NOP0;
1265         DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
1266         DC390_write8 (Sync_Period, pDCB->SyncPeriod);
1267         DC390_write8 (Sync_Offset, pDCB->SyncOffset);
1268         DC390_write8 (CtrlReg1, pDCB->CtrlR1);
1269         DC390_write8 (CtrlReg3, pDCB->CtrlR3);
1270         DC390_write8 (CtrlReg4, pDCB->CtrlR4);	/* ; Glitch eater */
1271         DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);	/* ;to release the /ACK signal */
1272     }
1273     
1274     
1275     static void 
1276     dc390_remove_dev (PACB pACB, PDCB pDCB)
1277     {
1278        PDCB pPrevDCB = pACB->pLinkDCB;
1279     
1280        if (pDCB->GoingSRBCnt > 1)
1281          {
1282     	DCBDEBUG(printk (KERN_INFO "DC390: Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n",
1283     		pDCB->TargetID, pDCB->TargetLUN, (int)pDCB, pDCB->GoingSRBCnt);)
1284     	return;
1285          };
1286        pACB->DCBmap[pDCB->TargetID] &= ~(1 << pDCB->TargetLUN);
1287        
1288        // The first one
1289        if (pDCB == pACB->pLinkDCB) 
1290        {
1291     	// The last one
1292     	if (pACB->pLastDCB == pDCB) {
1293     		pDCB->pNextDCB = 0; pACB->pLastDCB = 0;
1294     	}
1295     	pACB->pLinkDCB = pDCB->pNextDCB;
1296        }
1297        else
1298        {
1299     	while (pPrevDCB->pNextDCB != pDCB) pPrevDCB = pPrevDCB->pNextDCB;
1300     	pPrevDCB->pNextDCB = pDCB->pNextDCB;
1301     	if (pDCB == pACB->pLastDCB) pACB->pLastDCB = pPrevDCB;
1302        }
1303     
1304        DCBDEBUG(printk (KERN_INFO "DC390: Driver about to free DCB (ID %i, LUN %i): %p\n",
1305     	   pDCB->TargetID, pDCB->TargetLUN, pDCB);)
1306        if (pDCB == pACB->pActiveDCB) pACB->pActiveDCB = 0;
1307        if (pDCB == pACB->pLinkDCB) pACB->pLinkDCB = pDCB->pNextDCB;
1308        if (pDCB == pACB->pDCBRunRobin) pACB->pDCBRunRobin = pDCB->pNextDCB;
1309        kfree (pDCB); 
1310        pACB->DCBCnt--;
1311        /* pACB->DeviceCnt--; */
1312     };
1313     
1314     
1315     static UCHAR __inline__
1316     dc390_tagq_blacklist (char* name)
1317     {
1318        UCHAR i;
1319        for(i=0; i<BADDEVCNT; i++)
1320          if (memcmp (name, dc390_baddevname1[i], 28) == 0)
1321     	return 1;
1322        return 0;
1323     };
1324        
1325     
1326     static void 
1327     dc390_disc_tagq_set (PDCB pDCB, PSCSI_INQDATA ptr)
1328     {
1329        /* Check for SCSI format (ANSI and Response data format) */
1330        if ( (ptr->Vers & 0x07) >= 2 || (ptr->RDF & 0x0F) == 2 )
1331        {
1332     	if ( (ptr->Flags & SCSI_INQ_CMDQUEUE) &&
1333     	    (pDCB->DevMode & TAG_QUEUEING_) &&
1334     	    /* ((pDCB->DevType == TYPE_DISK) 
1335     		|| (pDCB->DevType == TYPE_MOD)) &&*/
1336     	    !dc390_tagq_blacklist (((char*)ptr)+8) )
1337     	  {
1338     	     if (pDCB->MaxCommand ==1) pDCB->MaxCommand = pDCB->pDCBACB->TagMaxNum;
1339     	     pDCB->SyncMode |= EN_TAG_QUEUEING /* | EN_ATN_STOP */;
1340     	     //pDCB->TagMask = 0;
1341     	  }
1342     	else
1343     	     pDCB->MaxCommand = 1;
1344          }
1345     };
1346     
1347     
1348     static void 
1349     dc390_add_dev (PACB pACB, PDCB pDCB, PSCSI_INQDATA ptr)
1350     {
1351        UCHAR bval1 = ptr->DevType & SCSI_DEVTYPE;
1352        pDCB->DevType = bval1;
1353        /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
1354     	dc390_disc_tagq_set (pDCB, ptr);
1355     };
1356     
1357     
1358     void
1359     dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
1360     {
1361         UCHAR  bval, status, i, DCB_removed;
1362         PSCSICMD pcmd;
1363         PSCSI_INQDATA  ptr;
1364         PSGL   ptr2;
1365         ULONG  swlval;
1366     
1367         pcmd = pSRB->pcmd; DCB_removed = 0;
1368         status = pSRB->TargetStatus;
1369         ptr = (PSCSI_INQDATA) (pcmd->request_buffer);
1370         if( pcmd->use_sg )
1371     	ptr = (PSCSI_INQDATA) (((PSGL) ptr)->address);
1372     	
1373         DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,
1374     		pSRB, pcmd->pid);)
1375         if(pSRB->SRBFlag & AUTO_REQSENSE)
1376         {	/* Last command was a Request Sense */
1377     	pSRB->SRBFlag &= ~AUTO_REQSENSE;
1378     	pSRB->AdaptStatus = 0;
1379     	pSRB->TargetStatus = CHECK_CONDITION << 1;
1380     #ifdef DC390_REMOVABLEDEBUG
1381     	switch (pcmd->sense_buffer[2] & 0x0f)
1382     	{	    
1383     	 case NOT_READY: printk (KERN_INFO "DC390: ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1384     				 pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
1385     				 status, pACB->scan_devices); break;
1386     	 case UNIT_ATTENTION: printk (KERN_INFO "DC390: ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1387     				      pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
1388     				      status, pACB->scan_devices); break;
1389     	 case ILLEGAL_REQUEST: printk (KERN_INFO "DC390: ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1390     				       pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
1391     				       status, pACB->scan_devices); break;
1392     	 case MEDIUM_ERROR: printk (KERN_INFO "DC390: ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1393     				    pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
1394     				    status, pACB->scan_devices); break;
1395     	 case HARDWARE_ERROR: printk (KERN_INFO "DC390: ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1396     				      pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
1397     				      status, pACB->scan_devices); break;
1398     	}
1399     #endif
1400     	//pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status);
1401     	if (status == (CHECK_CONDITION << 1))
1402     	{
1403     	    pcmd->result = MK_RES_LNX(0,DID_BAD_TARGET,0,/*CHECK_CONDITION*/0);
1404     	    goto ckc_e;
1405     	}
1406     	if(pSRB->RetryCnt == 0)
1407     	{
1408     	    //(UINT)(pSRB->pcmd->cmnd[0]) = pSRB->Segment0[0];
1409     	    pSRB->TotalXferredLen = pSRB->SavedTotXLen;
1410     	    if( (pSRB->TotalXferredLen) &&
1411     		(pSRB->TotalXferredLen >= pcmd->underflow) )
1412     		  SET_RES_DID(pcmd->result,DID_OK)
1413     	    else
1414     		  pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
1415     		  REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB->pcmd->cmnd[0],
1416     			(UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);)
1417     	    goto ckc_e;
1418     	}
1419     	else /* Retry */
1420     	{
1421     	    pSRB->RetryCnt--;
1422     	    pSRB->AdaptStatus = 0;
1423     	    pSRB->TargetStatus = 0;
1424     	    //*((PUINT) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
1425     	    //*((PUINT) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];
1426     	    /* Don't retry on TEST_UNIT_READY */
1427     	    if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */)
1428     	    {
1429     		pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
1430     		REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],
1431     		       (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);)
1432     		goto ckc_e;
1433     	    }
1434     	    SET_RES_DRV(pcmd->result,DRIVER_SENSE);
1435     	    pSRB->SGcount	 = (UCHAR) pSRB->SavedSGCount;
1436     	    //pSRB->ScsiCmdLen	 = (UCHAR) (pSRB->Segment1[0] >> 8);
1437     	    DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->target, pcmd->lun);)
1438     	    pSRB->SGIndex = 0;
1439     	    pSRB->TotalXferredLen = 0;
1440     	    pSRB->SGToBeXferLen = 0;
1441     	    if( pcmd->use_sg )
1442     		pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
1443     	    else if( pcmd->request_buffer )
1444     	    {
1445     		pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
1446     		pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
1447     		pSRB->Segmentx.length = pcmd->request_bufflen;
1448     	    }
1449     	    if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) {
1450     		dc390_Going_to_Waiting ( pDCB, pSRB );
1451     		dc390_waiting_timer (pACB, HZ/5);
1452     	    }
1453     	    return;
1454     	}
1455         }
1456         if( status )
1457         {
1458     	if( status_byte(status) == CHECK_CONDITION )
1459     	{
1460     	    REMOVABLEDEBUG(printk (KERN_INFO "DC390: Check_Condition (Cmd %02x, Id %02x, LUN %02x)\n",
1461     		    pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN);)
1462     	    if( (pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen) )
1463     	    {
1464     		bval = pSRB->SGcount;
1465     		swlval = 0;
1466     		ptr2 = pSRB->pSegmentList;
1467     		for( i=pSRB->SGIndex; i < bval; i++)
1468     		{
1469     		    swlval += ptr2->length;
1470     		    ptr2++;
1471     		}
1472     		REMOVABLEDEBUG(printk(KERN_INFO "XferredLen=%08x,NotXferLen=%08x\n",
1473     			(UINT) pSRB->TotalXferredLen, (UINT) swlval);)
1474     	    }
1475     	    dc390_RequestSense( pACB, pDCB, pSRB );
1476     	    return;
1477     	}
1478     	else if( status_byte(status) == QUEUE_FULL )
1479     	{
1480     	    bval = (UCHAR) pDCB->GoingSRBCnt;
1481     	    bval--;
1482     	    pDCB->MaxCommand = bval;
1483     	    dc390_freetag (pDCB, pSRB);
1484     	    dc390_Going_to_Waiting ( pDCB, pSRB );
1485     	    dc390_waiting_timer (pACB, HZ/5);
1486     	    pSRB->AdaptStatus = 0;
1487     	    pSRB->TargetStatus = 0;
1488     	    return;
1489     	}
1490     	else if(status == SCSI_STAT_SEL_TIMEOUT)
1491     	{
1492     	    pSRB->AdaptStatus = H_SEL_TIMEOUT;
1493     	    pSRB->TargetStatus = 0;
1494     	    pcmd->result = MK_RES(0,DID_NO_CONNECT,0,0);
1495     	    /* Devices are removed below ... */
1496     	}
1497     	else if (status_byte(status) == BUSY && 
1498     		 (pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) &&
1499     		 pACB->scan_devices)
1500     	{
1501     	    pSRB->AdaptStatus = 0;
1502     	    pSRB->TargetStatus = status;
1503     	    pcmd->result = MK_RES(0,0,pSRB->EndMessage,/*status*/0);
1504     	}
1505     	else
1506     	{   /* Another error */
1507     	    pSRB->AdaptStatus = 0;
1508     	    if( pSRB->RetryCnt )
1509     	    {	/* Retry */
1510     		//printk ("DC390: retry\n");
1511     		pSRB->RetryCnt--;
1512     		pSRB->TargetStatus = 0;
1513     		pSRB->SGIndex = 0;
1514     		pSRB->TotalXferredLen = 0;
1515     		pSRB->SGToBeXferLen = 0;
1516     		if( pcmd->use_sg )
1517     		    pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
1518     		else if( pcmd->request_buffer )
1519     		{
1520     		    pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
1521     		    pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
1522     		    pSRB->Segmentx.length = pcmd->request_bufflen;
1523     		}
1524     		if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) {
1525     		    dc390_Going_to_Waiting ( pDCB, pSRB );
1526     		    dc390_waiting_timer (pACB, HZ/5);
1527     		}
1528           		return;
1529     	    }
1530     	    else
1531     	    {	/* Report error */
1532     	      //pcmd->result = MK_RES(0, DID_ERROR, pSRB->EndMessage, status);
1533     	      SET_RES_DID(pcmd->result,DID_ERROR);
1534     	      SET_RES_MSG(pcmd->result,pSRB->EndMessage);
1535     	      SET_RES_TARGET(pcmd->result,status);
1536     	    }
1537     	}
1538         }
1539         else
1540         {	/*  Target status == 0 */
1541     	status = pSRB->AdaptStatus;
1542     	if(status & H_OVER_UNDER_RUN)
1543     	{
1544     	    pSRB->TargetStatus = 0;
1545     	    SET_RES_DID(pcmd->result,DID_OK);
1546     	    SET_RES_MSG(pcmd->result,pSRB->EndMessage);
1547     	}
1548     	else if( pSRB->SRBStatus & PARITY_ERROR)
1549     	{
1550     	    //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0);
1551     	    SET_RES_DID(pcmd->result,DID_PARITY);
1552     	    SET_RES_MSG(pcmd->result,pSRB->EndMessage);
1553     	}
1554     	else		       /* No error */
1555     	{
1556     	    pSRB->AdaptStatus = 0;
1557     	    pSRB->TargetStatus = 0;
1558     	    SET_RES_DID(pcmd->result,DID_OK);
1559     	}
1560         }
1561         if ((pcmd->result & RES_DID) == 0 &&
1562     	pcmd->cmnd[0] == INQUIRY && 
1563     	pcmd->cmnd[2] == 0 &&
1564     	pcmd->request_bufflen >= 8 &&
1565     	ptr &&
1566     	(ptr->Vers & 0x07) >= 2)
1567     	    pDCB->Inquiry7 = ptr->Flags;
1568     
1569     ckc_e:
1570         if( pACB->scan_devices )
1571         {
1572     	if( pcmd->cmnd[0] == TEST_UNIT_READY ||
1573     	    pcmd->cmnd[0] == INQUIRY)
1574     	{
1575     #ifdef DC390_DEBUG0
1576     	    printk (KERN_INFO "DC390: %s: result: %08x", 
1577     		    (pcmd->cmnd[0] == INQUIRY? "INQUIRY": "TEST_UNIT_READY"),
1578     		    pcmd->result);
1579     	    if (pcmd->result & (DRIVER_SENSE << 24)) printk (" (sense: %02x %02x %02x %02x)\n",
1580     				   pcmd->sense_buffer[0], pcmd->sense_buffer[1],
1581     				   pcmd->sense_buffer[2], pcmd->sense_buffer[3]);
1582     	    else printk ("\n");
1583     #endif
1584     	    if( (host_byte(pcmd->result) != DID_OK && !(status_byte(pcmd->result) & CHECK_CONDITION) && !(status_byte(pcmd->result) & BUSY)) ||
1585     	       ((driver_byte(pcmd->result) & DRIVER_SENSE) && (pcmd->sense_buffer[0] & 0x70) == 0x70 &&
1586     		(pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || host_byte(pcmd->result) & DID_ERROR )
1587     	    {
1588     	       /* device not present: remove */ 
1589     	       //dc390_Going_remove (pDCB, pSRB);
1590     	       dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
1591     	       
1592     	       if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&
1593     		  ((pcmd->lun == 0) || (pcmd->lun == pACB->pScsiHost->max_lun - 1)) )
1594     		 pACB->scan_devices = 0;
1595     	    }
1596     	    else
1597     	    {
1598     	        /* device present: add */
1599     		if( (pcmd->target == pACB->pScsiHost->max_id - 1) && 
1600     		    (pcmd->lun == pACB->pScsiHost->max_lun - 1) )
1601     		    pACB->scan_devices = END_SCAN ;
1602     	        /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */
1603     	    }
1604     	}
1605         }
1606        
1607         //if( pSRB->pcmd->cmnd[0] == INQUIRY && 
1608         //  (host_byte(pcmd->result) == DID_OK || status_byte(pcmd->result) & CHECK_CONDITION) )
1609         if( pcmd->cmnd[0] == INQUIRY && 
1610     	(pcmd->result == (DID_OK << 16) || status_byte(pcmd->result) & CHECK_CONDITION) )
1611          {
1612     	if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV && !DCB_removed)
1613     	  {
1614     	     //printk ("DC390: Type = nodev! (%02i-%i)\n", pcmd->target, pcmd->lun);
1615     	     /* device not present: remove */
1616     	     //dc390_Going_remove (pDCB, pSRB);
1617     	     dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
1618     	  }
1619     	else
1620     	  {
1621     	     /* device found: add */ 
1622     	     dc390_add_dev (pACB, pDCB, ptr);
1623     	     if (pACB->scan_devices) pACB->DeviceCnt++;
1624     	  }
1625     	if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&
1626     	    (pcmd->lun == pACB->pScsiHost->max_lun - 1) )
1627     	  pACB->scan_devices = 0;
1628          };
1629     
1630     #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,30)
1631         pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
1632     #endif
1633     
1634         if (!DCB_removed) dc390_Going_remove (pDCB, pSRB);
1635         /* Add to free list */
1636         dc390_Free_insert (pACB, pSRB);
1637     
1638         DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->pid);)
1639         DC390_UNLOCK_ACB_NI;
1640         pcmd->scsi_done (pcmd);
1641         DC390_LOCK_ACB_NI;
1642     
1643         dc390_Query_to_Waiting (pACB);
1644         dc390_Waiting_process (pACB);
1645         return;
1646     }
1647     
1648     
1649     /* Remove all SRBs from Going list and inform midlevel */
1650     void
1651     dc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd )
1652     {
1653         PDCB   pDCB, pdcb;
1654         PSRB   psrb, psrb2;
1655         UCHAR  i;
1656         PSCSICMD pcmd;
1657     
1658         pDCB = pACB->pLinkDCB;
1659         pdcb = pDCB;
1660         if (! pdcb) return;
1661         do
1662         {
1663     	psrb = pdcb->pGoingSRB;
1664     	for( i=0; i<pdcb->GoingSRBCnt; i++)
1665     	{
1666     	    psrb2 = psrb->pNextSRB;
1667     	    pcmd = psrb->pcmd;
1668     	    dc390_Free_insert (pACB, psrb);
1669     #ifndef USE_NEW_EH
1670     	    /* New EH will crash on being given timed out cmnds */
1671     	    if (pcmd == cmd)
1672     		pcmd->result = MK_RES(0,DID_ABORT,0,0);
1673     	    else
1674     		pcmd->result = MK_RES(0,DID_RESET,0,0);
1675     
1676     /*	    ReleaseSRB( pDCB, pSRB ); */
1677     
1678     	    DEBUG0(printk (KERN_DEBUG "DC390: DoingSRB_Done: done pid %li\n", pcmd->pid);)
1679     	    DC390_UNLOCK_ACB_NI;
1680     	    pcmd->scsi_done( pcmd );
1681     	    DC390_LOCK_ACB_NI;
1682     #endif	
1683     	    psrb  = psrb2;
1684     	}
1685     	pdcb->GoingSRBCnt = 0;;
1686     	pdcb->pGoingSRB = NULL;
1687     	pdcb->TagMask = 0;
1688     	pdcb = pdcb->pNextDCB;
1689         } while( pdcb != pDCB );
1690         dc390_Query_to_Waiting (pACB);
1691     }
1692     
1693     
1694     static void
1695     dc390_ResetSCSIBus( PACB pACB )
1696     {
1697         //DC390_write8 (ScsiCmd, RST_DEVICE_CMD);
1698         //udelay (250);
1699         //DC390_write8 (ScsiCmd, NOP_CMD);
1700     
1701         DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1702         DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1703         DC390_write8 (ScsiCmd, RST_SCSI_BUS_CMD);
1704         pACB->Connected = 0;
1705     
1706         return;
1707     }
1708     
1709     static void
1710     dc390_ScsiRstDetect( PACB pACB )
1711     {
1712         printk ("DC390: Rst_Detect: laststat = %08x\n", dc390_laststatus);
1713         //DEBUG0(printk(KERN_INFO "RST_DETECT,");)
1714     
1715         if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer);
1716         DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1717         /* Unlock before ? */
1718         /* delay half a second */
1719         udelay (1000);
1720         DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1721         pACB->pScsiHost->last_reset = jiffies + 5*HZ/2
1722     		    + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
1723         pACB->Connected = 0;
1724     
1725         if( pACB->ACBFlag & RESET_DEV )
1726     	pACB->ACBFlag |= RESET_DONE;
1727         else
1728         {   /* Reset was issued by sb else */
1729     	pACB->ACBFlag |= RESET_DETECT;
1730     
1731     	dc390_ResetDevParam( pACB );
1732     	dc390_DoingSRB_Done( pACB, 0 );
1733     	//dc390_RecoverSRB( pACB );
1734     	pACB->pActiveDCB = NULL;
1735     	pACB->ACBFlag = 0;
1736     	dc390_Waiting_process( pACB );
1737         }
1738         return;
1739     }
1740     
1741     
1742     static void __inline__
1743     dc390_RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB )
1744     {
1745         PSCSICMD  pcmd;
1746     
1747         REMOVABLEDEBUG(printk (KERN_INFO "DC390: RequestSense (Cmd %02x, Id %02x, LUN %02x)\n",
1748     	    pSRB->pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN);)
1749     
1750         pSRB->SRBFlag |= AUTO_REQSENSE;
1751         //pSRB->Segment0[0] = (UINT) pSRB->CmdBlock[0];
1752         //pSRB->Segment0[1] = (UINT) pSRB->CmdBlock[4];
1753         //pSRB->Segment1[0] = ((UINT)(pSRB->pcmd->cmd_len) << 8) + pSRB->SGcount;
1754         //pSRB->Segment1[1] = pSRB->TotalXferredLen;
1755         pSRB->SavedSGCount = pSRB->SGcount;
1756         pSRB->SavedTotXLen = pSRB->TotalXferredLen;
1757         pSRB->AdaptStatus = 0;
1758         pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */
1759     
1760         pcmd = pSRB->pcmd;
1761     
1762         pSRB->Segmentx.address = (PUCHAR) &(pcmd->sense_buffer);
1763         pSRB->Segmentx.length = sizeof(pcmd->sense_buffer);
1764         pSRB->pSegmentList = &pSRB->Segmentx;
1765         pSRB->SGcount = 1;
1766         pSRB->SGIndex = 0;
1767     
1768         //pSRB->CmdBlock[0] = REQUEST_SENSE;
1769         //pSRB->CmdBlock[1] = pDCB->TargetLUN << 5;
1770         //(USHORT) pSRB->CmdBlock[2] = 0;
1771         //(USHORT) pSRB->CmdBlock[4] = sizeof(pcmd->sense_buffer);
1772         //pSRB->ScsiCmdLen = 6;
1773     
1774         pSRB->TotalXferredLen = 0;
1775         pSRB->SGToBeXferLen = 0;
1776         if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) {
1777     	dc390_Going_to_Waiting ( pDCB, pSRB );
1778     	dc390_waiting_timer (pACB, HZ/5);
1779         }
1780     }
1781     
1782     
1783     
1784     static void __inline__
1785     dc390_InvalidCmd( PACB pACB )
1786     {
1787         if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) )
1788     	DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1789     }
1790     
1791