Mercurial > pt1
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); |