예제 #1
0
static inline void ENABLE_IRQ(void)
{
	if (IS_A_TT())
		atari_enable_irq(IRQ_TT_MFP_SCSI);
	else
		atari_enable_irq(IRQ_MFP_FSCSI);
}
예제 #2
0
static int atari_startup_irq(unsigned int irq)
{
	m68k_irq_startup(irq);
	atari_turnon_irq(irq);
	atari_enable_irq(irq);
	return 0;
}
예제 #3
0
파일: ataints.c 프로젝트: 0-T-0/ps4-linux
static unsigned int atari_irq_startup(struct irq_data *data)
{
	unsigned int irq = data->irq;

	m68k_irq_startup(data);
	atari_turnon_irq(irq);
	atari_enable_irq(irq);
	return 0;
}
예제 #4
0
static void atakeyb_rep( unsigned long ignore )

{
	kbd_pt_regs = NULL;

	/* Disable keyboard for the time we call handle_scancode(), else a race
	 * in the keyboard tty queue may happen */
	atari_disable_irq( IRQ_MFP_ACIA );
	del_timer( &atakeyb_rep_timer );

	/* A keyboard int may have come in before we disabled the irq, so
	 * double-check whether rep_scancode is still != 0 */
	if (rep_scancode) {
		atakeyb_rep_timer.expires = jiffies + key_repeat_rate;
		atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL;
		add_timer( &atakeyb_rep_timer );

		handle_scancode(rep_scancode);
	}

	atari_enable_irq( IRQ_MFP_ACIA );
}
예제 #5
0
파일: ataints.c 프로젝트: andreiw/mkunity
int atari_add_isr(unsigned long source, isrfunc isr, int type, void
		  *data, char *name)
{
	int vector;
	
	source &= ~IRQ_MACHSPEC;
	if (type < IRQ_TYPE_SLOW || type > IRQ_TYPE_PRIO) {
		printk ("atari_add_isr: Bad irq type %d requested from %s\n",
				type, name );
		return( 0 );
	}
	if (!IS_VALID_INTNO(source)) {
		printk ("atari_add_isr: Unknown irq %ld requested from %s\n",
				source, name );
		return( 0 );
	}
	vector = IRQ_SOURCE_TO_VECTOR(source);

	/*
	 * Check type/source combination: slow ints are (currently)
	 * only possible for MFP-interrupts.
	 */
	if (type == IRQ_TYPE_SLOW &&
		(source < STMFP_SOURCE_BASE || source >= SCC_SOURCE_BASE)) {
		printk ("atari_add_isr: Slow irq requested for non-MFP source %ld from %s\n",
				source, name );
		return( 0 );
	}
		
	if (vectors[vector] == bad_interrupt) {
		/* int has no handler yet */
		irq_handler[source].isr = isr;
		irq_handler[source].data = data;
		irq_param[source].type = type;
		irq_param[source].name = name;
		vectors[vector] =
			(type == IRQ_TYPE_SLOW) ? slow_handlers[source-STMFP_SOURCE_BASE] :
			(type == IRQ_TYPE_FAST) ? atari_fast_irq_handler :
									  atari_prio_irq_handler;
		/* If MFP int, also enable and umask it */
		atari_turnon_irq(source);
		atari_enable_irq(source);

		return 1;
	}
	else if (irq_param[source].type == type) {
		/* old handler is of same type -> handlers can be chained */
		isr_node_t *p;
		unsigned long flags;

		save_flags(flags);
		cli();

		if (irq_handler[source].isr != atari_call_isr_list) {
			/* Only one handler yet, make a node for this first one */
			p = new_isr_node();
			if (p == NULL) return 0;
			p->isr = irq_handler[source].isr;
			p->data = irq_handler[source].data;
			p->name = irq_param[source].name;
			p->next = NULL;

			irq_handler[source].isr = atari_call_isr_list;
			irq_handler[source].data = p;
			irq_param[source].name = "chained";
		}

		p = new_isr_node();
		if (p == NULL) return 0;
		p->isr = isr;
		p->data = data;
		p->name = name;
		/* new handlers are put in front of the queue */
		p->next = irq_handler[source].data;
		irq_handler[source].data = p;

		restore_flags(flags);
		return 1;
	}
	else {
		printk ("atari_add_isr: Irq %ld allocated by other type int (call from %s)\n",
				source, name );
		return( 0 );
	}
}
예제 #6
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;
}
예제 #7
0
파일: ataints.c 프로젝트: TitaniumBoy/lin
int atari_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
                      unsigned long flags, const char *devname, void *dev_id)
{
	int vector;
	unsigned long oflags = flags;

	/*
	 * The following is a hack to make some PCI card drivers work,
	 * which set the SA_SHIRQ flag.
	 */

	flags &= ~SA_SHIRQ;

	if (flags == SA_INTERRUPT) {
		printk ("%s: SA_INTERRUPT changed to IRQ_TYPE_SLOW for %s\n",
			__FUNCTION__, devname);
		flags = IRQ_TYPE_SLOW;
	}
	if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) {
		printk ("%s: Bad irq type 0x%lx <0x%lx> requested from %s\n",
		        __FUNCTION__, flags, oflags, devname);
		return -EINVAL;
	}
	if (!IS_VALID_INTNO(irq)) {
		printk ("%s: Unknown irq %d requested from %s\n",
		        __FUNCTION__, irq, devname);
		return -ENXIO;
	}
	vector = IRQ_SOURCE_TO_VECTOR(irq);

	/*
	 * Check type/source combination: slow ints are (currently)
	 * only possible for MFP-interrupts.
	 */
	if (flags == IRQ_TYPE_SLOW &&
		(irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE)) {
		printk ("%s: Slow irq requested for non-MFP source %d from %s\n",
		        __FUNCTION__, irq, devname);
		return -EINVAL;
	}
		
	if (vectors[vector] == bad_interrupt) {
		/* int has no handler yet */
		irq_handler[irq].handler = handler;
		irq_handler[irq].dev_id  = dev_id;
		irq_param[irq].flags   = flags;
		irq_param[irq].devname = devname;
		vectors[vector] =
			(flags == IRQ_TYPE_SLOW) ? slow_handlers[irq-STMFP_SOURCE_BASE] :
			(flags == IRQ_TYPE_FAST) ? atari_fast_irq_handler :
			                          atari_prio_irq_handler;
		/* If MFP int, also enable and umask it */
		atari_turnon_irq(irq);
		atari_enable_irq(irq);

		return 0;
	}
	else if (irq_param[irq].flags == flags) {
		/* old handler is of same type -> handlers can be chained */
		irq_node_t *node;
		unsigned long flags;

		save_flags(flags);
		cli();

		if (irq_handler[irq].handler != atari_call_irq_list) {
			/* Only one handler yet, make a node for this first one */
			if (!(node = new_irq_node()))
				return -ENOMEM;
			node->handler = irq_handler[irq].handler;
			node->dev_id  = irq_handler[irq].dev_id;
			node->devname = irq_param[irq].devname;
			node->next = NULL;

			irq_handler[irq].handler = atari_call_irq_list;
			irq_handler[irq].dev_id  = node;
			irq_param[irq].devname   = "chained";
		}

		if (!(node = new_irq_node()))
			return -ENOMEM;
		node->handler = handler;
		node->dev_id  = dev_id;
		node->devname = devname;
		/* new handlers are put in front of the queue */
		node->next = irq_handler[irq].dev_id;
		irq_handler[irq].dev_id = node;

		restore_flags(flags);
		return 0;
	} else {
		printk ("%s: Irq %d allocated by other type int (call from %s)\n",
		        __FUNCTION__, irq, devname);
		return -EBUSY;
	}
}
예제 #8
0
파일: ataints.c 프로젝트: 0-T-0/ps4-linux
static void atari_irq_enable(struct irq_data *data)
{
	atari_enable_irq(data->irq);
}