コード例 #1
0
VOID
DriverCleanup( struct DriverBase* AHIsubBase )
{
  struct EMU10kxBase* EMU10kxBase = (struct EMU10kxBase*) AHIsubBase;
  int i;

  ObtainSemaphore( &EMU10kxBase->camd.Semaphore );
  RemSemaphore( &EMU10kxBase->camd.Semaphore );
  ReleaseSemaphore( &EMU10kxBase->camd.Semaphore );

  for( i = 0; i < EMU10kxBase->cards_found; ++i )
  {
    emu10k1_irq_disable( &EMU10kxBase->driverdatas[ i ]->card,
			 INTE_MIDIRXENABLE );
    emu10k1_irq_disable( &EMU10kxBase->driverdatas[ i ]->card,
			 INTE_MIDITXENABLE );
    
    FreeDriverData( EMU10kxBase->driverdatas[ i ], AHIsubBase );
  }

  FreeVec( EMU10kxBase->driverdatas ); 
 
  CloseLibrary( OpenPciBase );
  CloseLibrary( (struct Library*) DOSBase );
}
コード例 #2
0
ファイル: cardmi.c プロジェクト: 3sOx/asuswrt-merlin
/* exist, send it up to IMIDI level.                            */
int emu10k1_mpuin_reset(struct emu10k1_card *card)
{
	struct emu10k1_mpuin *card_mpuin = card->mpuin;
	struct midi_queue *midiq;

	DPF(2, "emu10k1_mpuin_reset()\n");

	emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);

	while (card_mpuin->firstmidiq) {
		midiq = card_mpuin->firstmidiq;
		card_mpuin->firstmidiq = midiq->next;

		if (midiq->sizeLeft == midiq->length)
			emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGDATA, (unsigned long) midiq, 0);
		else
			emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);

		kfree(midiq);
	}

	card_mpuin->lastmidiq = NULL;
	card_mpuin->status &= ~FLAGS_MIDM_STARTED;

	return 0;
}
コード例 #3
0
VOID
CloseCAMDPort( struct Hook*         hook,
	       struct EMU10kxBase*  EMU10kxBase,
	       struct CloseMessage* msg )
{
  struct DriverBase*  AHIsubBase = (struct DriverBase*) EMU10kxBase;
  struct EMU10kxData* dd         = EMU10kxBase->driverdatas[ msg->PortNum ];

  emu10k1_irq_disable( &dd->card, INTE_MIDIRXENABLE );
  emu10k1_irq_disable( &dd->card, INTE_MIDITXENABLE );
  emu10k1_mpu_reset( &dd->card );
  
  ObtainSemaphore( &EMU10kxBase->semaphore );
  dd->camd_transmitfunc = NULL;
  dd->camd_receivefunc  = NULL;
  ReleaseSemaphore( &EMU10kxBase->semaphore );
}
コード例 #4
0
ULONG
OpenCAMDPort( struct Hook*        hook,
	      struct EMU10kxBase* EMU10kxBase,
	      struct OpenMessage* msg )
{
  struct DriverBase*  AHIsubBase = (struct DriverBase*) EMU10kxBase;
  struct EMU10kxData* dd;

  BOOL in_use;

//  KPrintF( "OpenCAMDPort(%ld,%ld)\n", msg->PortNum, msg->V40Mode );

  if( msg->PortNum >= EMU10kxBase->cards_found ||
      EMU10kxBase->driverdatas[ msg->PortNum ] == NULL )
  {
    Req( "No valid EMU10kxData for CAMD port %ld.", msg->PortNum );
    return FALSE;
  }

  dd = EMU10kxBase->driverdatas[ msg->PortNum ];
  
  ObtainSemaphore( &EMU10kxBase->semaphore );
  in_use = ( dd->camd_transmitfunc != NULL ||
	     dd->camd_receivefunc != NULL );
  if( !in_use )
  {
    dd->camd_v40          = msg->V40Mode;
    dd->camd_transmitfunc = msg->TransmitFunc;
    dd->camd_receivefunc  = msg->ReceiveFunc;
  }
  ReleaseSemaphore( &EMU10kxBase->semaphore );

  if( in_use )
  {
    return FALSE;
  }

  emu10k1_irq_disable( &dd->card, INTE_MIDIRXENABLE );
  emu10k1_irq_disable( &dd->card, INTE_MIDITXENABLE );
  emu10k1_mpu_reset( &dd->card );
  emu10k1_irq_enable( &dd->card, INTE_MIDIRXENABLE );

