diff options
Diffstat (limited to 'drivers/media/dvb/dvb-core')
-rw-r--r-- | drivers/media/dvb/dvb-core/dmxdev.c | 1 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_ca_en50221.c | 93 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_demux.c | 5 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.c | 125 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.h | 13 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_net.c | 22 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvbdev.c | 41 |
7 files changed, 149 insertions, 151 deletions
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 5394de2e4ce..f94bc31e3b3 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c @@ -24,7 +24,6 @@ #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/module.h> -#include <linux/moduleparam.h> #include <linux/poll.h> #include <linux/ioctl.h> #include <linux/wait.h> diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 4fadddb264d..084a508a03d 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -32,11 +32,11 @@ #include <linux/slab.h> #include <linux/list.h> #include <linux/module.h> -#include <linux/moduleparam.h> #include <linux/vmalloc.h> #include <linux/delay.h> #include <linux/spinlock.h> #include <linux/sched.h> +#include <linux/kthread.h> #include "dvb_ca_en50221.h" #include "dvb_ringbuffer.h" @@ -140,13 +140,7 @@ struct dvb_ca_private { wait_queue_head_t wait_queue; /* PID of the monitoring thread */ - pid_t thread_pid; - - /* Wait queue used when shutting thread down */ - wait_queue_head_t thread_queue; - - /* Flag indicating when thread should exit */ - unsigned int exit:1; + struct task_struct *thread; /* Flag indicating if the CA device is open */ unsigned int open:1; @@ -902,28 +896,10 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca) ca->wakeup = 1; mb(); - wake_up_interruptible(&ca->thread_queue); + wake_up_process(ca->thread); } /** - * Used by the CA thread to determine if an early wakeup is necessary - * - * @param ca CA instance. - */ -static int dvb_ca_en50221_thread_should_wakeup(struct dvb_ca_private *ca) -{ - if (ca->wakeup) { - ca->wakeup = 0; - return 1; - } - if (ca->exit) - return 1; - - return 0; -} - - -/** * Update the delay used by the thread. * * @param ca CA instance. @@ -982,7 +958,6 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) static int dvb_ca_en50221_thread(void *data) { struct dvb_ca_private *ca = data; - char name[15]; int slot; int flags; int status; @@ -991,28 +966,17 @@ static int dvb_ca_en50221_thread(void *data) dprintk("%s\n", __FUNCTION__); - /* setup kernel thread */ - snprintf(name, sizeof(name), "kdvb-ca-%i:%i", ca->dvbdev->adapter->num, ca->dvbdev->id); - - lock_kernel(); - daemonize(name); - sigfillset(¤t->blocked); - unlock_kernel(); - /* choose the correct initial delay */ dvb_ca_en50221_thread_update_delay(ca); /* main loop */ - while (!ca->exit) { + while (!kthread_should_stop()) { /* sleep for a bit */ - if (!ca->wakeup) { - flags = wait_event_interruptible_timeout(ca->thread_queue, - dvb_ca_en50221_thread_should_wakeup(ca), - ca->delay); - if ((flags == -ERESTARTSYS) || ca->exit) { - /* got signal or quitting */ - break; - } + while (!ca->wakeup) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(ca->delay); + if (kthread_should_stop()) + return 0; } ca->wakeup = 0; @@ -1181,10 +1145,6 @@ static int dvb_ca_en50221_thread(void *data) } } - /* completed */ - ca->thread_pid = 0; - mb(); - wake_up_interruptible(&ca->thread_queue); return 0; } @@ -1536,8 +1496,10 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) return -EIO; err = dvb_generic_open(inode, file); - if (err < 0) + if (err < 0) { + module_put(ca->pub->owner); return err; + } for (i = 0; i < ca->slot_count; i++) { @@ -1570,7 +1532,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct dvb_ca_private *ca = dvbdev->priv; - int err = 0; + int err; dprintk("%s\n", __FUNCTION__); @@ -1582,7 +1544,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) module_put(ca->pub->owner); - return 0; + return err; } @@ -1682,9 +1644,6 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, goto error; } init_waitqueue_head(&ca->wait_queue); - ca->thread_pid = 0; - init_waitqueue_head(&ca->thread_queue); - ca->exit = 0; ca->open = 0; ca->wakeup = 0; ca->next_read_slot = 0; @@ -1710,14 +1669,14 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, mb(); /* create a kthread for monitoring this CA device */ - - ret = kernel_thread(dvb_ca_en50221_thread, ca, 0); - - if (ret < 0) { - printk("dvb_ca_init: failed to start kernel_thread (%d)\n", ret); + ca->thread = kthread_run(dvb_ca_en50221_thread, ca, "kdvb-ca-%i:%i", + ca->dvbdev->adapter->num, ca->dvbdev->id); + if (IS_ERR(ca->thread)) { + ret = PTR_ERR(ca->thread); + printk("dvb_ca_init: failed to start kernel_thread (%d)\n", + ret); goto error; } - ca->thread_pid = ret; return 0; error: @@ -1748,17 +1707,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) dprintk("%s\n", __FUNCTION__); /* shutdown the thread if there was one */ - if (ca->thread_pid) { - if (kill_proc(ca->thread_pid, 0, 1) == -ESRCH) { - printk("dvb_ca_release adapter %d: thread PID %d already died\n", - ca->dvbdev->adapter->num, ca->thread_pid); - } else { - ca->exit = 1; - mb(); - dvb_ca_en50221_thread_wakeup(ca); - wait_event_interruptible(ca->thread_queue, ca->thread_pid == 0); - } - } + kthread_stop(ca->thread); for (i = 0; i < ca->slot_count; i++) { dvb_ca_en50221_slot_shutdown(ca, i); diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index cb6987fce26..7959020f931 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c @@ -373,13 +373,10 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) { struct dvb_demux_feed *feed; - struct list_head *pos, *head = &demux->feed_list; u16 pid = ts_pid(buf); int dvr_done = 0; - list_for_each(pos, head) { - feed = list_entry(pos, struct dvb_demux_feed, list_head); - + list_for_each_entry(feed, &demux->feed_list, list_head) { if ((feed->pid != pid) && (feed->pid != 0x2000)) continue; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index b6c7f6610ec..b203640ef1c 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -32,7 +32,6 @@ #include <linux/slab.h> #include <linux/poll.h> #include <linux/module.h> -#include <linux/moduleparam.h> #include <linux/list.h> #include <linux/freezer.h> #include <linux/jiffies.h> @@ -43,7 +42,7 @@ #include "dvbdev.h" static int dvb_frontend_debug; -static int dvb_shutdown_timeout = 5; +static int dvb_shutdown_timeout; static int dvb_force_auto_inversion; static int dvb_override_tune_delay; static int dvb_powerdown_on_sleep = 1; @@ -138,7 +137,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) dprintk ("%s\n", __FUNCTION__); - if (down_interruptible (&events->sem)) + if (mutex_lock_interruptible (&events->mtx)) return; wp = (events->eventw + 1) % MAX_EVENT; @@ -159,7 +158,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) events->eventw = wp; - up (&events->sem); + mutex_unlock(&events->mtx); e->status = status; @@ -197,7 +196,7 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, return ret; } - if (down_interruptible (&events->sem)) + if (mutex_lock_interruptible (&events->mtx)) return -ERESTARTSYS; memcpy (event, &events->events[events->eventr], @@ -205,7 +204,7 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, events->eventr = (events->eventr + 1) % MAX_EVENT; - up (&events->sem); + mutex_unlock(&events->mtx); return 0; } @@ -574,10 +573,9 @@ restart: dvb_frontend_swzigzag(fe); } - if (dvb_shutdown_timeout) { - if (dvb_powerdown_on_sleep) - if (fe->ops.set_voltage) - fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); + if (dvb_powerdown_on_sleep) { + if (fe->ops.set_voltage) + fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); if (fe->ops.tuner_ops.sleep) { fe->ops.tuner_ops.sleep(fe); if (fe->ops.i2c_gate_ctrl) @@ -697,6 +695,65 @@ static int dvb_frontend_start(struct dvb_frontend *fe) return 0; } +static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe, + u32 *freq_min, u32 *freq_max) +{ + *freq_min = max(fe->ops.info.frequency_min, fe->ops.tuner_ops.info.frequency_min); + + if (fe->ops.info.frequency_max == 0) + *freq_max = fe->ops.tuner_ops.info.frequency_max; + else if (fe->ops.tuner_ops.info.frequency_max == 0) + *freq_max = fe->ops.info.frequency_max; + else + *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max); + + if (*freq_min == 0 || *freq_max == 0) + printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n", + fe->dvb->num); +} + +static int dvb_frontend_check_parameters(struct dvb_frontend *fe, + struct dvb_frontend_parameters *parms) +{ + u32 freq_min; + u32 freq_max; + + /* range check: frequency */ + dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max); + if ((freq_min && parms->frequency < freq_min) || + (freq_max && parms->frequency > freq_max)) { + printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n", + fe->dvb->num, parms->frequency, freq_min, freq_max); + return -EINVAL; + } + + /* range check: symbol rate */ + if (fe->ops.info.type == FE_QPSK) { + if ((fe->ops.info.symbol_rate_min && + parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) || + (fe->ops.info.symbol_rate_max && + parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) { + printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n", + fe->dvb->num, parms->u.qpsk.symbol_rate, + fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); + return -EINVAL; + } + + } else if (fe->ops.info.type == FE_QAM) { + if ((fe->ops.info.symbol_rate_min && + parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) || + (fe->ops.info.symbol_rate_max && + parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) { + printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n", + fe->dvb->num, parms->u.qam.symbol_rate, + fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); + return -EINVAL; + } + } + + return 0; +} + static int dvb_frontend_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { @@ -707,7 +764,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, dprintk ("%s\n", __FUNCTION__); - if (!fe || fepriv->exit) + if (fepriv->exit) return -ENODEV; if ((file->f_flags & O_ACCMODE) == O_RDONLY && @@ -722,6 +779,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, case FE_GET_INFO: { struct dvb_frontend_info* info = parg; memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info)); + dvb_frontend_get_frequeny_limits(fe, &info->frequency_min, &info->frequency_max); /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't * do it, it is done for it. */ @@ -883,6 +941,11 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, case FE_SET_FRONTEND: { struct dvb_frontend_tune_settings fetunesettings; + if (dvb_frontend_check_parameters(fe, parg) < 0) { + err = -EINVAL; + break; + } + memcpy (&fepriv->parameters, parg, sizeof (struct dvb_frontend_parameters)); @@ -992,18 +1055,15 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) dprintk ("%s\n", __FUNCTION__); - if ((ret = dvb_generic_open (inode, file)) < 0) - return ret; - - if (fe->ops.ts_bus_ctrl) { - if ((ret = fe->ops.ts_bus_ctrl (fe, 1)) < 0) { - dvb_generic_release (inode, file); + if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) { + if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) return ret; - } } - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { + if ((ret = dvb_generic_open (inode, file)) < 0) + goto err1; + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { /* normal tune mode when opened R/W */ fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; fepriv->tone = -1; @@ -1011,13 +1071,20 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) ret = dvb_frontend_start (fe); if (ret) - dvb_generic_release (inode, file); + goto err2; /* empty event queue */ fepriv->events.eventr = fepriv->events.eventw = 0; } return ret; + +err2: + dvb_generic_release(inode, file); +err1: + if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) + fe->ops.ts_bus_ctrl(fe, 0); + return ret; } static int dvb_frontend_release(struct inode *inode, struct file *file) @@ -1032,16 +1099,18 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) if ((file->f_flags & O_ACCMODE) != O_RDONLY) fepriv->release_jiffies = jiffies; - if (fe->ops.ts_bus_ctrl) - fe->ops.ts_bus_ctrl (fe, 0); - ret = dvb_generic_release (inode, file); - if (dvbdev->users==-1 && fepriv->exit==1) { - fops_put(file->f_op); - file->f_op = NULL; - wake_up(&dvbdev->wait_queue); + if (dvbdev->users == -1) { + if (fepriv->exit == 1) { + fops_put(file->f_op); + file->f_op = NULL; + wake_up(&dvbdev->wait_queue); + } + if (fe->ops.ts_bus_ctrl) + fe->ops.ts_bus_ctrl(fe, 0); } + return ret; } @@ -1080,7 +1149,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, init_MUTEX (&fepriv->sem); init_waitqueue_head (&fepriv->wait_queue); init_waitqueue_head (&fepriv->events.wait_queue); - init_MUTEX (&fepriv->events.sem); + mutex_init(&fepriv->events.mtx); fe->dvb = dvb; fepriv->inversion = INVERSION_OFF; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index a770a87b9a9..a5262e852c8 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -35,6 +35,7 @@ #include <linux/module.h> #include <linux/errno.h> #include <linux/delay.h> +#include <linux/mutex.h> #include <linux/dvb/frontend.h> @@ -61,6 +62,13 @@ struct dvb_tuner_info { u32 bandwidth_step; }; +struct analog_parameters { + unsigned int frequency; + unsigned int mode; + unsigned int audmode; + u64 std; +}; + struct dvb_tuner_ops { struct dvb_tuner_info info; @@ -71,6 +79,7 @@ struct dvb_tuner_ops { /** This is for simple PLLs - set all parameters in one go. */ int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); + int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p); /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */ int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len); @@ -79,7 +88,9 @@ struct dvb_tuner_ops { int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); #define TUNER_STATUS_LOCKED 1 +#define TUNER_STATUS_STEREO 2 int (*get_status)(struct dvb_frontend *fe, u32 *status); + int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength); /** These are provided seperately from set_params in order to facilitate silicon * tuners which require sophisticated tuning loops, controlling each parameter seperately. */ @@ -142,7 +153,7 @@ struct dvb_fe_events { int eventr; int overflow; wait_queue_head_t wait_queue; - struct semaphore sem; + struct mutex mtx; }; struct dvb_frontend { diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 06800e5a077..a33eb5988c4 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -357,11 +357,6 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) static unsigned char *ule_where = ule_hist, ule_dump = 0; #endif - if (dev == NULL) { - printk( KERN_ERR "NO netdev struct!\n" ); - return; - } - /* For all TS cells in current buffer. * Appearently, we are called for every single TS cell. */ @@ -800,8 +795,8 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, } -static void dvb_net_sec(struct net_device *dev, const u8 *pkt, int -pkt_len) +static void dvb_net_sec(struct net_device *dev, + const u8 *pkt, int pkt_len) { u8 *eth; struct sk_buff *skb; @@ -1453,18 +1448,9 @@ static int dvb_net_close(struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct dvb_net *dvbnet = dvbdev->priv; - if (!dvbdev) - return -ENODEV; - - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - dvbdev->readers++; - } else { - dvbdev->writers++; - } - - dvbdev->users++; + dvb_generic_release(inode, file); - if(dvbdev->users == 1 && dvbnet->exit==1) { + if(dvbdev->users == 1 && dvbnet->exit == 1) { fops_put(file->f_op); file->f_op = NULL; wake_up(&dvbdev->wait_queue); diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 9ef0c00605e..56231d8edc0 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -25,7 +25,6 @@ #include <linux/errno.h> #include <linux/string.h> #include <linux/module.h> -#include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/slab.h> @@ -59,18 +58,13 @@ static struct class *dvb_class; static struct dvb_device* dvbdev_find_device (int minor) { - struct list_head *entry; + struct dvb_adapter *adap; - list_for_each (entry, &dvb_adapter_list) { - struct list_head *entry0; - struct dvb_adapter *adap; - adap = list_entry (entry, struct dvb_adapter, list_head); - list_for_each (entry0, &adap->device_list) { - struct dvb_device *dev; - dev = list_entry (entry0, struct dvb_device, list_head); + list_for_each_entry(adap, &dvb_adapter_list, list_head) { + struct dvb_device *dev; + list_for_each_entry(dev, &adap->device_list, list_head) if (nums2minor(adap->num, dev->type, dev->id) == minor) return dev; - } } return NULL; @@ -180,13 +174,10 @@ static int dvbdev_get_free_id (struct dvb_adapter *adap, int type) u32 id = 0; while (id < DVB_MAX_IDS) { - struct list_head *entry; - list_for_each (entry, &adap->device_list) { - struct dvb_device *dev; - dev = list_entry (entry, struct dvb_device, list_head); + struct dvb_device *dev; + list_for_each_entry(dev, &adap->device_list, list_head) if (dev->type == type && dev->id == id) goto skip; - } return id; skip: id++; @@ -200,7 +191,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, { struct dvb_device *dvbdev; struct file_operations *dvbdevfops; - struct class_device *clsdev; + struct device *clsdev; int id; mutex_lock(&dvbdev_register_lock); @@ -242,10 +233,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, mutex_unlock(&dvbdev_register_lock); - clsdev = class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, - nums2minor(adap->num, type, id)), - adap->device, "dvb%d.%s%d", adap->num, - dnames[type], id); + clsdev = device_create(dvb_class, adap->device, + MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), + "dvb%d.%s%d", adap->num, dnames[type], id); if (IS_ERR(clsdev)) { printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n", __FUNCTION__, adap->num, dnames[type], id, PTR_ERR(clsdev)); @@ -266,8 +256,8 @@ void dvb_unregister_device(struct dvb_device *dvbdev) if (!dvbdev) return; - class_device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num, - dvbdev->type, dvbdev->id))); + device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num, + dvbdev->type, dvbdev->id))); list_del (&dvbdev->list_head); kfree (dvbdev->fops); @@ -281,13 +271,10 @@ static int dvbdev_get_free_adapter_num (void) int num = 0; while (num < DVB_MAX_ADAPTERS) { - struct list_head *entry; - list_for_each (entry, &dvb_adapter_list) { - struct dvb_adapter *adap; - adap = list_entry (entry, struct dvb_adapter, list_head); + struct dvb_adapter *adap; + list_for_each_entry(adap, &dvb_adapter_list, list_head) if (adap->num == num) goto skip; - } return num; skip: num++; |