* calculate all the residue data that not yet transfered 
* calculate all the residue data that not yet tranfered 
static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,		u16 *pscsi_status){	struct DeviceCtlBlk *dcb = srb->dcb;	u16 scsi_status = *pscsi_status;	u32 d_left_counter = 0;	dprintkdbg(DBG_0, "data_out_phase0: (pid#%li) <%02i-%i>\n",		srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun);	/*	 * KG: We need to drain the buffers before we draw any conclusions!	 * This means telling the DMA to push the rest into SCSI, telling	 * SCSI to push the rest to the bus.	 * However, the device might have been the one to stop us (phase	 * change), and the data in transit just needs to be accounted so	 * it can be retransmitted.)	 */	/* 	 * KG: Stop DMA engine pushing more data into the SCSI FIFO	 * If we need more data, the DMA SG list will be freshly set up, anyway	 */	dprintkdbg(DBG_PIO, "data_out_phase0: "		"DMA{fifcnt=0x%02x fifostat=0x%02x} "		"SCSI{fifocnt=0x%02x cnt=0x%06x status=0x%04x} total=0x%06x\n",		DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),		DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),		DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),		DC395x_read32(acb, TRM_S1040_SCSI_COUNTER), scsi_status,		srb->total_xfer_length);	DC395x_write8(acb, TRM_S1040_DMA_CONTROL, STOPDMAXFER | CLRXFIFO);	if (!(srb->state & SRB_XFERPAD)) {		if (scsi_status & PARITYERROR)			srb->status |= PARITY_ERROR;		/*		 * KG: Right, we can't just rely on the SCSI_COUNTER, because this		 * is the no of bytes it got from the DMA engine not the no it 		 * transferred successfully to the device. (And the difference could		 * be as much as the FIFO size, I guess ...)		 */		if (!(scsi_status & SCSIXFERDONE)) {			/*			 * when data transfer from DMA FIFO to SCSI FIFO			 * if there was some data left in SCSI FIFO			 */			d_left_counter =			    (u32)(DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) &				  0x1F);			if (dcb->sync_period & WIDE_SYNC)				d_left_counter <<= 1;			dprintkdbg(DBG_KG, "data_out_phase0: FIFO contains %i %s\n"				"SCSI{fifocnt=0x%02x cnt=0x%08x} "				"DMA{fifocnt=0x%04x cnt=0x%02x ctr=0x%08x}\n",				DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),				(dcb->sync_period & WIDE_SYNC) ? "words" : "bytes",				DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),				DC395x_read32(acb, TRM_S1040_SCSI_COUNTER),				DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),				DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),				DC395x_read32(acb, TRM_S1040_DMA_CXCNT));		}		/*		 * calculate all the residue data that not yet transfered		 * SCSI transfer counter + left in SCSI FIFO data		 *		 * .....TRM_S1040_SCSI_COUNTER (24bits)		 * The counter always decrement by one for every SCSI byte transfer.		 * .....TRM_S1040_SCSI_FIFOCNT ( 5bits)		 * The counter is SCSI FIFO offset counter (in units of bytes or! words)		 */		if (srb->total_xfer_length > DC395x_LASTPIO)			d_left_counter +=			    DC395x_read32(acb, TRM_S1040_SCSI_COUNTER);		/* Is this a good idea? */		/*clear_fifo(acb, "DOP1"); */		/* KG: What is this supposed to be useful for? WIDE padding stuff? */		if (d_left_counter == 1 && dcb->sync_period & WIDE_SYNC		    && srb->cmd->request_bufflen % 2) {			d_left_counter = 0;			dprintkl(KERN_INFO,				"data_out_phase0: Discard 1 byte (0x%02x)\n",				scsi_status);		}		/*		 * KG: Oops again. Same thinko as above: The SCSI might have been		 * faster than the DMA engine, so that it ran out of data.		 * In that case, we have to do just nothing! 		 * But: Why the interrupt: No phase change. No XFERCNT_2_ZERO. Or?		 */		/*		 * KG: This is nonsense: We have been WRITING data to the bus		 * If the SCSI engine has no bytes left, how should the DMA engine?		 */		if (d_left_counter == 0) {			srb->total_xfer_length = 0;		} else {			/*			 * if transfer not yet complete			 * there were some data residue in SCSI FIFO or			 * SCSI transfer counter not empty			 */			long oldxferred =			    srb->total_xfer_length - d_left_counter;			const int diff =			    (dcb->sync_period & WIDE_SYNC) ? 2 : 1;			sg_update_list(srb, d_left_counter);			/* KG: Most ugly hack! Apparently, this works around a chip bug */			if ((srb->segment_x[srb->sg_index].length ==			     diff && srb->cmd->use_sg)			    || ((oldxferred & ~PAGE_MASK) ==				(PAGE_SIZE - diff))			    ) {				dprintkl(KERN_INFO, "data_out_phase0: "					"Work around chip bug (%i)?\n", diff);				d_left_counter =				    srb->total_xfer_length - diff;				sg_update_list(srb, d_left_counter);				/*srb->total_xfer_length -= diff; */				/*srb->virt_addr += diff; */				/*if (srb->cmd->use_sg) */				/*      srb->sg_index++; */			}		}	}	if ((*pscsi_status & PHASEMASK) != PH_DATA_OUT) {		cleanup_after_transfer(acb, srb);	}}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/b4b08e581fac8e0ba9ae348bdc13246c9798c99e/dc395x.c/buggy/drivers/scsi/dc395x.c