diff options
Diffstat (limited to 'drivers/media/dvb-core')
-rw-r--r-- | drivers/media/dvb-core/dvb-usb-ids.h | 6 | ||||
-rw-r--r-- | drivers/media/dvb-core/dvb_ca_en50221.c | 16 | ||||
-rw-r--r-- | drivers/media/dvb-core/dvb_frontend.c | 59 | ||||
-rw-r--r-- | drivers/media/dvb-core/dvb_frontend.h | 10 | ||||
-rw-r--r-- | drivers/media/dvb-core/dvb_net.c | 71 | ||||
-rw-r--r-- | drivers/media/dvb-core/dvb_net.h | 1 | ||||
-rw-r--r-- | drivers/media/dvb-core/dvbdev.c | 2 |
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 | ||
161 | static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca); | 164 | static 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 | ||
1252 | out_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 | ||
1053 | static void dtv_property_dump(struct dvb_frontend *fe, struct dtv_property *tvp) | 1068 | static 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 | ||
398 | struct dvb_frontend { | 408 | struct 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 | |
1464 | ioctl_error: | ||
1465 | mutex_unlock(&dvbnet->ioctl_mutex); | ||
1466 | return ret; | ||
1443 | } | 1467 | } |
1444 | 1468 | ||
1445 | static long dvb_net_ioctl(struct file *file, | 1469 | static 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 | ||
45 | void dvb_net_release(struct dvb_net *); | 46 | void 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; |