aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorSteven Toth <stoth@linuxtv.org>2008-09-04 20:19:43 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-12 07:37:03 -0400
commit13c97bf56724b4f2d3dac139fb4cb081a3c401dc (patch)
tree9b644b37993bb665301d147d03cbc045c388ada8 /drivers/media
parent5bd1b66359437864e6b46420ba6770c2b1c4362c (diff)
V4L/DVB (8988): S2API: Allow the properties to call legacy ioctls
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. Signed-off-by: Steven Toth <stoth@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c67
1 files changed, 59 insertions, 8 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index e68974b2fee9..86af06cf578c 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1156,9 +1156,16 @@ int tv_property_cache_submit(struct dvb_frontend *fe)
1156 return r; 1156 return r;
1157} 1157}
1158 1158
1159int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp) 1159static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
1160 unsigned int cmd, void *parg);
1161static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
1162 unsigned int cmd, void *parg);
1163
1164int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp,
1165 struct inode *inode, struct file *file)
1160{ 1166{
1161 int r = 0; 1167 int r = 0;
1168 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1162 printk("%s()\n", __FUNCTION__); 1169 printk("%s()\n", __FUNCTION__);
1163 tv_property_dump(tvp); 1170 tv_property_dump(tvp);
1164 1171
@@ -1181,7 +1188,9 @@ int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp)
1181 */ 1188 */
1182 fe->tv_property_cache.state = TV_SEQ_COMPLETE; 1189 fe->tv_property_cache.state = TV_SEQ_COMPLETE;
1183 printk("%s() Finalised property cache\n", __FUNCTION__); 1190 printk("%s() Finalised property cache\n", __FUNCTION__);
1184 r = tv_property_cache_submit(fe); 1191 r |= tv_property_cache_submit(fe);
1192 r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND,
1193 &fepriv->parameters);
1185 break; 1194 break;
1186 case TV_SET_FREQUENCY: 1195 case TV_SET_FREQUENCY:
1187 fe->tv_property_cache.frequency = tvp->u.data; 1196 fe->tv_property_cache.frequency = tvp->u.data;
@@ -1278,10 +1287,25 @@ int tv_property_process(struct dvb_frontend *fe, tv_property_t *tvp)
1278 case TV_GET_ISDB_LAYERC_SEGMENT_WIDTH: 1287 case TV_GET_ISDB_LAYERC_SEGMENT_WIDTH:
1279 tvp->u.data = fe->tv_property_cache.isdb_layerc_segment_width; 1288 tvp->u.data = fe->tv_property_cache.isdb_layerc_segment_width;
1280 break; 1289 break;
1281 1290 case TV_SET_VOLTAGE:
1291 fe->tv_property_cache.voltage = tvp->u.data;
1292 r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE,
1293 &fe->tv_property_cache.voltage);
1294 break;
1295 case TV_GET_VOLTAGE:
1296 tvp->u.data = fe->tv_property_cache.voltage;
1297 break;
1298 case TV_SET_TONE:
1299 fe->tv_property_cache.sectone = tvp->u.data;
1300 r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_TONE,
1301 (void *)fe->tv_property_cache.sectone);
1302 break;
1303 case TV_GET_TONE:
1304 tvp->u.data = fe->tv_property_cache.sectone;
1305 break;
1282 } 1306 }
1283 1307
1284 return 0; 1308 return r;
1285} 1309}
1286 1310
1287static int dvb_frontend_ioctl(struct inode *inode, struct file *file, 1311static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
@@ -1291,7 +1315,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
1291 struct dvb_frontend *fe = dvbdev->priv; 1315 struct dvb_frontend *fe = dvbdev->priv;
1292 struct dvb_frontend_private *fepriv = fe->frontend_priv; 1316 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1293 int err = -EOPNOTSUPP; 1317 int err = -EOPNOTSUPP;
1294 tv_property_t* tvp;
1295 1318
1296 dprintk ("%s\n", __func__); 1319 dprintk ("%s\n", __func__);
1297 1320
@@ -1306,6 +1329,25 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
1306 if (down_interruptible (&fepriv->sem)) 1329 if (down_interruptible (&fepriv->sem))
1307 return -ERESTARTSYS; 1330 return -ERESTARTSYS;
1308 1331
1332 if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY))
1333 err = dvb_frontend_ioctl_properties(inode, file, cmd, parg);
1334 else
1335 err = dvb_frontend_ioctl_legacy(inode, file, cmd, parg);
1336
1337 up(&fepriv->sem);
1338 return err;
1339}
1340
1341static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
1342 unsigned int cmd, void *parg)
1343{
1344 struct dvb_device *dvbdev = file->private_data;
1345 struct dvb_frontend *fe = dvbdev->priv;
1346 int err = -EOPNOTSUPP;
1347 tv_property_t *tvp;
1348
1349 dprintk("%s\n", __func__);
1350
1309 if(cmd == FE_SET_PROPERTY) { 1351 if(cmd == FE_SET_PROPERTY) {
1310 printk("%s() FE_SET_PROPERTY\n", __FUNCTION__); 1352 printk("%s() FE_SET_PROPERTY\n", __FUNCTION__);
1311 1353
@@ -1314,7 +1356,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
1314 /* TODO: ioctl userdata out of range check here */ 1356 /* TODO: ioctl userdata out of range check here */
1315 tvp = parg; 1357 tvp = parg;
1316 while(tvp->cmd != TV_SEQ_UNDEFINED) { 1358 while(tvp->cmd != TV_SEQ_UNDEFINED) {
1317 tv_property_process(fe, tvp); 1359 tv_property_process(fe, tvp, inode, file);
1318 if( (tvp->cmd == TV_SEQ_TERMINATE) || (tvp->cmd == TV_SEQ_COMPLETE) ) 1360 if( (tvp->cmd == TV_SEQ_TERMINATE) || (tvp->cmd == TV_SEQ_COMPLETE) )
1319 break; 1361 break;
1320 tvp++; 1362 tvp++;
@@ -1322,11 +1364,21 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
1322 1364
1323 if(fe->tv_property_cache.state == TV_SEQ_COMPLETE) { 1365 if(fe->tv_property_cache.state == TV_SEQ_COMPLETE) {
1324 printk("%s() Property cache is full, tuning\n", __FUNCTION__); 1366 printk("%s() Property cache is full, tuning\n", __FUNCTION__);
1325 cmd = FE_SET_FRONTEND;
1326 } 1367 }
1327 err = 0; 1368 err = 0;
1328 } 1369 }
1329 1370
1371 return err;
1372}
1373
1374static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
1375 unsigned int cmd, void *parg)
1376{
1377 struct dvb_device *dvbdev = file->private_data;
1378 struct dvb_frontend *fe = dvbdev->priv;
1379 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1380 int err = -EOPNOTSUPP;
1381
1330 switch (cmd) { 1382 switch (cmd) {
1331 case FE_GET_INFO: { 1383 case FE_GET_INFO: {
1332 struct dvb_frontend_info* info = parg; 1384 struct dvb_frontend_info* info = parg;
@@ -1585,7 +1637,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
1585 break; 1637 break;
1586 }; 1638 };
1587 1639
1588 up (&fepriv->sem);
1589 return err; 1640 return err;
1590} 1641}
1591 1642