From 458d337d90095b5d546c442e37de79db65fc9dfd Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 10 Sep 2008 00:39:20 -0400 Subject: add a general-purpose callback pointer to struct dvb_frontend From: Michael Krufky Remove tuner_callback pointers from tuner driver configuration and private state structures, replaced with a general-purpose callback pointer within struct dvb_frontend. A new parameter is added to the callback function, called component. This allows us to use this callback pointer by frontend components other than the tuner, if need be. So far, this is only used by tuner drivers. Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index 1207f29f2..a0c591b3b 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -234,6 +234,8 @@ struct dvb_frontend { void *sec_priv; void *analog_demod_priv; struct dtv_frontend_properties dtv_property_cache; +#define DVB_FRONTEND_COMPONENT_TUNER 0 + int (*callback)(void *adapter_priv, int component, int cmd, int arg); }; extern int dvb_register_frontend(struct dvb_adapter *dvb, -- cgit v1.2.3 From c20af2106a755d11b45e19ade56a98fa8bf6ca29 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 26 Sep 2008 11:29:03 +0200 Subject: implement proper locking in the dvb ca en50221 driver From: Matthias Dahl Concurrent access to a single DVB CA 50221 interface slot is generally discouraged. The underlying drivers (budget-av, budget-ci) do not implement proper locking and thus two transactions could (and do) interfere with on another. This fixes the following problems seen by others and myself: - sudden i/o errors when writing to the ci device which usually would result in an undefined state of the hw and require a software restart - errors about the CAM trying to send a buffer larger than the agreed size usually also resulting in an undefined state of the hw Due the to design of the DVB CA 50221 driver, implementing the locks in the underlying drivers would not be enough and still leave some race conditions, even though they were harder to trigger. Signed-off-by: Matthias Dahl Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c | 24 ++++++++++++++++++++--- linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.h | 6 ++++-- 2 files changed, 25 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') 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 f6016feab..19965a055 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -94,6 +94,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; @@ -712,14 +715,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; } @@ -988,6 +997,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 */ @@ -1123,7 +1134,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; @@ -1147,6 +1158,8 @@ static int dvb_ca_en50221_thread(void *data) } break; } + + mutex_unlock(&ca->slot_info[slot].slot_lock); } } @@ -1182,6 +1195,7 @@ 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) @@ -1189,6 +1203,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, 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); @@ -1309,7 +1324,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; @@ -1665,6 +1682,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)) { diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.h b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.h index 8467e63dd..7df2e1411 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.h @@ -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); -- cgit v1.2.3 From 3e2e701101286a530e336810f8ac8a2c546ed80e Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 4 Sep 2008 00:12:25 -0400 Subject: S2API: Added dvb frontend changes to support a newer tuning API From: Steven Toth This is an experimental patch to add a new tuning mechanism for dvb frontends. Rather than passing fixed structures across the user/kernel boundary, which need to be revised for each new modulation type (or feature the kernel developers want to add), this implements a simpler message based approach, allowing fe commands to be broken down into a series of small fixed size transactions, presented in an array. The goal is to avoid changing the user/kernel ABI in the future, by simply creating new frontend commands (and sequencies of commands) that help us add support for brand new demodulator, delivery system or statistics related commmands. known issues: checkpatch voilations feedback from various developers yet to be implemented, relating to namespace conventions, variable length array passing conventions, and generally some optimization. This patch should support all existing tuning mechanisms through the new API, as well as adding 8PSK, DVB-S2 NBC-QPSK and ISDB-T API support. For testing and exercise purposes, see the latest tune.c tool available from http://www.steventoth.net/linux/s2 Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 571 +++++++++++++++++++++++- linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 44 ++ 2 files changed, 609 insertions(+), 6 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 60a94dc85..e128bf221 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -766,6 +766,535 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, return 0; } +struct tv_cmds_h tv_cmds[] = { + [TV_SEQ_UNDEFINED] = { + .name = "TV_SEQ_UNDEFINED", + .cmd = TV_SEQ_UNDEFINED, + .set = 1, + }, + [TV_SEQ_START] = { + .name = "TV_SEQ_START", + .cmd = TV_SEQ_START, + .set = 1, + }, + [TV_SEQ_CONTINUE] = { + .name = "TV_SEQ_CONTINUE", + .cmd = TV_SEQ_CONTINUE, + .set = 1, + }, + [TV_SEQ_COMPLETE] = { + .name = "TV_SEQ_COMPLETE", + .cmd = TV_SEQ_COMPLETE, + .set = 1, + }, + [TV_SEQ_TERMINATE] = { + .name = "TV_SEQ_TERMINATE", + .cmd = TV_SEQ_TERMINATE, + .set = 1, + }, + + /* Set */ + [TV_SET_FREQUENCY] = { + .name = "TV_SET_FREQUENCY", + .cmd = TV_SET_FREQUENCY, + .set = 1, + }, + [TV_SET_BANDWIDTH] = { + .name = "TV_SET_BANDWIDTH", + .cmd = TV_SET_BANDWIDTH, + .set = 1, + }, + [TV_SET_MODULATION] = { + .name = "TV_SET_MODULATION", + .cmd = TV_SET_MODULATION, + .set = 1, + }, + [TV_SET_INVERSION] = { + .name = "TV_SET_INVERSION", + .cmd = TV_SET_INVERSION, + .set = 1, + }, + [TV_SET_DISEQC_MASTER] = { + .name = "TV_SET_DISEQC_MASTER", + .cmd = TV_SET_DISEQC_MASTER, + .set = 1, + .buffer = 1, + }, + [TV_SET_SYMBOLRATE] = { + .name = "TV_SET_SYMBOLRATE", + .cmd = TV_SET_SYMBOLRATE, + .set = 1, + }, + [TV_SET_INNERFEC] = { + .name = "TV_SET_INNERFEC", + .cmd = TV_SET_INNERFEC, + .set = 1, + }, + [TV_SET_VOLTAGE] = { + .name = "TV_SET_VOLTAGE", + .cmd = TV_SET_VOLTAGE, + .set = 1, + }, + [TV_SET_TONE] = { + .name = "TV_SET_TONE", + .cmd = TV_SET_TONE, + .set = 1, + }, + [TV_SET_PILOT] = { + .name = "TV_SET_PILOT", + .cmd = TV_SET_PILOT, + .set = 1, + }, + [TV_SET_ROLLOFF] = { + .name = "TV_SET_ROLLOFF", + .cmd = TV_SET_ROLLOFF, + .set = 1, + }, + [TV_SET_DELIVERY_SYSTEM] = { + .name = "TV_SET_DELIVERY_SYSTEM", + .cmd = TV_SET_DELIVERY_SYSTEM, + .set = 1, + }, + [TV_SET_ISDB_SEGMENT_NUM] = { + .name = "TV_SET_ISDB_SEGMENT_NUM", + .cmd = TV_SET_ISDB_SEGMENT_NUM, + .set = 1, + }, + [TV_SET_ISDB_SEGMENT_WIDTH] = { + .name = "TV_SET_ISDB_SEGMENT_WIDTH", + .cmd = TV_SET_ISDB_SEGMENT_WIDTH, + .set = 1, + }, + + /* Get */ + [TV_GET_FREQUENCY] = { + .name = "TV_GET_FREQUENCY", + .cmd = TV_GET_FREQUENCY, + .set = 0, + }, + [TV_GET_BANDWIDTH] = { + .name = "TV_GET_BANDWIDTH", + .cmd = TV_GET_BANDWIDTH, + .set = 0, + }, + [TV_GET_MODULATION] = { + .name = "TV_GET_MODULATION", + .cmd = TV_GET_MODULATION, + .set = 0, + }, + [TV_GET_INVERSION] = { + .name = "TV_GET_INVERSION", + .cmd = TV_GET_INVERSION, + .set = 0, + }, + [TV_GET_DISEQC_SLAVE_REPLY] = { + .name = "TV_GET_DISEQC_SLAVE_REPLY", + .cmd = TV_GET_DISEQC_SLAVE_REPLY, + .set = 0, + .buffer = 1, + }, + [TV_GET_SYMBOLRATE] = { + .name = "TV_GET_SYMBOLRATE", + .cmd = TV_GET_SYMBOLRATE, + .set = 0, + }, + [TV_GET_INNERFEC] = { + .name = "TV_GET_INNERFEC", + .cmd = TV_GET_INNERFEC, + .set = 0, + }, + [TV_GET_VOLTAGE] = { + .name = "TV_GET_VOLTAGE", + .cmd = TV_GET_VOLTAGE, + .set = 0, + }, + [TV_GET_TONE] = { + .name = "TV_GET_TONE", + .cmd = TV_GET_TONE, + .set = 0, + }, + [TV_GET_PILOT] = { + .name = "TV_GET_PILOT", + .cmd = TV_GET_PILOT, + .set = 0, + }, + [TV_GET_ROLLOFF] = { + .name = "TV_GET_ROLLOFF", + .cmd = TV_GET_ROLLOFF, + .set = 0, + }, + [TV_GET_DELIVERY_SYSTEM] = { + .name = "TV_GET_DELIVERY_SYSTEM", + .cmd = TV_GET_DELIVERY_SYSTEM, + .set = 0, + }, + [TV_GET_ISDB_SEGMENT_NUM] = { + .name = "TV_GET_ISDB_SEGMENT_NUM", + .cmd = TV_GET_ISDB_SEGMENT_NUM, + .set = 0, + }, + [TV_GET_ISDB_SEGMENT_WIDTH] = { + .name = "TV_GET_ISDB_SEGMENT_WIDTH", + .cmd = TV_GET_ISDB_SEGMENT_WIDTH, + .set = 0, + }, + [TV_GET_ISDB_LAYERA_FEC] = { + .name = "TV_GET_ISDB_LAYERA_FEC", + .cmd = TV_GET_ISDB_LAYERA_FEC, + .set = 0, + }, + [TV_GET_ISDB_LAYERA_MODULATION] = { + .name = "TV_GET_ISDB_LAYERA_MODULATION", + .cmd = TV_GET_ISDB_LAYERA_MODULATION, + .set = 0, + }, + [TV_GET_ISDB_LAYERA_SEGMENT_WIDTH] = { + .name = "TV_GET_ISDB_LAYERA_SEGMENT_WIDTH", + .cmd = TV_GET_ISDB_LAYERA_SEGMENT_WIDTH, + .set = 0, + }, + [TV_GET_ISDB_LAYERB_FEC] = { + .name = "TV_GET_ISDB_LAYERB_FEC", + .cmd = TV_GET_ISDB_LAYERB_FEC, + .set = 0, + }, + [TV_GET_ISDB_LAYERB_MODULATION] = { + .name = "TV_GET_ISDB_LAYERB_MODULATION", + .cmd = TV_GET_ISDB_LAYERB_MODULATION, + .set = 0, + }, + [TV_GET_ISDB_LAYERB_SEGMENT_WIDTH] = { + .name = "TV_GET_ISDB_LAYERB_SEGMENT_WIDTH", + .cmd = TV_GET_ISDB_LAYERB_SEGMENT_WIDTH, + .set = 0, + }, + [TV_GET_ISDB_LAYERC_FEC] = { + .name = "TV_GET_ISDB_LAYERC_FEC", + .cmd = TV_GET_ISDB_LAYERC_FEC, + .set = 0, + }, + [TV_GET_ISDB_LAYERC_MODULATION] = { + .name = "TV_GET_ISDB_LAYERC_MODULATION", + .cmd = TV_GET_ISDB_LAYERC_MODULATION, + .set = 0, + }, + [TV_GET_ISDB_LAYERC_SEGMENT_WIDTH] = { + .name = "TV_GET_ISDB_LAYERC_SEGMENT_WIDTH", + .cmd = TV_GET_ISDB_LAYERC_SEGMENT_WIDTH, + .set = 0, + }, +}; + +void tv_property_dump(tv_property_t *tvp) +{ + int i; + + printk("%s() tvp.cmd = 0x%08x (%s)\n" + ,__FUNCTION__ + ,tvp->cmd + ,tv_cmds[ tvp->cmd ].name); + + if(tv_cmds[ tvp->cmd ].buffer) { + + printk("%s() tvp.u.buffer.len = 0x%02x\n" + ,__FUNCTION__ + ,tvp->u.buffer.len); + + for(i = 0; i < tvp->u.buffer.len; i++) + printk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n" + ,__FUNCTION__ + ,i + ,tvp->u.buffer.data[i]); + + } else + printk("%s() tvp.u.data = 0x%08x\n", __FUNCTION__, tvp->u.data); +} + +int is_legacy_delivery_system(fe_delivery_system_t s) +{ + if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) || + (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS)) + return 1; + + return 0; +} + +int tv_property_cache_submit(struct dvb_frontend *fe) +{ + + /* We have to do one of two things: + * To support legacy devices using the new API we take values from + * the tv_cache and generate a legacy truning structure. + * + * Or, + * + * To support advanced tuning devices with the new API we + * notify the new advance driver type that a tuning operation is required + * and let it pull values from the cache as is, we don't need to + * pass structures. + * + * We'll use the modulation type to assess how this is handled. as the API + * progresses we'll probably want to have a flag in dvb_frontend_ops + * to allow the frontend driver to dictate how it likes to be tuned. + * + * Because of how this is attached to the ioctl handler for legacy support, + * it's important to return an appropriate result code with atleast the following + * three meanings: + * < 0 = processing error + * 0 = lecagy ioctl handler to submit a traditional set_frontend() call. + * 1 = lecagy ioctl handler should NOT submit a traditional set_frontend() call. + */ + + int r; + + struct tv_frontend_properties *c = &fe->tv_property_cache; + struct dvb_frontend_private *fepriv = fe->frontend_priv; + struct dvb_frontend_parameters p; + + printk("%s()\n", __FUNCTION__); + + /* For legacy delivery systems we don't need the delivery_system to be specified */ + if(is_legacy_delivery_system(c->delivery_system)) { + switch(c->modulation) { + case QPSK: + printk("%s() Preparing QPSK req\n", __FUNCTION__); + p.frequency = c->frequency; + p.inversion = c->inversion; + p.u.qpsk.symbol_rate = c->symbol_rate; + p.u.qpsk.fec_inner = c->fec_inner; + memcpy(&fepriv->parameters, &p, + sizeof (struct dvb_frontend_parameters)); + + /* Call the traditional tuning mechanisms. */ + + r = 0; + break; + case QAM_16: + case QAM_32: + case QAM_64: + case QAM_128: + case QAM_256: + case QAM_AUTO: + printk("%s() Preparing QAM req\n", __FUNCTION__); + p.frequency = c->frequency; + p.inversion = c->inversion; + p.u.qam.symbol_rate = c->symbol_rate; + p.u.vsb.modulation = c->modulation; + printk("%s() frequency = %d\n", __FUNCTION__, p.frequency); + printk("%s() QAM = %d\n", __FUNCTION__, p.u.vsb.modulation); + memcpy(&fepriv->parameters, &p, + sizeof (struct dvb_frontend_parameters)); + + /* At this point we're fully formed for backwards + * compatability and we need to return this + * via the ioctl handler as SET_FRONTEND (arg). + * We've already patched the new values into the + * frontends tuning structures so the ioctl code just + * continues as if a legacy tune structure was passed + * from userspace. + */ + + r = 0; + break; + case VSB_8: + case VSB_16: + printk("%s() Preparing VSB req\n", __FUNCTION__); + p.frequency = c->frequency; + p.u.vsb.modulation = c->modulation; + memcpy(&fepriv->parameters, &p, + sizeof (struct dvb_frontend_parameters)); + + /* Call the traditional tuning mechanisms. */ + + r = 0; + break; + /* TODO: Add any missing modulation types */ + default: + r = -1; + } + } else { + /* For advanced delivery systems / modulation types ... + * we seed the lecacy dvb_frontend_parameters structure + * so that the sanity checking code later in the IOCTL processing + * can validate our basic frequency ranges, symbolrates, modulation + * etc. + */ + r = -1; + + switch(c->modulation) { + case _8PSK: + case _16APSK: + case NBC_QPSK: + /* Just post a notification to the demod driver and let it pull + * the specific values it wants from its tv_property_cache. + * It can decide how best to use those parameters. + * IOCTL will call set_frontend (by default) due to zigzag + * support etc. + */ + if (fe->ops.set_params) + r = fe->ops.set_params(fe); + + p.frequency = c->frequency; + p.inversion = c->inversion; + p.u.qpsk.symbol_rate = c->symbol_rate; + p.u.qpsk.fec_inner = c->fec_inner; + memcpy(&fepriv->parameters, &p, + sizeof (struct dvb_frontend_parameters)); + + r = 0; + break; + default: + r = -1; + } + + if(c->delivery_system == SYS_ISDBT) { + /* Fake out a generic DVB-T request so we pass validation in the ioctl */ + p.frequency = c->frequency; + p.inversion = INVERSION_AUTO; + p.u.ofdm.constellation = QAM_AUTO; + p.u.ofdm.code_rate_HP = FEC_AUTO; + p.u.ofdm.code_rate_LP = FEC_AUTO; + p.u.ofdm.bandwidth = BANDWIDTH_AUTO; + p.u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; + p.u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; + p.u.ofdm.hierarchy_information = HIERARCHY_AUTO; + memcpy(&fepriv->parameters, &p, + sizeof (struct dvb_frontend_parameters)); + + r = 0; + } + } + return r; +} + +int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp) +{ + int r = 0; + printk("%s()\n", __FUNCTION__); + tv_property_dump(tvp); + + switch(tvp->cmd) { + case TV_SEQ_START: + case TV_SEQ_TERMINATE: + /* Reset a cache of data specific to the frontend here. This does + * not effect hardware. + */ + printk("%s() Flushing property cache\n", __FUNCTION__); + memset(&fe->tv_property_cache, 0, sizeof(struct tv_frontend_properties)); + fe->tv_property_cache.state = TV_SEQ_START; + fe->tv_property_cache.delivery_system = SYS_UNDEFINED; + break; + case TV_SEQ_COMPLETE: + /* interpret the cache of data, build either a traditional frontend + * tunerequest and submit it to a subset of the ioctl handler, + * or, call a new undefined method on the frontend to deal with + * all new tune requests. + */ + fe->tv_property_cache.state = TV_SEQ_COMPLETE; + printk("%s() Finalised property cache\n", __FUNCTION__); + r = tv_property_cache_submit(fe); + break; + case TV_SET_FREQUENCY: + fe->tv_property_cache.frequency = tvp->u.data; + break; + case TV_GET_FREQUENCY: + tvp->u.data = fe->tv_property_cache.frequency; + break; + case TV_SET_MODULATION: + fe->tv_property_cache.modulation = tvp->u.data; + break; + case TV_GET_MODULATION: + tvp->u.data = fe->tv_property_cache.modulation; + break; + case TV_SET_BANDWIDTH: + fe->tv_property_cache.bandwidth = tvp->u.data; + break; + case TV_GET_BANDWIDTH: + tvp->u.data = fe->tv_property_cache.bandwidth; + break; + case TV_SET_INVERSION: + fe->tv_property_cache.inversion = tvp->u.data; + break; + case TV_GET_INVERSION: + tvp->u.data = fe->tv_property_cache.inversion; + break; + case TV_SET_SYMBOLRATE: + fe->tv_property_cache.symbol_rate = tvp->u.data; + break; + case TV_GET_SYMBOLRATE: + tvp->u.data = fe->tv_property_cache.symbol_rate; + break; + case TV_SET_INNERFEC: + fe->tv_property_cache.fec_inner = tvp->u.data; + break; + case TV_GET_INNERFEC: + tvp->u.data = fe->tv_property_cache.fec_inner; + break; + case TV_SET_PILOT: + fe->tv_property_cache.pilot = tvp->u.data; + break; + case TV_GET_PILOT: + tvp->u.data = fe->tv_property_cache.pilot; + break; + case TV_SET_ROLLOFF: + fe->tv_property_cache.rolloff = tvp->u.data; + break; + case TV_GET_ROLLOFF: + tvp->u.data = fe->tv_property_cache.rolloff; + break; + case TV_SET_DELIVERY_SYSTEM: + fe->tv_property_cache.delivery_system = tvp->u.data; + break; + case TV_GET_DELIVERY_SYSTEM: + tvp->u.data = fe->tv_property_cache.delivery_system; + break; + + /* ISDB-T Support here */ + case TV_SET_ISDB_SEGMENT_NUM: + fe->tv_property_cache.isdb_segment_num = tvp->u.data; + break; + case TV_GET_ISDB_SEGMENT_NUM: + tvp->u.data = fe->tv_property_cache.isdb_segment_num; + break; + case TV_SET_ISDB_SEGMENT_WIDTH: + fe->tv_property_cache.isdb_segment_width = tvp->u.data; + break; + case TV_GET_ISDB_SEGMENT_WIDTH: + tvp->u.data = fe->tv_property_cache.isdb_segment_width; + break; + case TV_GET_ISDB_LAYERA_FEC: + tvp->u.data = fe->tv_property_cache.isdb_layera_fec; + break; + case TV_GET_ISDB_LAYERA_MODULATION: + tvp->u.data = fe->tv_property_cache.isdb_layera_modulation; + break; + case TV_GET_ISDB_LAYERA_SEGMENT_WIDTH: + tvp->u.data = fe->tv_property_cache.isdb_layera_segment_width; + break; + case TV_GET_ISDB_LAYERB_FEC: + tvp->u.data = fe->tv_property_cache.isdb_layerb_fec; + break; + case TV_GET_ISDB_LAYERB_MODULATION: + tvp->u.data = fe->tv_property_cache.isdb_layerb_modulation; + break; + case TV_GET_ISDB_LAYERB_SEGMENT_WIDTH: + tvp->u.data = fe->tv_property_cache.isdb_layerb_segment_width; + break; + case TV_GET_ISDB_LAYERC_FEC: + tvp->u.data = fe->tv_property_cache.isdb_layerc_fec; + break; + case TV_GET_ISDB_LAYERC_MODULATION: + tvp->u.data = fe->tv_property_cache.isdb_layerc_modulation; + break; + case TV_GET_ISDB_LAYERC_SEGMENT_WIDTH: + tvp->u.data = fe->tv_property_cache.isdb_layerc_segment_width; + break; + + } + + return 0; +} + static int dvb_frontend_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { @@ -773,6 +1302,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend_private *fepriv = fe->frontend_priv; int err = -EOPNOTSUPP; + tv_property_t* tvp; dprintk ("%s\n", __func__); @@ -787,6 +1317,27 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, if (down_interruptible (&fepriv->sem)) return -ERESTARTSYS; + if(cmd == FE_SET_PROPERTY) { + printk("%s() FE_SET_PROPERTY\n", __FUNCTION__); + + /* TODO: basic property validation here */ + + /* TODO: ioctl userdata out of range check here */ + tvp = parg; + while(tvp->cmd != TV_SEQ_UNDEFINED) { + tv_property_process(fe, tvp); + if( (tvp->cmd == TV_SEQ_TERMINATE) || (tvp->cmd == TV_SEQ_COMPLETE) ) + break; + tvp++; + } + + if(fe->tv_property_cache.state == TV_SEQ_COMPLETE) { + printk("%s() Property cache is full, tuning\n", __FUNCTION__); + cmd = FE_SET_FRONTEND; + } + err = 0; + } + switch (cmd) { case FE_GET_INFO: { struct dvb_frontend_info* info = parg; @@ -953,13 +1504,20 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, case FE_SET_FRONTEND: { struct dvb_frontend_tune_settings fetunesettings; - if (dvb_frontend_check_parameters(fe, parg) < 0) { - err = -EINVAL; - break; - } + if(fe->tv_property_cache.state == TV_SEQ_COMPLETE) { + if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) { + err = -EINVAL; + break; + } + } else { + if (dvb_frontend_check_parameters(fe, parg) < 0) { + err = -EINVAL; + break; + } - memcpy (&fepriv->parameters, parg, - sizeof (struct dvb_frontend_parameters)); + memcpy (&fepriv->parameters, parg, + sizeof (struct dvb_frontend_parameters)); + } memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); memcpy(&fetunesettings.parameters, parg, @@ -1042,6 +1600,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, return err; } + static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struct *wait) { struct dvb_device *dvbdev = file->private_data; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index aa4133f0b..61d53ee70 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -169,6 +169,10 @@ struct dvb_frontend_ops { struct dvb_tuner_ops tuner_ops; struct analog_demod_ops analog_ops; + + int (*set_property)(struct dvb_frontend* fe, tv_property_t* tvp); + int (*get_property)(struct dvb_frontend* fe, tv_property_t* tvp); + int (*set_params)(struct dvb_frontend* fe); }; #define MAX_EVENT 8 @@ -182,6 +186,45 @@ struct dvb_fe_events { struct mutex mtx; }; +struct tv_frontend_properties { + + /* Cache State */ + u32 state; + + u32 frequency; + fe_modulation_t modulation; + + fe_sec_voltage_t voltage; + fe_sec_tone_mode_t sectone; + fe_spectral_inversion_t inversion; + fe_code_rate_t fec_inner; + fe_transmit_mode_t transmission_mode; + fe_bandwidth_t bandwidth; + fe_guard_interval_t guard_interval; + fe_hierarchy_t hierarchy; + u32 symbol_rate; + fe_code_rate_t code_rate_HP; + fe_code_rate_t code_rate_LP; + + fe_pilot_t pilot; + fe_rolloff_t rolloff; + + fe_delivery_system_t delivery_system; + + /* ISDB-T specifics */ + u32 isdb_segment_num; + u32 isdb_segment_width; + fe_code_rate_t isdb_layera_fec; + fe_modulation_t isdb_layera_modulation; + u32 isdb_layera_segment_width; + fe_code_rate_t isdb_layerb_fec; + fe_modulation_t isdb_layerb_modulation; + u32 isdb_layerb_segment_width; + fe_code_rate_t isdb_layerc_fec; + fe_modulation_t isdb_layerc_modulation; + u32 isdb_layerc_segment_width; +}; + struct dvb_frontend { struct dvb_frontend_ops ops; struct dvb_adapter *dvb; @@ -190,6 +233,7 @@ struct dvb_frontend { void *frontend_priv; void *sec_priv; void *analog_demod_priv; + struct tv_frontend_properties tv_property_cache; }; extern int dvb_register_frontend(struct dvb_adapter *dvb, -- cgit v1.2.3 From 095219cbe03bb0401bd154ab1bd6dfb831f17a5a Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 4 Sep 2008 20:19:43 -0400 Subject: S2API: Allow the properties to call legacy ioctls From: Steven Toth SET_TONE and SET_VOLTAGE were not previously implemented. Two options existed. Either cut/paste from the previous ioctl handler into the process_properties function, which is code duplication. Or, split the current ioctl handler into it's two major pieces. Piece 1, responsible for input validation and semaphore acquiring Piece 2 the processing of the previous ioctls and finally, a new third pieces where the array of properties is processed, and can freely call the legacy ioctl handler without having to re-acquire the fepriv->sem semaphore. This is a clean approach and ensures the existing legacy ioctls are processed as they were previously (but with an extra function call) and allows the new API to share code without duplication. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 67 ++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index e128bf221..e17dd050c 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1167,9 +1167,16 @@ int tv_property_cache_submit(struct dvb_frontend *fe) return r; } -int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp) +static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, + unsigned int cmd, void *parg); +static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, + unsigned int cmd, void *parg); + +int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp, + struct inode *inode, struct file *file) { int r = 0; + struct dvb_frontend_private *fepriv = fe->frontend_priv; printk("%s()\n", __FUNCTION__); tv_property_dump(tvp); @@ -1192,7 +1199,9 @@ int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp) */ fe->tv_property_cache.state = TV_SEQ_COMPLETE; printk("%s() Finalised property cache\n", __FUNCTION__); - r = tv_property_cache_submit(fe); + r |= tv_property_cache_submit(fe); + r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, + &fepriv->parameters); break; case TV_SET_FREQUENCY: fe->tv_property_cache.frequency = tvp->u.data; @@ -1289,10 +1298,25 @@ int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp) case TV_GET_ISDB_LAYERC_SEGMENT_WIDTH: tvp->u.data = fe->tv_property_cache.isdb_layerc_segment_width; break; - + case TV_SET_VOLTAGE: + fe->tv_property_cache.voltage = tvp->u.data; + r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE, + &fe->tv_property_cache.voltage); + break; + case TV_GET_VOLTAGE: + tvp->u.data = fe->tv_property_cache.voltage; + break; + case TV_SET_TONE: + fe->tv_property_cache.sectone = tvp->u.data; + r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_TONE, + (void *)fe->tv_property_cache.sectone); + break; + case TV_GET_TONE: + tvp->u.data = fe->tv_property_cache.sectone; + break; } - return 0; + return r; } static int dvb_frontend_ioctl(struct inode *inode, struct file *file, @@ -1302,7 +1326,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend_private *fepriv = fe->frontend_priv; int err = -EOPNOTSUPP; - tv_property_t* tvp; dprintk ("%s\n", __func__); @@ -1317,6 +1340,25 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, if (down_interruptible (&fepriv->sem)) return -ERESTARTSYS; + if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) + err = dvb_frontend_ioctl_properties(inode, file, cmd, parg); + else + err = dvb_frontend_ioctl_legacy(inode, file, cmd, parg); + + up(&fepriv->sem); + return err; +} + +static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, + unsigned int cmd, void *parg) +{ + struct dvb_device *dvbdev = file->private_data; + struct dvb_frontend *fe = dvbdev->priv; + int err = -EOPNOTSUPP; + tv_property_t *tvp; + + dprintk("%s\n", __func__); + if(cmd == FE_SET_PROPERTY) { printk("%s() FE_SET_PROPERTY\n", __FUNCTION__); @@ -1325,7 +1367,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, /* TODO: ioctl userdata out of range check here */ tvp = parg; while(tvp->cmd != TV_SEQ_UNDEFINED) { - tv_property_process(fe, tvp); + tv_property_process(fe, tvp, inode, file); if( (tvp->cmd == TV_SEQ_TERMINATE) || (tvp->cmd == TV_SEQ_COMPLETE) ) break; tvp++; @@ -1333,11 +1375,21 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, if(fe->tv_property_cache.state == TV_SEQ_COMPLETE) { printk("%s() Property cache is full, tuning\n", __FUNCTION__); - cmd = FE_SET_FRONTEND; } err = 0; } + return err; +} + +static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, + unsigned int cmd, void *parg) +{ + struct dvb_device *dvbdev = file->private_data; + struct dvb_frontend *fe = dvbdev->priv; + struct dvb_frontend_private *fepriv = fe->frontend_priv; + int err = -EOPNOTSUPP; + switch (cmd) { case FE_GET_INFO: { struct dvb_frontend_info* info = parg; @@ -1596,7 +1648,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, break; }; - up (&fepriv->sem); return err; } -- cgit v1.2.3 From 6d9b01f13a3c2d24b45b7ca718606854e8cdf17a Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 8 Sep 2008 11:07:06 -0400 Subject: S2API: DVB-S/S2 voltage selection bug fix From: Steven Toth Thanks to Hans Werner for finding the problem. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index e17dd050c..fbe2b8c6d 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1301,7 +1301,7 @@ int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp, case TV_SET_VOLTAGE: fe->tv_property_cache.voltage = tvp->u.data; r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE, - &fe->tv_property_cache.voltage); + (void *)fe->tv_property_cache.voltage); break; case TV_GET_VOLTAGE: tvp->u.data = fe->tv_property_cache.voltage; -- cgit v1.2.3 From 68901d77882c18dcb4f6e1fa0309e93893f1a7a0 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 09:19:27 -0400 Subject: S2API: tv_ / TV_ to dtv_ / DTV_ namespace changes From: Steven Toth The group preferred dtv_ over tv_, this implements it. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 442 ++++++++++++------------ linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 8 +- 2 files changed, 225 insertions(+), 225 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index fbe2b8c6d..7a94aaa09 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -766,235 +766,235 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, return 0; } -struct tv_cmds_h tv_cmds[] = { - [TV_SEQ_UNDEFINED] = { - .name = "TV_SEQ_UNDEFINED", - .cmd = TV_SEQ_UNDEFINED, +struct dtv_cmds_h dtv_cmds[] = { + [DTV_SEQ_UNDEFINED] = { + .name = "DTV_SEQ_UNDEFINED", + .cmd = DTV_SEQ_UNDEFINED, .set = 1, }, - [TV_SEQ_START] = { - .name = "TV_SEQ_START", - .cmd = TV_SEQ_START, + [DTV_SEQ_START] = { + .name = "DTV_SEQ_START", + .cmd = DTV_SEQ_START, .set = 1, }, - [TV_SEQ_CONTINUE] = { - .name = "TV_SEQ_CONTINUE", - .cmd = TV_SEQ_CONTINUE, + [DTV_SEQ_CONTINUE] = { + .name = "DTV_SEQ_CONTINUE", + .cmd = DTV_SEQ_CONTINUE, .set = 1, }, - [TV_SEQ_COMPLETE] = { - .name = "TV_SEQ_COMPLETE", - .cmd = TV_SEQ_COMPLETE, + [DTV_SEQ_COMPLETE] = { + .name = "DTV_SEQ_COMPLETE", + .cmd = DTV_SEQ_COMPLETE, .set = 1, }, - [TV_SEQ_TERMINATE] = { - .name = "TV_SEQ_TERMINATE", - .cmd = TV_SEQ_TERMINATE, + [DTV_SEQ_TERMINATE] = { + .name = "DTV_SEQ_TERMINATE", + .cmd = DTV_SEQ_TERMINATE, .set = 1, }, /* Set */ - [TV_SET_FREQUENCY] = { - .name = "TV_SET_FREQUENCY", - .cmd = TV_SET_FREQUENCY, + [DTV_SET_FREQUENCY] = { + .name = "DTV_SET_FREQUENCY", + .cmd = DTV_SET_FREQUENCY, .set = 1, }, - [TV_SET_BANDWIDTH] = { - .name = "TV_SET_BANDWIDTH", - .cmd = TV_SET_BANDWIDTH, + [DTV_SET_BANDWIDTH] = { + .name = "DTV_SET_BANDWIDTH", + .cmd = DTV_SET_BANDWIDTH, .set = 1, }, - [TV_SET_MODULATION] = { - .name = "TV_SET_MODULATION", - .cmd = TV_SET_MODULATION, + [DTV_SET_MODULATION] = { + .name = "DTV_SET_MODULATION", + .cmd = DTV_SET_MODULATION, .set = 1, }, - [TV_SET_INVERSION] = { - .name = "TV_SET_INVERSION", - .cmd = TV_SET_INVERSION, + [DTV_SET_INVERSION] = { + .name = "DTV_SET_INVERSION", + .cmd = DTV_SET_INVERSION, .set = 1, }, - [TV_SET_DISEQC_MASTER] = { - .name = "TV_SET_DISEQC_MASTER", - .cmd = TV_SET_DISEQC_MASTER, + [DTV_SET_DISEQC_MASTER] = { + .name = "DTV_SET_DISEQC_MASTER", + .cmd = DTV_SET_DISEQC_MASTER, .set = 1, .buffer = 1, }, - [TV_SET_SYMBOLRATE] = { - .name = "TV_SET_SYMBOLRATE", - .cmd = TV_SET_SYMBOLRATE, + [DTV_SET_SYMBOLRATE] = { + .name = "DTV_SET_SYMBOLRATE", + .cmd = DTV_SET_SYMBOLRATE, .set = 1, }, - [TV_SET_INNERFEC] = { - .name = "TV_SET_INNERFEC", - .cmd = TV_SET_INNERFEC, + [DTV_SET_INNERFEC] = { + .name = "DTV_SET_INNERFEC", + .cmd = DTV_SET_INNERFEC, .set = 1, }, - [TV_SET_VOLTAGE] = { - .name = "TV_SET_VOLTAGE", - .cmd = TV_SET_VOLTAGE, + [DTV_SET_VOLTAGE] = { + .name = "DTV_SET_VOLTAGE", + .cmd = DTV_SET_VOLTAGE, .set = 1, }, - [TV_SET_TONE] = { - .name = "TV_SET_TONE", - .cmd = TV_SET_TONE, + [DTV_SET_TONE] = { + .name = "DTV_SET_TONE", + .cmd = DTV_SET_TONE, .set = 1, }, - [TV_SET_PILOT] = { - .name = "TV_SET_PILOT", - .cmd = TV_SET_PILOT, + [DTV_SET_PILOT] = { + .name = "DTV_SET_PILOT", + .cmd = DTV_SET_PILOT, .set = 1, }, - [TV_SET_ROLLOFF] = { - .name = "TV_SET_ROLLOFF", - .cmd = TV_SET_ROLLOFF, + [DTV_SET_ROLLOFF] = { + .name = "DTV_SET_ROLLOFF", + .cmd = DTV_SET_ROLLOFF, .set = 1, }, - [TV_SET_DELIVERY_SYSTEM] = { - .name = "TV_SET_DELIVERY_SYSTEM", - .cmd = TV_SET_DELIVERY_SYSTEM, + [DTV_SET_DELIVERY_SYSTEM] = { + .name = "DTV_SET_DELIVERY_SYSTEM", + .cmd = DTV_SET_DELIVERY_SYSTEM, .set = 1, }, - [TV_SET_ISDB_SEGMENT_NUM] = { - .name = "TV_SET_ISDB_SEGMENT_NUM", - .cmd = TV_SET_ISDB_SEGMENT_NUM, + [DTV_SET_ISDB_SEGMENT_NUM] = { + .name = "DTV_SET_ISDB_SEGMENT_NUM", + .cmd = DTV_SET_ISDB_SEGMENT_NUM, .set = 1, }, - [TV_SET_ISDB_SEGMENT_WIDTH] = { - .name = "TV_SET_ISDB_SEGMENT_WIDTH", - .cmd = TV_SET_ISDB_SEGMENT_WIDTH, + [DTV_SET_ISDB_SEGMENT_WIDTH] = { + .name = "DTV_SET_ISDB_SEGMENT_WIDTH", + .cmd = DTV_SET_ISDB_SEGMENT_WIDTH, .set = 1, }, /* Get */ - [TV_GET_FREQUENCY] = { - .name = "TV_GET_FREQUENCY", - .cmd = TV_GET_FREQUENCY, + [DTV_GET_FREQUENCY] = { + .name = "DTV_GET_FREQUENCY", + .cmd = DTV_GET_FREQUENCY, .set = 0, }, - [TV_GET_BANDWIDTH] = { - .name = "TV_GET_BANDWIDTH", - .cmd = TV_GET_BANDWIDTH, + [DTV_GET_BANDWIDTH] = { + .name = "DTV_GET_BANDWIDTH", + .cmd = DTV_GET_BANDWIDTH, .set = 0, }, - [TV_GET_MODULATION] = { - .name = "TV_GET_MODULATION", - .cmd = TV_GET_MODULATION, + [DTV_GET_MODULATION] = { + .name = "DTV_GET_MODULATION", + .cmd = DTV_GET_MODULATION, .set = 0, }, - [TV_GET_INVERSION] = { - .name = "TV_GET_INVERSION", - .cmd = TV_GET_INVERSION, + [DTV_GET_INVERSION] = { + .name = "DTV_GET_INVERSION", + .cmd = DTV_GET_INVERSION, .set = 0, }, - [TV_GET_DISEQC_SLAVE_REPLY] = { - .name = "TV_GET_DISEQC_SLAVE_REPLY", - .cmd = TV_GET_DISEQC_SLAVE_REPLY, + [DTV_GET_DISEQC_SLAVE_REPLY] = { + .name = "DTV_GET_DISEQC_SLAVE_REPLY", + .cmd = DTV_GET_DISEQC_SLAVE_REPLY, .set = 0, .buffer = 1, }, - [TV_GET_SYMBOLRATE] = { - .name = "TV_GET_SYMBOLRATE", - .cmd = TV_GET_SYMBOLRATE, + [DTV_GET_SYMBOLRATE] = { + .name = "DTV_GET_SYMBOLRATE", + .cmd = DTV_GET_SYMBOLRATE, .set = 0, }, - [TV_GET_INNERFEC] = { - .name = "TV_GET_INNERFEC", - .cmd = TV_GET_INNERFEC, + [DTV_GET_INNERFEC] = { + .name = "DTV_GET_INNERFEC", + .cmd = DTV_GET_INNERFEC, .set = 0, }, - [TV_GET_VOLTAGE] = { - .name = "TV_GET_VOLTAGE", - .cmd = TV_GET_VOLTAGE, + [DTV_GET_VOLTAGE] = { + .name = "DTV_GET_VOLTAGE", + .cmd = DTV_GET_VOLTAGE, .set = 0, }, - [TV_GET_TONE] = { - .name = "TV_GET_TONE", - .cmd = TV_GET_TONE, + [DTV_GET_TONE] = { + .name = "DTV_GET_TONE", + .cmd = DTV_GET_TONE, .set = 0, }, - [TV_GET_PILOT] = { - .name = "TV_GET_PILOT", - .cmd = TV_GET_PILOT, + [DTV_GET_PILOT] = { + .name = "DTV_GET_PILOT", + .cmd = DTV_GET_PILOT, .set = 0, }, - [TV_GET_ROLLOFF] = { - .name = "TV_GET_ROLLOFF", - .cmd = TV_GET_ROLLOFF, + [DTV_GET_ROLLOFF] = { + .name = "DTV_GET_ROLLOFF", + .cmd = DTV_GET_ROLLOFF, .set = 0, }, - [TV_GET_DELIVERY_SYSTEM] = { - .name = "TV_GET_DELIVERY_SYSTEM", - .cmd = TV_GET_DELIVERY_SYSTEM, + [DTV_GET_DELIVERY_SYSTEM] = { + .name = "DTV_GET_DELIVERY_SYSTEM", + .cmd = DTV_GET_DELIVERY_SYSTEM, .set = 0, }, - [TV_GET_ISDB_SEGMENT_NUM] = { - .name = "TV_GET_ISDB_SEGMENT_NUM", - .cmd = TV_GET_ISDB_SEGMENT_NUM, + [DTV_GET_ISDB_SEGMENT_NUM] = { + .name = "DTV_GET_ISDB_SEGMENT_NUM", + .cmd = DTV_GET_ISDB_SEGMENT_NUM, .set = 0, }, - [TV_GET_ISDB_SEGMENT_WIDTH] = { - .name = "TV_GET_ISDB_SEGMENT_WIDTH", - .cmd = TV_GET_ISDB_SEGMENT_WIDTH, + [DTV_GET_ISDB_SEGMENT_WIDTH] = { + .name = "DTV_GET_ISDB_SEGMENT_WIDTH", + .cmd = DTV_GET_ISDB_SEGMENT_WIDTH, .set = 0, }, - [TV_GET_ISDB_LAYERA_FEC] = { - .name = "TV_GET_ISDB_LAYERA_FEC", - .cmd = TV_GET_ISDB_LAYERA_FEC, + [DTV_GET_ISDB_LAYERA_FEC] = { + .name = "DTV_GET_ISDB_LAYERA_FEC", + .cmd = DTV_GET_ISDB_LAYERA_FEC, .set = 0, }, - [TV_GET_ISDB_LAYERA_MODULATION] = { - .name = "TV_GET_ISDB_LAYERA_MODULATION", - .cmd = TV_GET_ISDB_LAYERA_MODULATION, + [DTV_GET_ISDB_LAYERA_MODULATION] = { + .name = "DTV_GET_ISDB_LAYERA_MODULATION", + .cmd = DTV_GET_ISDB_LAYERA_MODULATION, .set = 0, }, - [TV_GET_ISDB_LAYERA_SEGMENT_WIDTH] = { - .name = "TV_GET_ISDB_LAYERA_SEGMENT_WIDTH", - .cmd = TV_GET_ISDB_LAYERA_SEGMENT_WIDTH, + [DTV_GET_ISDB_LAYERA_SEGMENT_WIDTH] = { + .name = "DTV_GET_ISDB_LAYERA_SEGMENT_WIDTH", + .cmd = DTV_GET_ISDB_LAYERA_SEGMENT_WIDTH, .set = 0, }, - [TV_GET_ISDB_LAYERB_FEC] = { - .name = "TV_GET_ISDB_LAYERB_FEC", - .cmd = TV_GET_ISDB_LAYERB_FEC, + [DTV_GET_ISDB_LAYERB_FEC] = { + .name = "DTV_GET_ISDB_LAYERB_FEC", + .cmd = DTV_GET_ISDB_LAYERB_FEC, .set = 0, }, - [TV_GET_ISDB_LAYERB_MODULATION] = { - .name = "TV_GET_ISDB_LAYERB_MODULATION", - .cmd = TV_GET_ISDB_LAYERB_MODULATION, + [DTV_GET_ISDB_LAYERB_MODULATION] = { + .name = "DTV_GET_ISDB_LAYERB_MODULATION", + .cmd = DTV_GET_ISDB_LAYERB_MODULATION, .set = 0, }, - [TV_GET_ISDB_LAYERB_SEGMENT_WIDTH] = { - .name = "TV_GET_ISDB_LAYERB_SEGMENT_WIDTH", - .cmd = TV_GET_ISDB_LAYERB_SEGMENT_WIDTH, + [DTV_GET_ISDB_LAYERB_SEGMENT_WIDTH] = { + .name = "DTV_GET_ISDB_LAYERB_SEGMENT_WIDTH", + .cmd = DTV_GET_ISDB_LAYERB_SEGMENT_WIDTH, .set = 0, }, - [TV_GET_ISDB_LAYERC_FEC] = { - .name = "TV_GET_ISDB_LAYERC_FEC", - .cmd = TV_GET_ISDB_LAYERC_FEC, + [DTV_GET_ISDB_LAYERC_FEC] = { + .name = "DTV_GET_ISDB_LAYERC_FEC", + .cmd = DTV_GET_ISDB_LAYERC_FEC, .set = 0, }, - [TV_GET_ISDB_LAYERC_MODULATION] = { - .name = "TV_GET_ISDB_LAYERC_MODULATION", - .cmd = TV_GET_ISDB_LAYERC_MODULATION, + [DTV_GET_ISDB_LAYERC_MODULATION] = { + .name = "DTV_GET_ISDB_LAYERC_MODULATION", + .cmd = DTV_GET_ISDB_LAYERC_MODULATION, .set = 0, }, - [TV_GET_ISDB_LAYERC_SEGMENT_WIDTH] = { - .name = "TV_GET_ISDB_LAYERC_SEGMENT_WIDTH", - .cmd = TV_GET_ISDB_LAYERC_SEGMENT_WIDTH, + [DTV_GET_ISDB_LAYERC_SEGMENT_WIDTH] = { + .name = "DTV_GET_ISDB_LAYERC_SEGMENT_WIDTH", + .cmd = DTV_GET_ISDB_LAYERC_SEGMENT_WIDTH, .set = 0, }, }; -void tv_property_dump(tv_property_t *tvp) +void dtv_property_dump(dtv_property_t *tvp) { int i; printk("%s() tvp.cmd = 0x%08x (%s)\n" ,__FUNCTION__ ,tvp->cmd - ,tv_cmds[ tvp->cmd ].name); + ,dtv_cmds[ tvp->cmd ].name); - if(tv_cmds[ tvp->cmd ].buffer) { + if(dtv_cmds[ tvp->cmd ].buffer) { printk("%s() tvp.u.buffer.len = 0x%02x\n" ,__FUNCTION__ @@ -1019,7 +1019,7 @@ int is_legacy_delivery_system(fe_delivery_system_t s) return 0; } -int tv_property_cache_submit(struct dvb_frontend *fe) +int dtv_property_cache_submit(struct dvb_frontend *fe) { /* We have to do one of two things: @@ -1047,7 +1047,7 @@ int tv_property_cache_submit(struct dvb_frontend *fe) int r; - struct tv_frontend_properties *c = &fe->tv_property_cache; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_parameters p; @@ -1126,7 +1126,7 @@ int tv_property_cache_submit(struct dvb_frontend *fe) case _16APSK: case NBC_QPSK: /* Just post a notification to the demod driver and let it pull - * the specific values it wants from its tv_property_cache. + * the specific values it wants from its dtv_property_cache. * It can decide how best to use those parameters. * IOCTL will call set_frontend (by default) due to zigzag * support etc. @@ -1172,147 +1172,147 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, unsigned int cmd, void *parg); -int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp, +int dtv_property_process(struct dvb_frontend *fe, dtv_property_t *tvp, struct inode *inode, struct file *file) { int r = 0; struct dvb_frontend_private *fepriv = fe->frontend_priv; printk("%s()\n", __FUNCTION__); - tv_property_dump(tvp); + dtv_property_dump(tvp); switch(tvp->cmd) { - case TV_SEQ_START: - case TV_SEQ_TERMINATE: + case DTV_SEQ_START: + case DTV_SEQ_TERMINATE: /* Reset a cache of data specific to the frontend here. This does * not effect hardware. */ printk("%s() Flushing property cache\n", __FUNCTION__); - memset(&fe->tv_property_cache, 0, sizeof(struct tv_frontend_properties)); - fe->tv_property_cache.state = TV_SEQ_START; - fe->tv_property_cache.delivery_system = SYS_UNDEFINED; + memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties)); + fe->dtv_property_cache.state = DTV_SEQ_START; + fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; break; - case TV_SEQ_COMPLETE: + case DTV_SEQ_COMPLETE: /* interpret the cache of data, build either a traditional frontend * tunerequest and submit it to a subset of the ioctl handler, * or, call a new undefined method on the frontend to deal with * all new tune requests. */ - fe->tv_property_cache.state = TV_SEQ_COMPLETE; + fe->dtv_property_cache.state = DTV_SEQ_COMPLETE; printk("%s() Finalised property cache\n", __FUNCTION__); - r |= tv_property_cache_submit(fe); + r |= dtv_property_cache_submit(fe); r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, &fepriv->parameters); break; - case TV_SET_FREQUENCY: - fe->tv_property_cache.frequency = tvp->u.data; + case DTV_SET_FREQUENCY: + fe->dtv_property_cache.frequency = tvp->u.data; break; - case TV_GET_FREQUENCY: - tvp->u.data = fe->tv_property_cache.frequency; + case DTV_GET_FREQUENCY: + tvp->u.data = fe->dtv_property_cache.frequency; break; - case TV_SET_MODULATION: - fe->tv_property_cache.modulation = tvp->u.data; + case DTV_SET_MODULATION: + fe->dtv_property_cache.modulation = tvp->u.data; break; - case TV_GET_MODULATION: - tvp->u.data = fe->tv_property_cache.modulation; + case DTV_GET_MODULATION: + tvp->u.data = fe->dtv_property_cache.modulation; break; - case TV_SET_BANDWIDTH: - fe->tv_property_cache.bandwidth = tvp->u.data; + case DTV_SET_BANDWIDTH: + fe->dtv_property_cache.bandwidth = tvp->u.data; break; - case TV_GET_BANDWIDTH: - tvp->u.data = fe->tv_property_cache.bandwidth; + case DTV_GET_BANDWIDTH: + tvp->u.data = fe->dtv_property_cache.bandwidth; break; - case TV_SET_INVERSION: - fe->tv_property_cache.inversion = tvp->u.data; + case DTV_SET_INVERSION: + fe->dtv_property_cache.inversion = tvp->u.data; break; - case TV_GET_INVERSION: - tvp->u.data = fe->tv_property_cache.inversion; + case DTV_GET_INVERSION: + tvp->u.data = fe->dtv_property_cache.inversion; break; - case TV_SET_SYMBOLRATE: - fe->tv_property_cache.symbol_rate = tvp->u.data; + case DTV_SET_SYMBOLRATE: + fe->dtv_property_cache.symbol_rate = tvp->u.data; break; - case TV_GET_SYMBOLRATE: - tvp->u.data = fe->tv_property_cache.symbol_rate; + case DTV_GET_SYMBOLRATE: + tvp->u.data = fe->dtv_property_cache.symbol_rate; break; - case TV_SET_INNERFEC: - fe->tv_property_cache.fec_inner = tvp->u.data; + case DTV_SET_INNERFEC: + fe->dtv_property_cache.fec_inner = tvp->u.data; break; - case TV_GET_INNERFEC: - tvp->u.data = fe->tv_property_cache.fec_inner; + case DTV_GET_INNERFEC: + tvp->u.data = fe->dtv_property_cache.fec_inner; break; - case TV_SET_PILOT: - fe->tv_property_cache.pilot = tvp->u.data; + case DTV_SET_PILOT: + fe->dtv_property_cache.pilot = tvp->u.data; break; - case TV_GET_PILOT: - tvp->u.data = fe->tv_property_cache.pilot; + case DTV_GET_PILOT: + tvp->u.data = fe->dtv_property_cache.pilot; break; - case TV_SET_ROLLOFF: - fe->tv_property_cache.rolloff = tvp->u.data; + case DTV_SET_ROLLOFF: + fe->dtv_property_cache.rolloff = tvp->u.data; break; - case TV_GET_ROLLOFF: - tvp->u.data = fe->tv_property_cache.rolloff; + case DTV_GET_ROLLOFF: + tvp->u.data = fe->dtv_property_cache.rolloff; break; - case TV_SET_DELIVERY_SYSTEM: - fe->tv_property_cache.delivery_system = tvp->u.data; + case DTV_SET_DELIVERY_SYSTEM: + fe->dtv_property_cache.delivery_system = tvp->u.data; break; - case TV_GET_DELIVERY_SYSTEM: - tvp->u.data = fe->tv_property_cache.delivery_system; + case DTV_GET_DELIVERY_SYSTEM: + tvp->u.data = fe->dtv_property_cache.delivery_system; break; /* ISDB-T Support here */ - case TV_SET_ISDB_SEGMENT_NUM: - fe->tv_property_cache.isdb_segment_num = tvp->u.data; + case DTV_SET_ISDB_SEGMENT_NUM: + fe->dtv_property_cache.isdb_segment_num = tvp->u.data; break; - case TV_GET_ISDB_SEGMENT_NUM: - tvp->u.data = fe->tv_property_cache.isdb_segment_num; + case DTV_GET_ISDB_SEGMENT_NUM: + tvp->u.data = fe->dtv_property_cache.isdb_segment_num; break; - case TV_SET_ISDB_SEGMENT_WIDTH: - fe->tv_property_cache.isdb_segment_width = tvp->u.data; + case DTV_SET_ISDB_SEGMENT_WIDTH: + fe->dtv_property_cache.isdb_segment_width = tvp->u.data; break; - case TV_GET_ISDB_SEGMENT_WIDTH: - tvp->u.data = fe->tv_property_cache.isdb_segment_width; + case DTV_GET_ISDB_SEGMENT_WIDTH: + tvp->u.data = fe->dtv_property_cache.isdb_segment_width; break; - case TV_GET_ISDB_LAYERA_FEC: - tvp->u.data = fe->tv_property_cache.isdb_layera_fec; + case DTV_GET_ISDB_LAYERA_FEC: + tvp->u.data = fe->dtv_property_cache.isdb_layera_fec; break; - case TV_GET_ISDB_LAYERA_MODULATION: - tvp->u.data = fe->tv_property_cache.isdb_layera_modulation; + case DTV_GET_ISDB_LAYERA_MODULATION: + tvp->u.data = fe->dtv_property_cache.isdb_layera_modulation; break; - case TV_GET_ISDB_LAYERA_SEGMENT_WIDTH: - tvp->u.data = fe->tv_property_cache.isdb_layera_segment_width; + case DTV_GET_ISDB_LAYERA_SEGMENT_WIDTH: + tvp->u.data = fe->dtv_property_cache.isdb_layera_segment_width; break; - case TV_GET_ISDB_LAYERB_FEC: - tvp->u.data = fe->tv_property_cache.isdb_layerb_fec; + case DTV_GET_ISDB_LAYERB_FEC: + tvp->u.data = fe->dtv_property_cache.isdb_layerb_fec; break; - case TV_GET_ISDB_LAYERB_MODULATION: - tvp->u.data = fe->tv_property_cache.isdb_layerb_modulation; + case DTV_GET_ISDB_LAYERB_MODULATION: + tvp->u.data = fe->dtv_property_cache.isdb_layerb_modulation; break; - case TV_GET_ISDB_LAYERB_SEGMENT_WIDTH: - tvp->u.data = fe->tv_property_cache.isdb_layerb_segment_width; + case DTV_GET_ISDB_LAYERB_SEGMENT_WIDTH: + tvp->u.data = fe->dtv_property_cache.isdb_layerb_segment_width; break; - case TV_GET_ISDB_LAYERC_FEC: - tvp->u.data = fe->tv_property_cache.isdb_layerc_fec; + case DTV_GET_ISDB_LAYERC_FEC: + tvp->u.data = fe->dtv_property_cache.isdb_layerc_fec; break; - case TV_GET_ISDB_LAYERC_MODULATION: - tvp->u.data = fe->tv_property_cache.isdb_layerc_modulation; + case DTV_GET_ISDB_LAYERC_MODULATION: + tvp->u.data = fe->dtv_property_cache.isdb_layerc_modulation; break; - case TV_GET_ISDB_LAYERC_SEGMENT_WIDTH: - tvp->u.data = fe->tv_property_cache.isdb_layerc_segment_width; + case DTV_GET_ISDB_LAYERC_SEGMENT_WIDTH: + tvp->u.data = fe->dtv_property_cache.isdb_layerc_segment_width; break; - case TV_SET_VOLTAGE: - fe->tv_property_cache.voltage = tvp->u.data; + case DTV_SET_VOLTAGE: + fe->dtv_property_cache.voltage = tvp->u.data; r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE, - (void *)fe->tv_property_cache.voltage); + (void *)fe->dtv_property_cache.voltage); break; - case TV_GET_VOLTAGE: - tvp->u.data = fe->tv_property_cache.voltage; + case DTV_GET_VOLTAGE: + tvp->u.data = fe->dtv_property_cache.voltage; break; - case TV_SET_TONE: - fe->tv_property_cache.sectone = tvp->u.data; + case DTV_SET_TONE: + fe->dtv_property_cache.sectone = tvp->u.data; r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_TONE, - (void *)fe->tv_property_cache.sectone); + (void *)fe->dtv_property_cache.sectone); break; - case TV_GET_TONE: - tvp->u.data = fe->tv_property_cache.sectone; + case DTV_GET_TONE: + tvp->u.data = fe->dtv_property_cache.sectone; break; } @@ -1355,7 +1355,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, struct dvb_device *dvbdev = file->private_data; struct dvb_frontend *fe = dvbdev->priv; int err = -EOPNOTSUPP; - tv_property_t *tvp; + dtv_property_t *tvp; dprintk("%s\n", __func__); @@ -1366,14 +1366,14 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, /* TODO: ioctl userdata out of range check here */ tvp = parg; - while(tvp->cmd != TV_SEQ_UNDEFINED) { - tv_property_process(fe, tvp, inode, file); - if( (tvp->cmd == TV_SEQ_TERMINATE) || (tvp->cmd == TV_SEQ_COMPLETE) ) + while(tvp->cmd != DTV_SEQ_UNDEFINED) { + dtv_property_process(fe, tvp, inode, file); + if( (tvp->cmd == DTV_SEQ_TERMINATE) || (tvp->cmd == DTV_SEQ_COMPLETE) ) break; tvp++; } - if(fe->tv_property_cache.state == TV_SEQ_COMPLETE) { + if(fe->dtv_property_cache.state == DTV_SEQ_COMPLETE) { printk("%s() Property cache is full, tuning\n", __FUNCTION__); } err = 0; @@ -1556,7 +1556,7 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, case FE_SET_FRONTEND: { struct dvb_frontend_tune_settings fetunesettings; - if(fe->tv_property_cache.state == TV_SEQ_COMPLETE) { + if(fe->dtv_property_cache.state == DTV_SEQ_COMPLETE) { if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) { err = -EINVAL; break; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index 61d53ee70..f376f281c 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -170,8 +170,8 @@ struct dvb_frontend_ops { struct dvb_tuner_ops tuner_ops; struct analog_demod_ops analog_ops; - int (*set_property)(struct dvb_frontend* fe, tv_property_t* tvp); - int (*get_property)(struct dvb_frontend* fe, tv_property_t* tvp); + int (*set_property)(struct dvb_frontend* fe, dtv_property_t* tvp); + int (*get_property)(struct dvb_frontend* fe, dtv_property_t* tvp); int (*set_params)(struct dvb_frontend* fe); }; @@ -186,7 +186,7 @@ struct dvb_fe_events { struct mutex mtx; }; -struct tv_frontend_properties { +struct dtv_frontend_properties { /* Cache State */ u32 state; @@ -233,7 +233,7 @@ struct dvb_frontend { void *frontend_priv; void *sec_priv; void *analog_demod_priv; - struct tv_frontend_properties tv_property_cache; + struct dtv_frontend_properties dtv_property_cache; }; extern int dvb_register_frontend(struct dvb_adapter *dvb, -- cgit v1.2.3 From 991e6d40e8d9894e3dba60323fad2c7b79948788 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 09:23:01 -0400 Subject: S2API: typedefs replaced, _SEQ_'s removed, fixed 16 command arrays replaced From: Steven Toth After discussion the following changes were made: 1. Removed the typedefs in frontend.h, use structures. 2. In the frontend.h, remove the 16 command limit on the API and switch to a flexible variable length API. For practical reasons a #define limits this to 64, this should be discussed. 3. Changed dvb-core ioctl handing to deal with variable sequences of commands. tune-v0.0.3.c is required to use this API, it contains the interface changes. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 83 +++++++++++++------------ linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 4 +- 2 files changed, 45 insertions(+), 42 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 7a94aaa09..98819daf8 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -767,29 +767,14 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, } struct dtv_cmds_h dtv_cmds[] = { - [DTV_SEQ_UNDEFINED] = { - .name = "DTV_SEQ_UNDEFINED", - .cmd = DTV_SEQ_UNDEFINED, + [DTV_TUNE] = { + .name = "DTV_TUNE", + .cmd = DTV_TUNE, .set = 1, }, - [DTV_SEQ_START] = { - .name = "DTV_SEQ_START", - .cmd = DTV_SEQ_START, - .set = 1, - }, - [DTV_SEQ_CONTINUE] = { - .name = "DTV_SEQ_CONTINUE", - .cmd = DTV_SEQ_CONTINUE, - .set = 1, - }, - [DTV_SEQ_COMPLETE] = { - .name = "DTV_SEQ_COMPLETE", - .cmd = DTV_SEQ_COMPLETE, - .set = 1, - }, - [DTV_SEQ_TERMINATE] = { - .name = "DTV_SEQ_TERMINATE", - .cmd = DTV_SEQ_TERMINATE, + [DTV_CLEAR] = { + .name = "DTV_CLEAR", + .cmd = DTV_CLEAR, .set = 1, }, @@ -985,7 +970,7 @@ struct dtv_cmds_h dtv_cmds[] = { }, }; -void dtv_property_dump(dtv_property_t *tvp) +void dtv_property_dump(struct dtv_property *tvp) { int i; @@ -1055,6 +1040,7 @@ int dtv_property_cache_submit(struct dvb_frontend *fe) /* For legacy delivery systems we don't need the delivery_system to be specified */ if(is_legacy_delivery_system(c->delivery_system)) { + printk("%s() legacy, modulation = %d\n", __FUNCTION__, c->modulation); switch(c->modulation) { case QPSK: printk("%s() Preparing QPSK req\n", __FUNCTION__); @@ -1172,7 +1158,7 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, unsigned int cmd, void *parg); -int dtv_property_process(struct dvb_frontend *fe, dtv_property_t *tvp, +int dtv_property_process(struct dvb_frontend *fe, struct dtv_property *tvp, struct inode *inode, struct file *file) { int r = 0; @@ -1181,23 +1167,22 @@ int dtv_property_process(struct dvb_frontend *fe, dtv_property_t *tvp, dtv_property_dump(tvp); switch(tvp->cmd) { - case DTV_SEQ_START: - case DTV_SEQ_TERMINATE: + case DTV_CLEAR: /* Reset a cache of data specific to the frontend here. This does * not effect hardware. */ printk("%s() Flushing property cache\n", __FUNCTION__); memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties)); - fe->dtv_property_cache.state = DTV_SEQ_START; + fe->dtv_property_cache.state = tvp->cmd; fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; break; - case DTV_SEQ_COMPLETE: + case DTV_TUNE: /* interpret the cache of data, build either a traditional frontend * tunerequest and submit it to a subset of the ioctl handler, * or, call a new undefined method on the frontend to deal with * all new tune requests. */ - fe->dtv_property_cache.state = DTV_SEQ_COMPLETE; + fe->dtv_property_cache.state = tvp->cmd; printk("%s() Finalised property cache\n", __FUNCTION__); r |= dtv_property_cache_submit(fe); r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, @@ -1355,30 +1340,48 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, struct dvb_device *dvbdev = file->private_data; struct dvb_frontend *fe = dvbdev->priv; int err = -EOPNOTSUPP; - dtv_property_t *tvp; + + struct dtv_properties *tvps = NULL; + struct dtv_property *tvp = NULL; + int i; dprintk("%s\n", __func__); if(cmd == FE_SET_PROPERTY) { printk("%s() FE_SET_PROPERTY\n", __FUNCTION__); - /* TODO: basic property validation here */ + tvps = (struct dtv_properties __user *)parg; - /* TODO: ioctl userdata out of range check here */ - tvp = parg; - while(tvp->cmd != DTV_SEQ_UNDEFINED) { - dtv_property_process(fe, tvp, inode, file); - if( (tvp->cmd == DTV_SEQ_TERMINATE) || (tvp->cmd == DTV_SEQ_COMPLETE) ) - break; - tvp++; + printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num); + printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props); + + /* Put an arbitrary limit on the number of messages that can + * be sent at once */ + if (tvps->num > DTV_IOCTL_MAX_MSGS) + return -EINVAL; + + tvp = (struct dtv_property *) kmalloc(tvps->num * + sizeof(struct dtv_property), GFP_KERNEL); + if (!tvp) { + err = -ENOMEM; + goto out; } - if(fe->dtv_property_cache.state == DTV_SEQ_COMPLETE) { + if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) { + err = -EFAULT; + goto out; + } + + for (i = 0; i < tvps->num; i++) + dtv_property_process(fe, tvp + i, inode, file); + + if(fe->dtv_property_cache.state == DTV_TUNE) { printk("%s() Property cache is full, tuning\n", __FUNCTION__); } err = 0; } - +out: + kfree(tvp); return err; } @@ -1556,7 +1559,7 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, case FE_SET_FRONTEND: { struct dvb_frontend_tune_settings fetunesettings; - if(fe->dtv_property_cache.state == DTV_SEQ_COMPLETE) { + if(fe->dtv_property_cache.state == DTV_TUNE) { if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) { err = -EINVAL; break; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index f376f281c..85d30201a 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -170,8 +170,8 @@ struct dvb_frontend_ops { struct dvb_tuner_ops tuner_ops; struct analog_demod_ops analog_ops; - int (*set_property)(struct dvb_frontend* fe, dtv_property_t* tvp); - int (*get_property)(struct dvb_frontend* fe, dtv_property_t* tvp); + int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp); + int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp); int (*set_params)(struct dvb_frontend* fe); }; -- cgit v1.2.3 From ce1c579ddcf7b3f27370a985b9563af2e4907a9b Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 09:34:19 -0400 Subject: S2API: Cleanup SYMBOLRATE, INNERFEC -> SYMBOL_RATE, INNER_FEC From: Steven Toth This is now consistent with the existing API. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 98819daf8..9f9a92457 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -805,14 +805,14 @@ struct dtv_cmds_h dtv_cmds[] = { .set = 1, .buffer = 1, }, - [DTV_SET_SYMBOLRATE] = { - .name = "DTV_SET_SYMBOLRATE", - .cmd = DTV_SET_SYMBOLRATE, + [DTV_SET_SYMBOL_RATE] = { + .name = "DTV_SET_SYMBOL_RATE", + .cmd = DTV_SET_SYMBOL_RATE, .set = 1, }, - [DTV_SET_INNERFEC] = { - .name = "DTV_SET_INNERFEC", - .cmd = DTV_SET_INNERFEC, + [DTV_SET_INNER_FEC] = { + .name = "DTV_SET_INNER_FEC", + .cmd = DTV_SET_INNER_FEC, .set = 1, }, [DTV_SET_VOLTAGE] = { @@ -878,14 +878,14 @@ struct dtv_cmds_h dtv_cmds[] = { .set = 0, .buffer = 1, }, - [DTV_GET_SYMBOLRATE] = { - .name = "DTV_GET_SYMBOLRATE", - .cmd = DTV_GET_SYMBOLRATE, + [DTV_GET_SYMBOL_RATE] = { + .name = "DTV_GET_SYMBOL_RATE", + .cmd = DTV_GET_SYMBOL_RATE, .set = 0, }, - [DTV_GET_INNERFEC] = { - .name = "DTV_GET_INNERFEC", - .cmd = DTV_GET_INNERFEC, + [DTV_GET_INNER_FEC] = { + .name = "DTV_GET_INNER_FEC", + .cmd = DTV_GET_INNER_FEC, .set = 0, }, [DTV_GET_VOLTAGE] = { @@ -1212,16 +1212,16 @@ int dtv_property_process(struct dvb_frontend *fe, struct dtv_property *tvp, case DTV_GET_INVERSION: tvp->u.data = fe->dtv_property_cache.inversion; break; - case DTV_SET_SYMBOLRATE: + case DTV_SET_SYMBOL_RATE: fe->dtv_property_cache.symbol_rate = tvp->u.data; break; - case DTV_GET_SYMBOLRATE: + case DTV_GET_SYMBOL_RATE: tvp->u.data = fe->dtv_property_cache.symbol_rate; break; - case DTV_SET_INNERFEC: + case DTV_SET_INNER_FEC: fe->dtv_property_cache.fec_inner = tvp->u.data; break; - case DTV_GET_INNERFEC: + case DTV_GET_INNER_FEC: tvp->u.data = fe->dtv_property_cache.fec_inner; break; case DTV_SET_PILOT: -- cgit v1.2.3 From 60bc4d4c87081996e0d9a995671f4b3f52441a41 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 22:52:32 -0400 Subject: S2API: Reduce demod driver complexity by using a cache sync From: Steven Toth For demod drivers, we want a single tuning function (set_frontend) to have access to the properly constructed dvb_frontend_parameters structure, or the cache values - regardless of whether the legacy or new API is being used. This cuts down on redundant code in the demod drivers and ensures the tuning parameters are consistent regardless of the API entry type. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 9f9a92457..e618aa131 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1004,6 +1004,42 @@ int is_legacy_delivery_system(fe_delivery_system_t s) return 0; } +/* Synchronise the legacy tuning parameters into the cache, so that demodulator + * drivers can use a single set_frontend tuning function, regardless of whether + * it's being used for the legacy or new API, reducing code and complexity. + */ +void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + c->frequency = p->frequency; + c->inversion = p->inversion; + + switch (fe->ops.info.type) { + case FE_QPSK: + c->symbol_rate = p->u.qpsk.symbol_rate; + c->fec_inner = p->u.qpsk.fec_inner; + break; + case FE_QAM: + c->symbol_rate = p->u.qam.symbol_rate; + c->fec_inner = p->u.qam.fec_inner; + c->modulation = p->u.qam.modulation; + break; + case FE_OFDM: + c->bandwidth = p->u.ofdm.bandwidth; + c->code_rate_HP = p->u.ofdm.code_rate_HP; + c->code_rate_LP = p->u.ofdm.code_rate_LP; + c->modulation = p->u.ofdm.constellation; + c->transmission_mode = p->u.ofdm.transmission_mode; + c->guard_interval = p->u.ofdm.guard_interval; + c->hierarchy = p->u.ofdm.hierarchy_information; + break; + case FE_ATSC: + c->modulation = p->u.vsb.modulation; + break; + } +} + int dtv_property_cache_submit(struct dvb_frontend *fe) { @@ -1559,6 +1595,8 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, case FE_SET_FRONTEND: { struct dvb_frontend_tune_settings fetunesettings; + dtv_property_cache_sync(fe, &fepriv->parameters); + if(fe->dtv_property_cache.state == DTV_TUNE) { if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) { err = -EINVAL; -- cgit v1.2.3 From 31b33763bbe39a4cf92fd54b60312687aace97a1 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 23:27:13 -0400 Subject: S2API: Cleanup code that prepares tuning structures. From: Steven Toth Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 219 ++++++++++-------------- 1 file changed, 91 insertions(+), 128 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index e618aa131..5a97f749d 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1012,6 +1012,8 @@ void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parame { struct dtv_frontend_properties *c = &fe->dtv_property_cache; + printk("%s()\n", __FUNCTION__); + c->frequency = p->frequency; c->inversion = p->inversion; @@ -1040,153 +1042,114 @@ void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parame } } -int dtv_property_cache_submit(struct dvb_frontend *fe) +/* Ensure the cached values are set correctly in the frontend + * legacy tuning structures, for the advanced tuning API. + */ +void dtv_property_legacy_params_sync(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct dvb_frontend_private *fepriv = fe->frontend_priv; + struct dvb_frontend_parameters *p = &fepriv->parameters; - /* We have to do one of two things: - * To support legacy devices using the new API we take values from - * the tv_cache and generate a legacy truning structure. - * - * Or, - * - * To support advanced tuning devices with the new API we - * notify the new advance driver type that a tuning operation is required - * and let it pull values from the cache as is, we don't need to - * pass structures. - * - * We'll use the modulation type to assess how this is handled. as the API - * progresses we'll probably want to have a flag in dvb_frontend_ops - * to allow the frontend driver to dictate how it likes to be tuned. - * - * Because of how this is attached to the ioctl handler for legacy support, - * it's important to return an appropriate result code with atleast the following - * three meanings: - * < 0 = processing error - * 0 = lecagy ioctl handler to submit a traditional set_frontend() call. - * 1 = lecagy ioctl handler should NOT submit a traditional set_frontend() call. - */ + printk("%s()\n", __FUNCTION__); - int r; + p->frequency = c->frequency; + p->inversion = c->inversion; + switch (fe->ops.info.type) { + case FE_QPSK: + printk("%s() Preparing QPSK req\n", __FUNCTION__); + p->u.qpsk.symbol_rate = c->symbol_rate; + p->u.qpsk.fec_inner = c->fec_inner; + break; + case FE_QAM: + printk("%s() Preparing QAM req\n", __FUNCTION__); + p->u.qam.symbol_rate = c->symbol_rate; + p->u.qam.fec_inner = c->fec_inner; + p->u.qam.modulation = c->modulation; + break; + case FE_OFDM: + printk("%s() Preparing OFDM req\n", __FUNCTION__); + p->u.ofdm.bandwidth = c->bandwidth; + p->u.ofdm.code_rate_HP = c->code_rate_HP; + p->u.ofdm.code_rate_LP = c->code_rate_LP; + p->u.ofdm.constellation = c->modulation; + p->u.ofdm.transmission_mode = c->transmission_mode; + p->u.ofdm.guard_interval = c->guard_interval; + p->u.ofdm.hierarchy_information = c->hierarchy; + break; + case FE_ATSC: + printk("%s() Preparing VSB req\n", __FUNCTION__); + p->u.vsb.modulation = c->modulation; + break; + } +} + +/* Ensure the cached values are set correctly in the frontend + * legacy tuning structures, for the legacy tuning API. + */ +void dtv_property_adv_params_sync(struct dvb_frontend *fe) +{ struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_frontend_parameters p; + struct dvb_frontend_parameters *p = &fepriv->parameters; printk("%s()\n", __FUNCTION__); - /* For legacy delivery systems we don't need the delivery_system to be specified */ - if(is_legacy_delivery_system(c->delivery_system)) { - printk("%s() legacy, modulation = %d\n", __FUNCTION__, c->modulation); - switch(c->modulation) { - case QPSK: - printk("%s() Preparing QPSK req\n", __FUNCTION__); - p.frequency = c->frequency; - p.inversion = c->inversion; - p.u.qpsk.symbol_rate = c->symbol_rate; - p.u.qpsk.fec_inner = c->fec_inner; - memcpy(&fepriv->parameters, &p, - sizeof (struct dvb_frontend_parameters)); + p->frequency = c->frequency; + p->inversion = c->inversion; - /* Call the traditional tuning mechanisms. */ + switch(c->modulation) { + case _8PSK: + case _16APSK: + case NBC_QPSK: + p->u.qpsk.symbol_rate = c->symbol_rate; + p->u.qpsk.fec_inner = c->fec_inner; + break; + default: + break; + } - r = 0; - break; - case QAM_16: - case QAM_32: - case QAM_64: - case QAM_128: - case QAM_256: - case QAM_AUTO: - printk("%s() Preparing QAM req\n", __FUNCTION__); - p.frequency = c->frequency; - p.inversion = c->inversion; - p.u.qam.symbol_rate = c->symbol_rate; - p.u.vsb.modulation = c->modulation; - printk("%s() frequency = %d\n", __FUNCTION__, p.frequency); - printk("%s() QAM = %d\n", __FUNCTION__, p.u.vsb.modulation); - memcpy(&fepriv->parameters, &p, - sizeof (struct dvb_frontend_parameters)); + if(c->delivery_system == SYS_ISDBT) { + /* Fake out a generic DVB-T request so we pass validation in the ioctl */ + p->frequency = c->frequency; + p->inversion = INVERSION_AUTO; + p->u.ofdm.constellation = QAM_AUTO; + p->u.ofdm.code_rate_HP = FEC_AUTO; + p->u.ofdm.code_rate_LP = FEC_AUTO; + p->u.ofdm.bandwidth = BANDWIDTH_AUTO; + p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; + p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; + p->u.ofdm.hierarchy_information = HIERARCHY_AUTO; + } +} - /* At this point we're fully formed for backwards - * compatability and we need to return this - * via the ioctl handler as SET_FRONTEND (arg). - * We've already patched the new values into the - * frontends tuning structures so the ioctl code just - * continues as if a legacy tune structure was passed - * from userspace. - */ +void dtv_property_cache_submit(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; - r = 0; - break; - case VSB_8: - case VSB_16: - printk("%s() Preparing VSB req\n", __FUNCTION__); - p.frequency = c->frequency; - p.u.vsb.modulation = c->modulation; - memcpy(&fepriv->parameters, &p, - sizeof (struct dvb_frontend_parameters)); + printk("%s()\n", __FUNCTION__); - /* Call the traditional tuning mechanisms. */ + /* For legacy delivery systems we don't need the delivery_system to + * be specified, but we populate the older structures from the cache + * so we can call set_frontend on older drivers. + */ + if(is_legacy_delivery_system(c->delivery_system)) { + + printk("%s() legacy, modulation = %d\n", __FUNCTION__, c->modulation); + dtv_property_legacy_params_sync(fe); - r = 0; - break; - /* TODO: Add any missing modulation types */ - default: - r = -1; - } } else { + printk("%s() adv, modulation = %d\n", __FUNCTION__, c->modulation); + /* For advanced delivery systems / modulation types ... * we seed the lecacy dvb_frontend_parameters structure * so that the sanity checking code later in the IOCTL processing * can validate our basic frequency ranges, symbolrates, modulation * etc. */ - r = -1; - - switch(c->modulation) { - case _8PSK: - case _16APSK: - case NBC_QPSK: - /* Just post a notification to the demod driver and let it pull - * the specific values it wants from its dtv_property_cache. - * It can decide how best to use those parameters. - * IOCTL will call set_frontend (by default) due to zigzag - * support etc. - */ - if (fe->ops.set_params) - r = fe->ops.set_params(fe); - - p.frequency = c->frequency; - p.inversion = c->inversion; - p.u.qpsk.symbol_rate = c->symbol_rate; - p.u.qpsk.fec_inner = c->fec_inner; - memcpy(&fepriv->parameters, &p, - sizeof (struct dvb_frontend_parameters)); - - r = 0; - break; - default: - r = -1; - } - - if(c->delivery_system == SYS_ISDBT) { - /* Fake out a generic DVB-T request so we pass validation in the ioctl */ - p.frequency = c->frequency; - p.inversion = INVERSION_AUTO; - p.u.ofdm.constellation = QAM_AUTO; - p.u.ofdm.code_rate_HP = FEC_AUTO; - p.u.ofdm.code_rate_LP = FEC_AUTO; - p.u.ofdm.bandwidth = BANDWIDTH_AUTO; - p.u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; - p.u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; - p.u.ofdm.hierarchy_information = HIERARCHY_AUTO; - memcpy(&fepriv->parameters, &p, - sizeof (struct dvb_frontend_parameters)); - - r = 0; - } + dtv_property_adv_params_sync(fe); } - return r; } static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, @@ -1214,13 +1177,13 @@ int dtv_property_process(struct dvb_frontend *fe, struct dtv_property *tvp, break; case DTV_TUNE: /* interpret the cache of data, build either a traditional frontend - * tunerequest and submit it to a subset of the ioctl handler, - * or, call a new undefined method on the frontend to deal with - * all new tune requests. + * tunerequest so we can pass validation in the FE_SET_FRONTEND + * ioctl. */ fe->dtv_property_cache.state = tvp->cmd; printk("%s() Finalised property cache\n", __FUNCTION__); - r |= dtv_property_cache_submit(fe); + dtv_property_cache_submit(fe); + r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, &fepriv->parameters); break; -- cgit v1.2.3 From 68c60334487dbea91c1e89b8d5034623b1b4dbc8 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 23:33:04 -0400 Subject: S2API: ISDBT_SEGMENT_NUM -> ISDBT_SEGMENT_IDX From: Steven Toth Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 20 ++++++++++---------- linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 5a97f749d..405fc7eab 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -840,9 +840,9 @@ struct dtv_cmds_h dtv_cmds[] = { .cmd = DTV_SET_DELIVERY_SYSTEM, .set = 1, }, - [DTV_SET_ISDB_SEGMENT_NUM] = { - .name = "DTV_SET_ISDB_SEGMENT_NUM", - .cmd = DTV_SET_ISDB_SEGMENT_NUM, + [DTV_SET_ISDB_SEGMENT_IDX] = { + .name = "DTV_SET_ISDB_SEGMENT_IDX", + .cmd = DTV_SET_ISDB_SEGMENT_IDX, .set = 1, }, [DTV_SET_ISDB_SEGMENT_WIDTH] = { @@ -913,9 +913,9 @@ struct dtv_cmds_h dtv_cmds[] = { .cmd = DTV_GET_DELIVERY_SYSTEM, .set = 0, }, - [DTV_GET_ISDB_SEGMENT_NUM] = { - .name = "DTV_GET_ISDB_SEGMENT_NUM", - .cmd = DTV_GET_ISDB_SEGMENT_NUM, + [DTV_GET_ISDB_SEGMENT_IDX] = { + .name = "DTV_GET_ISDB_SEGMENT_IDX", + .cmd = DTV_GET_ISDB_SEGMENT_IDX, .set = 0, }, [DTV_GET_ISDB_SEGMENT_WIDTH] = { @@ -1243,11 +1243,11 @@ int dtv_property_process(struct dvb_frontend *fe, struct dtv_property *tvp, break; /* ISDB-T Support here */ - case DTV_SET_ISDB_SEGMENT_NUM: - fe->dtv_property_cache.isdb_segment_num = tvp->u.data; + case DTV_SET_ISDB_SEGMENT_IDX: + fe->dtv_property_cache.isdb_segment_idx = tvp->u.data; break; - case DTV_GET_ISDB_SEGMENT_NUM: - tvp->u.data = fe->dtv_property_cache.isdb_segment_num; + case DTV_GET_ISDB_SEGMENT_IDX: + tvp->u.data = fe->dtv_property_cache.isdb_segment_idx; break; case DTV_SET_ISDB_SEGMENT_WIDTH: fe->dtv_property_cache.isdb_segment_width = tvp->u.data; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index 85d30201a..1c2090966 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -212,7 +212,7 @@ struct dtv_frontend_properties { fe_delivery_system_t delivery_system; /* ISDB-T specifics */ - u32 isdb_segment_num; + u32 isdb_segment_idx; u32 isdb_segment_width; fe_code_rate_t isdb_layera_fec; fe_modulation_t isdb_layera_modulation; -- cgit v1.2.3 From 78ac88986b11f05c64e919c58df4d5033ed70e19 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 23:53:50 -0400 Subject: S2API: Ensure cache->delivery_system is set at all times. From: Steven Toth This helps complex demods which support different modulation types be better informed. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 405fc7eab..35351d6ed 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1021,11 +1021,13 @@ void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parame case FE_QPSK: c->symbol_rate = p->u.qpsk.symbol_rate; c->fec_inner = p->u.qpsk.fec_inner; + c->delivery_system = SYS_DVBS; break; case FE_QAM: c->symbol_rate = p->u.qam.symbol_rate; c->fec_inner = p->u.qam.fec_inner; c->modulation = p->u.qam.modulation; + c->delivery_system = SYS_DVBC_ANNEX_AC; break; case FE_OFDM: c->bandwidth = p->u.ofdm.bandwidth; @@ -1035,9 +1037,14 @@ void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parame c->transmission_mode = p->u.ofdm.transmission_mode; c->guard_interval = p->u.ofdm.guard_interval; c->hierarchy = p->u.ofdm.hierarchy_information; + c->delivery_system = SYS_DVBT; break; case FE_ATSC: c->modulation = p->u.vsb.modulation; + if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) + c->delivery_system = SYS_ATSC; + else + c->delivery_system = SYS_DVBC_ANNEX_B; break; } } @@ -1061,12 +1068,14 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe) printk("%s() Preparing QPSK req\n", __FUNCTION__); p->u.qpsk.symbol_rate = c->symbol_rate; p->u.qpsk.fec_inner = c->fec_inner; + c->delivery_system = SYS_DVBS; break; case FE_QAM: printk("%s() Preparing QAM req\n", __FUNCTION__); p->u.qam.symbol_rate = c->symbol_rate; p->u.qam.fec_inner = c->fec_inner; p->u.qam.modulation = c->modulation; + c->delivery_system = SYS_DVBC_ANNEX_AC; break; case FE_OFDM: printk("%s() Preparing OFDM req\n", __FUNCTION__); @@ -1077,10 +1086,15 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe) p->u.ofdm.transmission_mode = c->transmission_mode; p->u.ofdm.guard_interval = c->guard_interval; p->u.ofdm.hierarchy_information = c->hierarchy; + c->delivery_system = SYS_DVBT; break; case FE_ATSC: printk("%s() Preparing VSB req\n", __FUNCTION__); p->u.vsb.modulation = c->modulation; + if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) + c->delivery_system = SYS_ATSC; + else + c->delivery_system = SYS_DVBC_ANNEX_B; break; } } -- cgit v1.2.3 From 72a780c4333fa7b78c93bdc12cf740ca51389daa Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 12 Sep 2008 00:34:28 -0400 Subject: S2API: Remove the DTV_SET_ and DTV_GET_ prefixes From: Steven Toth The API now assumes that ioctl calls for FE_SET_PROPERTY and all set commands, and FE_GET_PROPERTY are get commands. Simplification. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 431 ++++++++++++------------ 1 file changed, 212 insertions(+), 219 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 35351d6ed..3df500179 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -779,193 +779,128 @@ struct dtv_cmds_h dtv_cmds[] = { }, /* Set */ - [DTV_SET_FREQUENCY] = { - .name = "DTV_SET_FREQUENCY", - .cmd = DTV_SET_FREQUENCY, + [DTV_FREQUENCY] = { + .name = "DTV_FREQUENCY", + .cmd = DTV_FREQUENCY, .set = 1, }, - [DTV_SET_BANDWIDTH] = { - .name = "DTV_SET_BANDWIDTH", - .cmd = DTV_SET_BANDWIDTH, + [DTV_BANDWIDTH] = { + .name = "DTV_BANDWIDTH", + .cmd = DTV_BANDWIDTH, .set = 1, }, - [DTV_SET_MODULATION] = { - .name = "DTV_SET_MODULATION", - .cmd = DTV_SET_MODULATION, + [DTV_MODULATION] = { + .name = "DTV_MODULATION", + .cmd = DTV_MODULATION, .set = 1, }, - [DTV_SET_INVERSION] = { - .name = "DTV_SET_INVERSION", - .cmd = DTV_SET_INVERSION, + [DTV_INVERSION] = { + .name = "DTV_INVERSION", + .cmd = DTV_INVERSION, .set = 1, }, - [DTV_SET_DISEQC_MASTER] = { - .name = "DTV_SET_DISEQC_MASTER", - .cmd = DTV_SET_DISEQC_MASTER, + [DTV_DISEQC_MASTER] = { + .name = "DTV_DISEQC_MASTER", + .cmd = DTV_DISEQC_MASTER, .set = 1, .buffer = 1, }, - [DTV_SET_SYMBOL_RATE] = { - .name = "DTV_SET_SYMBOL_RATE", - .cmd = DTV_SET_SYMBOL_RATE, + [DTV_SYMBOL_RATE] = { + .name = "DTV_SYMBOL_RATE", + .cmd = DTV_SYMBOL_RATE, .set = 1, }, - [DTV_SET_INNER_FEC] = { - .name = "DTV_SET_INNER_FEC", - .cmd = DTV_SET_INNER_FEC, + [DTV_INNER_FEC] = { + .name = "DTV_INNER_FEC", + .cmd = DTV_INNER_FEC, .set = 1, }, - [DTV_SET_VOLTAGE] = { - .name = "DTV_SET_VOLTAGE", - .cmd = DTV_SET_VOLTAGE, + [DTV_VOLTAGE] = { + .name = "DTV_VOLTAGE", + .cmd = DTV_VOLTAGE, .set = 1, }, - [DTV_SET_TONE] = { - .name = "DTV_SET_TONE", - .cmd = DTV_SET_TONE, + [DTV_TONE] = { + .name = "DTV_TONE", + .cmd = DTV_TONE, .set = 1, }, - [DTV_SET_PILOT] = { - .name = "DTV_SET_PILOT", - .cmd = DTV_SET_PILOT, + [DTV_PILOT] = { + .name = "DTV_PILOT", + .cmd = DTV_PILOT, .set = 1, }, - [DTV_SET_ROLLOFF] = { - .name = "DTV_SET_ROLLOFF", - .cmd = DTV_SET_ROLLOFF, + [DTV_ROLLOFF] = { + .name = "DTV_ROLLOFF", + .cmd = DTV_ROLLOFF, .set = 1, }, - [DTV_SET_DELIVERY_SYSTEM] = { - .name = "DTV_SET_DELIVERY_SYSTEM", - .cmd = DTV_SET_DELIVERY_SYSTEM, + [DTV_DELIVERY_SYSTEM] = { + .name = "DTV_DELIVERY_SYSTEM", + .cmd = DTV_DELIVERY_SYSTEM, .set = 1, }, - [DTV_SET_ISDB_SEGMENT_IDX] = { - .name = "DTV_SET_ISDB_SEGMENT_IDX", - .cmd = DTV_SET_ISDB_SEGMENT_IDX, + [DTV_ISDB_SEGMENT_IDX] = { + .name = "DTV_ISDB_SEGMENT_IDX", + .cmd = DTV_ISDB_SEGMENT_IDX, .set = 1, }, - [DTV_SET_ISDB_SEGMENT_WIDTH] = { - .name = "DTV_SET_ISDB_SEGMENT_WIDTH", - .cmd = DTV_SET_ISDB_SEGMENT_WIDTH, + [DTV_ISDB_SEGMENT_WIDTH] = { + .name = "DTV_ISDB_SEGMENT_WIDTH", + .cmd = DTV_ISDB_SEGMENT_WIDTH, .set = 1, }, /* Get */ - [DTV_GET_FREQUENCY] = { - .name = "DTV_GET_FREQUENCY", - .cmd = DTV_GET_FREQUENCY, - .set = 0, - }, - [DTV_GET_BANDWIDTH] = { - .name = "DTV_GET_BANDWIDTH", - .cmd = DTV_GET_BANDWIDTH, - .set = 0, - }, - [DTV_GET_MODULATION] = { - .name = "DTV_GET_MODULATION", - .cmd = DTV_GET_MODULATION, - .set = 0, - }, - [DTV_GET_INVERSION] = { - .name = "DTV_GET_INVERSION", - .cmd = DTV_GET_INVERSION, - .set = 0, - }, - [DTV_GET_DISEQC_SLAVE_REPLY] = { - .name = "DTV_GET_DISEQC_SLAVE_REPLY", - .cmd = DTV_GET_DISEQC_SLAVE_REPLY, + [DTV_DISEQC_SLAVE_REPLY] = { + .name = "DTV_DISEQC_SLAVE_REPLY", + .cmd = DTV_DISEQC_SLAVE_REPLY, .set = 0, .buffer = 1, }, - [DTV_GET_SYMBOL_RATE] = { - .name = "DTV_GET_SYMBOL_RATE", - .cmd = DTV_GET_SYMBOL_RATE, - .set = 0, - }, - [DTV_GET_INNER_FEC] = { - .name = "DTV_GET_INNER_FEC", - .cmd = DTV_GET_INNER_FEC, - .set = 0, - }, - [DTV_GET_VOLTAGE] = { - .name = "DTV_GET_VOLTAGE", - .cmd = DTV_GET_VOLTAGE, - .set = 0, - }, - [DTV_GET_TONE] = { - .name = "DTV_GET_TONE", - .cmd = DTV_GET_TONE, - .set = 0, - }, - [DTV_GET_PILOT] = { - .name = "DTV_GET_PILOT", - .cmd = DTV_GET_PILOT, - .set = 0, - }, - [DTV_GET_ROLLOFF] = { - .name = "DTV_GET_ROLLOFF", - .cmd = DTV_GET_ROLLOFF, - .set = 0, - }, - [DTV_GET_DELIVERY_SYSTEM] = { - .name = "DTV_GET_DELIVERY_SYSTEM", - .cmd = DTV_GET_DELIVERY_SYSTEM, - .set = 0, - }, - [DTV_GET_ISDB_SEGMENT_IDX] = { - .name = "DTV_GET_ISDB_SEGMENT_IDX", - .cmd = DTV_GET_ISDB_SEGMENT_IDX, - .set = 0, - }, - [DTV_GET_ISDB_SEGMENT_WIDTH] = { - .name = "DTV_GET_ISDB_SEGMENT_WIDTH", - .cmd = DTV_GET_ISDB_SEGMENT_WIDTH, + [DTV_ISDB_LAYERA_FEC] = { + .name = "DTV_ISDB_LAYERA_FEC", + .cmd = DTV_ISDB_LAYERA_FEC, .set = 0, }, - [DTV_GET_ISDB_LAYERA_FEC] = { - .name = "DTV_GET_ISDB_LAYERA_FEC", - .cmd = DTV_GET_ISDB_LAYERA_FEC, + [DTV_ISDB_LAYERA_MODULATION] = { + .name = "DTV_ISDB_LAYERA_MODULATION", + .cmd = DTV_ISDB_LAYERA_MODULATION, .set = 0, }, - [DTV_GET_ISDB_LAYERA_MODULATION] = { - .name = "DTV_GET_ISDB_LAYERA_MODULATION", - .cmd = DTV_GET_ISDB_LAYERA_MODULATION, + [DTV_ISDB_LAYERA_SEGMENT_WIDTH] = { + .name = "DTV_ISDB_LAYERA_SEGMENT_WIDTH", + .cmd = DTV_ISDB_LAYERA_SEGMENT_WIDTH, .set = 0, }, - [DTV_GET_ISDB_LAYERA_SEGMENT_WIDTH] = { - .name = "DTV_GET_ISDB_LAYERA_SEGMENT_WIDTH", - .cmd = DTV_GET_ISDB_LAYERA_SEGMENT_WIDTH, + [DTV_ISDB_LAYERB_FEC] = { + .name = "DTV_ISDB_LAYERB_FEC", + .cmd = DTV_ISDB_LAYERB_FEC, .set = 0, }, - [DTV_GET_ISDB_LAYERB_FEC] = { - .name = "DTV_GET_ISDB_LAYERB_FEC", - .cmd = DTV_GET_ISDB_LAYERB_FEC, + [DTV_ISDB_LAYERB_MODULATION] = { + .name = "DTV_ISDB_LAYERB_MODULATION", + .cmd = DTV_ISDB_LAYERB_MODULATION, .set = 0, }, - [DTV_GET_ISDB_LAYERB_MODULATION] = { - .name = "DTV_GET_ISDB_LAYERB_MODULATION", - .cmd = DTV_GET_ISDB_LAYERB_MODULATION, + [DTV_ISDB_LAYERB_SEGMENT_WIDTH] = { + .name = "DTV_ISDB_LAYERB_SEGMENT_WIDTH", + .cmd = DTV_ISDB_LAYERB_SEGMENT_WIDTH, .set = 0, }, - [DTV_GET_ISDB_LAYERB_SEGMENT_WIDTH] = { - .name = "DTV_GET_ISDB_LAYERB_SEGMENT_WIDTH", - .cmd = DTV_GET_ISDB_LAYERB_SEGMENT_WIDTH, + [DTV_ISDB_LAYERC_FEC] = { + .name = "DTV_ISDB_LAYERC_FEC", + .cmd = DTV_ISDB_LAYERC_FEC, .set = 0, }, - [DTV_GET_ISDB_LAYERC_FEC] = { - .name = "DTV_GET_ISDB_LAYERC_FEC", - .cmd = DTV_GET_ISDB_LAYERC_FEC, + [DTV_ISDB_LAYERC_MODULATION] = { + .name = "DTV_ISDB_LAYERC_MODULATION", + .cmd = DTV_ISDB_LAYERC_MODULATION, .set = 0, }, - [DTV_GET_ISDB_LAYERC_MODULATION] = { - .name = "DTV_GET_ISDB_LAYERC_MODULATION", - .cmd = DTV_GET_ISDB_LAYERC_MODULATION, - .set = 0, - }, - [DTV_GET_ISDB_LAYERC_SEGMENT_WIDTH] = { - .name = "DTV_GET_ISDB_LAYERC_SEGMENT_WIDTH", - .cmd = DTV_GET_ISDB_LAYERC_SEGMENT_WIDTH, + [DTV_ISDB_LAYERC_SEGMENT_WIDTH] = { + .name = "DTV_ISDB_LAYERC_SEGMENT_WIDTH", + .cmd = DTV_ISDB_LAYERC_SEGMENT_WIDTH, .set = 0, }, }; @@ -1171,7 +1106,92 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, unsigned int cmd, void *parg); -int dtv_property_process(struct dvb_frontend *fe, struct dtv_property *tvp, +int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, + struct inode *inode, struct file *file) +{ + int r = 0; + + printk("%s()\n", __FUNCTION__); + + dtv_property_dump(tvp); + + switch(tvp->cmd) { + case DTV_FREQUENCY: + tvp->u.data = fe->dtv_property_cache.frequency; + break; + case DTV_MODULATION: + tvp->u.data = fe->dtv_property_cache.modulation; + break; + case DTV_BANDWIDTH: + tvp->u.data = fe->dtv_property_cache.bandwidth; + break; + case DTV_INVERSION: + tvp->u.data = fe->dtv_property_cache.inversion; + break; + case DTV_SYMBOL_RATE: + tvp->u.data = fe->dtv_property_cache.symbol_rate; + break; + case DTV_INNER_FEC: + tvp->u.data = fe->dtv_property_cache.fec_inner; + break; + case DTV_PILOT: + tvp->u.data = fe->dtv_property_cache.pilot; + break; + case DTV_ROLLOFF: + tvp->u.data = fe->dtv_property_cache.rolloff; + break; + case DTV_DELIVERY_SYSTEM: + tvp->u.data = fe->dtv_property_cache.delivery_system; + break; + + /* ISDB-T Support here */ + case DTV_ISDB_SEGMENT_IDX: + tvp->u.data = fe->dtv_property_cache.isdb_segment_idx; + break; + case DTV_ISDB_SEGMENT_WIDTH: + tvp->u.data = fe->dtv_property_cache.isdb_segment_width; + break; + case DTV_ISDB_LAYERA_FEC: + tvp->u.data = fe->dtv_property_cache.isdb_layera_fec; + break; + case DTV_ISDB_LAYERA_MODULATION: + tvp->u.data = fe->dtv_property_cache.isdb_layera_modulation; + break; + case DTV_ISDB_LAYERA_SEGMENT_WIDTH: + tvp->u.data = fe->dtv_property_cache.isdb_layera_segment_width; + break; + case DTV_ISDB_LAYERB_FEC: + tvp->u.data = fe->dtv_property_cache.isdb_layerb_fec; + break; + case DTV_ISDB_LAYERB_MODULATION: + tvp->u.data = fe->dtv_property_cache.isdb_layerb_modulation; + break; + case DTV_ISDB_LAYERB_SEGMENT_WIDTH: + tvp->u.data = fe->dtv_property_cache.isdb_layerb_segment_width; + break; + case DTV_ISDB_LAYERC_FEC: + tvp->u.data = fe->dtv_property_cache.isdb_layerc_fec; + break; + case DTV_ISDB_LAYERC_MODULATION: + tvp->u.data = fe->dtv_property_cache.isdb_layerc_modulation; + break; + case DTV_ISDB_LAYERC_SEGMENT_WIDTH: + tvp->u.data = fe->dtv_property_cache.isdb_layerc_segment_width; + break; + case DTV_VOLTAGE: + tvp->u.data = fe->dtv_property_cache.voltage; + break; + case DTV_TONE: + tvp->u.data = fe->dtv_property_cache.sectone; + break; + default: + r = -1; + } + + return r; +} + +int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, struct inode *inode, struct file *file) { int r = 0; @@ -1201,117 +1221,53 @@ int dtv_property_process(struct dvb_frontend *fe, struct dtv_property *tvp, r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, &fepriv->parameters); break; - case DTV_SET_FREQUENCY: + case DTV_FREQUENCY: fe->dtv_property_cache.frequency = tvp->u.data; break; - case DTV_GET_FREQUENCY: - tvp->u.data = fe->dtv_property_cache.frequency; - break; - case DTV_SET_MODULATION: + case DTV_MODULATION: fe->dtv_property_cache.modulation = tvp->u.data; break; - case DTV_GET_MODULATION: - tvp->u.data = fe->dtv_property_cache.modulation; - break; - case DTV_SET_BANDWIDTH: + case DTV_BANDWIDTH: fe->dtv_property_cache.bandwidth = tvp->u.data; break; - case DTV_GET_BANDWIDTH: - tvp->u.data = fe->dtv_property_cache.bandwidth; - break; - case DTV_SET_INVERSION: + case DTV_INVERSION: fe->dtv_property_cache.inversion = tvp->u.data; break; - case DTV_GET_INVERSION: - tvp->u.data = fe->dtv_property_cache.inversion; - break; - case DTV_SET_SYMBOL_RATE: + case DTV_SYMBOL_RATE: fe->dtv_property_cache.symbol_rate = tvp->u.data; break; - case DTV_GET_SYMBOL_RATE: - tvp->u.data = fe->dtv_property_cache.symbol_rate; - break; - case DTV_SET_INNER_FEC: + case DTV_INNER_FEC: fe->dtv_property_cache.fec_inner = tvp->u.data; break; - case DTV_GET_INNER_FEC: - tvp->u.data = fe->dtv_property_cache.fec_inner; - break; - case DTV_SET_PILOT: + case DTV_PILOT: fe->dtv_property_cache.pilot = tvp->u.data; break; - case DTV_GET_PILOT: - tvp->u.data = fe->dtv_property_cache.pilot; - break; - case DTV_SET_ROLLOFF: + case DTV_ROLLOFF: fe->dtv_property_cache.rolloff = tvp->u.data; break; - case DTV_GET_ROLLOFF: - tvp->u.data = fe->dtv_property_cache.rolloff; - break; - case DTV_SET_DELIVERY_SYSTEM: + case DTV_DELIVERY_SYSTEM: fe->dtv_property_cache.delivery_system = tvp->u.data; break; - case DTV_GET_DELIVERY_SYSTEM: - tvp->u.data = fe->dtv_property_cache.delivery_system; - break; /* ISDB-T Support here */ - case DTV_SET_ISDB_SEGMENT_IDX: + case DTV_ISDB_SEGMENT_IDX: fe->dtv_property_cache.isdb_segment_idx = tvp->u.data; break; - case DTV_GET_ISDB_SEGMENT_IDX: - tvp->u.data = fe->dtv_property_cache.isdb_segment_idx; - break; - case DTV_SET_ISDB_SEGMENT_WIDTH: + case DTV_ISDB_SEGMENT_WIDTH: fe->dtv_property_cache.isdb_segment_width = tvp->u.data; break; - case DTV_GET_ISDB_SEGMENT_WIDTH: - tvp->u.data = fe->dtv_property_cache.isdb_segment_width; - break; - case DTV_GET_ISDB_LAYERA_FEC: - tvp->u.data = fe->dtv_property_cache.isdb_layera_fec; - break; - case DTV_GET_ISDB_LAYERA_MODULATION: - tvp->u.data = fe->dtv_property_cache.isdb_layera_modulation; - break; - case DTV_GET_ISDB_LAYERA_SEGMENT_WIDTH: - tvp->u.data = fe->dtv_property_cache.isdb_layera_segment_width; - break; - case DTV_GET_ISDB_LAYERB_FEC: - tvp->u.data = fe->dtv_property_cache.isdb_layerb_fec; - break; - case DTV_GET_ISDB_LAYERB_MODULATION: - tvp->u.data = fe->dtv_property_cache.isdb_layerb_modulation; - break; - case DTV_GET_ISDB_LAYERB_SEGMENT_WIDTH: - tvp->u.data = fe->dtv_property_cache.isdb_layerb_segment_width; - break; - case DTV_GET_ISDB_LAYERC_FEC: - tvp->u.data = fe->dtv_property_cache.isdb_layerc_fec; - break; - case DTV_GET_ISDB_LAYERC_MODULATION: - tvp->u.data = fe->dtv_property_cache.isdb_layerc_modulation; - break; - case DTV_GET_ISDB_LAYERC_SEGMENT_WIDTH: - tvp->u.data = fe->dtv_property_cache.isdb_layerc_segment_width; - break; - case DTV_SET_VOLTAGE: + case DTV_VOLTAGE: fe->dtv_property_cache.voltage = tvp->u.data; r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE, (void *)fe->dtv_property_cache.voltage); break; - case DTV_GET_VOLTAGE: - tvp->u.data = fe->dtv_property_cache.voltage; - break; - case DTV_SET_TONE: + case DTV_TONE: fe->dtv_property_cache.sectone = tvp->u.data; r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_TONE, (void *)fe->dtv_property_cache.sectone); break; - case DTV_GET_TONE: - tvp->u.data = fe->dtv_property_cache.sectone; - break; + default: + r = -1; } return r; @@ -1386,13 +1342,50 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, } for (i = 0; i < tvps->num; i++) - dtv_property_process(fe, tvp + i, inode, file); + dtv_property_process_set(fe, tvp + i, inode, file); if(fe->dtv_property_cache.state == DTV_TUNE) { printk("%s() Property cache is full, tuning\n", __FUNCTION__); } err = 0; - } + } else + if(cmd == FE_GET_PROPERTY) { + printk("%s() FE_GET_PROPERTY\n", __FUNCTION__); + + tvps = (struct dtv_properties __user *)parg; + + printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num); + printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props); + + /* Put an arbitrary limit on the number of messages that can + * be sent at once */ + if (tvps->num > DTV_IOCTL_MAX_MSGS) + return -EINVAL; + + tvp = (struct dtv_property *) kmalloc(tvps->num * + sizeof(struct dtv_property), GFP_KERNEL); + if (!tvp) { + err = -ENOMEM; + goto out; + } + + if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) { + err = -EFAULT; + goto out; + } + + for (i = 0; i < tvps->num; i++) + dtv_property_process_get(fe, tvp + i, inode, file); + + if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) { + err = -EFAULT; + goto out; + } + + err = 0; + } else + err = -EOPNOTSUPP; + out: kfree(tvp); return err; -- cgit v1.2.3 From 099550d3d61d1b5857297d96bd736b6457011396 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 12 Sep 2008 00:37:37 -0400 Subject: S2API: Implement GET/SET handing to the demods From: Steven Toth The frontends will be notified (if they chose) of all _get and _set commands so they can help determine result or action. Results are now returned to userspace correctly. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 21 +++++++++++++++++---- linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 1 - 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 3df500179..b63e193ce 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1115,6 +1115,13 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, dtv_property_dump(tvp); + /* Allow the frontend to validate incoming properties */ + if (fe->ops.get_property) + r = fe->ops.get_property(fe, tvp); + + if (r < 0) + return r; + switch(tvp->cmd) { case DTV_FREQUENCY: tvp->u.data = fe->dtv_property_cache.frequency; @@ -1199,6 +1206,13 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, printk("%s()\n", __FUNCTION__); dtv_property_dump(tvp); + /* Allow the frontend to validate incoming properties */ + if (fe->ops.set_property) + r = fe->ops.set_property(fe, tvp); + + if (r < 0) + return r; + switch(tvp->cmd) { case DTV_CLEAR: /* Reset a cache of data specific to the frontend here. This does @@ -1342,12 +1356,12 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, } for (i = 0; i < tvps->num; i++) - dtv_property_process_set(fe, tvp + i, inode, file); + err |= dtv_property_process_set(fe, tvp + i, inode, file); if(fe->dtv_property_cache.state == DTV_TUNE) { printk("%s() Property cache is full, tuning\n", __FUNCTION__); } - err = 0; + } else if(cmd == FE_GET_PROPERTY) { printk("%s() FE_GET_PROPERTY\n", __FUNCTION__); @@ -1375,14 +1389,13 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, } for (i = 0; i < tvps->num; i++) - dtv_property_process_get(fe, tvp + i, inode, file); + err |= dtv_property_process_get(fe, tvp + i, inode, file); if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) { err = -EFAULT; goto out; } - err = 0; } else err = -EOPNOTSUPP; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index 1c2090966..784e8fe1d 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -172,7 +172,6 @@ struct dvb_frontend_ops { int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp); int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp); - int (*set_params)(struct dvb_frontend* fe); }; #define MAX_EVENT 8 -- cgit v1.2.3 From d5bd2a43985d53bd37e31d640177c9b5306716d7 Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Fri, 12 Sep 2008 20:49:06 +0300 Subject: Bug fix: ioctl FE_SET_PROPERTY/FE_GET_PROPERTY always return error From: Igor M. Liplianin Bug fix: ioctl FE_SET_PROPERTY/FE_GET_PROPERTY always return error Signed-off-by: Igor M. Liplianin --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index b63e193ce..ab821d5f8 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1322,7 +1322,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, { struct dvb_device *dvbdev = file->private_data; struct dvb_frontend *fe = dvbdev->priv; - int err = -EOPNOTSUPP; + int err = 0; struct dtv_properties *tvps = NULL; struct dtv_property *tvp = NULL; -- cgit v1.2.3 From 9dcfc9e3a50997d1024e86a0ad8686c7d027f6de Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 13 Sep 2008 14:09:07 -0400 Subject: S2API: Allow reliable use of old and new api on the same frontend, regardless. From: Steven Toth Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index ab821d5f8..6a8b45d58 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1310,8 +1310,10 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) err = dvb_frontend_ioctl_properties(inode, file, cmd, parg); - else + else { + fe->dtv_property_cache.state = DTV_UNDEFINED; err = dvb_frontend_ioctl_legacy(inode, file, cmd, parg); + } up(&fepriv->sem); return err; @@ -1578,8 +1580,6 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, case FE_SET_FRONTEND: { struct dvb_frontend_tune_settings fetunesettings; - dtv_property_cache_sync(fe, &fepriv->parameters); - if(fe->dtv_property_cache.state == DTV_TUNE) { if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) { err = -EINVAL; @@ -1591,6 +1591,7 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, break; } + dtv_property_cache_sync(fe, &fepriv->parameters); memcpy (&fepriv->parameters, parg, sizeof (struct dvb_frontend_parameters)); } -- cgit v1.2.3 From 997940c5b22eab62f570dcd410179b8a60f1ad84 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 13 Sep 2008 15:56:34 -0400 Subject: S2API: Changed bandwidth to be expressed in HZ From: Steven Toth Also added some compat code for the older API. Added more ISDB message/command suggestions, current not connected in dvb-core. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 33 ++++++++++++++++++------- linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 2 +- 2 files changed, 25 insertions(+), 10 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 6a8b45d58..c8865d639 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -784,9 +784,9 @@ struct dtv_cmds_h dtv_cmds[] = { .cmd = DTV_FREQUENCY, .set = 1, }, - [DTV_BANDWIDTH] = { - .name = "DTV_BANDWIDTH", - .cmd = DTV_BANDWIDTH, + [DTV_BANDWIDTH_HZ] = { + .name = "DTV_BANDWIDTH_HZ", + .cmd = DTV_BANDWIDTH_HZ, .set = 1, }, [DTV_MODULATION] = { @@ -965,7 +965,15 @@ void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parame c->delivery_system = SYS_DVBC_ANNEX_AC; break; case FE_OFDM: - c->bandwidth = p->u.ofdm.bandwidth; + if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) + c->bandwidth_hz = 6000000; + else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) + c->bandwidth_hz = 7000000; + else if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) + c->bandwidth_hz = 8000000; + else + /* Including BANDWIDTH_AUTO */ + c->bandwidth_hz = 0; c->code_rate_HP = p->u.ofdm.code_rate_HP; c->code_rate_LP = p->u.ofdm.code_rate_LP; c->modulation = p->u.ofdm.constellation; @@ -1014,7 +1022,14 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe) break; case FE_OFDM: printk("%s() Preparing OFDM req\n", __FUNCTION__); - p->u.ofdm.bandwidth = c->bandwidth; + if (c->bandwidth_hz == 6000000) + p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; + else if (c->bandwidth_hz == 7000000) + p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; + else if (c->bandwidth_hz == 8000000) + p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; + else + p->u.ofdm.bandwidth = BANDWIDTH_AUTO; p->u.ofdm.code_rate_HP = c->code_rate_HP; p->u.ofdm.code_rate_LP = c->code_rate_LP; p->u.ofdm.constellation = c->modulation; @@ -1129,8 +1144,8 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, case DTV_MODULATION: tvp->u.data = fe->dtv_property_cache.modulation; break; - case DTV_BANDWIDTH: - tvp->u.data = fe->dtv_property_cache.bandwidth; + case DTV_BANDWIDTH_HZ: + tvp->u.data = fe->dtv_property_cache.bandwidth_hz; break; case DTV_INVERSION: tvp->u.data = fe->dtv_property_cache.inversion; @@ -1241,8 +1256,8 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, case DTV_MODULATION: fe->dtv_property_cache.modulation = tvp->u.data; break; - case DTV_BANDWIDTH: - fe->dtv_property_cache.bandwidth = tvp->u.data; + case DTV_BANDWIDTH_HZ: + fe->dtv_property_cache.bandwidth_hz = tvp->u.data; break; case DTV_INVERSION: fe->dtv_property_cache.inversion = tvp->u.data; diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index 784e8fe1d..2fa37f5a0 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -198,7 +198,7 @@ struct dtv_frontend_properties { fe_spectral_inversion_t inversion; fe_code_rate_t fec_inner; fe_transmit_mode_t transmission_mode; - fe_bandwidth_t bandwidth; + u32 bandwidth_hz; /* 0 = AUTO */ fe_guard_interval_t guard_interval; fe_hierarchy_t hierarchy; u32 symbol_rate; -- cgit v1.2.3 From 7d66b3c4dc460d812e2f899802be74dc0c7be39b Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 13 Sep 2008 17:15:17 -0400 Subject: S2API: Bugfix related to syncing the cache when used with the old API. From: Steven Toth Many thanks to Darron Broad for pointing out the obvious. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index c8865d639..98aaa1a65 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1606,9 +1606,9 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, break; } - dtv_property_cache_sync(fe, &fepriv->parameters); memcpy (&fepriv->parameters, parg, sizeof (struct dvb_frontend_parameters)); + dtv_property_cache_sync(fe, &fepriv->parameters); } memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); -- cgit v1.2.3 From b5c6a451c061b83cfe6f69eb794646879afd7025 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Tue, 23 Sep 2008 21:21:26 -0400 Subject: S2API: Deactivate the ISDB-T definitions From: Steven Toth We don't want to push the ISDB-T definitions into the kernel until we have a high level of confidence in the ISDB-T API. More testing is required before this code is released. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 11 ++++++++--- linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 98aaa1a65..5c1193524 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -840,6 +840,7 @@ struct dtv_cmds_h dtv_cmds[] = { .cmd = DTV_DELIVERY_SYSTEM, .set = 1, }, +#if 0 [DTV_ISDB_SEGMENT_IDX] = { .name = "DTV_ISDB_SEGMENT_IDX", .cmd = DTV_ISDB_SEGMENT_IDX, @@ -850,7 +851,7 @@ struct dtv_cmds_h dtv_cmds[] = { .cmd = DTV_ISDB_SEGMENT_WIDTH, .set = 1, }, - +#endif /* Get */ [DTV_DISEQC_SLAVE_REPLY] = { .name = "DTV_DISEQC_SLAVE_REPLY", @@ -858,6 +859,7 @@ struct dtv_cmds_h dtv_cmds[] = { .set = 0, .buffer = 1, }, +#if 0 [DTV_ISDB_LAYERA_FEC] = { .name = "DTV_ISDB_LAYERA_FEC", .cmd = DTV_ISDB_LAYERA_FEC, @@ -903,6 +905,7 @@ struct dtv_cmds_h dtv_cmds[] = { .cmd = DTV_ISDB_LAYERC_SEGMENT_WIDTH, .set = 0, }, +#endif }; void dtv_property_dump(struct dtv_property *tvp) @@ -1165,7 +1168,7 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, case DTV_DELIVERY_SYSTEM: tvp->u.data = fe->dtv_property_cache.delivery_system; break; - +#if 0 /* ISDB-T Support here */ case DTV_ISDB_SEGMENT_IDX: tvp->u.data = fe->dtv_property_cache.isdb_segment_idx; @@ -1200,6 +1203,7 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, case DTV_ISDB_LAYERC_SEGMENT_WIDTH: tvp->u.data = fe->dtv_property_cache.isdb_layerc_segment_width; break; +#endif case DTV_VOLTAGE: tvp->u.data = fe->dtv_property_cache.voltage; break; @@ -1277,7 +1281,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, case DTV_DELIVERY_SYSTEM: fe->dtv_property_cache.delivery_system = tvp->u.data; break; - +#if 0 /* ISDB-T Support here */ case DTV_ISDB_SEGMENT_IDX: fe->dtv_property_cache.isdb_segment_idx = tvp->u.data; @@ -1285,6 +1289,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, case DTV_ISDB_SEGMENT_WIDTH: fe->dtv_property_cache.isdb_segment_width = tvp->u.data; break; +#endif case DTV_VOLTAGE: fe->dtv_property_cache.voltage = tvp->u.data; r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE, diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h index 2fa37f5a0..1207f29f2 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -209,7 +209,7 @@ struct dtv_frontend_properties { fe_rolloff_t rolloff; fe_delivery_system_t delivery_system; - +#if 0 /* ISDB-T specifics */ u32 isdb_segment_idx; u32 isdb_segment_width; @@ -222,6 +222,7 @@ struct dtv_frontend_properties { fe_code_rate_t isdb_layerc_fec; fe_modulation_t isdb_layerc_modulation; u32 isdb_layerc_segment_width; +#endif }; struct dvb_frontend { -- cgit v1.2.3 From 57ba167023f217da9151306b24ac58d039441bad Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 24 Sep 2008 10:00:37 +0200 Subject: Fix deadlock in demux code From: Andreas Oberritter The functions dvb_dmxdev_section_callback, dvb_dmxdev_ts_callback, dvb_dmx_swfilter_packet, dvb_dmx_swfilter_packets, dvb_dmx_swfilter and dvb_dmx_swfilter_204 may be called from both interrupt and process context. Therefore they need to be protected by spin_lock_irqsave() instead of spin_lock(). This fixes a deadlock discovered by lockdep. Signed-off-by: Andreas Oberritter Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dmxdev.c | 16 +++++++++------- linux/drivers/media/dvb/dvb-core/dvb_demux.c | 16 ++++++++++------ 2 files changed, 19 insertions(+), 13 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index 069d847ba..0c733c66a 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -364,15 +364,16 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, enum dmx_success success) { struct dmxdev_filter *dmxdevfilter = filter->priv; + unsigned long flags; int ret; if (dmxdevfilter->buffer.error) { wake_up(&dmxdevfilter->buffer.queue); return 0; } - spin_lock(&dmxdevfilter->dev->lock); + spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); if (dmxdevfilter->state != DMXDEV_STATE_GO) { - spin_unlock(&dmxdevfilter->dev->lock); + spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); return 0; } del_timer(&dmxdevfilter->timer); @@ -391,7 +392,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, } if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) dmxdevfilter->state = DMXDEV_STATE_DONE; - spin_unlock(&dmxdevfilter->dev->lock); + spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); wake_up(&dmxdevfilter->buffer.queue); return 0; } @@ -403,11 +404,12 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, { struct dmxdev_filter *dmxdevfilter = feed->priv; struct dvb_ringbuffer *buffer; + unsigned long flags; int ret; - spin_lock(&dmxdevfilter->dev->lock); + spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { - spin_unlock(&dmxdevfilter->dev->lock); + spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); return 0; } @@ -417,7 +419,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, else buffer = &dmxdevfilter->dev->dvr_buffer; if (buffer->error) { - spin_unlock(&dmxdevfilter->dev->lock); + spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); wake_up(&buffer->queue); return 0; } @@ -428,7 +430,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, dvb_ringbuffer_flush(buffer); buffer->error = ret; } - spin_unlock(&dmxdevfilter->dev->lock); + spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); wake_up(&buffer->queue); return 0; } diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index e2eca0b1f..a2c1fd5d2 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c @@ -399,7 +399,9 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count) { - spin_lock(&demux->lock); + unsigned long flags; + + spin_lock_irqsave(&demux->lock, flags); while (count--) { if (buf[0] == 0x47) @@ -407,16 +409,17 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, buf += 188; } - spin_unlock(&demux->lock); + spin_unlock_irqrestore(&demux->lock, flags); } EXPORT_SYMBOL(dvb_dmx_swfilter_packets); void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) { + unsigned long flags; int p = 0, i, j; - spin_lock(&demux->lock); + spin_lock_irqsave(&demux->lock, flags); if (demux->tsbufp) { i = demux->tsbufp; @@ -449,17 +452,18 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock(&demux->lock); + spin_unlock_irqrestore(&demux->lock, flags); } EXPORT_SYMBOL(dvb_dmx_swfilter); void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) { + unsigned long flags; int p = 0, i, j; u8 tmppack[188]; - spin_lock(&demux->lock); + spin_lock_irqsave(&demux->lock, flags); if (demux->tsbufp) { i = demux->tsbufp; @@ -500,7 +504,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock(&demux->lock); + spin_unlock_irqrestore(&demux->lock, flags); } EXPORT_SYMBOL(dvb_dmx_swfilter_204); -- cgit v1.2.3 From 506cfbf07f4322d8a43fd8bd0055c142db5cf615 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 25 Sep 2008 23:16:25 -0400 Subject: S2API: Implement result codes for individual commands From: Steven Toth This allows application developers to determine which particular command in a sequence is invalid, or failing with error. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 5c1193524..9f3a61827 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1377,8 +1377,10 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, goto out; } - for (i = 0; i < tvps->num; i++) - err |= dtv_property_process_set(fe, tvp + i, inode, file); + for (i = 0; i < tvps->num; i++) { + (tvp + i)->result = dtv_property_process_set(fe, tvp + i, inode, file); + err |= (tvp + i)->result; + } if(fe->dtv_property_cache.state == DTV_TUNE) { printk("%s() Property cache is full, tuning\n", __FUNCTION__); @@ -1410,8 +1412,10 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, goto out; } - for (i = 0; i < tvps->num; i++) - err |= dtv_property_process_get(fe, tvp + i, inode, file); + for (i = 0; i < tvps->num; i++) { + (tvp + i)->result = dtv_property_process_get(fe, tvp + i, inode, file); + err |= (tvp + i)->result; + } if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) { err = -EFAULT; -- cgit v1.2.3 From 1bded05663a0aea1702e531a19694c6b670dc7d2 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 25 Sep 2008 23:29:49 -0400 Subject: S2API: Add DTV_API_VERSION command From: Steven Toth This allows application developers to query the dvb-core API version dynamically, helping developers understand whether certain features will be available. Priority: normal Signed-off-by: Steven Toth --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 9f3a61827..6f0dc252f 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -45,6 +45,7 @@ #include "dvb_frontend.h" #include "dvbdev.h" #include "compat.h" +#include static int dvb_frontend_debug; static int dvb_shutdown_timeout; @@ -906,6 +907,11 @@ struct dtv_cmds_h dtv_cmds[] = { .set = 0, }, #endif + [DTV_API_VERSION] = { + .name = "DTV_API_VERSION", + .cmd = DTV_API_VERSION, + .set = 0, + }, }; void dtv_property_dump(struct dtv_property *tvp) @@ -1210,6 +1216,9 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, case DTV_TONE: tvp->u.data = fe->dtv_property_cache.sectone; break; + case DTV_API_VERSION: + tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR; + break; default: r = -1; } -- cgit v1.2.3