lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <1361982341-5322-1-git-send-email-michail.kurachkin@promwad.com>
Date:	Wed, 27 Feb 2013 19:25:41 +0300
From:	Michail Kurachkin <michail.kurachkin@...mwad.com>
To:	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
	Kuten Ivan <Ivan.Kuten@...mwad.com>,
	"benavi@...vell.com" <benavi@...vell.com>,
	Palstsiuk Viktar <Viktar.Palstsiuk@...mwad.com>,
	Dmitriy Gorokh <dmitriy.gorokh@...mwad.com>
CC:	Michail Kurochkin <michail.kurachkin@...mwad.com>
Subject: [PATCH 5/9] refactoring request/free voice channels

From: Michail Kurochkin <michail.kurachkin@...mwad.com>

Signed-off-by: Michail Kurochkin <michail.kurachkin@...mwad.com>
---
 drivers/staging/tdm/kirkwood_tdm.c |  162 +++++++++++++++++++++++++-----------
 drivers/staging/tdm/kirkwood_tdm.h |   10 ++-
 drivers/staging/tdm/tdm.h          |    5 +-
 drivers/staging/tdm/tdm_core.c     |   65 +++++++--------
 4 files changed, 154 insertions(+), 88 deletions(-)

diff --git a/drivers/staging/tdm/kirkwood_tdm.c b/drivers/staging/tdm/kirkwood_tdm.c
index 4366d38..e4a9106 100644
--- a/drivers/staging/tdm/kirkwood_tdm.c
+++ b/drivers/staging/tdm/kirkwood_tdm.c
@@ -75,7 +75,7 @@ static int kirkwood_tdm_hw_init(struct tdm_controller *tdm)
 	u32 control_val = 0;
 	u32 pclk_freq;
 	unsigned long flags;
-	spinlock_t lock;
+	static spinlock_t lock;
 	spin_lock_init(&lock);
 
 
@@ -192,13 +192,14 @@ static void kirkwood_tdm_hw_deinit(struct tdm_controller *tdm)
 }
 
 /**
- * Setup hardware voice channel
+ * Initialization hardware voice channel
+ * for specify TDM device
+ * @param tdm_dev - specify TDM device
  * @param ch - voice hardware channel
  * @return 0 - OK
  */
-int kirkwood_setup_voice_channel(struct tdm_voice_channel* ch)
+static int kirkwood_init_voice_channel(struct tdm_device *tdm_dev, struct tdm_voice_channel* ch)
 {
-	struct tdm_device *tdm_dev = to_tdm_device(ch->dev);
 	struct tdm_controller *tdm = tdm_dev->controller;
 	struct tdm_controller_hw_settings *hw = tdm->settings;
 	struct kirkwood_tdm *onchip_tdm =
@@ -208,15 +209,15 @@ int kirkwood_setup_voice_channel(struct tdm_voice_channel* ch)
 	unsigned long timeout;
 	u32 state;
 	int i;
-
+	int rc = 0;
 	u8 voice_num = ch->channel_num;
 
 	/* calculate buffer size */
 	ch->buffer_len = tdm_dev->buffer_sample_count * hw->channel_size;
 
 	/* Request timeslot for voice channel */
-	writeb(ch->tdm_channel, (u8*)&regs->chan_time_slot_ctrl + 2 * voice_num);
-	writeb(ch->tdm_channel, (u8*)&regs->chan_time_slot_ctrl + 1 + 2 * voice_num);
+	writeb(tdm_dev->tdm_channel_num, (u8*)&regs->chan_time_slot_ctrl + 2 * voice_num);
+	writeb(tdm_dev->tdm_channel_num, (u8*)&regs->chan_time_slot_ctrl + 1 + 2 * voice_num);
 
 	/* FIXME: move coherent_dma_mask to board specific */
 	tdm_dev->dev.coherent_dma_mask = 0xffffffff;
@@ -226,11 +227,12 @@ int kirkwood_setup_voice_channel(struct tdm_voice_channel* ch)
 		/* allocate memory for DMA receiver */
 		onchip_ch->rx_buf[i] =
 		        dma_alloc_coherent(&tdm_dev->dev,
-		        ch->buffer_len, onchip_ch->rx_buff_phy + i, GFP_DMA);
+		        ch->buffer_len, onchip_ch->rx_buff_phy + i, GFP_KERNEL);
 
 		if (onchip_ch->rx_buf == NULL) {
 			dev_err(ch->dev, "Can't allocate memory for TDM receiver DMA buffer\n");
-			return -ENOMEM;
+			rc = -ENOMEM;
+			goto out1;
 		}
 		memset(onchip_ch->rx_buf[i], 0, ch->buffer_len);
 
