⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cardmo.c

📁 鼎力推荐!本程序是基于嵌入式LUNUX系统开发的源程序代码
💻 C
字号:
/*      ********************************************************************** *     cardmo.c - MIDI UART output HAL for emu10k1 driver  *     Copyright 1999, 2000 Creative Labs, Inc.  *  **********************************************************************  *  *     Date                 Author          Summary of changes  *     ----                 ------          ------------------  *     October 20, 1999     Bertrand Lee    base code release  *     November 2, 1999     Alan Cox        cleaned up *  **********************************************************************  *  *     This program is free software; you can redistribute it and/or  *     modify it under the terms of the GNU General Public License as  *     published by the Free Software Foundation; either version 2 of  *     the License, or (at your option) any later version.  *  *     This program is distributed in the hope that it will be useful,  *     but WITHOUT ANY WARRANTY; without even the implied warranty of  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *     GNU General Public License for more details.  *  *     You should have received a copy of the GNU General Public  *     License along with this program; if not, write to the Free  *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,  *     USA.  *  **********************************************************************  */#include <linux/slab.h>#include "hwaccess.h"#include "8010.h"#include "cardmo.h"#include "irqmgr.h"/* Installs the IRQ handler for the MPU out port               * * and initialize parameters                                    */int emu10k1_mpuout_open(struct emu10k1_card *card, struct midi_openinfo *openinfo){	struct emu10k1_mpuout *card_mpuout = card->mpuout;	DPF(2, "emu10k1_mpuout_open()\n");	if (!(card_mpuout->status & FLAGS_AVAILABLE))		return -1;	/* Copy open info and mark channel as in use */	card_mpuout->intr = 0;	card_mpuout->openinfo = *openinfo;	card_mpuout->status &= ~FLAGS_AVAILABLE;	card_mpuout->laststatus = 0x80;	card_mpuout->firstmidiq = NULL;	card_mpuout->lastmidiq = NULL;	emu10k1_mpu_reset(card);	emu10k1_mpu_acquire(card);	return 0;}int emu10k1_mpuout_close(struct emu10k1_card *card){	struct emu10k1_mpuout *card_mpuout = card->mpuout;	struct midi_queue *midiq;	struct midi_hdr *midihdr;	unsigned long flags;	DPF(2, "emu10k1_mpuout_close()\n");	emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);	spin_lock_irqsave(&card_mpuout->lock, flags);	while (card_mpuout->firstmidiq != NULL) {		midiq = card_mpuout->firstmidiq;		midihdr = (struct midi_hdr *) midiq->refdata;		card_mpuout->firstmidiq = midiq->next;		kfree(midihdr->data);		kfree(midihdr);		kfree(midiq);	}	card_mpuout->lastmidiq = NULL;	emu10k1_mpu_release(card);	card_mpuout->status |= FLAGS_AVAILABLE;	spin_unlock_irqrestore(&card_mpuout->lock, flags);	return 0;}/* If there isn't enough buffer space, reject Midi Buffer.     ** Otherwise, disable TX, create object to hold Midi            **  uffer, update buffer flags and other parameters             ** before enabling TX again.                                    */int emu10k1_mpuout_add_buffer(struct emu10k1_card *card, struct midi_hdr *midihdr){	struct emu10k1_mpuout *card_mpuout = card->mpuout;	struct midi_queue *midiq;	unsigned long flags;	DPF(2, "emu10k1_mpuout_add_buffer()\n");	if (card_mpuout->state == CARDMIDIOUT_STATE_SUSPEND)		return 0;	midihdr->flags |= MIDIBUF_INQUEUE;	midihdr->flags &= ~MIDIBUF_DONE;	if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_KERNEL)) == NULL) {		/* Message lost */		return -1;	}	midiq->next = NULL;	midiq->qtype = 1;	midiq->length = midihdr->bufferlength;	midiq->sizeLeft = midihdr->bufferlength;	midiq->midibyte = midihdr->data;	midiq->refdata = (unsigned long) midihdr;	spin_lock_irqsave(&card_mpuout->lock, flags);	if (card_mpuout->firstmidiq == NULL) {		card_mpuout->firstmidiq = midiq;		card_mpuout->lastmidiq = midiq;	} else {		(card_mpuout->lastmidiq)->next = midiq;		card_mpuout->lastmidiq = midiq;	}	card_mpuout->intr = 0;	emu10k1_irq_enable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);	spin_unlock_irqrestore(&card_mpuout->lock, flags);	return 0;}void emu10k1_mpuout_bh(unsigned long refdata){	struct emu10k1_card *card = (struct emu10k1_card *) refdata;	struct emu10k1_mpuout *card_mpuout = card->mpuout;	int cByteSent = 0;	struct midi_queue *midiq;	struct midi_queue *doneq = NULL;	unsigned long flags;	spin_lock_irqsave(&card_mpuout->lock, flags);	while (card_mpuout->firstmidiq != NULL) {		midiq = card_mpuout->firstmidiq;		while (cByteSent < 4 && midiq->sizeLeft) {			if (emu10k1_mpu_write_data(card, *midiq->midibyte) < 0) {				DPF(2, "emu10k1_mpuoutDpcCallback error!!\n");			} else {				++cByteSent;				--midiq->sizeLeft;				++midiq->midibyte;			}		}		if (midiq->sizeLeft == 0) {			if (doneq == NULL)				doneq = midiq;			card_mpuout->firstmidiq = midiq->next;		} else			break;	}	if (card_mpuout->firstmidiq == NULL)		card_mpuout->lastmidiq = NULL;	if (doneq != NULL) {		while (doneq != card_mpuout->firstmidiq) {			unsigned long callback_msg[3];			midiq = doneq;			doneq = midiq->next;			if (midiq->qtype) {				callback_msg[0] = 0;				callback_msg[1] = midiq->length;				callback_msg[2] = midiq->refdata;				emu10k1_midi_callback(ICARDMIDI_OUTLONGDATA, card_mpuout->openinfo.refdata, callback_msg);			} else if (((u8) midiq->refdata) < 0xF0 && ((u8) midiq->refdata) > 0x7F)				card_mpuout->laststatus = (u8) midiq->refdata;			kfree(midiq);		}	}	if ((card_mpuout->firstmidiq != NULL) || cByteSent) {		card_mpuout->intr = 0;		emu10k1_irq_enable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);	}	spin_unlock_irqrestore(&card_mpuout->lock, flags);	return;}int emu10k1_mpuout_irqhandler(struct emu10k1_card *card){	struct emu10k1_mpuout *card_mpuout = card->mpuout;	DPF(4, "emu10k1_mpuout_irqhandler\n");	card_mpuout->intr = 1;	emu10k1_irq_disable(card, card->is_audigy ? A_INTE_MIDITXENABLE : INTE_MIDITXENABLE);	tasklet_hi_schedule(&card_mpuout->tasklet);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -