aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Toth <stoth@linuxtv.org>2008-09-11 09:23:01 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-12 07:37:04 -0400
commite7fee0f3aa111d42cdcfc1470cfdc21dde0cdbe2 (patch)
treefedd63397870c4f97b26176ed3b7e2d660d77957
parent56f0680a28397f4b412fc14f60ac380b910ee328 (diff)
V4L/DVB (8996): S2API: typedefs replaced, _SEQ_'s removed, fixed 16 command arrays replaced
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. Signed-off-by: Steven Toth <stoth@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c83
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h4
-rw-r--r--drivers/media/dvb/frontends/cx24116.c2
-rw-r--r--include/linux/dvb/frontend.h27
4 files changed, 63 insertions, 53 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 9c4761506d2d..763da968236f 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -756,29 +756,14 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
756} 756}
757 757
758struct dtv_cmds_h dtv_cmds[] = { 758struct dtv_cmds_h dtv_cmds[] = {
759 [DTV_SEQ_UNDEFINED] = { 759 [DTV_TUNE] = {
760 .name = "DTV_SEQ_UNDEFINED", 760 .name = "DTV_TUNE",
761 .cmd = DTV_SEQ_UNDEFINED, 761 .cmd = DTV_TUNE,
762 .set = 1, 762 .set = 1,
763 }, 763 },
764 [DTV_SEQ_START] = { 764 [DTV_CLEAR] = {
765 .name = "DTV_SEQ_START", 765 .name = "DTV_CLEAR",
766 .cmd = DTV_SEQ_START, 766 .cmd = DTV_CLEAR,
767 .set = 1,
768 },
769 [DTV_SEQ_CONTINUE] = {
770 .name = "DTV_SEQ_CONTINUE",
771 .cmd = DTV_SEQ_CONTINUE,
772 .set = 1,
773 },
774 [DTV_SEQ_COMPLETE] = {
775 .name = "DTV_SEQ_COMPLETE",
776 .cmd = DTV_SEQ_COMPLETE,
777 .set = 1,
778 },
779 [DTV_SEQ_TERMINATE] = {
780 .name = "DTV_SEQ_TERMINATE",
781 .cmd = DTV_SEQ_TERMINATE,
782 .set = 1, 767 .set = 1,
783 }, 768 },
784 769
@@ -974,7 +959,7 @@ struct dtv_cmds_h dtv_cmds[] = {
974 }, 959 },
975}; 960};
976 961
977void dtv_property_dump(dtv_property_t *tvp) 962void dtv_property_dump(struct dtv_property *tvp)
978{ 963{
979 int i; 964 int i;
980 965
@@ -1044,6 +1029,7 @@ int dtv_property_cache_submit(struct dvb_frontend *fe)
1044 1029
1045 /* For legacy delivery systems we don't need the delivery_system to be specified */ 1030 /* For legacy delivery systems we don't need the delivery_system to be specified */
1046 if(is_legacy_delivery_system(c->delivery_system)) { 1031 if(is_legacy_delivery_system(c->delivery_system)) {
1032 printk("%s() legacy, modulation = %d\n", __FUNCTION__, c->modulation);
1047 switch(c->modulation) { 1033 switch(c->modulation) {
1048 case QPSK: 1034 case QPSK:
1049 printk("%s() Preparing QPSK req\n", __FUNCTION__); 1035 printk("%s() Preparing QPSK req\n", __FUNCTION__);
@@ -1161,7 +1147,7 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
1161static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, 1147static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
1162 unsigned int cmd, void *parg); 1148 unsigned int cmd, void *parg);
1163 1149
1164int dtv_property_process(struct dvb_frontend *fe, dtv_property_t *tvp, 1150int dtv_property_process(struct dvb_frontend *fe, struct dtv_property *tvp,
1165 struct inode *inode, struct file *file) 1151 struct inode *inode, struct file *file)
1166{ 1152{
1167 int r = 0; 1153 int r = 0;
@@ -1170,23 +1156,22 @@ int dtv_property_process(struct dvb_frontend *fe, dtv_property_t *tvp,
1170 dtv_property_dump(tvp); 1156 dtv_property_dump(tvp);
1171 1157
1172 switch(tvp->cmd) { 1158 switch(tvp->cmd) {
1173 case DTV_SEQ_START: 1159 case DTV_CLEAR:
1174 case DTV_SEQ_TERMINATE:
1175 /* Reset a cache of data specific to the frontend here. This does 1160 /* Reset a cache of data specific to the frontend here. This does
1176 * not effect hardware. 1161 * not effect hardware.
1177 */ 1162 */
1178 printk("%s() Flushing property cache\n", __FUNCTION__); 1163 printk("%s() Flushing property cache\n", __FUNCTION__);
1179 memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties)); 1164 memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties));
1180 fe->dtv_property_cache.state = DTV_SEQ_START; 1165 fe->dtv_property_cache.state = tvp->cmd;
1181 fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; 1166 fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
1182 break; 1167 break;
1183 case DTV_SEQ_COMPLETE: 1168 case DTV_TUNE:
1184 /* interpret the cache of data, build either a traditional frontend 1169 /* interpret the cache of data, build either a traditional frontend
1185 * tunerequest and submit it to a subset of the ioctl handler, 1170 * tunerequest and submit it to a subset of the ioctl handler,
1186 * or, call a new undefined method on the frontend to deal with 1171 * or, call a new undefined method on the frontend to deal with
1187 * all new tune requests. 1172 * all new tune requests.
1188 */ 1173 */
1189 fe->dtv_property_cache.state = DTV_SEQ_COMPLETE; 1174 fe->dtv_property_cache.state = tvp->cmd;
1190 printk("%s() Finalised property cache\n", __FUNCTION__); 1175 printk("%s() Finalised property cache\n", __FUNCTION__);
1191 r |= dtv_property_cache_submit(fe); 1176 r |= dtv_property_cache_submit(fe);
1192 r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, 1177 r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND,
@@ -1344,30 +1329,48 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
1344 struct dvb_device *dvbdev = file->private_data; 1329 struct dvb_device *dvbdev = file->private_data;
1345 struct dvb_frontend *fe = dvbdev->priv; 1330 struct dvb_frontend *fe = dvbdev->priv;
1346 int err = -EOPNOTSUPP; 1331 int err = -EOPNOTSUPP;
1347 dtv_property_t *tvp; 1332
1333 struct dtv_properties *tvps = NULL;
1334 struct dtv_property *tvp = NULL;
1335 int i;
1348 1336
1349 dprintk("%s\n", __func__); 1337 dprintk("%s\n", __func__);
1350 1338
1351 if(cmd == FE_SET_PROPERTY) { 1339 if(cmd == FE_SET_PROPERTY) {
1352 printk("%s() FE_SET_PROPERTY\n", __FUNCTION__); 1340 printk("%s() FE_SET_PROPERTY\n", __FUNCTION__);
1353 1341
1354 /* TODO: basic property validation here */ 1342 tvps = (struct dtv_properties __user *)parg;
1355 1343
1356 /* TODO: ioctl userdata out of range check here */ 1344 printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num);
1357 tvp = parg; 1345 printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props);
1358 while(tvp->cmd != DTV_SEQ_UNDEFINED) { 1346
1359 dtv_property_process(fe, tvp, inode, file); 1347 /* Put an arbitrary limit on the number of messages that can
1360 if( (tvp->cmd == DTV_SEQ_TERMINATE) || (tvp->cmd == DTV_SEQ_COMPLETE) ) 1348 * be sent at once */
1361 break; 1349 if (tvps->num > DTV_IOCTL_MAX_MSGS)
1362 tvp++; 1350 return -EINVAL;
1351
1352 tvp = (struct dtv_property *) kmalloc(tvps->num *
1353 sizeof(struct dtv_property), GFP_KERNEL);
1354 if (!tvp) {
1355 err = -ENOMEM;
1356 goto out;
1363 } 1357 }
1364 1358
1365 if(fe->dtv_property_cache.state == DTV_SEQ_COMPLETE) { 1359 if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
1360 err = -EFAULT;
1361 goto out;
1362 }
1363
1364 for (i = 0; i < tvps->num; i++)
1365 dtv_property_process(fe, tvp + i, inode, file);
1366
1367 if(fe->dtv_property_cache.state == DTV_TUNE) {
1366 printk("%s() Property cache is full, tuning\n", __FUNCTION__); 1368 printk("%s() Property cache is full, tuning\n", __FUNCTION__);
1367 } 1369 }
1368 err = 0; 1370 err = 0;
1369 } 1371 }
1370 1372out:
1373 kfree(tvp);
1371 return err; 1374 return err;
1372} 1375}
1373 1376
@@ -1545,7 +1548,7 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
1545 case FE_SET_FRONTEND: { 1548 case FE_SET_FRONTEND: {
1546 struct dvb_frontend_tune_settings fetunesettings; 1549 struct dvb_frontend_tune_settings fetunesettings;
1547 1550
1548 if(fe->dtv_property_cache.state == DTV_SEQ_COMPLETE) { 1551 if(fe->dtv_property_cache.state == DTV_TUNE) {
1549 if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) { 1552 if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) {
1550 err = -EINVAL; 1553 err = -EINVAL;
1551 break; 1554 break;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index f376f281cde2..85d30201a695 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -170,8 +170,8 @@ struct dvb_frontend_ops {
170 struct dvb_tuner_ops tuner_ops; 170 struct dvb_tuner_ops tuner_ops;
171 struct analog_demod_ops analog_ops; 171 struct analog_demod_ops analog_ops;
172 172
173 int (*set_property)(struct dvb_frontend* fe, dtv_property_t* tvp); 173 int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
174 int (*get_property)(struct dvb_frontend* fe, dtv_property_t* tvp); 174 int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
175 int (*set_params)(struct dvb_frontend* fe); 175 int (*set_params)(struct dvb_frontend* fe);
176}; 176};
177 177
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
index f150fa24ff9f..9f93930a2594 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -796,7 +796,7 @@ static int cx24116_initfe(struct dvb_frontend* fe)
796 return cx24116_diseqc_init(fe); 796 return cx24116_diseqc_init(fe);
797} 797}
798 798
799static int cx24116_set_property(struct dvb_frontend *fe, dtv_property_t* tvp) 799static int cx24116_set_property(struct dvb_frontend *fe, struct dtv_property* tvp)
800{ 800{
801 dprintk("%s(..)\n", __func__); 801 dprintk("%s(..)\n", __func__);
802 return 0; 802 return 0;
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index aeace74b5366..f667bf377a7b 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -251,11 +251,8 @@ struct dvb_frontend_event {
251 * binary compatability. 251 * binary compatability.
252 */ 252 */
253typedef enum dtv_cmd_types { 253typedef enum dtv_cmd_types {
254 DTV_SEQ_UNDEFINED, 254 DTV_TUNE,
255 DTV_SEQ_START, 255 DTV_CLEAR,
256 DTV_SEQ_CONTINUE,
257 DTV_SEQ_COMPLETE,
258 DTV_SEQ_TERMINATE,
259 256
260 DTV_SET_FREQUENCY, 257 DTV_SET_FREQUENCY,
261 DTV_SET_MODULATION, 258 DTV_SET_MODULATION,
@@ -348,22 +345,32 @@ struct dtv_cmds_h {
348 __u32 reserved:30; /* Align */ 345 __u32 reserved:30; /* Align */
349}; 346};
350 347
351typedef struct { 348struct dtv_property {
352 __u32 cmd; 349 __u32 cmd;
350 __u32 reserved[3];
353 union { 351 union {
352 __s32 valuemin;
353 __s32 valuemax;
354 __u32 data; 354 __u32 data;
355 struct { 355 struct {
356 __u8 data[32]; 356 __u8 data[32];
357 __u32 len; 357 __u32 len;
358 __u32 reserved1[3];
359 void *reserved2;
358 } buffer; 360 } buffer;
359 } u; 361 } u;
360} dtv_property_t; 362} __attribute__ ((packed));
361 363
362/* No more than 16 properties during any given ioctl */ 364/* No more than 16 properties during any given ioctl */
363typedef dtv_property_t dtv_properties_t[16]; 365struct dtv_properties {
366 __u32 num;
367 struct dtv_property *props;
368};
369
370#define DTV_IOCTL_MAX_MSGS 64
364 371
365#define FE_SET_PROPERTY _IOW('o', 82, dtv_properties_t) 372#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties)
366#define FE_GET_PROPERTY _IOR('o', 83, dtv_properties_t) 373#define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties)
367 374
368 375
369/** 376/**