@@ -238,20 +240,16 @@ int kirkwood_setup_voice_channel(struct tdm_voice_channel* ch)
 		/* allocate memory for DMA transmitter */
 		onchip_ch->tx_buf[i] =
 		        dma_alloc_coherent(&tdm_dev->dev,
-		        ch->buffer_len, onchip_ch->tx_buff_phy + i, GFP_DMA);
+		        ch->buffer_len, onchip_ch->tx_buff_phy + i, GFP_KERNEL);
 
 		if (onchip_ch->tx_buf == NULL) {
 			dev_err(ch->dev, "Can't allocate memory for TDM transmitter DMA buffer\n");
-			return -ENOMEM;
+			rc = -ENOMEM;
+			goto out1;
 		}
 		memset(onchip_ch->tx_buf[i], 0, ch->buffer_len);
 	}
 
-	atomic_set(&onchip_ch->write_rx_buf_num, 0);
-	atomic_set(&onchip_ch->write_tx_buf_num, 0);
-	atomic_set(&onchip_ch->read_rx_buf_num, 0);
-	atomic_set(&onchip_ch->read_tx_buf_num, 0);
-
 	/* Set length for DMA */
 	writel(((tdm_dev->buffer_sample_count - 32) << 8) | tdm_dev->buffer_sample_count,
 	       &regs->chan0_total_sample + voice_num);
@@ -262,8 +260,10 @@ int kirkwood_setup_voice_channel(struct tdm_voice_channel* ch)
 		state = readl(&regs->chan0_buff_ownership + 4 * voice_num) & 0x100;
 		if(time_after(jiffies, timeout)) {
 			dev_err(ch->dev, "Can`t program DMA tx buffer\n");
-			return -EBUSY;
+			rc = -EBUSY;
+			goto out1;
 		}
+		schedule();
 	} while(state);
 
 	/* Set DMA buffers fo transmitter */
@@ -277,8 +277,10 @@ int kirkwood_setup_voice_channel(struct tdm_voice_channel* ch)
 		state = readl(&regs->chan0_buff_ownership + 4 * voice_num) & 1;
 		if(time_after(jiffies, timeout)) {
 			dev_err(ch->dev, "Can`t program DMA rx buffer\n");
-			return -EBUSY;
+			rc = -EBUSY;
+			goto out1;
 		}
+		schedule();
 	} while(state);
 
 	/* Set DMA buffers for receiver */
@@ -286,11 +288,51 @@ int kirkwood_setup_voice_channel(struct tdm_voice_channel* ch)
 	    &regs->chan0_receive_start_addr + 4 * voice_num);
 	writeb(0x1, (u8*)(&regs->chan0_buff_ownership + 4 * voice_num) );
 
