Commit 5811cf99 authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab

V4L/DVB (10756): cx18: Slim down instance handling, build names from v4l2_device.name

Convert card instance handling to a lighter weight mechanism like ivtv.
Also convert name strings and debug messages to use v4l2_device.name.
Signed-off-by: default avatarAndy Walls <awalls@radix.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 1a267046
...@@ -39,10 +39,6 @@ ...@@ -39,10 +39,6 @@
#include <media/tveeprom.h> #include <media/tveeprom.h>
/* var to keep track of the number of array elements in use */
int cx18_cards_active;
/* If you have already X v4l cards, then set this to X. This way /* If you have already X v4l cards, then set this to X. This way
the device numbers stay matched. Example: you have a WinTV card the device numbers stay matched. Example: you have a WinTV card
without radio and a Compro H900 with. Normally this would give a without radio and a Compro H900 with. Normally this would give a
...@@ -50,12 +46,6 @@ int cx18_cards_active; ...@@ -50,12 +46,6 @@ int cx18_cards_active;
setting this to 1 you ensure that radio0 is now also radio1. */ setting this to 1 you ensure that radio0 is now also radio1. */
int cx18_first_minor; int cx18_first_minor;
/* Master variable for all cx18 info */
struct cx18 *cx18_cards[CX18_MAX_CARDS];
/* Protects cx18_cards_active */
DEFINE_SPINLOCK(cx18_cards_lock);
/* add your revision and whatnot here */ /* add your revision and whatnot here */
static struct pci_device_id cx18_pci_tbl[] __devinitdata = { static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
{PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
...@@ -65,6 +55,8 @@ static struct pci_device_id cx18_pci_tbl[] __devinitdata = { ...@@ -65,6 +55,8 @@ static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, cx18_pci_tbl); MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
static atomic_t cx18_instance = ATOMIC_INIT(0);
/* Parameter declarations */ /* Parameter declarations */
static int cardtype[CX18_MAX_CARDS]; static int cardtype[CX18_MAX_CARDS];
static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
...@@ -491,9 +483,9 @@ static void cx18_process_options(struct cx18 *cx) ...@@ -491,9 +483,9 @@ static void cx18_process_options(struct cx18 *cx)
cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */ cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
} }
cx->options.cardtype = cardtype[cx->num]; cx->options.cardtype = cardtype[cx->instance];
cx->options.tuner = tuner[cx->num]; cx->options.tuner = tuner[cx->instance];
cx->options.radio = radio[cx->num]; cx->options.radio = radio[cx->instance];
cx->std = cx18_parse_std(cx); cx->std = cx18_parse_std(cx);
if (cx->options.cardtype == -1) { if (cx->options.cardtype == -1) {
...@@ -550,7 +542,7 @@ static void cx18_process_options(struct cx18 *cx) ...@@ -550,7 +542,7 @@ static void cx18_process_options(struct cx18 *cx)
} }
/* Precondition: the cx18 structure has been memset to 0. Only /* Precondition: the cx18 structure has been memset to 0. Only
the dev and num fields have been filled in. the dev and instance fields have been filled in.
No assumptions on the card type may be made here (see cx18_init_struct2 No assumptions on the card type may be made here (see cx18_init_struct2
for that). for that).
*/ */
...@@ -567,7 +559,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) ...@@ -567,7 +559,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
mutex_init(&cx->epu2apu_mb_lock); mutex_init(&cx->epu2apu_mb_lock);
mutex_init(&cx->epu2cpu_mb_lock); mutex_init(&cx->epu2cpu_mb_lock);
cx->work_queue = create_singlethread_workqueue(cx->name); cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name);
if (cx->work_queue == NULL) { if (cx->work_queue == NULL) {
CX18_ERR("Unable to create work hander thread\n"); CX18_ERR("Unable to create work hander thread\n");
return -ENOMEM; return -ENOMEM;
...@@ -647,15 +639,16 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, ...@@ -647,15 +639,16 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
CX18_DEBUG_INFO("Enabling pci device\n"); CX18_DEBUG_INFO("Enabling pci device\n");
if (pci_enable_device(pci_dev)) { if (pci_enable_device(pci_dev)) {
CX18_ERR("Can't enable device %d!\n", cx->num); CX18_ERR("Can't enable device %d!\n", cx->instance);
return -EIO; return -EIO;
} }
if (pci_set_dma_mask(pci_dev, 0xffffffff)) { if (pci_set_dma_mask(pci_dev, 0xffffffff)) {
CX18_ERR("No suitable DMA available on card %d.\n", cx->num); CX18_ERR("No suitable DMA available, card %d\n", cx->instance);
return -EIO; return -EIO;
} }
if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) { if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num); CX18_ERR("Cannot request encoder memory region, card %d\n",
cx->instance);
return -EIO; return -EIO;
} }
...@@ -741,44 +734,42 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, ...@@ -741,44 +734,42 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
u32 devtype; u32 devtype;
struct cx18 *cx; struct cx18 *cx;
spin_lock(&cx18_cards_lock); /* FIXME - module parameter arrays constrain max instances */
i = atomic_inc_return(&cx18_instance) - 1;
/* Make sure we've got a place for this card */ if (i >= CX18_MAX_CARDS) {
if (cx18_cards_active == CX18_MAX_CARDS) { printk(KERN_ERR "cx18: cannot manage card %d, driver has a "
printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n", "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1);
cx18_cards_active);
spin_unlock(&cx18_cards_lock);
return -ENOMEM; return -ENOMEM;
} }
cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC); cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
if (!cx) { if (cx == NULL) {
spin_unlock(&cx18_cards_lock); printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n",
i);
return -ENOMEM; return -ENOMEM;
} }
cx18_cards[cx18_cards_active] = cx;
cx->num = cx18_cards_active++;
snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num);
CX18_INFO("Initializing card #%d\n", cx->num);
spin_unlock(&cx18_cards_lock);
cx->pci_dev = pci_dev; cx->pci_dev = pci_dev;
cx->instance = i;
retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev); retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
if (retval) { if (retval) {
CX18_ERR("Call to v4l2_device_register() failed\n"); printk(KERN_ERR "cx18: v4l2_device_register of card %d failed"
goto err; "\n", cx->instance);
kfree(cx);
return retval;
} }
CX18_DEBUG_INFO("registered v4l2_device name: %s\n", cx->v4l2_dev.name); snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d",
cx->instance);
CX18_INFO("Initializing card %d\n", cx->instance);
cx18_process_options(cx); cx18_process_options(cx);
if (cx->options.cardtype == -1) { if (cx->options.cardtype == -1) {
retval = -ENODEV; retval = -ENODEV;
goto unregister_v4l2; goto err;
} }
if (cx18_init_struct1(cx)) { if (cx18_init_struct1(cx)) {
retval = -ENOMEM; retval = -ENOMEM;
goto unregister_v4l2; goto err;
} }
CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
...@@ -829,8 +820,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, ...@@ -829,8 +820,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
goto free_map; goto free_map;
} }
CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active);
if (cx->card->hw_all & CX18_HW_TVEEPROM) { if (cx->card->hw_all & CX18_HW_TVEEPROM) {
/* Based on the model number the cardtype may be changed. /* Based on the model number the cardtype may be changed.
The PCI IDs are not always reliable. */ The PCI IDs are not always reliable. */
...@@ -847,7 +836,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, ...@@ -847,7 +836,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
/* Register IRQ */ /* Register IRQ */
retval = request_irq(cx->pci_dev->irq, cx18_irq_handler, retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx); IRQF_SHARED | IRQF_DISABLED,
cx->v4l2_dev.name, (void *)cx);
if (retval) { if (retval) {
CX18_ERR("Failed to register irq %d\n", retval); CX18_ERR("Failed to register irq %d\n", retval);
goto free_i2c; goto free_i2c;
...@@ -933,8 +923,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, ...@@ -933,8 +923,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
goto free_streams; goto free_streams;
} }
CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name); CX18_INFO("Initialized card: %s\n", cx->card_name);
return 0; return 0;
free_streams: free_streams:
...@@ -949,18 +938,13 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, ...@@ -949,18 +938,13 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
release_mem_region(cx->base_addr, CX18_MEM_SIZE); release_mem_region(cx->base_addr, CX18_MEM_SIZE);
free_workqueue: free_workqueue:
destroy_workqueue(cx->work_queue); destroy_workqueue(cx->work_queue);
unregister_v4l2:
v4l2_device_unregister(&cx->v4l2_dev);
err: err:
if (retval == 0) if (retval == 0)
retval = -ENODEV; retval = -ENODEV;
CX18_ERR("Error %d on initialization\n", retval); CX18_ERR("Error %d on initialization\n", retval);
i = cx->num; v4l2_device_unregister(&cx->v4l2_dev);
spin_lock(&cx18_cards_lock); kfree(cx);
kfree(cx18_cards[i]);
cx18_cards[i] = NULL;
spin_unlock(&cx18_cards_lock);
return retval; return retval;
} }
...@@ -1069,9 +1053,9 @@ static void cx18_cancel_epu_work_orders(struct cx18 *cx) ...@@ -1069,9 +1053,9 @@ static void cx18_cancel_epu_work_orders(struct cx18 *cx)
static void cx18_remove(struct pci_dev *pci_dev) static void cx18_remove(struct pci_dev *pci_dev)
{ {
struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
struct cx18 *cx = container_of(v4l2_dev, struct cx18, v4l2_dev); struct cx18 *cx = to_cx18(v4l2_dev);
CX18_DEBUG_INFO("Removing Card #%d\n", cx->num); CX18_DEBUG_INFO("Removing Card\n");
/* Stop all captures */ /* Stop all captures */
CX18_DEBUG_INFO("Stopping all streams\n"); CX18_DEBUG_INFO("Stopping all streams\n");
...@@ -1099,10 +1083,12 @@ static void cx18_remove(struct pci_dev *pci_dev) ...@@ -1099,10 +1083,12 @@ static void cx18_remove(struct pci_dev *pci_dev)
release_mem_region(cx->base_addr, CX18_MEM_SIZE); release_mem_region(cx->base_addr, CX18_MEM_SIZE);
pci_disable_device(cx->pci_dev); pci_disable_device(cx->pci_dev);
/* FIXME - we leak cx->vbi.sliced_mpeg_data[i] allocations */
v4l2_device_unregister(v4l2_dev); CX18_INFO("Removed %s\n", cx->card_name);
CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num); v4l2_device_unregister(v4l2_dev);
kfree(cx);
} }
/* define a pci_driver for card detection */ /* define a pci_driver for card detection */
...@@ -1117,8 +1103,6 @@ static int module_start(void) ...@@ -1117,8 +1103,6 @@ static int module_start(void)
{ {
printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION);
memset(cx18_cards, 0, sizeof(cx18_cards));
/* Validate parameters */ /* Validate parameters */
if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n", printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n",
...@@ -1141,16 +1125,7 @@ static int module_start(void) ...@@ -1141,16 +1125,7 @@ static int module_start(void)
static void module_cleanup(void) static void module_cleanup(void)
{ {
int i;
pci_unregister_driver(&cx18_pci_driver); pci_unregister_driver(&cx18_pci_driver);
for (i = 0; i < cx18_cards_active; i++) {
if (cx18_cards[i] == NULL)
continue;
kfree(cx18_cards[i]);
}
} }
module_init(module_start); module_init(module_start);
......
...@@ -144,12 +144,12 @@ ...@@ -144,12 +144,12 @@
/* Flag to turn on high volume debugging */ /* Flag to turn on high volume debugging */
#define CX18_DBGFLG_HIGHVOL (1 << 8) #define CX18_DBGFLG_HIGHVOL (1 << 8)
/* NOTE: extra space before comma in 'cx->num , ## args' is required for /* NOTE: extra space before comma in 'fmt , ## args' is required for
gcc-2.95, otherwise it won't compile. */ gcc-2.95, otherwise it won't compile. */
#define CX18_DEBUG(x, type, fmt, args...) \ #define CX18_DEBUG(x, type, fmt, args...) \
do { \ do { \
if ((x) & cx18_debug) \ if ((x) & cx18_debug) \
printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \ v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
} while (0) } while (0)
#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args) #define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args) #define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
...@@ -163,7 +163,7 @@ ...@@ -163,7 +163,7 @@
#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \ #define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
do { \ do { \
if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \ if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \ v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
} while (0) } while (0)
#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args) #define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args) #define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
...@@ -175,9 +175,9 @@ ...@@ -175,9 +175,9 @@
#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args) #define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
/* Standard kernel messages */ /* Standard kernel messages */
#define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args) #define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args)
#define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args) #define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args)
#define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args) #define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args)
/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */ /* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
#define MPEG_FRAME_TYPE_IFRAME 1 #define MPEG_FRAME_TYPE_IFRAME 1
...@@ -445,8 +445,7 @@ struct cx18_i2c_algo_callback_data { ...@@ -445,8 +445,7 @@ struct cx18_i2c_algo_callback_data {
/* Struct to hold info about cx18 cards */ /* Struct to hold info about cx18 cards */
struct cx18 { struct cx18 {
int num; /* board number, -1 during init! */ int instance;
char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
struct v4l2_device v4l2_dev; struct v4l2_device v4l2_dev;
...@@ -455,8 +454,8 @@ struct cx18 { ...@@ -455,8 +454,8 @@ struct cx18 {
const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
u8 is_50hz; u8 is_50hz;
u8 is_60hz; u8 is_60hz;
u8 is_out_50hz; u8 is_out_50hz; /* FIXME - remove, we don't have an output decoder */
u8 is_out_60hz; u8 is_out_60hz; /* FIXME - remove, we don't have an output decoder */
u8 nof_inputs; /* number of video inputs */ u8 nof_inputs; /* number of video inputs */
u8 nof_audio_inputs; /* number of audio inputs */ u8 nof_audio_inputs; /* number of audio inputs */
u16 buffer_id; /* buffer ID counter */ u16 buffer_id; /* buffer ID counter */
...@@ -547,11 +546,13 @@ struct cx18 { ...@@ -547,11 +546,13 @@ struct cx18 {
v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */ v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
}; };
static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
{
return container_of(v4l2_dev, struct cx18, v4l2_dev);
}
/* Globals */ /* Globals */
extern struct cx18 *cx18_cards[];
extern int cx18_cards_active;
extern int cx18_first_minor; extern int cx18_first_minor;
extern spinlock_t cx18_cards_lock;
/*==============Prototypes==================*/ /*==============Prototypes==================*/
......
...@@ -682,38 +682,15 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) ...@@ -682,38 +682,15 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
int cx18_v4l2_open(struct file *filp) int cx18_v4l2_open(struct file *filp)
{ {
int res, x, y = 0; int res;
struct cx18 *cx = NULL; struct video_device *video_dev = video_devdata(filp);
struct cx18_stream *s = NULL; struct cx18_stream *s = video_get_drvdata(video_dev);
int minor = video_devdata(filp)->minor; struct cx18 *cx = s->cx;;
/* Find which card this open was on */
spin_lock(&cx18_cards_lock);
for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
/* find out which stream this open was on */
for (y = 0; y < CX18_MAX_STREAMS; y++) {
if (cx18_cards[x] == NULL)
continue;
s = &cx18_cards[x]->streams[y];
if (s->video_dev && s->video_dev->minor == minor) {
cx = cx18_cards[x];
break;
}
}
}
spin_unlock(&cx18_cards_lock);
if (cx == NULL) {
/* Couldn't find a device registered
on that minor, shouldn't happen! */
printk(KERN_WARNING "No cx18 device found on minor %d\n",
minor);
return -ENXIO;
}
mutex_lock(&cx->serialize_lock); mutex_lock(&cx->serialize_lock);
if (cx18_init_on_first_open(cx)) { if (cx18_init_on_first_open(cx)) {
CX18_ERR("Failed to initialize on minor %d\n", minor); CX18_ERR("Failed to initialize on minor %d\n",
video_dev->minor);
mutex_unlock(&cx->serialize_lock); mutex_unlock(&cx->serialize_lock);
return -ENXIO; return -ENXIO;
} }
......
...@@ -358,7 +358,7 @@ int init_cx18_i2c(struct cx18 *cx) ...@@ -358,7 +358,7 @@ int init_cx18_i2c(struct cx18 *cx)
cx->i2c_adap[i].algo_data = &cx->i2c_algo[i]; cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name), sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
" #%d-%d", cx->num, i); " #%d-%d", cx->instance, i);
i2c_set_adapdata(&cx->i2c_adap[i], cx); i2c_set_adapdata(&cx->i2c_adap[i], cx);
memcpy(&cx->i2c_client[i], &cx18_i2c_client_template, memcpy(&cx->i2c_client[i], &cx18_i2c_client_template,
......
...@@ -387,20 +387,17 @@ static int cx18_g_chip_ident(struct file *file, void *fh, ...@@ -387,20 +387,17 @@ static int cx18_g_chip_ident(struct file *file, void *fh,
static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
{ {
struct v4l2_dbg_register *regs = arg; struct v4l2_dbg_register *regs = arg;
unsigned long flags;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&cx18_cards_lock, flags);
regs->size = 4; regs->size = 4;
if (cmd == VIDIOC_DBG_G_REGISTER) if (cmd == VIDIOC_DBG_G_REGISTER)
regs->val = cx18_read_enc(cx, regs->reg); regs->val = cx18_read_enc(cx, regs->reg);
else else
cx18_write_enc(cx, regs->val, regs->reg); cx18_write_enc(cx, regs->val, regs->reg);
spin_unlock_irqrestore(&cx18_cards_lock, flags);
return 0; return 0;
} }
...@@ -847,7 +844,7 @@ static int cx18_log_status(struct file *file, void *fh) ...@@ -847,7 +844,7 @@ static int cx18_log_status(struct file *file, void *fh)
int i; int i;
CX18_INFO("================= START STATUS CARD #%d " CX18_INFO("================= START STATUS CARD #%d "
"=================\n", cx->num); "=================\n", cx->instance);
CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name); CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
if (cx->hw_flags & CX18_HW_TVEEPROM) { if (cx->hw_flags & CX18_HW_TVEEPROM) {
struct tveeprom tv; struct tveeprom tv;
...@@ -865,7 +862,7 @@ static int cx18_log_status(struct file *file, void *fh) ...@@ -865,7 +862,7 @@ static int cx18_log_status(struct file *file, void *fh)
mutex_unlock(&cx->gpio_lock); mutex_unlock(&cx->gpio_lock);
CX18_INFO("Tuner: %s\n", CX18_INFO("Tuner: %s\n",
test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
cx2341x_log_status(&cx->params, cx->name); cx2341x_log_status(&cx->params, cx->v4l2_dev.name);
CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags); CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
for (i = 0; i < CX18_MAX_STREAMS; i++) { for (i = 0; i < CX18_MAX_STREAMS; i++) {
struct cx18_stream *s = &cx->streams[i]; struct cx18_stream *s = &cx->streams[i];
...@@ -880,7 +877,8 @@ static int cx18_log_status(struct file *file, void *fh) ...@@ -880,7 +877,8 @@ static int cx18_log_status(struct file *file, void *fh)
CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
(long long)cx->mpg_data_received, (long long)cx->mpg_data_received,
(long long)cx->vbi_data_inserted); (long long)cx->vbi_data_inserted);
CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num); CX18_INFO("================== END STATUS CARD #%d "
"==================\n", cx->instance);
return 0; return 0;
} }
......
...@@ -130,7 +130,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) ...@@ -130,7 +130,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
struct cx18_stream *s = &cx->streams[type]; struct cx18_stream *s = &cx->streams[type];
u32 cap = cx->v4l2_cap; u32 cap = cx->v4l2_cap;
int num_offset = cx18_stream_info[type].num_offset; int num_offset = cx18_stream_info[type].num_offset;
int num = cx->num + cx18_first_minor + num_offset; int num = cx->instance + cx18_first_minor + num_offset;
/* These four fields are always initialized. If video_dev == NULL, then /* These four fields are always initialized. If video_dev == NULL, then
this stream is not in use. In that case no other fields but these this stream is not in use. In that case no other fields but these
...@@ -170,11 +170,11 @@ static int cx18_prep_dev(struct cx18 *cx, int type) ...@@ -170,11 +170,11 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
return -ENOMEM; return -ENOMEM;
} }
snprintf(s->video_dev->name, sizeof(s->video_dev->name), "cx18-%d", snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
cx->num); cx->v4l2_dev.name, s->name);
s->video_dev->num = num; s->video_dev->num = num;
s->video_dev->parent = &cx->pci_dev->dev; s->video_dev->v4l2_dev = &cx->v4l2_dev;
s->video_dev->fops = &cx18_v4l2_enc_fops; s->video_dev->fops = &cx18_v4l2_enc_fops;
s->video_dev->release = video_device_release; s->video_dev->release = video_device_release;
s->video_dev->tvnorms = V4L2_STD_ALL; s->video_dev->tvnorms = V4L2_STD_ALL;
...@@ -239,6 +239,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) ...@@ -239,6 +239,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
num = s_mpg->video_dev->num num = s_mpg->video_dev->num
+ cx18_stream_info[type].num_offset; + cx18_stream_info[type].num_offset;
} }
video_set_drvdata(s->video_dev, s);
/* Register device. First try the desired minor, then any free one. */ /* Register device. First try the desired minor, then any free one. */
ret = video_register_device(s->video_dev, vfl_type, num); ret = video_register_device(s->video_dev, vfl_type, num);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment