aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ngene
diff options
context:
space:
mode:
authorOliver Endriss <o.endriss@gmx.de>2011-01-10 04:36:23 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:31:46 -0400
commit3d0cef2c3c7e19a2425f8e1379a535c46427951b (patch)
tree928660fe19b9be5ddea33f8cdebf826251fd8655 /drivers/media/dvb/ngene
parent179fd15a99175e8e22516edbb1894c3348842f3a (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.c109
-rw-r--r--drivers/media/dvb/ngene/ngene.h2
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
1540err_fe: 1549err:
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;