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