summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/b2c2
diff options
context:
space:
mode:
authorJohannes Stezenbach <devnull@localhost>2004-12-19 17:57:03 +0000
committerJohannes Stezenbach <devnull@localhost>2004-12-19 17:57:03 +0000
commitd9242aaaec257a126af7bfb24cf8d7552c2c9538 (patch)
tree919bfb0566d1a9c42546b530249994a92c081ff8 /linux/drivers/media/dvb/b2c2
parent90019e6129b6d234bd991a89e1f78a6011e4ad55 (diff)
downloadmediapointer-dvb-s2-d9242aaaec257a126af7bfb24cf8d7552c2c9538.tar.gz
mediapointer-dvb-s2-d9242aaaec257a126af7bfb24cf8d7552c2c9538.tar.bz2
- release_adapter does not really balance claim_adapter. release_adapter does.
- unneeded tests in free_adapter_object: + kfree(NULL) does not hurt (and it will not happen anyway); + irq has already been successfully requested; - propagation of the error status code through driver_initialize; - check the status code in skystar2_probe; - skystar2_remove: no need to test adapter->dvb_adapter against NULL. If such is its value, the driver has oopsen long before due to: skystar2_probe -> dvb_dmxdev_init -> dvb_register_device -> dvbdev_get_free_id -> list_for_each (entry, &adap->device_list) ^^^^ -> NULL Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Diffstat (limited to 'linux/drivers/media/dvb/b2c2')
-rw-r--r--linux/drivers/media/dvb/b2c2/skystar2.c147
1 files changed, 85 insertions, 62 deletions
diff --git a/linux/drivers/media/dvb/b2c2/skystar2.c b/linux/drivers/media/dvb/b2c2/skystar2.c
index 000c84a76..7e54ef5ae 100644
--- a/linux/drivers/media/dvb/b2c2/skystar2.c
+++ b/linux/drivers/media/dvb/b2c2/skystar2.c
@@ -1746,22 +1746,25 @@ static void free_dma_queue(struct adapter *adapter)
free_dma_queue_one(adapter, *p);
}
+static void release_adapter(struct adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ iounmap(adapter->io_mem);
+ pci_disable_device(pdev);
+ pci_release_region(pdev, 0);
+ pci_release_region(pdev, 1);
+}
+
static void free_adapter_object(struct adapter *adapter)
{
dprintk("%s:\n", __FUNCTION__);
close_stream(adapter, 0);
-
- if (adapter->irq != 0)
- free_irq(adapter->irq, adapter);
-
+ free_irq(adapter->irq, adapter);
free_dma_queue(adapter);
-
- if (adapter->io_mem)
- iounmap(adapter->io_mem);
-
- if (adapter != 0)
- kfree(adapter);
+ release_adapter(adapter);
+ kfree(adapter);
}
static struct pci_driver skystar2_pci_driver;
@@ -1871,11 +1874,12 @@ static int driver_initialize(struct pci_dev *pdev)
{
struct adapter *adapter;
u32 tmp;
+ int ret = -ENOMEM;
- if (!(adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL))) {
+ adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL);
+ if (!adapter) {
dprintk("%s: out of memory!\n", __FUNCTION__);
-
- return -ENOMEM;
+ goto out;
}
memset(adapter, 0, sizeof(struct adapter));
@@ -1885,20 +1889,16 @@ static int driver_initialize(struct pci_dev *pdev)
adapter->pdev = pdev;
adapter->irq = pdev->irq;
- if ((claim_adapter(adapter)) != 1) {
- free_adapter_object(adapter);
-
- return -ENODEV;
- }
+ ret = claim_adapter(adapter);
+ if (ret < 0)
+ goto err_kfree;
irq_dma_enable_disable_irq(adapter, 0);
- if (request_irq(pdev->irq, isr, 0x4000000, "Skystar2", adapter) != 0) {
+ ret = request_irq(pdev->irq, isr, 0x4000000, "Skystar2", adapter);
+ if (ret < 0) {
dprintk("%s: unable to allocate irq=%d !\n", __FUNCTION__, pdev->irq);
-
- free_adapter_object(adapter);
-
- return -ENODEV;
+ goto err_release_adapter;
}
read_reg_dw(adapter, 0x208);
@@ -1906,11 +1906,9 @@ static int driver_initialize(struct pci_dev *pdev)
write_reg_dw(adapter, 0x210, 0xb2ff);
write_reg_dw(adapter, 0x208, 0x40);
- if (init_dma_queue(adapter) < 0) {
- free_adapter_object(adapter);
-
- return -ENODEV;
- }
+ ret = init_dma_queue(adapter);
+ if (ret < 0)
+ goto err_free_irq;
adapter->b2c2_revision = (read_reg_dw(adapter, 0x204) >> 0x18);
@@ -1927,11 +1925,8 @@ static int driver_initialize(struct pci_dev *pdev)
default:
printk("%s: The revision of the FlexCop chip on your card is %d\n", __FILE__, adapter->b2c2_revision);
printk("%s: This driver works only with FlexCopII(rev.130), FlexCopIIB(rev.195) and FlexCopIII(rev.192).\n", __FILE__);
- free_adapter_object(adapter);
- pci_set_drvdata(pdev, NULL);
- pci_release_region(pdev, 1);
- pci_release_region(pdev, 0);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_free_dma_queue;
}
decide_how_many_hw_filters(adapter);
@@ -1977,7 +1972,19 @@ static int driver_initialize(struct pci_dev *pdev)
adapter->lock = SPIN_LOCK_UNLOCKED;
- return 0;
+out:
+ return ret;
+
+err_free_dma_queue:
+ free_dma_queue(adapter);
+err_free_irq:
+ free_irq(pdev->irq, adapter);
+err_release_adapter:
+ release_adapter(adapter);
+err_kfree:
+ pci_set_drvdata(pdev, NULL);
+ kfree(adapter);
+ goto out;
}
static void driver_halt(struct pci_dev *pdev)
@@ -2477,23 +2484,20 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct adapter *adapter;
struct dvb_adapter *dvb_adapter;
struct dvb_demux *dvbdemux;
+ int ret = -ENODEV;
- int ret;
-
- if (pdev == NULL)
- return -ENODEV;
-
- if (driver_initialize(pdev) != 0)
- return -ENODEV;
+ if (!pdev)
+ goto out;
- dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name, THIS_MODULE);
+ ret = driver_initialize(pdev);
+ if (ret < 0)
+ goto out;
- if (dvb_adapter == NULL) {
+ ret = dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name,
+ THIS_MODULE);
+ if (ret < 0) {
printk("%s: Error registering DVB adapter\n", __FUNCTION__);
-
- driver_halt(pdev);
-
- return -ENODEV;
+ goto err_halt;
}
adapter = (struct adapter *) pci_get_drvdata(pdev);
@@ -2519,10 +2523,9 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->i2c_adap.algo_data = NULL;
adapter->i2c_adap.id = I2C_ALGO_BIT;
- if (i2c_add_adapter(&adapter->i2c_adap) < 0) {
- dvb_unregister_adapter (adapter->dvb_adapter);
- return -ENOMEM;
- }
+ ret = i2c_add_adapter(&adapter->i2c_adap);
+ if (ret < 0)
+ goto err_dvb_unregister;
dvbdemux = &adapter->demux;
@@ -2534,7 +2537,9 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dvbdemux->write_to_decoder = NULL;
dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
- dvb_dmx_init(&adapter->demux);
+ ret = dvb_dmx_init(&adapter->demux);
+ if (ret < 0)
+ goto err_i2c_del;
adapter->hw_frontend.source = DMX_FRONTEND_0;
@@ -2542,27 +2547,45 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->dmxdev.demux = &dvbdemux->dmx;
adapter->dmxdev.capabilities = 0;
- dvb_dmxdev_init(&adapter->dmxdev, adapter->dvb_adapter);
+ ret = dvb_dmxdev_init(&adapter->dmxdev, adapter->dvb_adapter);
+ if (ret < 0)
+ goto err_dmx_release;
ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
if (ret < 0)
- return ret;
+ goto err_dmxdev_release;
adapter->mem_frontend.source = DMX_MEMORY_FE;
ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
if (ret < 0)
- return ret;
+ goto err_remove_hw_frontend;
ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
if (ret < 0)
- return ret;
+ goto err_remove_mem_frontend;
dvb_net_init(adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
frontend_init(adapter);
+out:
+ return ret;
- return 0;
+err_remove_mem_frontend:
+ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
+err_remove_hw_frontend:
+ dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
+err_dmxdev_release:
+ dvb_dmxdev_release(&adapter->dmxdev);
+err_dmx_release:
+ dvb_dmx_release(&adapter->demux);
+err_i2c_del:
+ i2c_del_adapter(&adapter->i2c_adap);
+err_dvb_unregister:
+ dvb_unregister_adapter(adapter->dvb_adapter);
+err_halt:
+ driver_halt(pdev);
+ goto out;
}
static void skystar2_remove(struct pci_dev *pdev)
@@ -2586,13 +2609,13 @@ static void skystar2_remove(struct pci_dev *pdev)
dvb_dmxdev_release(&adapter->dmxdev);
dvb_dmx_release(&adapter->demux);
- if (adapter->fe != NULL) dvb_unregister_frontend(adapter->fe);
+ if (adapter->fe != NULL)
+ dvb_unregister_frontend(adapter->fe);
- if (adapter->dvb_adapter != NULL) {
- i2c_del_adapter(&adapter->i2c_adap);
+ dvb_unregister_adapter(adapter->dvb_adapter);
+
+ i2c_del_adapter(&adapter->i2c_adap);
- dvb_unregister_adapter(adapter->dvb_adapter);
- }
driver_halt(pdev);
}
}