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

📄 dv1394.c

📁 ieee1394驱动,不多说了!直接可以在linux2.6内核中使用
💻 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;}/*** 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_for_cpu(&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]);			xferstatus = le32_to_cpu(block->u.in.il.q[3]) >> 16;			xferstatus &= 0x1F;			irq_printk("ir_tasklet_func: xferStatus/resCount [%d] = 0x%08x\n", i, le32_to_cpu(block->u.in.il.q[3]) );			/* get the current frame */			f = video->frames[video->active_frame];			/* exclude empty packet */			if (packet_length > 8 && xferstatus == 0x11) {				/* check for start of frame */				/* DRD> Changed to check section type ([0]>>5==0)				   and dif sequence ([1]>>4==0) */				sof = ( (p->data[0] >> 5) == 0 && (p->data[1] >> 4) == 0);				dbc = (int) (p->cip_h1 >> 24);				if ( video->continuity_counter != -1 && dbc > ((video->continuity_counter + 1) % 256) )				{					printk(KERN_WARNING "dv1394: discontinuity detected, dropping all frames\n" );					video->dropped_frames += video->n_clear_frames + 1;					video->first_frame = 0;					video->n_clear_frames = 0;					video->first_clear_frame = -1;				}				video->continuity_counter = dbc;				if (!video->first_frame) {					if (sof) {						video->first_frame = 1;					}				} else if (sof) {					/* close current frame */					frame_reset(f);  /* f->state = STATE_CLEAR */					video->n_clear_frames++;					if (video->n_clear_frames > video->n_frames) {						video->dropped_frames++;						printk(KERN_WARNING "dv1394: dropped a frame during reception\n" );						video->n_clear_frames = video->n_frames-1;						video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames;					}					if (video->first_clear_frame == -1)						video->first_clear_frame = video->active_frame;					/* get the next frame */					video->active_frame = (video->active_frame + 1) % video->n_frames;					f = video->frames[video->active_frame];					irq_printk("   frame received, active_frame = %d, n_clear_frames = %d, first_clear_frame = %d\n",						   video->active_frame, video->n_clear_frames, video->first_clear_frame);				}				if (video->first_frame) {					if (sof) {						/* open next frame */						f->state = FRAME_READY;					}					/* copy to buffer */					if (f->n_packets > (video->frame_size / 480)) {						printk(KERN_ERR "frame buffer overflow during receive\n");					}					frame_put_packet(f, p);				} /* first_frame */			}			/* stop, end of ready packets */			else if (xferstatus == 0) {				break;			}			/* reset xferStatus & resCount */			block->u.in.il.q[3] = cpu_to_le32(512);			/* terminate dma chain at this (next) packet */			next_i = video->current_packet;			f = video->frames[next_i / MAX_PACKETS];			next = &(f->descriptor_pool[next_i % MAX_PACKETS]);			next_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma;			next->u.in.il.q[0] |= 3 << 20; /* enable interrupt */			next->u.in.il.q[2] = 0; /* disable branch */			/* link previous to next */			prev_i = (next_i == 0) ? (MAX_PACKETS * video->n_frames - 1) : (next_i - 1);			f = video->frames[prev_i / MAX_PACKETS];			prev = &(f->descriptor_pool[prev_i % MAX_PACKETS]);			if (prev_i % (MAX_PACKETS/2)) {				prev->u.in.il.q[0] &= ~(3 << 20); /* no interrupt */			} else {				prev->u.in.il.q[0] |= 3 << 20; /* enable interrupt */			}			prev->u.in.il.q[2] = cpu_to_le32(next_dma | 1); /* set Z=1 */			wmb();			/* wake up DMA in case it fell asleep */			reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 12));			/* advance packet_buffer cursor */			video->current_packet = (video->current_packet + 1) % (MAX_PACKETS * video->n_frames);		} /* for all packets */		wake = 1; /* why the hell not? */	} /* receive interrupt */	if (wake) {		kill_fasync(&video->fasync, SIGIO, POLL_IN);		/* wake readers/writers/ioctl'ers */		wake_up_interruptible(&video->waitq);	}out:	spin_unlock(&video->spinlock);}static struct cdev dv1394_cdev;static const struct file_operations dv1394_fops={	.owner =	THIS_MODULE,	.poll =         dv1394_poll,	.unlocked_ioctl = dv1394_ioctl,#ifdef CONFIG_COMPAT	.compat_ioctl = dv1394_compat_ioctl,#endif	.mmap =		dv1394_mmap,	.open =		dv1394_open,	.write =        dv1394_write,	.read =         dv1394_read,	.release =	dv1394_release,	.fasync =       dv1394_fasync,};/*** HOTPLUG STUFF **********************************************************//* * Export information about protocols/devices supported by this driver. */static struct ieee1394_device_id dv1394_id_table[] = {	{		.match_flags	= IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,		.version	= AVC_SW_VERSION_ENTRY & 0xffffff	},	{ }};MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);static struct hpsb_protocol_driver dv1394_driver = {	.name		= "dv1394",	.id_table	= dv1394_id_table,};/*** IEEE1394 HPSB CALLBACKS ***********************************************/static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes mode){	struct video_card *video;	unsigned long flags;	int i;	video = kzalloc(sizeof(*video), GFP_KERNEL);	if (!video) {		printk(KERN_ERR "dv1394: cannot allocate video_card\n");		return -1;	}	video->ohci = ohci;	/* lower 2 bits of id indicate which of four "plugs"	   per host */	video->id = ohci->host->id << 2;	if (format == DV1394_NTSC)		video->id |= mode;	else		video->id |= 2 + mode;	video->ohci_it_ctx = -1;	video->ohci_ir_ctx = -1;	video->ohci_IsoXmitContextControlSet = 0;	video->ohci_IsoXmitContextControlClear = 0;	video->ohci_IsoXmitCommandPtr = 0;	video->ohci_IsoRcvContextControlSet = 0;	video->ohci_IsoRcvContextControlClear = 0;	video->ohci_IsoRcvCommandPtr = 0;	video->ohci_IsoRcvContextMatch = 0;	video->n_frames = 0; /* flag that video is not initialized */	video->channel = 63; /* default to broadcast channel */	video->active_frame = -1;	/* initialize the following */	video->pal_or_ntsc = format;	video->cip_n = 0; /* 0 = use builtin default */	video->cip_d = 0;	video->syt_offset = 0;	video->mode = mode;	for (i = 0; i < DV1394_MAX_FRAMES; i++)		video->frames[i] = NULL;	dma_region_init(&video->dv_buf);	video->dv_buf_size = 0;	dma_region_init(&video->packet_buf);	video->packet_buf_size = 0;	clear_bit(0, &video->open);	spin_lock_init(&video->spinlock);	video->dma_running = 0;	mutex_init(&video->mtx);	init_waitqueue_head(&video->waitq);	video->fasync = NULL;	spin_lock_irqsave(&dv1394_cards_lock, flags);	INIT_LIST_HEAD(&video->list);	list_add_tail(&video->list, &dv1394_cards);	spin_unlock_irqrestore(&dv1394_cards_lock, flags);	debug_printk("dv1394: dv1394_init() OK on ID %d\n", video->id);	return 0;}static void dv1394_remove_host(struct hpsb_host *host){	struct video_card *video, *tmp_video;	unsigned long flags;	int found_ohci_card = 0;	do {		video = NULL;		spin_lock_irqsave(&dv1394_cards_lock, flags);		list_for_each_entry(tmp_video, &dv1394_cards, list) {			if ((tmp_video->id >> 2) == host->id) {	

⌨️ 快捷键说明

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