comparison driver/pt1_pci.c @ 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 8f30a05cded2
comparison
equal deleted inserted replaced
36:65c8ac567074 37:c359e7adf700
64 { 0, } 64 { 0, }
65 }; 65 };
66 MODULE_DEVICE_TABLE(pci, pt1_pci_tbl); 66 MODULE_DEVICE_TABLE(pci, pt1_pci_tbl);
67 #define DEV_NAME "pt1video" 67 #define DEV_NAME "pt1video"
68 68
69 #define PACKET_SIZE 188 // 1パケット長
69 #define MAX_READ_BLOCK 4 // 1度に読み出す最大DMAバッファ数 70 #define MAX_READ_BLOCK 4 // 1度に読み出す最大DMAバッファ数
70 #define MAX_PCI_DEVICE 128 // 最大64枚 71 #define MAX_PCI_DEVICE 128 // 最大64枚
71 #define DMA_SIZE 4096 // DMAバッファサイズ 72 #define DMA_SIZE 4096 // DMAバッファサイズ
72 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) 73 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
73 #define DMA_RING_SIZE 128 // RINGサイズ 74 #define DMA_RING_SIZE 128 // RINGサイズ
112 113
113 struct _PT1_CHANNEL{ 114 struct _PT1_CHANNEL{
114 __u32 valid ; // 使用中フラグ 115 __u32 valid ; // 使用中フラグ
115 __u32 address ; // I2Cアドレス 116 __u32 address ; // I2Cアドレス
116 __u32 channel ; // チャネル番号 117 __u32 channel ; // チャネル番号
117 int type ; // チャネルタイプ 118 int type ; // チャネルタイプ
119 __u32 packet_size ; // パケットサイズ
118 __u32 drop ; // パケットドロップ数 120 __u32 drop ; // パケットドロップ数
119 struct mutex lock ; // CH別mutex_lock用 121 struct mutex lock ; // CH別mutex_lock用
120 __u32 size ; // DMAされたサイズ 122 __u32 size ; // DMAされたサイズ
121 __u32 maxsize ; // DMA用バッファサイズ 123 __u32 maxsize ; // DMA用バッファサイズ
122 __u32 bufsize ; // チャネルに割り振られたサイズ 124 __u32 bufsize ; // チャネルに割り振られたサイズ
124 __u32 counetererr ; // 転送カウンタ1エラー 126 __u32 counetererr ; // 転送カウンタ1エラー
125 __u32 transerr ; // 転送エラー 127 __u32 transerr ; // 転送エラー
126 __u32 minor ; // マイナー番号 128 __u32 minor ; // マイナー番号
127 __u8 *buf; // CH別受信メモリ 129 __u8 *buf; // CH別受信メモリ
128 __u8 req_dma ; // 溢れたチャネル 130 __u8 req_dma ; // 溢れたチャネル
131 __u8 packet_buf[PACKET_SIZE] ; // 溢れたチャネル
129 PT1_DEVICE *ptr ; // カード別情報 132 PT1_DEVICE *ptr ; // カード別情報
130 wait_queue_head_t wait_q ; // for poll on reading 133 wait_queue_head_t wait_q ; // for poll on reading
131 }; 134 };
132 135
133 // I2Cアドレス(video0, 1 = ISDB-S) (video2, 3 = ISDB-T) 136 // I2Cアドレス(video0, 1 = ISDB-S) (video2, 3 = ISDB-T)
180 int ring_pos = 0; 183 int ring_pos = 0;
181 int data_pos = 0 ; 184 int data_pos = 0 ;
182 int lp ; 185 int lp ;
183 int chno ; 186 int chno ;
184 int lp2 ; 187 int lp2 ;
188 int dma_channel ;
189 int packet_pos ;
185 __u32 *dataptr ; 190 __u32 *dataptr ;
186 __u32 *curdataptr ; 191 __u32 *curdataptr ;
187 __u32 val ; 192 __u32 val ;
188 union mpacket{ 193 union mpacket{
189 __u32 val ; 194 __u32 val ;
208 micro.val = *dataptr ; 213 micro.val = *dataptr ;
209 curdataptr = dataptr ; 214 curdataptr = dataptr ;
210 data_pos += 1 ; 215 data_pos += 1 ;
211 for(lp = 0 ; lp < (DMA_SIZE / sizeof(__u32)) ; lp++, dataptr++){ 216 for(lp = 0 ; lp < (DMA_SIZE / sizeof(__u32)) ; lp++, dataptr++){
212 micro.val = *dataptr ; 217 micro.val = *dataptr ;
218 dma_channel = ((micro.packet.head >> 5) & 0x07);
219 //チャネル情報不正
220 if(dma_channel > MAX_CHANNEL){
221 printk(KERN_ERR "DMA Channel Number Error(%d)\n", dma_channel);
222 continue ;
223 }
213 chno = real_chanel[(((micro.packet.head >> 5) & 0x07) - 1)]; 224 chno = real_chanel[(((micro.packet.head >> 5) & 0x07) - 1)];
225 packet_pos = ((micro.packet.head >> 2) & 0x07);
214 channel = dev_conf->channel[chno] ; 226 channel = dev_conf->channel[chno] ;
215 // エラーチェック 227 // エラーチェック
216 if((micro.packet.head & MICROPACKET_ERROR)){ 228 if((micro.packet.head & MICROPACKET_ERROR)){
217 val = readl(dev_conf->regs); 229 val = readl(dev_conf->regs);
218 if((val & BIT_RAM_OVERFLOW)){ 230 if((val & BIT_RAM_OVERFLOW)){
248 channel->drop += 1 ; 260 channel->drop += 1 ;
249 }else{ 261 }else{
250 break ; 262 break ;
251 } 263 }
252 } 264 }
265 // 先頭で、一時バッファに残っている場合
266 if((micro.packet.head & 0x02) && (channel->packet_size != 0)){
267 channel->packet_size = 0 ;
268 }
253 // データコピー 269 // データコピー
254 for(lp2 = 2 ; lp2 >= 0 ; lp2--){ 270 for(lp2 = 2 ; lp2 >= 0 ; lp2--){
255 channel->buf[channel->size] = micro.packet.data[lp2]; 271 channel->packet_buf[channel->packet_size] = micro.packet.data[lp2] ;
256 channel->size += 1 ; 272 channel->packet_size += 1 ;
273 }
274
275 // パケットが出来たらコピーする
276 if(channel->packet_size >= PACKET_SIZE){
277 memcpy(&channel->buf[channel->size],
278 channel->packet_buf, PACKET_SIZE);
279 channel->size += PACKET_SIZE ;
280 channel->packet_size = 0 ;
257 } 281 }
258 mutex_unlock(&channel->lock); 282 mutex_unlock(&channel->lock);
259 } 283 }
260 curdataptr[(DMA_SIZE / sizeof(__u32)) - 2] = 0; 284 curdataptr[(DMA_SIZE / sizeof(__u32)) - 2] = 0;
261 285
310 channel->drop = 0 ; 334 channel->drop = 0 ;
311 channel->valid = TRUE ; 335 channel->valid = TRUE ;
312 channel->overflow = 0 ; 336 channel->overflow = 0 ;
313 channel->counetererr = 0 ; 337 channel->counetererr = 0 ;
314 channel->transerr = 0 ; 338 channel->transerr = 0 ;
339 channel->packet_size = 0 ;
315 file->private_data = channel; 340 file->private_data = channel;
316 mutex_lock(&channel->lock); 341 mutex_lock(&channel->lock);
317 // データ初期化 342 // データ初期化
318 channel->size = 0 ; 343 channel->size = 0 ;
319 mutex_unlock(&channel->lock); 344 mutex_unlock(&channel->lock);