  return TRUE;
}
コード例 #5
0
ファイル: cardmi.c プロジェクト: 3sOx/asuswrt-merlin
int emu10k1_mpuin_close(struct emu10k1_card *card)
{
	struct emu10k1_mpuin *card_mpuin = card->mpuin;

	DPF(2, "emu10k1_mpuin_close()\n");

	/* Check if there are pending input SysEx buffers */
	if (card_mpuin->firstmidiq != NULL) {
		ERROR();
		return -1;
	}

	/* Disable RX interrupt */
	emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);

	emu10k1_mpu_release(card);

	card_mpuin->status |= FLAGS_AVAILABLE;	/* set */
	card_mpuin->status &= ~FLAGS_MIDM_STARTED;	/* clear */

	return 0;
}
コード例 #6
0
ファイル: cardmi.c プロジェクト: 3sOx/asuswrt-merlin
int emu10k1_mpuin_stop(struct emu10k1_card *card)
{
	struct emu10k1_mpuin *card_mpuin = card->mpuin;
	struct midi_queue *midiq;
	unsigned long flags;

	DPF(2, "emu10k1_mpuin_stop()\n");

	emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDIRXENABLE : INTE_MIDIRXENABLE);

	card_mpuin->status &= ~FLAGS_MIDM_STARTED;	/* clear */

	if (card_mpuin->firstmidiq) {
		spin_lock_irqsave(&card_mpuin->lock, flags);

		midiq = card_mpuin->firstmidiq;
		if (midiq != NULL) {
			if (midiq->sizeLeft == midiq->length)
				midiq = NULL;
			else {
				card_mpuin->firstmidiq = midiq->next;
				if (card_mpuin->firstmidiq == NULL)
					card_mpuin->lastmidiq = NULL;
			}
		}

		spin_unlock_irqrestore(&card_mpuin->lock, flags);

		if (midiq) {
			emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);
			kfree(midiq);
		}
	}

	return 0;
}
コード例 #7
0
ファイル: irqmgr.c プロジェクト: Antonio-Zhou/Linux-2.6.11
irqreturn_t emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	struct emu10k1_card *card = (struct emu10k1_card *) dev_id;
	u32 irqstatus, irqstatus_tmp;
	int handled = 0;

	DPD(4, "emu10k1_interrupt called, irq =  %u\n", irq);

	/*
	 ** NOTE :
	 ** We do a 'while loop' here cos on certain machines, with both
	 ** playback and recording going on at the same time, IRQs will
	 ** stop coming in after a while. Checking IPND indeed shows that
	 ** there are interrupts pending but the PIC says no IRQs pending.
	 ** I suspect that some boards need edge-triggered IRQs but are not
	 ** getting that condition if we don't completely clear the IPND
	 ** (make sure no more interrupts are pending).
	 ** - Eric
	 */

	while ((irqstatus = inl(card->iobase + IPR))) {
		DPD(4, "irq status %#x\n", irqstatus);

		irqstatus_tmp = irqstatus;

		if (irqstatus & IRQTYPE_TIMER) {
			emu10k1_timer_irqhandler(card);
			irqstatus &= ~IRQTYPE_TIMER;
		}

		if (irqstatus & IRQTYPE_DSP) {
			emu10k1_dsp_irqhandler(card);
			irqstatus &= ~IRQTYPE_DSP;
		}

		if (irqstatus & IRQTYPE_MPUIN) {
			emu10k1_mpuin_irqhandler(card);
			irqstatus &= ~IRQTYPE_MPUIN;
		}

		if (irqstatus & IRQTYPE_MPUOUT) {
			emu10k1_mpuout_irqhandler(card);
			irqstatus &= ~IRQTYPE_MPUOUT;
		}

		if (irqstatus & IPR_MUTE) {
			emu10k1_mute_irqhandler(card);
			irqstatus &=~IPR_MUTE;
		}

		if (irqstatus & IPR_VOLINCR) {
			emu10k1_volincr_irqhandler(card);
			irqstatus &=~IPR_VOLINCR;
		}

		if (irqstatus & IPR_VOLDECR) {
			emu10k1_voldecr_irqhandler(card);
			irqstatus &=~IPR_VOLDECR;
		}

		if (irqstatus){
			printk(KERN_ERR "emu10k1: Warning, unhandled interrupt: %#08x\n", irqstatus);
			//make sure any interrupts we don't handle are disabled:
			emu10k1_irq_disable(card, ~(INTE_MIDIRXENABLE | INTE_MIDITXENABLE | INTE_INTERVALTIMERENB |
						INTE_VOLDECRENABLE | INTE_VOLINCRENABLE | INTE_MUTEENABLE |
						INTE_FXDSPENABLE));
		}

		/* acknowledge interrupt */
		outl(irqstatus_tmp, card->iobase + IPR);
		handled = 1;
	}
	return IRQ_RETVAL(handled);
}