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

📄 dv1394.c

📁 IEE1394 火线接口驱动 for linux
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif	return 0;}static int dv1394_release(struct inode *inode, struct file *file){	struct video_card *video = file_to_video_card(file);	/* OK to free the DMA buffer, no more mappings can exist */	do_dv1394_shutdown(video, 1);	/* clean up async I/O users */	dv1394_fasync(-1, file, 0);		/* give someone else a turn */	clear_bit(0, &video->open);	return 0;}/*** PROC_FS INTERFACE ******************************************************/#ifdef CONFIG_PROC_FSstatic LIST_HEAD(dv1394_procfs);struct dv1394_procfs_entry {	struct list_head list;    struct proc_dir_entry *procfs;	char name[32];	struct dv1394_procfs_entry *parent;};static spinlock_t dv1394_procfs_lock = SPIN_LOCK_UNLOCKED;static int dv1394_procfs_read( char *page, char **start, off_t off,			int count, int *eof, void *data){	struct video_card *video = (struct video_card*) data;	snprintf( page, count, 		"\format=%s\n\channel=%d\n\cip_n=%lu\n\cip_d=%lu\n\syt_offset=%u\n",		(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"),		video->channel,		video->cip_n, video->cip_d, video->syt_offset );	return strlen(page);}/* lifted from the stallion.c driver */#undef  TOLOWER#define TOLOWER(x)      ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))static unsigned long atol(char *str){	unsigned long   val;	int             base, c;	char            *sp;	val = 0;	sp = str;	if ((*sp == '0') && (*(sp+1) == 'x')) {		base = 16;		sp += 2;	} else if (*sp == '0') {		base = 8;		sp++;	} else {		base = 10;	}	for (; (*sp != 0); sp++) {		c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');		if ((c < 0) || (c >= base)) {			printk(KERN_ERR "dv1394: atol() invalid argument %s\n", str);			val = 0;			break;		}		val = (val * base) + c;	}	return(val);}static int dv1394_procfs_write( struct file *file,			const char *buffer, unsigned long count, void *data){	int len = 0;	char new_value[65];	char *pos;	struct video_card *video = (struct video_card*) data;		if (count > 64)		len = 64;	else		len = count;					if (copy_from_user( new_value, buffer, len))		return -EFAULT;		new_value[len] = 0;	pos = strchr(new_value, '=');	if (pos != NULL) {		int val_len = len - (pos-new_value) - 1;		char buf[65];		memset(buf, 0, 65);		strncpy(buf, pos+1, val_len);		if (buf[val_len-1] == '\n') buf[val_len-1] = 0;				if (strnicmp( new_value, "format", (pos-new_value)) == 0) {			if (strnicmp( buf, "NTSC", val_len) == 0)				video->pal_or_ntsc = DV1394_NTSC;			else if (strnicmp( buf, "PAL", val_len) == 0)				video->pal_or_ntsc = DV1394_PAL;						} else if (strnicmp( new_value, "cip_n", (pos-new_value)) == 0) {			video->cip_n = atol(buf);		} else if (strnicmp( new_value, "cip_d", (pos-new_value)) == 0) {			video->cip_d = atol(buf);		} else if (strnicmp( new_value, "syt_offset", (pos-new_value)) == 0) {			video->syt_offset = atol(buf);		} else if (strnicmp( new_value, "channel", (pos-new_value)) == 0) {			video->channel = atol(buf);		}	}		return len;}struct dv1394_procfs_entry *dv1394_procfs_find( char *name){	struct list_head *lh;	struct dv1394_procfs_entry *p;			spin_lock( &dv1394_procfs_lock);	if (!list_empty(&dv1394_procfs)) {		list_for_each(lh, &dv1394_procfs) {			p = list_entry(lh, struct dv1394_procfs_entry, list);			if (!strncmp(p->name, name, sizeof(p->name))) {				spin_unlock( &dv1394_procfs_lock);				return p;			}		}	}	spin_unlock( &dv1394_procfs_lock);	return NULL;}static int dv1394_procfs_add_entry(struct video_card *video){	char buf[32];	struct dv1394_procfs_entry *p;	struct dv1394_procfs_entry *parent;	p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL);	if (!p) {		printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n");		goto err;	}	memset(p, 0, sizeof(struct dv1394_procfs_entry));		snprintf(buf, sizeof(buf), "dv/host%d/%s", (video->id>>2),						(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"));			parent = dv1394_procfs_find(buf);	if (parent == NULL) {		printk(KERN_ERR "dv1394: unable to locate parent procfs of %s\n", buf);		goto err_free;	}		p->procfs = create_proc_entry( 						(video->mode == MODE_RECEIVE ? "in" : "out"),						0666, parent->procfs);	if (p->procfs == NULL) {		printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/%s/%s\n",			parent->name,			(video->mode == MODE_RECEIVE ? "in" : "out"));		goto err_free;	}		p->procfs->owner = THIS_MODULE;	p->procfs->data = video;	p->procfs->read_proc = dv1394_procfs_read;	p->procfs->write_proc = dv1394_procfs_write;	spin_lock( &dv1394_procfs_lock);	INIT_LIST_HEAD(&p->list);	list_add_tail(&p->list, &dv1394_procfs);	spin_unlock( &dv1394_procfs_lock);		return 0;	 err_free:	kfree(p); err:	return -ENOMEM;}static intdv1394_procfs_add_dir( char *name,					struct dv1394_procfs_entry *parent, 					struct dv1394_procfs_entry **out){	struct dv1394_procfs_entry *p;	p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL);	if (!p) {		printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n");		goto err;	}	memset(p, 0, sizeof(struct dv1394_procfs_entry));		if (parent == NULL) {		snprintf(p->name, sizeof(p->name), "%s", name);		p->procfs = proc_mkdir( name, ieee1394_procfs_entry);	} else {		snprintf(p->name, sizeof(p->name), "%s/%s", parent->name, name);		p->procfs = proc_mkdir( name, parent->procfs);	}	if (p->procfs == NULL) {		printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/%s\n", p->name);		goto err_free;	}	p->procfs->owner = THIS_MODULE;	p->parent = parent;	if (out != NULL) *out = p;	spin_lock( &dv1394_procfs_lock);	INIT_LIST_HEAD(&p->list);	list_add_tail(&p->list, &dv1394_procfs);	spin_unlock( &dv1394_procfs_lock);	return 0;	 err_free:	kfree(p); err:	return -ENOMEM;}void dv1394_procfs_del( char *name){	struct dv1394_procfs_entry *p = dv1394_procfs_find(name);	if (p != NULL) {		if (p->parent == NULL)			remove_proc_entry(p->name, ieee1394_procfs_entry);		else			remove_proc_entry(p->name, p->parent->procfs);				spin_lock( &dv1394_procfs_lock);		list_del(&p->list);		spin_unlock( &dv1394_procfs_lock);		kfree(p);	}}#endif /* CONFIG_PROC_FS *//*** DEVICE DRIVER HANDLERS ************************************************/static void it_tasklet_func(unsigned long data){	int wake = 0;	struct video_card *video = (struct video_card*) data;	spin_lock(&video->spinlock);	if (!video->dma_running)		goto out;	irq_printk("ContextControl = %08x, CommandPtr = %08x\n", 	       reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),	       reg_read(video->ohci, video->ohci_IsoXmitCommandPtr)	       );		if ( (video->ohci_it_ctx != -1) &&	    (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) {		struct frame *f;		unsigned int frame, i;				if (video->active_frame == -1)			frame = 0;		else			frame = video->active_frame;		/* check all the DMA-able frames */		for (i = 0; i < video->n_frames; i++, frame = (frame+1) % video->n_frames) {			irq_printk("IRQ checking frame %d...", frame);			f = video->frames[frame];			if (f->state != FRAME_READY) {				irq_printk("clear, skipping\n");				/* we don't own this frame */				continue;			}			irq_printk("DMA\n");			/* check the frame begin semaphore to see if we can free the previous frame */			if ( *(f->frame_begin_timestamp) ) {				int prev_frame;				struct frame *prev_f;								/* don't reset, need this later *(f->frame_begin_timestamp) = 0; */				irq_printk("  BEGIN\n");				prev_frame = frame - 1;				if (prev_frame == -1)					prev_frame += video->n_frames;				prev_f = video->frames[prev_frame];								/* make sure we can actually garbage collect				   this frame */				if ( (prev_f->state == FRAME_READY) &&				    prev_f->done && (!f->done) ) 				{					frame_reset(prev_f);					video->n_clear_frames++;					wake = 1;					video->active_frame = frame;					irq_printk("  BEGIN - freeing previous frame %d, new active frame is %d\n", prev_frame, frame);				} else {					irq_printk("  BEGIN - can't free yet\n");				}				f->done = 1;			}		     			/* see if we need to set the timestamp for the next frame */			if ( *(f->mid_frame_timestamp) ) {				struct frame *next_frame;				u32 begin_ts, ts_cyc, ts_off;				*(f->mid_frame_timestamp) = 0;				begin_ts = le32_to_cpu(*(f->frame_begin_timestamp));				irq_printk("  MIDDLE - first packet was sent at cycle %4u (%2u), assigned timestamp was (%2u) %4u\n",					   begin_ts & 0x1FFF, begin_ts & 0xF,					   f->assigned_timestamp >> 12, f->assigned_timestamp & 0xFFF);				/* prepare next frame and assign timestamp */				next_frame = video->frames[ (frame+1) % video->n_frames ];				if (next_frame->state == FRAME_READY) {					irq_printk("  MIDDLE - next frame is ready, good\n");				} else {					debug_printk("dv1394: Underflow! At least one frame has been dropped.\n");					next_frame = f;				}				/* set the timestamp to the timestamp of the last frame sent,				   plus the length of the last frame sent, plus the syt latency */				ts_cyc = begin_ts & 0xF;				/* advance one frame, plus syt latency (typically 2-3) */				ts_cyc += f->n_packets + video->syt_offset ; 				ts_off = 0; 				ts_cyc += ts_off/3072;				ts_off %= 3072;				next_frame->assigned_timestamp = ((ts_cyc&0xF) << 12) + ts_off;				if (next_frame->cip_syt1) {					next_frame->cip_syt1->b[6] = next_frame->assigned_timestamp >> 8;					next_frame->cip_syt1->b[7] = next_frame->assigned_timestamp & 0xFF;				}				if (next_frame->cip_syt2) {					next_frame->cip_syt2->b[6] = next_frame->assigned_timestamp >> 8;					next_frame->cip_syt2->b[7] = next_frame->assigned_timestamp & 0xFF;				}			}			/* see if the frame looped */			if ( *(f->frame_end_timestamp) ) {				*(f->frame_end_timestamp) = 0;				debug_printk("  END - the frame looped at least once\n");				video->dropped_frames++;			}				} /* for (each frame) */	}	if (wake) {		kill_fasync(&video->fasync, SIGIO, POLL_OUT);				/* wake readers/writers/ioctl'ers */		wake_up_interruptible(&video->waitq);	}out:	spin_unlock(&video->spinlock);}static void ir_tasklet_func(unsigned long data){	int wake = 0;	struct video_card *video = (struct video_card*) data;	spin_lock(&video->spinlock);	if (!video->dma_running)		goto out;		if ( (video->ohci_ir_ctx != -1) &&	    (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) )	{ 		int sof=0; /* start-of-frame flag */		struct frame *f;		u16 packet_length, packet_time;		int i, dbc=0;		struct DMA_descriptor_block *block = NULL;		u16 xferstatus;		int next_i, prev_i;		struct DMA_descriptor_block *next = NULL;		dma_addr_t next_dma = 0;		struct DMA_descriptor_block *prev = NULL;		/* loop over all descriptors in all frames */		for (i = 0; i < video->n_frames*MAX_PACKETS; i++) {			struct packet *p = dma_region_i(&video->packet_buf, struct packet, video->current_packet);			/* make sure we are seeing the latest changes to p */			dma_region_sync(&video->packet_buf,					(unsigned long) p - (unsigned long) video->packet_buf.kvirt,					sizeof(struct packet));								packet_length = le16_to_cpu(p->data_length);			packet_time   = le16_to_cpu(p->timestamp);				irq_printk("received packet %02d, timestamp=%04x, length=%04x, sof=%02x%02x\n", video->current_packet,				   packet_time, packet_length, 				   p->data[0], p->data[1]);						/* get the descriptor based on packet_buffer cursor */			f = video->frames[video->current_packet / MAX_PACKETS];			block = &(f->descriptor_pool[video->current_packet % MAX_PACKETS]);			xfe

⌨️ 快捷键说明

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