-	return 0;
+out0:
+	return rc;
+
+out1:
+	kirkwood_reset_voice_channel(tdm_dev);
+	return rc;
 }
 
 
 /**
+ * Release and reset hardware voice channel
+ * free DMA buffers.
+ * @param tdm_dev - TDM device early requested voice channel
+ * @return 0 - OK
+ */
+int kirkwood_release_voice_channel(struct tdm_device *tdm_dev)
+{
+	struct tdm_voice_channel* ch = tdm_dev->ch;
+	struct kirkwood_tdm_voice *onchip_ch = ch->private_data;
+	int i;
+
+	if (!tdm_dev->ch)
+		return -ENODEV;
+
+	for(i = 0; i < COUNT_DMA_BUFFERS_PER_CHANNEL; i++)
+	{
+		if (onchip_ch->rx_buf[i])
+		{
+			dma_free_coherent(&ch->dev,
+			        ch->buffer_len, onchip_ch->rx_buf[i], onchip_ch->rx_buff_phy + i);
+			onchip_ch->rx_buf[i] = 0;
+		}
+
+		if (onchip_ch->tx_buf[i])
+		{
+			dma_free_coherent(&ch->dev,
+			        ch->buffer_len, onchip_ch->tx_buf[i], onchip_ch->tx_buff_phy + i);
+			onchip_ch->tx_buf[i] = 0;
+		}
+	}
+
+	return 0;
+}
+
+/**
  * Run tdm transmitter and receiver
  * @param tdm_dev - tdm device
  * @return 0 - ok
@@ -304,8 +346,8 @@ int kirkwood_tdm_run_audio(struct tdm_device *tdm_dev)
 	struct tdm_voice_channel *ch = tdm_dev->ch;
 	struct kirkwood_tdm_voice *onchip_ch = ch->private_data;
 
-	memset(onchip_ch->tx_buf[0], 0, ch->buffer_len);
-	memset(onchip_ch->tx_buf[1], 0, ch->buffer_len);
+	for (i = 0; i < COUNT_DMA_BUFFERS_PER_CHANNEL; i++)
+		memset(onchip_ch->tx_buf[i], 0, ch->buffer_len);
 
 	writeb(0x1, (u8 *)(&regs->chan0_enable_disable + 4 * ch->channel_num) + 1);
 	writeb(0x1, (u8 *)(&regs->chan0_enable_disable + 4 * ch->channel_num) );
@@ -364,11 +406,18 @@ int kirkwood_tdm_stop_audio(struct tdm_device *tdm_dev)
  */
 int get_tx_latency(struct kirkwood_tdm_voice *onchip_ch)
 {
-	if (atomic_read(&onchip_ch->read_tx_buf_num) <= atomic_read(&onchip_ch->write_tx_buf_num))
-		return atomic_read(&onchip_ch->write_tx_buf_num) - atomic_read(&onchip_ch->read_tx_buf_num);
+	unsigned long flags;
+	int latency;
+
+	spin_lock_irqsave(&onchip_ch->lock, flags);
+	if (onchip_ch->read_tx_buf_num <= onchip_ch->write_tx_buf_num)
+		latency = onchip_ch->write_tx_buf_num - onchip_ch->read_tx_buf_num;
 	else
-		return COUNT_DMA_BUFFERS_PER_CHANNEL - atomic_read(&onchip_ch->read_tx_buf_num)
-		       + atomic_read(&onchip_ch->write_tx_buf_num);
+		latency = COUNT_DMA_BUFFERS_PER_CHANNEL - onchip_ch->read_tx_buf_num
+		       + onchip_ch->write_tx_buf_num;
+	spin_unlock_irqrestore(&onchip_ch->lock, flags);
+
+	return latency;
 }
 
 
@@ -379,11 +428,18 @@ int get_tx_latency(struct kirkwood_tdm_voice *onchip_ch)
  */
 int get_rx_latency(struct kirkwood_tdm_voice *onchip_ch)
 {
-	if (atomic_read(&onchip_ch->read_rx_buf_num) <= atomic_read(&onchip_ch->write_rx_buf_num))
-		return atomic_read(&onchip_ch->write_rx_buf_num) - atomic_read(&onchip_ch->read_rx_buf_num);
+	unsigned long flags;
+	int latency;
+
+	spin_lock_irqsave(&onchip_ch->lock, flags);
+	if (onchip_ch->read_rx_buf_num <= onchip_ch->write_rx_buf_num)
+		latency = onchip_ch->write_rx_buf_num - onchip_ch->read_rx_buf_num;
 	else
-		return COUNT_DMA_BUFFERS_PER_CHANNEL - atomic_read(&onchip_ch->read_rx_buf_num)
-		       + atomic_read(&onchip_ch->write_rx_buf_num);
+		latency = COUNT_DMA_BUFFERS_PER_CHANNEL - onchip_ch->read_rx_buf_num
+		       + onchip_ch->write_rx_buf_num;
+	spin_unlock_irqrestore(&onchip_ch->lock, flags);
+
+	return latency;
 }
 
 
@@ -421,7 +477,7 @@ int kirkwood_poll_tx(struct tdm_device *tdm_dev)
  * @param num - current buffer number
  * @return next buffer number
  */
