diff driver/pt1_pci.c @ 40:8f30a05cded2

imported patch dmactlalloc
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 28 Apr 2009 17:16:48 +0900
parents c359e7adf700
children 51a006a8d843
line wrap: on
line diff
--- a/driver/pt1_pci.c	Fri Apr 17 22:52:35 2009 +0900
+++ b/driver/pt1_pci.c	Tue Apr 28 17:16:48 2009 +0900
@@ -70,16 +70,14 @@
 #define		MAX_READ_BLOCK	4			// 1度に読み出す最大DMAバッファ数
 #define		MAX_PCI_DEVICE		128		// 最大64枚
 #define		DMA_SIZE	4096			// DMAバッファサイズ
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
 #define		DMA_RING_SIZE	128			// RINGサイズ
 #define		DMA_RING_MAX	511			// 1RINGにいくつ詰めるか(1023はNGで511まで)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) 
 #define		CHANEL_DMA_SIZE	(2*1024*1024)	// 地デジ用(16Mbps)
 #define		BS_CHANEL_DMA_SIZE	(4*1024*1024)	// BS用(32Mbps)
 #else
-#define		DMA_RING_SIZE	28			// RINGサイズ
-#define		DMA_RING_MAX	511			// 1RINGにいくつ詰めるか(1023はNGで511まで)
-#define		CHANEL_DMA_SIZE	(1*128*1024)	// 地デジ用(16Mbps)
-#define		BS_CHANEL_DMA_SIZE	(1*128*1024)	// BS用(32Mbps)
+#define		CHANEL_DMA_SIZE	(1*128*1024)	// 地デジ用(1Mbps)
+#define		BS_CHANEL_DMA_SIZE	(1*128*1024)	// BS用(1Mbps)
 #endif
 
 typedef	struct	_DMA_CONTROL{
@@ -102,7 +100,7 @@
 	__u32			base_minor ;
 	struct	cdev	cdev[MAX_CHANNEL];
 	wait_queue_head_t	dma_wait_q ;// for poll on reading
-	DMA_CONTROL		dmactl[DMA_RING_SIZE];
+	DMA_CONTROL		*dmactl[DMA_RING_SIZE];
 	PT1_CHANNEL		*channel[MAX_CHANNEL];
 }PT1_DEVICE;
 
@@ -157,7 +155,7 @@
 	// データ初期化
 	for(ring_pos = 0 ; ring_pos < DMA_RING_SIZE ; ring_pos++){
 		for(data_pos = 0 ; data_pos < DMA_RING_MAX ; data_pos++){
-			dataptr = dev_conf->dmactl[ring_pos].data[data_pos];
+			dataptr = (dev_conf->dmactl[ring_pos])->data[data_pos];
 			dataptr[(DMA_SIZE / sizeof(__u32)) - 2] = 0;
 		}
 	}
@@ -205,7 +203,7 @@
 		}
 
 		for(;;){
-			dataptr = dev_conf->dmactl[ring_pos].data[data_pos];
+			dataptr = (dev_conf->dmactl[ring_pos])->data[data_pos];
 			// データあり?
 			if(dataptr[(DMA_SIZE / sizeof(__u32)) - 2] == 0){
 				break ;
@@ -539,7 +537,7 @@
 		memcpy(ptr, &addr, sizeof(__u32));
 		ptr += 1 ;
 
-		dmactl = &dev_conf->dmactl[lp];
+		dmactl = dev_conf->dmactl[lp];
 		for(lp2 = 0 ; lp2 < DMA_RING_MAX ; lp2++){
 			dmaptr = pci_alloc_consistent(pdev, DMA_SIZE, &dmactl->ring_dma[lp2]);
 			if(dmaptr == NULL){
@@ -584,10 +582,10 @@
 			pci_free_consistent(pdev, DMA_SIZE,
 								dev_conf->dmaptr[lp], dev_conf->ring_dma[lp]);
 			for(lp2 = 0 ; lp2 < DMA_RING_MAX ; lp2++){
-				if(dev_conf->dmactl[lp].data[lp2] != NULL){
+				if((dev_conf->dmactl[lp])->data[lp2] != NULL){
 					pci_free_consistent(pdev, DMA_SIZE,
-										dev_conf->dmactl[lp].data[lp2],
-										dev_conf->dmactl[lp].ring_dma[lp2]);
+										(dev_conf->dmactl[lp])->data[lp2],
+										(dev_conf->dmactl[lp])->ring_dma[lp2]);
 				}
 			}
 		}
@@ -603,6 +601,7 @@
 	u16			cmd ;
 	PT1_DEVICE	*dev_conf ;
 	PT1_CHANNEL	*channel ;
+	int i;
 	struct resource *dummy;
 
 	rc = pci_enable_device(pdev);
@@ -631,6 +630,18 @@
 		printk(KERN_ERR "PT1:out of memory !");
 		return -ENOMEM ;
 	}
+	for (i = 0; i < DMA_RING_SIZE; i++) {
+		dev_conf->dmactl[i] = kzalloc(sizeof(DMA_CONTROL), GFP_KERNEL);
+		if(!dev_conf->dmactl[i]){
+			int j;
+			for (j = 0; j < i; j++) {
+				kfree(dev_conf->dmactl[j]);
+			}
+			kfree(dev_conf);
+			printk(KERN_ERR "PT1:out of memory !");
+			return -ENOMEM ;
+		}
+	}
 	// PCIアドレスをマップする
 	dev_conf->mmio_start = pci_resource_start(pdev, 0);
 	dev_conf->mmio_len = pci_resource_len(pdev, 0);
@@ -784,6 +795,9 @@
 	writel(0, dev_conf->regs + 4);
 	iounmap(dev_conf->regs);
 	release_mem_region(dev_conf->mmio_start, dev_conf->mmio_len);
+	for (i = 0; i < DMA_RING_SIZE; i++) {
+		kfree(dev_conf->dmactl[i]);
+	}
 	kfree(dev_conf);
 out_err_regbase:
 	return -EIO;
@@ -796,6 +810,7 @@
 	int		lp ;
 	__u32	val ;
 	PT1_DEVICE	*dev_conf = (PT1_DEVICE *)pci_get_drvdata(pdev);
+	int		i;
 
 	if(dev_conf){
 		if(dev_conf->kthread) {
@@ -830,6 +845,9 @@
 		settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_OFF);
 		release_mem_region(dev_conf->mmio_start, dev_conf->mmio_len);
 		iounmap(dev_conf->regs);
+		for (i = 0; i < DMA_RING_SIZE; i++) {
+			kfree(dev_conf->dmactl[i]);
+		}
 		device[dev_conf->card_number] = NULL;
 		kfree(dev_conf);
 	}