summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb
diff options
context:
space:
mode:
authorAndrew de Quincy <devnull@localhost>2005-07-23 22:24:31 +0000
committerAndrew de Quincy <devnull@localhost>2005-07-23 22:24:31 +0000
commitdc3d59ccae0329939665505d585f92c2095591ca (patch)
treeca5c5ef102581b19cdc94630abea644b4be7921e /linux/drivers/media/dvb
parentfc5fdeb9baf0a40a275635f2cc5280445e39c581 (diff)
downloadmediapointer-dvb-s2-dc3d59ccae0329939665505d585f92c2095591ca.tar.gz
mediapointer-dvb-s2-dc3d59ccae0329939665505d585f92c2095591ca.tar.bz2
Convert to using read/write spinlocks to fix kernel errors as reported by
Michael Ditum Signed-off-by: Andrew de Quincey <adq_dvb@lidskialf.net>
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c68
1 files changed, 38 insertions, 30 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 0eb9aa711..b9d596883 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -35,7 +35,7 @@
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
-#include <linux/rwsem.h>
+#include <linux/spinlock.h>
#include "dvb_ca_en50221.h"
#include "dvb_ringbuffer.h"
@@ -110,8 +110,8 @@ struct dvb_ca_slot {
/* size of the buffer to use when talking to the CAM */
int link_buf_size;
- /* semaphore for syncing access to slot structure */
- struct rw_semaphore sem;
+ /* spinlock for syncing access to slot structure */
+ rwlock_t lock;
/* buffer for incoming packets */
struct dvb_ringbuffer rx_buffer;
@@ -594,6 +594,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb
int status;
u8 buf[HOST_LINK_BUF_SIZE];
int i;
+ unsigned long irqsave;
dprintk("%s\n", __FUNCTION__);
@@ -601,14 +602,14 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb
if (ebuf == NULL) {
int buf_free;
- down_read(&ca->slot_info[slot].sem);
+ read_lock_irqsave(&ca->slot_info[slot].lock, irqsave);
if (ca->slot_info[slot].rx_buffer.data == NULL) {
- up_read(&ca->slot_info[slot].sem);
+ read_unlock_irqrestore(&ca->slot_info[slot].lock, irqsave);
status = -EIO;
goto exit;
}
buf_free = dvb_ringbuffer_free(&ca->slot_info[slot].rx_buffer);
- up_read(&ca->slot_info[slot].sem);
+ read_unlock_irqrestore(&ca->slot_info[slot].lock, irqsave);
if (buf_free < (ca->slot_info[slot].link_buf_size + DVB_RINGBUFFER_PKTHDRSIZE)) {
status = -EAGAIN;
@@ -679,14 +680,14 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb
/* OK, add it to the receive buffer, or copy into external buffer if supplied */
if (ebuf == NULL) {
- down_read(&ca->slot_info[slot].sem);
+ read_lock_irqsave(&ca->slot_info[slot].lock, irqsave);
if (ca->slot_info[slot].rx_buffer.data == NULL) {
- up_read(&ca->slot_info[slot].sem);
+ read_unlock_irqrestore(&ca->slot_info[slot].lock, irqsave);
status = -EIO;
goto exit;
}
dvb_ringbuffer_pkt_write(&ca->slot_info[slot].rx_buffer, buf, bytes_read);
- up_read(&ca->slot_info[slot].sem);
+ read_unlock_irqrestore(&ca->slot_info[slot].lock, irqsave);
} else {
memcpy(ebuf, buf, bytes_read);
}
@@ -800,13 +801,14 @@ EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
{
dprintk("%s\n", __FUNCTION__);
+ unsigned long irqsave;
- down_write(&ca->slot_info[slot].sem);
+ write_lock_irqsave(&ca->slot_info[slot].lock, irqsave);
ca->pub->slot_shutdown(ca->pub, slot);
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
vfree(ca->slot_info[slot].rx_buffer.data);
ca->slot_info[slot].rx_buffer.data = NULL;
- up_write(&ca->slot_info[slot].sem);
+ write_unlock_irqrestore(&ca->slot_info[slot].lock, irqsave);
/* need to wake up all processes to check if they're now
trying to write to a defunct CAM */
@@ -1000,6 +1002,7 @@ static int dvb_ca_en50221_thread(void *data)
int status;
int pktcount;
void *rxbuf;
+ unsigned long irqsave;
dprintk("%s\n", __FUNCTION__);
@@ -1133,9 +1136,9 @@ static int dvb_ca_en50221_thread(void *data)
dvb_ca_en50221_thread_update_delay(ca);
break;
}
- down_write(&ca->slot_info[slot].sem);
+ write_lock_irqsave(&ca->slot_info[slot].lock, irqsave);
dvb_ringbuffer_init(&ca->slot_info[slot].rx_buffer, rxbuf, RX_BUFFER_SIZE);
- up_write(&ca->slot_info[slot].sem);
+ write_unlock_irqrestore(&ca->slot_info[slot].lock, irqsave);
ca->pub->slot_ts_enable(ca->pub, slot);
ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_RUNNING;
@@ -1366,7 +1369,9 @@ exit:
/**
* Condition for waking up in dvb_ca_en50221_io_read_condition
*/
-static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, int *result, int *_slot)
+static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca,
+ int *result, int *_slot,
+ unsigned long *irqsave)
{
int slot;
int slot_count = 0;
@@ -1381,10 +1386,10 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, int *resu
if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING)
goto nextslot;
- down_read(&ca->slot_info[slot].sem);
+ read_lock_irqsave(&ca->slot_info[slot].lock, *irqsave);
if (ca->slot_info[slot].rx_buffer.data == NULL) {
- up_read(&ca->slot_info[slot].sem);
+ read_unlock_irqrestore(&ca->slot_info[slot].lock, *irqsave);
return 0;
}
@@ -1403,9 +1408,9 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, int *resu
}
if (!found)
- up_read(&ca->slot_info[slot].sem);
+ read_unlock_irqrestore(&ca->slot_info[slot].lock, *irqsave);
- nextslot:
+nextslot:
slot = (slot + 1) % ca->slot_count;
slot_count++;
}
@@ -1440,6 +1445,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
size_t fraglen;
int pktlen;
int dispose = 0;
+ unsigned long irqsave;
dprintk("%s\n", __FUNCTION__);
@@ -1448,7 +1454,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
return -EINVAL;
/* wait for some data */
- if ((status = dvb_ca_en50221_io_read_condition(ca, &result, &slot)) == 0) {
+ if ((status = dvb_ca_en50221_io_read_condition(ca, &result, &slot, &irqsave)) == 0) {
/* if we're in nonblocking mode, exit immediately */
if (file->f_flags & O_NONBLOCK)
@@ -1457,7 +1463,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
/* wait for some data */
status = wait_event_interruptible(ca->wait_queue,
dvb_ca_en50221_io_read_condition
- (ca, &result, &slot));
+ (ca, &result, &slot, &irqsave));
}
if ((status < 0) || (result < 0)) {
if (result)
@@ -1510,8 +1516,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
goto exit;
status = pktlen;
- exit:
- up_read(&ca->slot_info[slot].sem);
+exit:
+ read_unlock_irqrestore(&ca->slot_info[slot].lock, irqsave);
return status;
}
@@ -1530,6 +1536,7 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
struct dvb_ca_private *ca = dvbdev->priv;
int err;
int i;
+ unsigned long irqsave;
dprintk("%s\n", __FUNCTION__);
@@ -1543,11 +1550,11 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
for (i = 0; i < ca->slot_count; i++) {
if (ca->slot_info[i].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
- down_write(&ca->slot_info[i].sem);
+ read_lock_irqsave(&ca->slot_info[i].lock, irqsave);
if (ca->slot_info[i].rx_buffer.data != NULL) {
dvb_ringbuffer_flush(&ca->slot_info[i].rx_buffer);
}
- up_write(&ca->slot_info[i].sem);
+ read_unlock_irqrestore(&ca->slot_info[i].lock, irqsave);
}
}
@@ -1602,11 +1609,12 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
unsigned int mask = 0;
int slot;
int result = 0;
+ unsigned long irqsave;
dprintk("%s\n", __FUNCTION__);
- if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
- up_read(&ca->slot_info[slot].sem);
+ if (dvb_ca_en50221_io_read_condition(ca, &result, &slot, &irqsave) == 1) {
+ read_unlock_irqrestore(&ca->slot_info[slot].lock, irqsave);
mask |= POLLIN;
}
@@ -1617,8 +1625,8 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
/* wait for something to happen */
poll_wait(file, &ca->wait_queue, wait);
- if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
- up_read(&ca->slot_info[slot].sem);
+ if (dvb_ca_en50221_io_read_condition(ca, &result, &slot, &irqsave) == 1) {
+ read_unlock_irqrestore(&ca->slot_info[slot].lock, irqsave);
mask |= POLLIN;
}
@@ -1708,7 +1716,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
atomic_set(&ca->slot_info[i].camchange_count, 0);
ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
- init_rwsem(&ca->slot_info[i].sem);
+ ca->slot_info[i].lock = RW_LOCK_UNLOCKED;
}
if (signal_pending(current)) {
@@ -1728,7 +1736,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
ca->thread_pid = ret;
return 0;
- error:
+error:
if (ca != NULL) {
if (ca->dvbdev != NULL)
dvb_unregister_device(ca->dvbdev);