aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb-core')
-rw-r--r--drivers/media/dvb-core/dvb-usb-ids.h6
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.c16
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c59
-rw-r--r--drivers/media/dvb-core/dvb_frontend.h10
-rw-r--r--drivers/media/dvb-core/dvb_net.c71
-rw-r--r--drivers/media/dvb-core/dvb_net.h1
-rw-r--r--drivers/media/dvb-core/dvbdev.c2
7 files changed, 132 insertions, 33 deletions
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 388c2eb4d747..399e1042d351 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -172,6 +172,7 @@
172#define USB_PID_TWINHAN_VP7045_WARM 0x3206 172#define USB_PID_TWINHAN_VP7045_WARM 0x3206
173#define USB_PID_TWINHAN_VP7021_COLD 0x3207 173#define USB_PID_TWINHAN_VP7021_COLD 0x3207
174#define USB_PID_TWINHAN_VP7021_WARM 0x3208 174#define USB_PID_TWINHAN_VP7021_WARM 0x3208
175#define USB_PID_TWINHAN_VP7049 0x3219
175#define USB_PID_TINYTWIN 0x3226 176#define USB_PID_TINYTWIN 0x3226
176#define USB_PID_TINYTWIN_2 0xe402 177#define USB_PID_TINYTWIN_2 0xe402
177#define USB_PID_TINYTWIN_3 0x9016 178#define USB_PID_TINYTWIN_3 0x9016
@@ -233,10 +234,15 @@
233#define USB_PID_AVERMEDIA_A815M 0x815a 234#define USB_PID_AVERMEDIA_A815M 0x815a
234#define USB_PID_AVERMEDIA_A835 0xa835 235#define USB_PID_AVERMEDIA_A835 0xa835
235#define USB_PID_AVERMEDIA_B835 0xb835 236#define USB_PID_AVERMEDIA_B835 0xb835
237#define USB_PID_AVERMEDIA_A835B_1835 0x1835
238#define USB_PID_AVERMEDIA_A835B_2835 0x2835
239#define USB_PID_AVERMEDIA_A835B_3835 0x3835
240#define USB_PID_AVERMEDIA_A835B_4835 0x4835
236#define USB_PID_AVERMEDIA_1867 0x1867 241#define USB_PID_AVERMEDIA_1867 0x1867
237#define USB_PID_AVERMEDIA_A867 0xa867 242#define USB_PID_AVERMEDIA_A867 0xa867
238#define USB_PID_AVERMEDIA_TWINSTAR 0x0825 243#define USB_PID_AVERMEDIA_TWINSTAR 0x0825
239#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 244#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
245#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
240#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d 246#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
241#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 247#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
242#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 248#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
index 9be65a3b931f..0aac3096728e 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
@@ -156,6 +156,9 @@ struct dvb_ca_private {
156 156
157 /* Slot to start looking for data to read from in the next user-space read operation */ 157 /* Slot to start looking for data to read from in the next user-space read operation */
158 int next_read_slot; 158 int next_read_slot;
159
160 /* mutex serializing ioctls */
161 struct mutex ioctl_mutex;
159}; 162};
160 163
161static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca); 164static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca);
@@ -1191,6 +1194,9 @@ static int dvb_ca_en50221_io_do_ioctl(struct file *file,
1191 1194
1192 dprintk("%s\n", __func__); 1195 dprintk("%s\n", __func__);
1193 1196
1197 if (mutex_lock_interruptible(&ca->ioctl_mutex))
1198 return -ERESTARTSYS;
1199
1194 switch (cmd) { 1200 switch (cmd) {
1195 case CA_RESET: 1201 case CA_RESET:
1196 for (slot = 0; slot < ca->slot_count; slot++) { 1202 for (slot = 0; slot < ca->slot_count; slot++) {
@@ -1221,8 +1227,10 @@ static int dvb_ca_en50221_io_do_ioctl(struct file *file,
1221 case CA_GET_SLOT_INFO: { 1227 case CA_GET_SLOT_INFO: {
1222 struct ca_slot_info *info = parg; 1228 struct ca_slot_info *info = parg;
1223 1229
1224 if ((info->num > ca->slot_count) || (info->num < 0)) 1230 if ((info->num > ca->slot_count) || (info->num < 0)) {
1225 return -EINVAL; 1231 err = -EINVAL;
1232 goto out_unlock;
1233 }
1226 1234
1227 info->type = CA_CI_LINK; 1235 info->type = CA_CI_LINK;
1228 info->flags = 0; 1236 info->flags = 0;
@@ -1241,6 +1249,8 @@ static int dvb_ca_en50221_io_do_ioctl(struct file *file,
1241 break; 1249 break;
1242 } 1250 }
1243 1251
1252out_unlock:
1253 mutex_unlock(&ca->ioctl_mutex);
1244 return err; 1254 return err;
1245} 1255}
1246 1256
@@ -1695,6 +1705,8 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
1695 mutex_init(&ca->slot_info[i].slot_lock); 1705 mutex_init(&ca->slot_info[i].slot_lock);
1696 } 1706 }
1697 1707
1708 mutex_init(&ca->ioctl_mutex);
1709
1698 if (signal_pending(current)) { 1710 if (signal_pending(current)) {
1699 ret = -EINTR; 1711 ret = -EINTR;
1700 goto error; 1712 goto error;
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 0223ad255cb4..6e50a7581568 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -603,6 +603,7 @@ static int dvb_frontend_thread(void *data)
603 enum dvbfe_algo algo; 603 enum dvbfe_algo algo;
604 604
605 bool re_tune = false; 605 bool re_tune = false;
606 bool semheld = false;
606 607
607 dev_dbg(fe->dvb->device, "%s:\n", __func__); 608 dev_dbg(fe->dvb->device, "%s:\n", __func__);
608 609
@@ -626,6 +627,8 @@ restart:
626 627
627 if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { 628 if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
628 /* got signal or quitting */ 629 /* got signal or quitting */
630 if (!down_interruptible(&fepriv->sem))
631 semheld = true;
629 fepriv->exit = DVB_FE_NORMAL_EXIT; 632 fepriv->exit = DVB_FE_NORMAL_EXIT;
630 break; 633 break;
631 } 634 }
@@ -741,6 +744,8 @@ restart:
741 fepriv->exit = DVB_FE_NO_EXIT; 744 fepriv->exit = DVB_FE_NO_EXIT;
742 mb(); 745 mb();
743 746
747 if (semheld)
748 up(&fepriv->sem);
744 dvb_frontend_wakeup(fe); 749 dvb_frontend_wakeup(fe);
745 return 0; 750 return 0;
746} 751}
@@ -1048,6 +1053,16 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
1048 _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B, 0, 0), 1053 _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B, 0, 0),
1049 _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C, 0, 0), 1054 _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C, 0, 0),
1050 _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D, 0, 0), 1055 _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D, 0, 0),
1056
1057 /* Statistics API */
1058 _DTV_CMD(DTV_STAT_SIGNAL_STRENGTH, 0, 0),
1059 _DTV_CMD(DTV_STAT_CNR, 0, 0),
1060 _DTV_CMD(DTV_STAT_PRE_ERROR_BIT_COUNT, 0, 0),
1061 _DTV_CMD(DTV_STAT_PRE_TOTAL_BIT_COUNT, 0, 0),
1062 _DTV_CMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0, 0),
1063 _DTV_CMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0, 0),
1064 _DTV_CMD(DTV_STAT_ERROR_BLOCK_COUNT, 0, 0),
1065 _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0),
1051}; 1066};
1052 1067
1053static void dtv_property_dump(struct dvb_frontend *fe, struct dtv_property *tvp) 1068static void dtv_property_dump(struct dvb_frontend *fe, struct dtv_property *tvp)
@@ -1438,7 +1453,35 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
1438 tvp->u.data = c->lna; 1453 tvp->u.data = c->lna;
1439 break; 1454 break;
1440 1455
1456 /* Fill quality measures */
1457 case DTV_STAT_SIGNAL_STRENGTH:
1458 tvp->u.st = c->strength;
1459 break;
1460 case DTV_STAT_CNR:
1461 tvp->u.st = c->cnr;
1462 break;
1463 case DTV_STAT_PRE_ERROR_BIT_COUNT:
1464 tvp->u.st = c->pre_bit_error;
1465 break;
1466 case DTV_STAT_PRE_TOTAL_BIT_COUNT:
1467 tvp->u.st = c->pre_bit_count;
1468 break;
1469 case DTV_STAT_POST_ERROR_BIT_COUNT:
1470 tvp->u.st = c->post_bit_error;
1471 break;
1472 case DTV_STAT_POST_TOTAL_BIT_COUNT:
1473 tvp->u.st = c->post_bit_count;
1474 break;
1475 case DTV_STAT_ERROR_BLOCK_COUNT:
1476 tvp->u.st = c->block_error;
1477 break;
1478 case DTV_STAT_TOTAL_BLOCK_COUNT:
1479 tvp->u.st = c->block_count;
1480 break;
1441 default: 1481 default:
1482 dev_dbg(fe->dvb->device,
1483 "%s: FE property %d doesn't exist\n",
1484 __func__, tvp->cmd);
1442 return -EINVAL; 1485 return -EINVAL;
1443 } 1486 }
1444 1487
@@ -1823,16 +1866,20 @@ static int dvb_frontend_ioctl(struct file *file,
1823 int err = -EOPNOTSUPP; 1866 int err = -EOPNOTSUPP;
1824 1867
1825 dev_dbg(fe->dvb->device, "%s: (%d)\n", __func__, _IOC_NR(cmd)); 1868 dev_dbg(fe->dvb->device, "%s: (%d)\n", __func__, _IOC_NR(cmd));
1826 if (fepriv->exit != DVB_FE_NO_EXIT) 1869 if (down_interruptible(&fepriv->sem))
1870 return -ERESTARTSYS;
1871
1872 if (fepriv->exit != DVB_FE_NO_EXIT) {
1873 up(&fepriv->sem);
1827 return -ENODEV; 1874 return -ENODEV;
1875 }
1828 1876
1829 if ((file->f_flags & O_ACCMODE) == O_RDONLY && 1877 if ((file->f_flags & O_ACCMODE) == O_RDONLY &&
1830 (_IOC_DIR(cmd) != _IOC_READ || cmd == FE_GET_EVENT || 1878 (_IOC_DIR(cmd) != _IOC_READ || cmd == FE_GET_EVENT ||
1831 cmd == FE_DISEQC_RECV_SLAVE_REPLY)) 1879 cmd == FE_DISEQC_RECV_SLAVE_REPLY)) {
1880 up(&fepriv->sem);
1832 return -EPERM; 1881 return -EPERM;
1833 1882 }
1834 if (down_interruptible (&fepriv->sem))
1835 return -ERESTARTSYS;
1836 1883
1837 if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) 1884 if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY))
1838 err = dvb_frontend_ioctl_properties(file, cmd, parg); 1885 err = dvb_frontend_ioctl_properties(file, cmd, parg);
@@ -2246,7 +2293,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
2246 printk("%s switch command: 0x%04lx\n", __func__, swcmd); 2293 printk("%s switch command: 0x%04lx\n", __func__, swcmd);
2247 do_gettimeofday(&nexttime); 2294 do_gettimeofday(&nexttime);
2248 if (dvb_frontend_debug) 2295 if (dvb_frontend_debug)
2249 memcpy(&tv[0], &nexttime, sizeof(struct timeval)); 2296 tv[0] = nexttime;
2250 /* before sending a command, initialize by sending 2297 /* before sending a command, initialize by sending
2251 * a 32ms 18V to the switch 2298 * a 32ms 18V to the switch
2252 */ 2299 */
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 97112cd88a17..b34922a08156 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -393,6 +393,16 @@ struct dtv_frontend_properties {
393 u8 atscmh_sccc_code_mode_d; 393 u8 atscmh_sccc_code_mode_d;
394 394
395 u32 lna; 395 u32 lna;
396
397 /* statistics data */
398 struct dtv_fe_stats strength;
399 struct dtv_fe_stats cnr;
400 struct dtv_fe_stats pre_bit_error;
401 struct dtv_fe_stats pre_bit_count;
402 struct dtv_fe_stats post_bit_error;
403 struct dtv_fe_stats post_bit_count;
404 struct dtv_fe_stats block_error;
405 struct dtv_fe_stats block_count;
396}; 406};
397 407
398struct dvb_frontend { 408struct dvb_frontend {
diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c
index c2117688aa23..44225b186f6d 100644
--- a/drivers/media/dvb-core/dvb_net.c
+++ b/drivers/media/dvb-core/dvb_net.c
@@ -1345,26 +1345,35 @@ static int dvb_net_do_ioctl(struct file *file,
1345{ 1345{
1346 struct dvb_device *dvbdev = file->private_data; 1346 struct dvb_device *dvbdev = file->private_data;
1347 struct dvb_net *dvbnet = dvbdev->priv; 1347 struct dvb_net *dvbnet = dvbdev->priv;
1348 int ret = 0;
1348 1349
1349 if (((file->f_flags&O_ACCMODE)==O_RDONLY)) 1350 if (((file->f_flags&O_ACCMODE)==O_RDONLY))
1350 return -EPERM; 1351 return -EPERM;
1351 1352
1353 if (mutex_lock_interruptible(&dvbnet->ioctl_mutex))
1354 return -ERESTARTSYS;
1355
1352 switch (cmd) { 1356 switch (cmd) {
1353 case NET_ADD_IF: 1357 case NET_ADD_IF:
1354 { 1358 {
1355 struct dvb_net_if *dvbnetif = parg; 1359 struct dvb_net_if *dvbnetif = parg;
1356 int result; 1360 int result;
1357 1361
1358 if (!capable(CAP_SYS_ADMIN)) 1362 if (!capable(CAP_SYS_ADMIN)) {
1359 return -EPERM; 1363 ret = -EPERM;
1364 goto ioctl_error;
1365 }
1360 1366
1361 if (!try_module_get(dvbdev->adapter->module)) 1367 if (!try_module_get(dvbdev->adapter->module)) {
1362 return -EPERM; 1368 ret = -EPERM;
1369 goto ioctl_error;
1370 }
1363 1371
1364 result=dvb_net_add_if(dvbnet, dvbnetif->pid, dvbnetif->feedtype); 1372 result=dvb_net_add_if(dvbnet, dvbnetif->pid, dvbnetif->feedtype);
1365 if (result<0) { 1373 if (result<0) {
1366 module_put(dvbdev->adapter->module); 1374 module_put(dvbdev->adapter->module);
1367 return result; 1375 ret = result;
1376 goto ioctl_error;
1368 } 1377 }
1369 dvbnetif->if_num=result; 1378 dvbnetif->if_num=result;
1370 break; 1379 break;
@@ -1376,8 +1385,10 @@ static int dvb_net_do_ioctl(struct file *file,
1376 struct dvb_net_if *dvbnetif = parg; 1385 struct dvb_net_if *dvbnetif = parg;
1377 1386
1378 if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || 1387 if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
1379 !dvbnet->state[dvbnetif->if_num]) 1388 !dvbnet->state[dvbnetif->if_num]) {
1380 return -EINVAL; 1389 ret = -EINVAL;
1390 goto ioctl_error;
1391 }
1381 1392
1382 netdev = dvbnet->device[dvbnetif->if_num]; 1393 netdev = dvbnet->device[dvbnetif->if_num];
1383 1394
@@ -1388,16 +1399,18 @@ static int dvb_net_do_ioctl(struct file *file,
1388 } 1399 }
1389 case NET_REMOVE_IF: 1400 case NET_REMOVE_IF:
1390 { 1401 {
1391 int ret; 1402 if (!capable(CAP_SYS_ADMIN)) {
1392 1403 ret = -EPERM;
1393 if (!capable(CAP_SYS_ADMIN)) 1404 goto ioctl_error;
1394 return -EPERM; 1405 }
1395 if ((unsigned long) parg >= DVB_NET_DEVICES_MAX) 1406 if ((unsigned long) parg >= DVB_NET_DEVICES_MAX) {
1396 return -EINVAL; 1407 ret = -EINVAL;
1408 goto ioctl_error;
1409 }
1397 ret = dvb_net_remove_if(dvbnet, (unsigned long) parg); 1410 ret = dvb_net_remove_if(dvbnet, (unsigned long) parg);
1398 if (!ret) 1411 if (!ret)
1399 module_put(dvbdev->adapter->module); 1412 module_put(dvbdev->adapter->module);
1400 return ret; 1413 break;
1401 } 1414 }
1402 1415
1403 /* binary compatibility cruft */ 1416 /* binary compatibility cruft */
@@ -1406,16 +1419,21 @@ static int dvb_net_do_ioctl(struct file *file,
1406 struct __dvb_net_if_old *dvbnetif = parg; 1419 struct __dvb_net_if_old *dvbnetif = parg;
1407 int result; 1420 int result;
1408 1421
1409 if (!capable(CAP_SYS_ADMIN)) 1422 if (!capable(CAP_SYS_ADMIN)) {
1410 return -EPERM; 1423 ret = -EPERM;
1424 goto ioctl_error;
1425 }
1411 1426
1412 if (!try_module_get(dvbdev->adapter->module)) 1427 if (!try_module_get(dvbdev->adapter->module)) {
1413 return -EPERM; 1428 ret = -EPERM;
1429 goto ioctl_error;
1430 }
1414 1431
1415 result=dvb_net_add_if(dvbnet, dvbnetif->pid, DVB_NET_FEEDTYPE_MPE); 1432 result=dvb_net_add_if(dvbnet, dvbnetif->pid, DVB_NET_FEEDTYPE_MPE);
1416 if (result<0) { 1433 if (result<0) {
1417 module_put(dvbdev->adapter->module); 1434 module_put(dvbdev->adapter->module);
1418 return result; 1435 ret = result;
1436 goto ioctl_error;
1419 } 1437 }
1420 dvbnetif->if_num=result; 1438 dvbnetif->if_num=result;
1421 break; 1439 break;
@@ -1427,8 +1445,10 @@ static int dvb_net_do_ioctl(struct file *file,
1427 struct __dvb_net_if_old *dvbnetif = parg; 1445 struct __dvb_net_if_old *dvbnetif = parg;
1428 1446
1429 if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || 1447 if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
1430 !dvbnet->state[dvbnetif->if_num]) 1448 !dvbnet->state[dvbnetif->if_num]) {
1431 return -EINVAL; 1449 ret = -EINVAL;
1450 goto ioctl_error;
1451 }
1432 1452
1433 netdev = dvbnet->device[dvbnetif->if_num]; 1453 netdev = dvbnet->device[dvbnetif->if_num];
1434 1454
@@ -1437,9 +1457,13 @@ static int dvb_net_do_ioctl(struct file *file,
1437 break; 1457 break;
1438 } 1458 }
1439 default: 1459 default:
1440 return -ENOTTY; 1460 ret = -ENOTTY;
1461 break;
1441 } 1462 }
1442 return 0; 1463
1464ioctl_error:
1465 mutex_unlock(&dvbnet->ioctl_mutex);
1466 return ret;
1443} 1467}
1444 1468
1445static long dvb_net_ioctl(struct file *file, 1469static long dvb_net_ioctl(struct file *file,
@@ -1505,6 +1529,7 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
1505{ 1529{
1506 int i; 1530 int i;
1507 1531
1532 mutex_init(&dvbnet->ioctl_mutex);
1508 dvbnet->demux = dmx; 1533 dvbnet->demux = dmx;
1509 1534
1510 for (i=0; i<DVB_NET_DEVICES_MAX; i++) 1535 for (i=0; i<DVB_NET_DEVICES_MAX; i++)
diff --git a/drivers/media/dvb-core/dvb_net.h b/drivers/media/dvb-core/dvb_net.h
index 1e53acd50cf4..ede78e8c8aa8 100644
--- a/drivers/media/dvb-core/dvb_net.h
+++ b/drivers/media/dvb-core/dvb_net.h
@@ -40,6 +40,7 @@ struct dvb_net {
40 int state[DVB_NET_DEVICES_MAX]; 40 int state[DVB_NET_DEVICES_MAX];
41 unsigned int exit:1; 41 unsigned int exit:1;
42 struct dmx_demux *demux; 42 struct dmx_demux *demux;
43 struct mutex ioctl_mutex;
43}; 44};
44 45
45void dvb_net_release(struct dvb_net *); 46void dvb_net_release(struct dvb_net *);
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index d33101aaf0b5..401ef64f92c6 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -418,10 +418,8 @@ int dvb_usercopy(struct file *file,
418 } 418 }
419 419
420 /* call driver */ 420 /* call driver */
421 mutex_lock(&dvbdev_mutex);
422 if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD) 421 if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
423 err = -ENOTTY; 422 err = -ENOTTY;
424 mutex_unlock(&dvbdev_mutex);
425 423
426 if (err < 0) 424 if (err < 0)
427 goto out; 425 goto out;