changeset 37:c359e7adf700

propagate upstream change: - when wrong channel number is passed, the driver puts an error message and discards data.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 07 Apr 2009 05:42:18 +0900
parents 65c8ac567074
children 3228f5cde349
files driver/pt1_pci.c
diffstat 1 files changed, 28 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/driver/pt1_pci.c	Fri Mar 13 14:32:44 2009 +0900
+++ b/driver/pt1_pci.c	Tue Apr 07 05:42:18 2009 +0900
@@ -66,6 +66,7 @@
 MODULE_DEVICE_TABLE(pci, pt1_pci_tbl);
 #define		DEV_NAME	"pt1video"
 
+#define		PACKET_SIZE			188		// 1パケット長
 #define		MAX_READ_BLOCK	4			// 1度に読み出す最大DMAバッファ数
 #define		MAX_PCI_DEVICE		128		// 最大64枚
 #define		DMA_SIZE	4096			// DMAバッファサイズ
@@ -114,7 +115,8 @@
 	__u32			valid ;			// 使用中フラグ
 	__u32			address ;		// I2Cアドレス
 	__u32			channel ;		// チャネル番号
-	int				type ;			// チャネルタイプ
+	int			type ;			// チャネルタイプ
+	__u32			packet_size ;	// パケットサイズ
 	__u32			drop ;			// パケットドロップ数
 	struct mutex		lock ;			// CH別mutex_lock用
 	__u32			size ;			// DMAされたサイズ
@@ -126,6 +128,7 @@
 	__u32			minor ;			// マイナー番号
 	__u8			*buf;			// CH別受信メモリ
 	__u8			req_dma ;		// 溢れたチャネル
+	__u8			packet_buf[PACKET_SIZE] ;		// 溢れたチャネル
 	PT1_DEVICE		*ptr ;			// カード別情報
 	wait_queue_head_t	wait_q ;	// for poll on reading
 };
@@ -182,6 +185,8 @@
 	int		lp ;
 	int		chno ;
 	int		lp2 ;
+	int		dma_channel ;
+	int		packet_pos ;
 	__u32	*dataptr ;
 	__u32	*curdataptr ;
 	__u32	val ;
@@ -210,7 +215,14 @@
 			data_pos += 1 ;
 			for(lp = 0 ; lp < (DMA_SIZE / sizeof(__u32)) ; lp++, dataptr++){
 				micro.val = *dataptr ;
+				dma_channel = ((micro.packet.head >> 5) & 0x07);
+				//チャネル情報不正
+				if(dma_channel > MAX_CHANNEL){
+					printk(KERN_ERR "DMA Channel Number Error(%d)\n", dma_channel);
+					continue ;
+				}
 				chno = real_chanel[(((micro.packet.head >> 5) & 0x07) - 1)];
+				packet_pos = ((micro.packet.head >> 2) & 0x07);
 				channel = dev_conf->channel[chno] ;
 				//  エラーチェック
 				if((micro.packet.head & MICROPACKET_ERROR)){
@@ -250,10 +262,22 @@
 						break ;
 					}
 				}
+				// 先頭で、一時バッファに残っている場合
+				if((micro.packet.head & 0x02) &&  (channel->packet_size != 0)){
+					channel->packet_size = 0 ;
+				}
 				// データコピー
 				for(lp2 = 2 ; lp2 >= 0 ; lp2--){
-					channel->buf[channel->size] = micro.packet.data[lp2];
-					channel->size += 1 ;
+					channel->packet_buf[channel->packet_size] = micro.packet.data[lp2] ;
+					channel->packet_size += 1 ;
+				}
+
+				// パケットが出来たらコピーする
+				if(channel->packet_size >= PACKET_SIZE){
+					memcpy(&channel->buf[channel->size],
+							channel->packet_buf, PACKET_SIZE);
+					channel->size += PACKET_SIZE ;
+					channel->packet_size = 0 ;
 				}
 				mutex_unlock(&channel->lock);
 			}
@@ -312,6 +336,7 @@
 					channel->overflow = 0 ;
 					channel->counetererr = 0 ;
 					channel->transerr = 0 ;
+					channel->packet_size = 0 ;
 					file->private_data = channel;
 					mutex_lock(&channel->lock);
 					// データ初期化