@@ -35,6 +35,17 @@
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+/*
+ * FIXME - remove this conservative lock kludge, when the offending drivers
+ * that make some calls improperly from an interrupt context are fixed.
+ */
+int dmxdev_conservative_locks;
+
+module_param_named(conservative_locks, dmxdev_conservative_locks, int, 0644);
+MODULE_PARM_DESC(conservative_locks,
+ "Work around for drivers that make calls\n"
+ "\t\twith interrupts disabled (default:0/off).");
#define dprintk if (debug) printk
@@ -364,16 +375,22 @@
enum dmx_success success)
{
struct dmxdev_filter *dmxdevfilter = filter->priv;
- unsigned long flags;
+ unsigned long flags = 0;
int ret;
if (dmxdevfilter->buffer.error) {
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
- spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
+ else
+ spin_lock(&dmxdevfilter->dev->lock);
if (dmxdevfilter->state != DMXDEV_STATE_GO) {
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ else
+ spin_unlock(&dmxdevfilter->dev->lock);
return 0;
}
del_timer(&dmxdevfilter->timer);
@@ -392,7 +409,10 @@
}
if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
dmxdevfilter->state = DMXDEV_STATE_DONE;
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ else
+ spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
@@ -404,12 +424,18 @@
{
struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer;
- unsigned long flags;
+ unsigned long flags = 0;
int ret;
- spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
+ else
+ spin_lock(&dmxdevfilter->dev->lock);
if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ else
+ spin_unlock(&dmxdevfilter->dev->lock);
return 0;
}
@@ -419,7 +445,10 @@
else
buffer = &dmxdevfilter->dev->dvr_buffer;
if (buffer->error) {
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ else
+ spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&buffer->queue);
return 0;
}
@@ -430,7 +459,10 @@
dvb_ringbuffer_flush(buffer);
buffer->error = ret;
}
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ else
+ spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&buffer->queue);
return 0;
}
@@ -37,6 +37,12 @@
** #define DVB_DEMUX_SECTION_LOSS_LOG to monitor payload loss in the syslog
*/
// #define DVB_DEMUX_SECTION_LOSS_LOG
+
+/*
+ * FIXME - remove this conservative lock kludge, when the offending drivers
+ * that make some calls improperly from an interrupt context are fixed.
+ */
+extern int dmxdev_conservative_locks;
/******************************************************************************
* static inlined helper functions
@@ -399,9 +405,12 @@
void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
size_t count)
{
- unsigned long flags;
+ unsigned long flags = 0;
- spin_lock_irqsave(&demux->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_lock_irqsave(&demux->lock, flags);
+ else
+ spin_lock(&demux->lock);
while (count--) {
if (buf[0] == 0x47)
@@ -409,17 +418,23 @@
buf += 188;
}
- spin_unlock_irqrestore(&demux->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_unlock_irqrestore(&demux->lock, flags);
+ else
+ spin_unlock(&demux->lock);
}
EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
{
- unsigned long flags;
+ unsigned long flags = 0;
int p = 0, i, j;
- spin_lock_irqsave(&demux->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_lock_irqsave(&demux->lock, flags);
+ else
+ spin_lock(&demux->lock);
if (demux->tsbufp) {
i = demux->tsbufp;
@@ -452,18 +467,24 @@
}
bailout:
- spin_unlock_irqrestore(&demux->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_unlock_irqrestore(&demux->lock, flags);
+ else
+ spin_unlock(&demux->lock);
}
EXPORT_SYMBOL(dvb_dmx_swfilter);
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
{
- unsigned long flags;
+ unsigned long flags = 0;
int p = 0, i, j;
u8 tmppack[188];
- spin_lock_irqsave(&demux->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_lock_irqsave(&demux->lock, flags);
+ else
+ spin_lock(&demux->lock);
if (demux->tsbufp) {
i = demux->tsbufp;
@@ -504,7 +525,10 @@
}
bailout:
- spin_unlock_irqrestore(&demux->lock, flags);
+ if (dmxdev_conservative_locks)
+ spin_unlock_irqrestore(&demux->lock, flags);
+ else
+ spin_unlock(&demux->lock);
}
EXPORT_SYMBOL(dvb_dmx_swfilter_204);