diff options
author | Oliver Endriss <o.endriss@gmx.de> | 2011-01-10 04:36:23 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:31:46 -0400 |
commit | 3d0cef2c3c7e19a2425f8e1379a535c46427951b (patch) | |
tree | 928660fe19b9be5ddea33f8cdebf826251fd8655 /drivers/media/dvb/ngene | |
parent | 179fd15a99175e8e22516edbb1894c3348842f3a (diff) |
[media] ngene: Improved channel initialisation and release
Refactored code for channel initialisation and release:
- Do not create device nodes which are not required.
- Better error handling.
Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/ngene')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-core.c | 109 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene.h | 2 |
2 files changed, 60 insertions, 51 deletions
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index a14b69c44cc1..175a0f6c2a4c 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c | |||
@@ -1432,25 +1432,24 @@ static void release_channel(struct ngene_channel *chan) | |||
1432 | { | 1432 | { |
1433 | struct dvb_demux *dvbdemux = &chan->demux; | 1433 | struct dvb_demux *dvbdemux = &chan->demux; |
1434 | struct ngene *dev = chan->dev; | 1434 | struct ngene *dev = chan->dev; |
1435 | struct ngene_info *ni = dev->card_info; | ||
1436 | int io = ni->io_type[chan->number]; | ||
1437 | 1435 | ||
1438 | if (chan->dev->cmd_timeout_workaround && chan->running) | 1436 | if (chan->running) |
1439 | set_transfer(chan, 0); | 1437 | set_transfer(chan, 0); |
1440 | 1438 | ||
1441 | tasklet_kill(&chan->demux_tasklet); | 1439 | tasklet_kill(&chan->demux_tasklet); |
1442 | 1440 | ||
1443 | if (chan->number >= 2 && chan->number <= 3 && dev->ci.en) | 1441 | if (chan->ci_dev) { |
1444 | return; | 1442 | dvb_unregister_device(chan->ci_dev); |
1443 | chan->ci_dev = NULL; | ||
1444 | } | ||
1445 | 1445 | ||
1446 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | 1446 | if (chan->fe) { |
1447 | if (chan->ci_dev) | 1447 | dvb_unregister_frontend(chan->fe); |
1448 | dvb_unregister_device(chan->ci_dev); | 1448 | dvb_frontend_detach(chan->fe); |
1449 | if (chan->fe) { | 1449 | chan->fe = NULL; |
1450 | dvb_unregister_frontend(chan->fe); | 1450 | } |
1451 | dvb_frontend_detach(chan->fe); | 1451 | |
1452 | chan->fe = NULL; | 1452 | if (chan->has_demux) { |
1453 | } | ||
1454 | dvb_net_release(&chan->dvbnet); | 1453 | dvb_net_release(&chan->dvbnet); |
1455 | dvbdemux->dmx.close(&dvbdemux->dmx); | 1454 | dvbdemux->dmx.close(&dvbdemux->dmx); |
1456 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, | 1455 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, |
@@ -1459,9 +1458,12 @@ static void release_channel(struct ngene_channel *chan) | |||
1459 | &chan->mem_frontend); | 1458 | &chan->mem_frontend); |
1460 | dvb_dmxdev_release(&chan->dmxdev); | 1459 | dvb_dmxdev_release(&chan->dmxdev); |
1461 | dvb_dmx_release(&chan->demux); | 1460 | dvb_dmx_release(&chan->demux); |
1461 | chan->has_demux = false; | ||
1462 | } | ||
1462 | 1463 | ||
1463 | if (chan->number == 0 || !one_adapter) | 1464 | if (chan->has_adapter) { |
1464 | dvb_unregister_adapter(&dev->adapter[chan->number]); | 1465 | dvb_unregister_adapter(&dev->adapter[chan->number]); |
1466 | chan->has_adapter = false; | ||
1465 | } | 1467 | } |
1466 | } | 1468 | } |
1467 | 1469 | ||
@@ -1479,12 +1481,27 @@ static int init_channel(struct ngene_channel *chan) | |||
1479 | chan->type = io; | 1481 | chan->type = io; |
1480 | chan->mode = chan->type; /* for now only one mode */ | 1482 | chan->mode = chan->type; /* for now only one mode */ |
1481 | 1483 | ||
1484 | if (io & NGENE_IO_TSIN) { | ||
1485 | chan->fe = NULL; | ||
1486 | if (ni->demod_attach[nr]) { | ||
1487 | ret = ni->demod_attach[nr](chan); | ||
1488 | if (ret < 0) | ||
1489 | goto err; | ||
1490 | } | ||
1491 | if (chan->fe && ni->tuner_attach[nr]) { | ||
1492 | ret = ni->tuner_attach[nr](chan); | ||
1493 | if (ret < 0) | ||
1494 | goto err; | ||
1495 | } | ||
1496 | } | ||
1497 | |||
1498 | if (!dev->ci.en && (io & NGENE_IO_TSOUT)) | ||
1499 | return 0; | ||
1500 | |||
1482 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | 1501 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { |
1483 | if (nr >= STREAM_AUDIOIN1) | 1502 | if (nr >= STREAM_AUDIOIN1) |
1484 | chan->DataFormatFlags = DF_SWAP32; | 1503 | chan->DataFormatFlags = DF_SWAP32; |
1485 | 1504 | ||
1486 | if (nr >= 2 && nr <= 3 && dev->ci.en) | ||
1487 | return 0; | ||
1488 | if (nr == 0 || !one_adapter || dev->first_adapter == NULL) { | 1505 | if (nr == 0 || !one_adapter || dev->first_adapter == NULL) { |
1489 | adapter = &dev->adapter[nr]; | 1506 | adapter = &dev->adapter[nr]; |
1490 | ret = dvb_register_adapter(adapter, "nGene", | 1507 | ret = dvb_register_adapter(adapter, "nGene", |
@@ -1492,13 +1509,32 @@ static int init_channel(struct ngene_channel *chan) | |||
1492 | &chan->dev->pci_dev->dev, | 1509 | &chan->dev->pci_dev->dev, |
1493 | adapter_nr); | 1510 | adapter_nr); |
1494 | if (ret < 0) | 1511 | if (ret < 0) |
1495 | return ret; | 1512 | goto err; |
1496 | if (dev->first_adapter == NULL) | 1513 | if (dev->first_adapter == NULL) |
1497 | dev->first_adapter = adapter; | 1514 | dev->first_adapter = adapter; |
1498 | } else { | 1515 | chan->has_adapter = true; |
1516 | } else | ||
1499 | adapter = dev->first_adapter; | 1517 | adapter = dev->first_adapter; |
1500 | } | 1518 | } |
1519 | |||
1520 | if (dev->ci.en && (io & NGENE_IO_TSOUT)) { | ||
1521 | dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); | ||
1522 | set_transfer(chan, 1); | ||
1523 | set_transfer(&chan->dev->channel[2], 1); | ||
1524 | dvb_register_device(adapter, &chan->ci_dev, | ||
1525 | &ngene_dvbdev_ci, (void *) chan, | ||
1526 | DVB_DEVICE_SEC); | ||
1527 | if (!chan->ci_dev) | ||
1528 | goto err; | ||
1529 | } | ||
1501 | 1530 | ||
1531 | if (chan->fe) { | ||
1532 | if (dvb_register_frontend(adapter, chan->fe) < 0) | ||
1533 | goto err; | ||
1534 | chan->has_demux = true; | ||
1535 | } | ||
1536 | |||
1537 | if (chan->has_demux) { | ||
1502 | ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", | 1538 | ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", |
1503 | ngene_start_feed, | 1539 | ngene_start_feed, |
1504 | ngene_stop_feed, chan); | 1540 | ngene_stop_feed, chan); |
@@ -1506,45 +1542,16 @@ static int init_channel(struct ngene_channel *chan) | |||
1506 | &chan->hw_frontend, | 1542 | &chan->hw_frontend, |
1507 | &chan->mem_frontend, adapter); | 1543 | &chan->mem_frontend, adapter); |
1508 | ret = dvb_net_init(adapter, &chan->dvbnet, &chan->demux.dmx); | 1544 | ret = dvb_net_init(adapter, &chan->dvbnet, &chan->demux.dmx); |
1509 | |||
1510 | if (dev->ci.en && (io&NGENE_IO_TSOUT)) { | ||
1511 | dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); | ||
1512 | set_transfer(chan, 1); | ||
1513 | set_transfer(&chan->dev->channel[2], 1); | ||
1514 | |||
1515 | dvb_register_device(adapter, &chan->ci_dev, | ||
1516 | &ngene_dvbdev_ci, (void *) chan, | ||
1517 | DVB_DEVICE_SEC); | ||
1518 | } | ||
1519 | } | 1545 | } |
1520 | 1546 | ||
1521 | if (io & NGENE_IO_TSIN) { | ||
1522 | chan->fe = NULL; | ||
1523 | if (ni->demod_attach[nr]) { | ||
1524 | ret = ni->demod_attach[nr](chan); | ||
1525 | if (ret < 0) | ||
1526 | goto err_fe; | ||
1527 | } | ||
1528 | if (chan->fe && ni->tuner_attach[nr]) { | ||
1529 | ret = ni->tuner_attach[nr](chan); | ||
1530 | if (ret < 0) | ||
1531 | goto err_fe; | ||
1532 | } | ||
1533 | if (chan->fe) { | ||
1534 | if (dvb_register_frontend(adapter, chan->fe) < 0) | ||
1535 | goto err_fe; | ||
1536 | } | ||
1537 | } | ||
1538 | return ret; | 1547 | return ret; |
1539 | 1548 | ||
1540 | err_fe: | 1549 | err: |
1541 | if (chan->fe) { | 1550 | if (chan->fe) { |
1542 | dvb_frontend_detach(chan->fe); | 1551 | dvb_frontend_detach(chan->fe); |
1543 | chan->fe = NULL; | 1552 | chan->fe = NULL; |
1544 | } | 1553 | } |
1545 | /* FIXME: this causes an oops... */ | 1554 | release_channel(chan); |
1546 | /* release_channel(chan); */ | ||
1547 | /* return ret; */ | ||
1548 | return 0; | 1555 | return 0; |
1549 | } | 1556 | } |
1550 | 1557 | ||
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h index 5894abd91af5..40fce9e3ae66 100644 --- a/drivers/media/dvb/ngene/ngene.h +++ b/drivers/media/dvb/ngene/ngene.h | |||
@@ -639,6 +639,8 @@ struct ngene_channel { | |||
639 | int number; | 639 | int number; |
640 | int type; | 640 | int type; |
641 | int mode; | 641 | int mode; |
642 | bool has_adapter; | ||
643 | bool has_demux; | ||
642 | 644 | ||
643 | struct dvb_frontend *fe; | 645 | struct dvb_frontend *fe; |
644 | struct dmxdev dmxdev; | 646 | struct dmxdev dmxdev; |