-static int inc_next_dma_buf_num(int num)
+static inline int inc_next_dma_buf_num(int num)
 {
 	num ++;
 	if (num >= COUNT_DMA_BUFFERS_PER_CHANNEL)
@@ -445,6 +501,7 @@ static int kirkwood_send(struct tdm_voice_channel *ch, u8 *data)
 {
 	struct kirkwood_tdm_voice *onchip_ch = ch->private_data;
 	int rc = 0;
+	unsigned long flags;
 
 	rc = wait_event_interruptible(ch->tx_queue,
 	                         get_tx_latency(onchip_ch) > 1);
@@ -452,10 +509,12 @@ static int kirkwood_send(struct tdm_voice_channel *ch, u8 *data)
 	if (rc)
 		return rc;
 
-	memcpy(onchip_ch->tx_buf[atomic_read(&onchip_ch->read_tx_buf_num)], data,
+	spin_lock_irqsave(&onchip_ch->lock, flags);
+	memcpy(onchip_ch->tx_buf[onchip_ch->read_tx_buf_num], data,
 	       ch->buffer_len);
-	atomic_set(&onchip_ch->read_tx_buf_num,
-		inc_next_dma_buf_num(atomic_read(&onchip_ch->read_tx_buf_num)));
+	onchip_ch->read_tx_buf_num =
+		inc_next_dma_buf_num(onchip_ch->read_tx_buf_num);
+	spin_unlock_irqrestore(&onchip_ch->lock, flags);
 	return rc;
 }
 
@@ -473,6 +532,7 @@ static int kirkwood_recv(struct tdm_voice_channel *ch, u8 *data)
 {
 	struct kirkwood_tdm_voice *onchip_ch = ch->private_data;
 	int rc = 0;
+	unsigned long flags;
 
 	rc = wait_event_interruptible(ch->rx_queue,
 	                         get_rx_latency(onchip_ch) > 1);
@@ -480,10 +540,12 @@ static int kirkwood_recv(struct tdm_voice_channel *ch, u8 *data)
 	if (rc)
 		return rc;
 
-	memcpy(data, onchip_ch->rx_buf[atomic_read(&onchip_ch->read_rx_buf_num)],
+	spin_lock_irqsave(&onchip_ch->lock, flags);
+	memcpy(data, onchip_ch->rx_buf[onchip_ch->read_rx_buf_num],
 	       ch->buffer_len);
-	atomic_set(&onchip_ch->read_rx_buf_num,
-		   inc_next_dma_buf_num(atomic_read(&onchip_ch->read_rx_buf_num)));
+	onchip_ch->read_rx_buf_num =
+		   inc_next_dma_buf_num(onchip_ch->read_rx_buf_num);
+	spin_unlock_irqrestore(&onchip_ch->lock, flags);
 	return rc;
 }
 
@@ -595,11 +657,11 @@ static irqreturn_t kirkwood_tdm_irq(s32 irq, void *context_data)
 		switch(mode) {
 		case IRQ_RECEIVE: {
 			/* get next buffer number, and move write/read pointer */
-			next_buf_num = inc_next_dma_buf_num(atomic_read(&onchip_ch->write_rx_buf_num));
-			atomic_set(&onchip_ch->write_rx_buf_num, next_buf_num);
-			if(next_buf_num == atomic_read(&onchip_ch->read_rx_buf_num))
-				atomic_set(&onchip_ch->read_rx_buf_num,
-				           inc_next_dma_buf_num(atomic_read(&onchip_ch->read_rx_buf_num)));
+			next_buf_num = inc_next_dma_buf_num(onchip_ch->write_rx_buf_num);
+			onchip_ch->write_rx_buf_num = next_buf_num;
+			if(next_buf_num == onchip_ch->read_rx_buf_num)
+				onchip_ch->read_rx_buf_num =
+				           inc_next_dma_buf_num(onchip_ch->read_rx_buf_num);
 
 			/* if receive overflow event */
 			if (overflow) {
@@ -631,11 +693,11 @@ static irqreturn_t kirkwood_tdm_irq(s32 irq, void *context_data)
 
 		case IRQ_TRANSMIT: {
 			/* get next buffer number, and move write/read pointer */
-			next_buf_num = inc_next_dma_buf_num(atomic_read(&onchip_ch->write_tx_buf_num));
-			atomic_set(&onchip_ch->write_tx_buf_num, next_buf_num);
-			if(next_buf_num == atomic_read(&onchip_ch->read_tx_buf_num))
-				atomic_set(&onchip_ch->read_tx_buf_num,
-				           inc_next_dma_buf_num(atomic_read(&onchip_ch->read_tx_buf_num)));
+			next_buf_num = inc_next_dma_buf_num(onchip_ch->write_tx_buf_num);
+			onchip_ch->write_tx_buf_num=  next_buf_num;
+			if(next_buf_num == onchip_ch->read_tx_buf_num)
+				onchip_ch->read_tx_buf_num =
+				           inc_next_dma_buf_num(onchip_ch->read_tx_buf_num);
 
 			/* if transmit overflow event */
 			if (overflow) {
@@ -777,7 +839,8 @@ static int __init kirkwood_tdm_probe(struct platform_device *pdev)
 	/* Set controller data */
 	tdm->bus_num = pdev->id;
 	tdm->settings = hw;
-	tdm->setup_voice_channel = kirkwood_setup_voice_channel;
+	tdm->init_voice_channel = kirkwood_init_voice_channel;
+	tdm->release_voice_channel = kirkwood_release_voice_channel;
 	tdm->recv = kirkwood_recv;
 	tdm->send = kirkwood_send;
 	tdm->run_audio = kirkwood_tdm_run_audio;
@@ -787,13 +850,16 @@ static int __init kirkwood_tdm_probe(struct platform_device *pdev)
 
 	for (i = 0; i < KIRKWOOD_MAX_VOICE_CHANNELS; i++)
 	{
+			struct kirkwood_tdm_voice *oncip_ch = onchip_tdm->voice_channels + i;
+
+	        spin_lock_init(&oncip_ch->lock);
 	        ch = tdm_alloc_voice_channel();
 	        if (ch == NULL) {
 	                dev_err(&pdev->dev, "Can`t alloc voice channel %d\n", i);
 	                goto out1;
 	        }
 
-            tdm_register_new_voice_channel(tdm, ch, (void *)(onchip_tdm->voice_channels + i));
+            tdm_register_new_voice_channel(tdm, ch, (void *)oncip_ch);
 	}
 
 
diff --git a/drivers/staging/tdm/kirkwood_tdm.h b/drivers/staging/tdm/kirkwood_tdm.h
index 6c7f34d..fe7aadf 100644
--- a/drivers/staging/tdm/kirkwood_tdm.h
+++ b/drivers/staging/tdm/kirkwood_tdm.h
@@ -58,6 +58,8 @@ struct kirkwood_tdm_regs {
  * Data specified for kirkwood hardware voice channel
  */
 struct kirkwood_tdm_voice {
+	spinlock_t		lock;
+
 	/* Transmitter and receiver buffers split to half.
 	 * While first half buffer is filling by DMA controller,
 	 * second half buffer is used by consumer and etc.
@@ -67,10 +69,10 @@ struct kirkwood_tdm_voice {
 
 	dma_addr_t tx_buff_phy[COUNT_DMA_BUFFERS_PER_CHANNEL]; /*  two physical pointers to tx_buf */
 	dma_addr_t rx_buff_phy[COUNT_DMA_BUFFERS_PER_CHANNEL]; /*  two physical pointers to rx_buf */
-	atomic_t write_tx_buf_num; /*  current writing transmit buffer number */
-	atomic_t read_tx_buf_num; /*  current reading transmit buffer number */
-	atomic_t write_rx_buf_num; /*  current writing receive buffer number */
-	atomic_t read_rx_buf_num; /*  current reading receive buffer number */
+	u8 write_tx_buf_num; /*  current writing transmit buffer number */
+	u8 read_tx_buf_num; /*  current reading transmit buffer number */
+	u8 write_rx_buf_num; /*  current writing receive buffer number */
+	u8 read_rx_buf_num; /*  current reading receive buffer number */
 };
 
 
diff --git a/drivers/staging/tdm/tdm.h b/drivers/staging/tdm/tdm.h
index ee7b5bf..80c1460 100644
--- a/drivers/staging/tdm/tdm.h
+++ b/drivers/staging/tdm/tdm.h
@@ -53,7 +53,7 @@ struct tdm_voice_channel {
 	wait_queue_head_t tx_queue;
 	wait_queue_head_t rx_queue;
 
-        struct list_head list; /*  Union all tdm voice channels by one controller */
+	struct list_head list; /*  Union all tdm voice channels by one controller */
 
 	struct device *dev; /*  device requested voice channel */
 };
@@ -106,7 +106,8 @@ struct tdm_controller {
 	/*  TDM hardware settings */
 	struct tdm_controller_hw_settings *settings;
 
-	int (*setup_voice_channel)(struct tdm_voice_channel *ch);
+	int (*init_voice_channel)(struct tdm_device *tdm_dev, struct tdm_voice_channel* ch);
+	int (*release_voice_channel)(struct tdm_device *tdm_dev);
 	int (*send)(struct tdm_voice_channel *ch, u8 *data);
 	int (*recv)(struct tdm_voice_channel *ch, u8 *data);
 	int (*run_audio)(struct tdm_device *tdm_dev);
diff --git a/drivers/staging/tdm/tdm_core.c b/drivers/staging/tdm/tdm_core.c
index 0182a4f..f3ac6fc 100644
--- a/drivers/staging/tdm/tdm_core.c
+++ b/drivers/staging/tdm/tdm_core.c
@@ -174,53 +174,64 @@ EXPORT_SYMBOL_GPL(tdm_unregister_driver);
 
 
 /**
- * Request unused voice channel
+ * Request and init unused voice channel
  * @param tdm_dev - TDM device requested voice channel
  * @return pointer to voice channel
  */
 struct tdm_voice_channel *request_voice_channel(struct tdm_device *tdm_dev) {
-        struct tdm_controller *tdm = tdm_dev->controller;
-        struct tdm_voice_channel *ch;
-        unsigned long flags;
+	struct tdm_controller *tdm = tdm_dev->controller;
+	struct tdm_voice_channel *ch;
+	unsigned long flags;
+	int rc;
 
-        spin_lock_irqsave(&tdm->lock, flags);
+	spin_lock_irqsave(&tdm->lock, flags);
 
 	list_for_each_entry(ch, &tdm->voice_channels, list)
                 if (ch->dev == NULL) {
                         ch->dev = &tdm_dev->dev;
+                        ch->mode_wideband = tdm_dev->mode_wideband;
+                        ch->tdm_channel = tdm_dev->tdm_channel_num;
                         tdm_dev->ch = ch;
                         spin_unlock_irqrestore(&tdm->lock, flags);
+                        rc = tdm->init_voice_channel(tdm_dev, ch);
+                        if (rc)
+                        {
+                            dev_err(&tdm_dev->dev, "Can't init TDM voice channel\n");
+                        	return NULL;
+                        }
+
                         return ch;
                 }
 
-        spin_unlock_irqrestore(&tdm->lock, flags);
-        return NULL;
+	spin_unlock_irqrestore(&tdm->lock, flags);
+	return NULL;
 }
 
 /**
- * Release requested voice channel
+ * Release requested early voice channel
  * @param TDM device requested early voice channel
  * @return 0 - OK
  */
 int release_voice_channel(struct tdm_device *tdm_dev)
 {
-        struct tdm_controller *tdm = tdm_dev->controller;
-        struct tdm_voice_channel *ch;
-        unsigned long flags;
+	struct tdm_controller *tdm = tdm_dev->controller;
+	struct tdm_voice_channel *ch;
+	unsigned long flags;
 
-        spin_lock_irqsave(&tdm->lock, flags);
+	spin_lock_irqsave(&tdm->lock, flags);
 
-        tdm_dev->ch = NULL;
+	tdm_dev->ch = NULL;
 	list_for_each_entry(ch, &tdm->voice_channels, list)
-                if (ch->dev == &tdm_dev->dev) {
-                        ch->dev = NULL;
-                        spin_unlock_irqrestore(&tdm->lock, flags);
-                        return 0;
-                }
+			if (ch->dev == &tdm_dev->dev) {
+					tdm->release_voice_channel(tdm_dev);
+					ch->dev = NULL;
+					spin_unlock_irqrestore(&tdm->lock, flags);
+					return 0;
+			}
 
-        spin_unlock_irqrestore(&tdm->lock, flags);
+	spin_unlock_irqrestore(&tdm->lock, flags);
 
-        return -ENODEV;
+	return -ENODEV;
 }
 
 
@@ -326,7 +337,6 @@ struct tdm_voice_channel *tdm_alloc_voice_channel(void)
         if (!ch)
                 return NULL;
 
-        memset(ch, 0, sizeof *ch);
         init_waitqueue_head(&ch->tx_queue);
         init_waitqueue_head(&ch->rx_queue);
 
@@ -614,19 +624,6 @@ int tdm_add_device(struct tdm_device *tdm_dev)
                 goto done;
         }
 
-        printk("ch = %s\n", dev_name(ch->dev));
-
-        /* Configuring voice channel */
-        ch->mode_wideband = tdm_dev->mode_wideband;
-        ch->tdm_channel = tdm_dev->tdm_channel_num;
-
-        /* Run setup voice channel */
-        status = tdm_dev->controller->setup_voice_channel(ch);
-        if (status < 0) {
-                dev_err(dev, "can't setup voice channel, status %d\n", status);
-                goto done;
-        }
-
         /* Device may be bound to an active driver when this returns */
         status = device_add(&tdm_dev->dev);
         if (status < 0)
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