Exemple #1
0
static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
{
	unsigned short csr = dregs->csr;

	dregs->csr &= ~CSR_DMA_ENABLE;


#ifdef SUN3_SCSI_DEBUG
	printk("scsi_intr csr %x\n", csr);
#endif

	if(csr & ~CSR_GOOD) {
		if(csr & CSR_DMA_BUSERR) {
			printk("scsi%d: bus error in dma\n", default_instance->host_no);
#ifdef SUN3_SCSI_DEBUG
			printk("scsi: residual %x count %x addr %p dmaaddr %x\n", 
			       dregs->fifo_count,
			       dregs->dma_count_lo | (dregs->dma_count_hi << 16),
			       sun3_dma_orig_addr,
			       dregs->dma_addr_lo | (dregs->dma_addr_hi << 16));
#endif
		}

		if(csr & CSR_DMA_CONFLICT) {
			printk("scsi%d: dma conflict\n", default_instance->host_no);
		}
	}

	if(csr & (CSR_SDB_INT | CSR_DMA_INT))
		NCR5380_intr(irq, dummy, fp);
}
Exemple #2
0
static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
{
	unsigned short csr = dregs->csr;
	int handled = 0;

#ifdef SUN3_SCSI_VME
	dregs->csr &= ~CSR_DMA_ENABLE;
#endif

	if(csr & ~CSR_GOOD) {
		if(csr & CSR_DMA_BUSERR) {
			printk("scsi%d: bus error in dma\n", default_instance->host_no);
		}

		if(csr & CSR_DMA_CONFLICT) {
			printk("scsi%d: dma conflict\n", default_instance->host_no);
		}
		handled = 1;
	}

	if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
		NCR5380_intr(irq, dummy);
		handled = 1;
	}

	return IRQ_RETVAL(handled);
}
Exemple #3
0
static irqreturn_t scsi_falcon_intr (int irq, void *dummy, struct pt_regs *fp)
{
#ifdef REAL_DMA
	int dma_stat;

	/* Turn off DMA and select sector counter register before
	 * accessing the status register (Atari recommendation!)
	 */
	st_dma.dma_mode_status = 0x90;
	dma_stat = st_dma.dma_mode_status;

	/* Bit 0 indicates some error in the DMA process... don't know
	 * what happened exactly (no further docu).
	 */
	if (!(dma_stat & 0x01)) {
		/* DMA error */
		printk(KERN_CRIT "SCSI DMA error near 0x%08lx!\n", SCSI_DMA_GETADR());
	}

	/* If the DMA was active, but now bit 1 is not clear, it is some
	 * other 5380 interrupt that finishes the DMA transfer. We have to
	 * calculate the number of residual bytes and give a warning if
	 * bytes are stuck in the ST-DMA fifo (there's no way to reach them!)
	 */
	if (atari_dma_active && (dma_stat & 0x02)) {
		unsigned long	transferred;

		transferred = SCSI_DMA_GETADR() - atari_dma_startaddr;
		/* The ST-DMA address is incremented in 2-byte steps, but the
		 * data are written only in 16-byte chunks. If the number of
		 * transferred bytes is not divisible by 16, the remainder is
		 * lost somewhere in outer space.
		 */
		if (transferred & 15)
			printk(KERN_ERR "SCSI DMA error: %ld bytes lost in "
			       "ST-DMA fifo\n", transferred & 15);

		atari_dma_residual = HOSTDATA_DMALEN - transferred;
		DMA_PRINTK("SCSI DMA: There are %ld residual bytes.\n",
			   atari_dma_residual);
	}
	else
		atari_dma_residual = 0;
	atari_dma_active = 0;

	if (atari_dma_orig_addr) {
		/* If the dribble buffer was used on a read operation, copy the DMA-ed
		 * data to the original destination address.
		 */
		memcpy(atari_dma_orig_addr, phys_to_virt(atari_dma_startaddr),
		       HOSTDATA_DMALEN - atari_dma_residual);
		atari_dma_orig_addr = NULL;
	}

#endif /* REAL_DMA */

	NCR5380_intr (0, 0, 0);
	return IRQ_HANDLED;
}
Exemple #4
0
static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
{
	unsigned short csr = dregs->csr;

	if(csr & ~CSR_GOOD) {
		if(csr & CSR_DMA_BUSERR) {
			printk("scsi%d: bus error in dma\n", default_instance->host_no);
		}

		if(csr & CSR_DMA_CONFLICT) {
			printk("scsi%d: dma conflict\n", default_instance->host_no);
		}
	}

	if(csr & (CSR_SDB_INT | CSR_DMA_INT))
		NCR5380_intr(irq, dummy, fp);
}
static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
{
	unsigned short csr = dregs->csr;
	int handled = 0;

	if(csr & ~CSR_GOOD) {
		if(csr & CSR_DMA_BUSERR) {
			printk("scsi%d: bus error in dma\n", default_instance->host_no);
		}

		if(csr & CSR_DMA_CONFLICT) {
			printk("scsi%d: dma conflict\n", default_instance->host_no);
		}
		handled = 1;
	}

	if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
		NCR5380_intr(irq, dummy, fp);
		handled = 1;
	}

	return IRQ_RETVAL(handled);
}
Exemple #6
0
static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
{
	unsigned short csr = dregs->csr;
	int handled = 0;

	if(csr & ~CSR_GOOD) {
		if(csr & CSR_DMA_BUSERR) {
;
		}

		if(csr & CSR_DMA_CONFLICT) {
;
		}
		handled = 1;
	}

	if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
		NCR5380_intr(irq, dummy);
		handled = 1;
	}

	return IRQ_RETVAL(handled);
}
Exemple #7
0
static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
{
	unsigned short csr = dregs->csr;
	int handled = 0;

	dregs->csr &= ~CSR_DMA_ENABLE;


#ifdef SUN3_SCSI_DEBUG
	printk("scsi_intr csr %x\n", csr);
#endif

	if(csr & ~CSR_GOOD) {
		if(csr & CSR_DMA_BUSERR) {
			printk("scsi%d: bus error in dma\n", default_instance->host_no);
#ifdef SUN3_SCSI_DEBUG
			printk("scsi: residual %x count %x addr %p dmaaddr %x\n",
			       dregs->fifo_count,
			       dregs->dma_count_lo | (dregs->dma_count_hi << 16),
			       sun3_dma_orig_addr,
			       dregs->dma_addr_lo | (dregs->dma_addr_hi << 16));
#endif
		}

		if(csr & CSR_DMA_CONFLICT) {
			printk("scsi%d: dma conflict\n", default_instance->host_no);
		}
		handled = 1;
	}

	if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
		NCR5380_intr(irq, dummy);
		handled = 1;
	}

	return IRQ_RETVAL(handled);
}
Exemple #8
0
static irqreturn_t scsi_tt_intr (int irq, void *dummy, struct pt_regs *fp)
{
#ifdef REAL_DMA
	int dma_stat;

	dma_stat = tt_scsi_dma.dma_ctrl;

	INT_PRINTK("scsi%d: NCR5380 interrupt, DMA status = %02x\n",
		   atari_scsi_host->host_no, dma_stat & 0xff);

	/* Look if it was the DMA that has interrupted: First possibility
	 * is that a bus error occurred...
	 */
	if (dma_stat & 0x80) {
		if (!scsi_dma_is_ignored_buserr( dma_stat )) {
			printk(KERN_ERR "SCSI DMA caused bus error near 0x%08lx\n",
			       SCSI_DMA_READ_P(dma_addr));
			printk(KERN_CRIT "SCSI DMA bus error -- bad DMA programming!");
		}
	}

	/* If the DMA is active but not finished, we have the case
	 * that some other 5380 interrupt occurred within the DMA transfer.
	 * This means we have residual bytes, if the desired end address
	 * is not yet reached. Maybe we have to fetch some bytes from the
	 * rest data register, too. The residual must be calculated from
	 * the address pointer, not the counter register, because only the
	 * addr reg counts bytes not yet written and pending in the rest
	 * data reg!
	 */
	if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
		atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P( dma_addr ) -
												atari_dma_startaddr);

		DMA_PRINTK("SCSI DMA: There are %ld residual bytes.\n",
			   atari_dma_residual);

		if ((signed int)atari_dma_residual < 0)
			atari_dma_residual = 0;
		if ((dma_stat & 1) == 0) {
			/* After read operations, we maybe have to
			   transport some rest bytes */
			atari_scsi_fetch_restbytes();
		}
		else {
			/* There seems to be a nasty bug in some SCSI-DMA/NCR
			   combinations: If a target disconnects while a write
			   operation is going on, the address register of the
			   DMA may be a few bytes farer than it actually read.
			   This is probably due to DMA prefetching and a delay
			   between DMA and NCR.  Experiments showed that the
			   dma_addr is 9 bytes to high, but this could vary.
			   The problem is, that the residual is thus calculated
			   wrong and the next transfer will start behind where
			   it should.  So we round up the residual to the next
			   multiple of a sector size, if it isn't already a
			   multiple and the originally expected transfer size
			   was.  The latter condition is there to ensure that
			   the correction is taken only for "real" data
			   transfers and not for, e.g., the parameters of some
			   other command.  These shouldn't disconnect anyway.
			   */
			if (atari_dma_residual & 0x1ff) {
				DMA_PRINTK("SCSI DMA: DMA bug corrected, "
					   "difference %ld bytes\n",
					   512 - (atari_dma_residual & 0x1ff));
				atari_dma_residual = (atari_dma_residual + 511) & ~0x1ff;
			}
		}
		tt_scsi_dma.dma_ctrl = 0;
	}

	/* If the DMA is finished, fetch the rest bytes and turn it off */
	if (dma_stat & 0x40) {
		atari_dma_residual = 0;
		if ((dma_stat & 1) == 0)
			atari_scsi_fetch_restbytes();
		tt_scsi_dma.dma_ctrl = 0;
	}

#endif /* REAL_DMA */
	
	NCR5380_intr (0, 0, 0);

#if 0
	/* To be sure the int is not masked */
	atari_enable_irq( IRQ_TT_MFP_SCSI );
#endif
	return IRQ_HANDLED;
}