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