Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 130739
b: refs/heads/master
c: d7e4384
h: refs/heads/master
i:
  130737: d17e6ae
  130735: 96b23aa
v: v3
  • Loading branch information
Matthias Dahl authored and Mauro Carvalho Chehab committed Jan 29, 2009
1 parent ce16bdb commit bda2e5c
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0c37dd7a9052529cd9346b04530be7878c03e429
refs/heads/master: d7e43844e40e07cadc48f1733b9738659f83b38c
24 changes: 21 additions & 3 deletions trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ struct dvb_ca_slot {
/* current state of the CAM */
int slot_state;

/* mutex used for serializing access to one CI slot */
struct mutex slot_lock;

/* Number of CAMCHANGES that have occurred since last processing */
atomic_t camchange_count;

Expand Down Expand Up @@ -711,14 +714,20 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
dprintk("%s\n", __func__);


// sanity check
/* sanity check */
if (bytes_write > ca->slot_info[slot].link_buf_size)
return -EINVAL;

/* check if interface is actually waiting for us to read from it, or if a read is in progress */
/* it is possible we are dealing with a single buffer implementation,
thus if there is data available for read or if there is even a read
already in progress, we do nothing but awake the kernel thread to
process the data if necessary. */
if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
goto exitnowrite;
if (status & (STATUSREG_DA | STATUSREG_RE)) {
if (status & STATUSREG_DA)
dvb_ca_en50221_thread_wakeup(ca);

status = -EAGAIN;
goto exitnowrite;
}
Expand Down Expand Up @@ -987,6 +996,8 @@ static int dvb_ca_en50221_thread(void *data)
/* go through all the slots processing them */
for (slot = 0; slot < ca->slot_count; slot++) {

mutex_lock(&ca->slot_info[slot].slot_lock);

// check the cam status + deal with CAMCHANGEs
while (dvb_ca_en50221_check_camstatus(ca, slot)) {
/* clear down an old CI slot if necessary */
Expand Down Expand Up @@ -1122,7 +1133,7 @@ static int dvb_ca_en50221_thread(void *data)

case DVB_CA_SLOTSTATE_RUNNING:
if (!ca->open)
continue;
break;

// poll slots for data
pktcount = 0;
Expand All @@ -1146,6 +1157,8 @@ static int dvb_ca_en50221_thread(void *data)
}
break;
}

mutex_unlock(&ca->slot_info[slot].slot_lock);
}
}

Expand Down Expand Up @@ -1181,13 +1194,15 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case CA_RESET:
for (slot = 0; slot < ca->slot_count; slot++) {
mutex_lock(&ca->slot_info[slot].slot_lock);
if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
dvb_ca_en50221_slot_shutdown(ca, slot);
if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
dvb_ca_en50221_camchange_irq(ca->pub,
slot,
DVB_CA_EN50221_CAMCHANGE_INSERTED);
}
mutex_unlock(&ca->slot_info[slot].slot_lock);
}
ca->next_read_slot = 0;
dvb_ca_en50221_thread_wakeup(ca);
Expand Down Expand Up @@ -1308,7 +1323,9 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
goto exit;
}

mutex_lock(&ca->slot_info[slot].slot_lock);
status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
mutex_unlock(&ca->slot_info[slot].slot_lock);
if (status == (fraglen + 2)) {
written = 1;
break;
Expand Down Expand Up @@ -1664,6 +1681,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;
mutex_init(&ca->slot_info[i].slot_lock);
}

if (signal_pending(current)) {
Expand Down
6 changes: 4 additions & 2 deletions trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ struct dvb_ca_en50221 {
/* the module owning this structure */
struct module* owner;

/* NOTE: the read_*, write_* and poll_slot_status functions must use locks as
* they may be called from several threads at once */
/* NOTE: the read_*, write_* and poll_slot_status functions will be
* called for different slots concurrently and need to use locks where
* and if appropriate. There will be no concurrent access to one slot.
*/

/* functions for accessing attribute memory on the CAM */
int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);
Expand Down

0 comments on commit bda2e5c

Please sign in to comment.