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