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