diff options
-rw-r--r-- | drivers/media/video/Kconfig | 9 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 4 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-streams.c | 41 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 8 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 6 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 40 | ||||
-rw-r--r-- | drivers/media/video/v4l2-dev.c | 96 | ||||
-rw-r--r-- | include/media/v4l2-dev.h | 12 |
8 files changed, 128 insertions, 88 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index e28e292fe202..2dce16f863bb 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -72,6 +72,15 @@ config VIDEO_ADV_DEBUG | |||
72 | V4L devices. | 72 | V4L devices. |
73 | In doubt, say N. | 73 | In doubt, say N. |
74 | 74 | ||
75 | config VIDEO_FIXED_MINOR_RANGES | ||
76 | bool "Enable old-style fixed minor ranges for video devices" | ||
77 | default n | ||
78 | ---help--- | ||
79 | Say Y here to enable the old-style fixed-range minor assignments. | ||
80 | Only useful if you rely on the old behavior and use mknod instead of udev. | ||
81 | |||
82 | When in doubt, say N. | ||
83 | |||
75 | config VIDEO_HELPER_CHIPS_AUTO | 84 | config VIDEO_HELPER_CHIPS_AUTO |
76 | bool "Autoselect pertinent encoders/decoders and other helper chips" | 85 | bool "Autoselect pertinent encoders/decoders and other helper chips" |
77 | default y | 86 | default y |
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 6bf9ac8c4e70..085121c2b47f 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -175,7 +175,7 @@ MODULE_PARM_DESC(enc_pcm_buffers, | |||
175 | "Encoder PCM buffers (in MB)\n" | 175 | "Encoder PCM buffers (in MB)\n" |
176 | "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); | 176 | "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); |
177 | 177 | ||
178 | MODULE_PARM_DESC(cx18_first_minor, "Set minor assigned to first card"); | 178 | MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card"); |
179 | 179 | ||
180 | MODULE_AUTHOR("Hans Verkuil"); | 180 | MODULE_AUTHOR("Hans Verkuil"); |
181 | MODULE_DESCRIPTION("CX23418 driver"); | 181 | MODULE_DESCRIPTION("CX23418 driver"); |
@@ -959,7 +959,7 @@ static int module_start(void) | |||
959 | 959 | ||
960 | /* Validate parameters */ | 960 | /* Validate parameters */ |
961 | if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { | 961 | if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { |
962 | printk(KERN_ERR "cx18: Exiting, ivtv_first_minor must be between 0 and %d\n", | 962 | printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n", |
963 | CX18_MAX_CARDS - 1); | 963 | CX18_MAX_CARDS - 1); |
964 | return -1; | 964 | return -1; |
965 | } | 965 | } |
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index c752a6a4dbd3..0c8e7542cf60 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -57,7 +57,7 @@ static struct file_operations cx18_v4l2_enc_fops = { | |||
57 | static struct { | 57 | static struct { |
58 | const char *name; | 58 | const char *name; |
59 | int vfl_type; | 59 | int vfl_type; |
60 | int minor_offset; | 60 | int num_offset; |
61 | int dma; | 61 | int dma; |
62 | enum v4l2_buf_type buf_type; | 62 | enum v4l2_buf_type buf_type; |
63 | struct file_operations *fops; | 63 | struct file_operations *fops; |
@@ -144,8 +144,8 @@ static int cx18_prep_dev(struct cx18 *cx, int type) | |||
144 | { | 144 | { |
145 | struct cx18_stream *s = &cx->streams[type]; | 145 | struct cx18_stream *s = &cx->streams[type]; |
146 | u32 cap = cx->v4l2_cap; | 146 | u32 cap = cx->v4l2_cap; |
147 | int minor_offset = cx18_stream_info[type].minor_offset; | 147 | int num_offset = cx18_stream_info[type].num_offset; |
148 | int minor; | 148 | int num = cx->num + cx18_first_minor + num_offset; |
149 | 149 | ||
150 | /* These four fields are always initialized. If v4l2dev == NULL, then | 150 | /* These four fields are always initialized. If v4l2dev == NULL, then |
151 | this stream is not in use. In that case no other fields but these | 151 | this stream is not in use. In that case no other fields but these |
@@ -164,9 +164,6 @@ static int cx18_prep_dev(struct cx18 *cx, int type) | |||
164 | !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE))) | 164 | !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE))) |
165 | return 0; | 165 | return 0; |
166 | 166 | ||
167 | /* card number + user defined offset + device offset */ | ||
168 | minor = cx->num + cx18_first_minor + minor_offset; | ||
169 | |||
170 | /* User explicitly selected 0 buffers for these streams, so don't | 167 | /* User explicitly selected 0 buffers for these streams, so don't |
171 | create them. */ | 168 | create them. */ |
172 | if (cx18_stream_info[type].dma != PCI_DMA_NONE && | 169 | if (cx18_stream_info[type].dma != PCI_DMA_NONE && |
@@ -177,7 +174,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) | |||
177 | 174 | ||
178 | cx18_stream_init(cx, type); | 175 | cx18_stream_init(cx, type); |
179 | 176 | ||
180 | if (minor_offset == -1) | 177 | if (num_offset == -1) |
181 | return 0; | 178 | return 0; |
182 | 179 | ||
183 | /* allocate and initialize the v4l2 video device structure */ | 180 | /* allocate and initialize the v4l2 video device structure */ |
@@ -191,7 +188,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) | |||
191 | snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", | 188 | snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", |
192 | cx->num); | 189 | cx->num); |
193 | 190 | ||
194 | s->v4l2dev->minor = minor; | 191 | s->v4l2dev->num = num; |
195 | s->v4l2dev->parent = &cx->dev->dev; | 192 | s->v4l2dev->parent = &cx->dev->dev; |
196 | s->v4l2dev->fops = cx18_stream_info[type].fops; | 193 | s->v4l2dev->fops = cx18_stream_info[type].fops; |
197 | s->v4l2dev->release = video_device_release; | 194 | s->v4l2dev->release = video_device_release; |
@@ -227,7 +224,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type) | |||
227 | { | 224 | { |
228 | struct cx18_stream *s = &cx->streams[type]; | 225 | struct cx18_stream *s = &cx->streams[type]; |
229 | int vfl_type = cx18_stream_info[type].vfl_type; | 226 | int vfl_type = cx18_stream_info[type].vfl_type; |
230 | int minor; | 227 | int num; |
231 | 228 | ||
232 | /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? | 229 | /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? |
233 | * We need a VFL_TYPE_TS defined. | 230 | * We need a VFL_TYPE_TS defined. |
@@ -245,38 +242,44 @@ static int cx18_reg_dev(struct cx18 *cx, int type) | |||
245 | if (s->v4l2dev == NULL) | 242 | if (s->v4l2dev == NULL) |
246 | return 0; | 243 | return 0; |
247 | 244 | ||
248 | minor = s->v4l2dev->minor; | 245 | num = s->v4l2dev->num; |
246 | /* card number + user defined offset + device offset */ | ||
247 | if (type != CX18_ENC_STREAM_TYPE_MPG) { | ||
248 | struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; | ||
249 | |||
250 | if (s_mpg->v4l2dev) | ||
251 | num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset; | ||
252 | } | ||
249 | 253 | ||
250 | /* Register device. First try the desired minor, then any free one. */ | 254 | /* Register device. First try the desired minor, then any free one. */ |
251 | if (video_register_device(s->v4l2dev, vfl_type, minor) && | 255 | if (video_register_device(s->v4l2dev, vfl_type, num)) { |
252 | video_register_device(s->v4l2dev, vfl_type, -1)) { | 256 | CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n", |
253 | CX18_ERR("Couldn't register v4l2 device for %s minor %d\n", | 257 | s->name, num); |
254 | s->name, minor); | ||
255 | video_device_release(s->v4l2dev); | 258 | video_device_release(s->v4l2dev); |
256 | s->v4l2dev = NULL; | 259 | s->v4l2dev = NULL; |
257 | return -ENOMEM; | 260 | return -ENOMEM; |
258 | } | 261 | } |
259 | minor = s->v4l2dev->minor; | 262 | num = s->v4l2dev->num; |
260 | 263 | ||
261 | switch (vfl_type) { | 264 | switch (vfl_type) { |
262 | case VFL_TYPE_GRABBER: | 265 | case VFL_TYPE_GRABBER: |
263 | CX18_INFO("Registered device video%d for %s (%d MB)\n", | 266 | CX18_INFO("Registered device video%d for %s (%d MB)\n", |
264 | minor, s->name, cx->options.megabytes[type]); | 267 | num, s->name, cx->options.megabytes[type]); |
265 | break; | 268 | break; |
266 | 269 | ||
267 | case VFL_TYPE_RADIO: | 270 | case VFL_TYPE_RADIO: |
268 | CX18_INFO("Registered device radio%d for %s\n", | 271 | CX18_INFO("Registered device radio%d for %s\n", |
269 | minor - MINOR_VFL_TYPE_RADIO_MIN, s->name); | 272 | num, s->name); |
270 | break; | 273 | break; |
271 | 274 | ||
272 | case VFL_TYPE_VBI: | 275 | case VFL_TYPE_VBI: |
273 | if (cx->options.megabytes[type]) | 276 | if (cx->options.megabytes[type]) |
274 | CX18_INFO("Registered device vbi%d for %s (%d MB)\n", | 277 | CX18_INFO("Registered device vbi%d for %s (%d MB)\n", |
275 | minor - MINOR_VFL_TYPE_VBI_MIN, | 278 | num, |
276 | s->name, cx->options.megabytes[type]); | 279 | s->name, cx->options.megabytes[type]); |
277 | else | 280 | else |
278 | CX18_INFO("Registered device vbi%d for %s\n", | 281 | CX18_INFO("Registered device vbi%d for %s\n", |
279 | minor - MINOR_VFL_TYPE_VBI_MIN, s->name); | 282 | num, s->name); |
280 | break; | 283 | break; |
281 | } | 284 | } |
282 | 285 | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 50d2c7a9b3c1..c53649e5315b 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -1600,8 +1600,7 @@ static void em28xx_release_resources(struct em28xx *dev) | |||
1600 | /*FIXME: I2C IR should be disconnected */ | 1600 | /*FIXME: I2C IR should be disconnected */ |
1601 | 1601 | ||
1602 | em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n", | 1602 | em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n", |
1603 | dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, | 1603 | dev->vdev->num, dev->vbi_dev->num); |
1604 | dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); | ||
1605 | list_del(&dev->devlist); | 1604 | list_del(&dev->devlist); |
1606 | if (dev->sbutton_input_dev) | 1605 | if (dev->sbutton_input_dev) |
1607 | em28xx_deregister_snapshot_button(dev); | 1606 | em28xx_deregister_snapshot_button(dev); |
@@ -2073,8 +2072,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | |||
2073 | video_mux(dev, 0); | 2072 | video_mux(dev, 0); |
2074 | 2073 | ||
2075 | em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", | 2074 | em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", |
2076 | dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, | 2075 | dev->vdev->num, dev->vbi_dev->num); |
2077 | dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); | ||
2078 | 2076 | ||
2079 | mutex_lock(&em28xx_extension_devlist_lock); | 2077 | mutex_lock(&em28xx_extension_devlist_lock); |
2080 | if (!list_empty(&em28xx_extension_devlist)) { | 2078 | if (!list_empty(&em28xx_extension_devlist)) { |
@@ -2274,7 +2272,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
2274 | em28xx_warn | 2272 | em28xx_warn |
2275 | ("device /dev/video%d is open! Deregistration and memory " | 2273 | ("device /dev/video%d is open! Deregistration and memory " |
2276 | "deallocation are deferred on close.\n", | 2274 | "deallocation are deferred on close.\n", |
2277 | dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN); | 2275 | dev->vdev->num); |
2278 | 2276 | ||
2279 | dev->state |= DEV_MISCONFIGURED; | 2277 | dev->state |= DEV_MISCONFIGURED; |
2280 | em28xx_uninit_isoc(dev); | 2278 | em28xx_uninit_isoc(dev); |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 6b04930d1278..7aa61b617496 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -61,14 +61,14 @@ | |||
61 | #include "tuner-xc2028.h" | 61 | #include "tuner-xc2028.h" |
62 | 62 | ||
63 | /* var to keep track of the number of array elements in use */ | 63 | /* var to keep track of the number of array elements in use */ |
64 | int ivtv_cards_active = 0; | 64 | int ivtv_cards_active; |
65 | 65 | ||
66 | /* If you have already X v4l cards, then set this to X. This way | 66 | /* If you have already X v4l cards, then set this to X. This way |
67 | the device numbers stay matched. Example: you have a WinTV card | 67 | the device numbers stay matched. Example: you have a WinTV card |
68 | without radio and a PVR-350 with. Normally this would give a | 68 | without radio and a PVR-350 with. Normally this would give a |
69 | video1 device together with a radio0 device for the PVR. By | 69 | video1 device together with a radio0 device for the PVR. By |
70 | setting this to 1 you ensure that radio0 is now also radio1. */ | 70 | setting this to 1 you ensure that radio0 is now also radio1. */ |
71 | int ivtv_first_minor = 0; | 71 | int ivtv_first_minor; |
72 | 72 | ||
73 | /* Master variable for all ivtv info */ | 73 | /* Master variable for all ivtv info */ |
74 | struct ivtv *ivtv_cards[IVTV_MAX_CARDS]; | 74 | struct ivtv *ivtv_cards[IVTV_MAX_CARDS]; |
@@ -251,7 +251,7 @@ MODULE_PARM_DESC(newi2c, | |||
251 | "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" | 251 | "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" |
252 | "\t\t\tDefault is autodetect"); | 252 | "\t\t\tDefault is autodetect"); |
253 | 253 | ||
254 | MODULE_PARM_DESC(ivtv_first_minor, "Set minor assigned to first card"); | 254 | MODULE_PARM_DESC(ivtv_first_minor, "Set kernel number assigned to first card"); |
255 | 255 | ||
256 | MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); | 256 | MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); |
257 | MODULE_DESCRIPTION("CX23415/CX23416 driver"); | 257 | MODULE_DESCRIPTION("CX23415/CX23416 driver"); |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 730e85d86fc8..24273fbea470 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -75,7 +75,7 @@ static const struct file_operations ivtv_v4l2_dec_fops = { | |||
75 | static struct { | 75 | static struct { |
76 | const char *name; | 76 | const char *name; |
77 | int vfl_type; | 77 | int vfl_type; |
78 | int minor_offset; | 78 | int num_offset; |
79 | int dma, pio; | 79 | int dma, pio; |
80 | enum v4l2_buf_type buf_type; | 80 | enum v4l2_buf_type buf_type; |
81 | const struct file_operations *fops; | 81 | const struct file_operations *fops; |
@@ -171,8 +171,8 @@ static void ivtv_stream_init(struct ivtv *itv, int type) | |||
171 | static int ivtv_prep_dev(struct ivtv *itv, int type) | 171 | static int ivtv_prep_dev(struct ivtv *itv, int type) |
172 | { | 172 | { |
173 | struct ivtv_stream *s = &itv->streams[type]; | 173 | struct ivtv_stream *s = &itv->streams[type]; |
174 | int minor_offset = ivtv_stream_info[type].minor_offset; | 174 | int num_offset = ivtv_stream_info[type].num_offset; |
175 | int minor; | 175 | int num = itv->num + ivtv_first_minor + num_offset; |
176 | 176 | ||
177 | /* These four fields are always initialized. If v4l2dev == NULL, then | 177 | /* These four fields are always initialized. If v4l2dev == NULL, then |
178 | this stream is not in use. In that case no other fields but these | 178 | this stream is not in use. In that case no other fields but these |
@@ -188,9 +188,6 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) | |||
188 | if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 188 | if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) |
189 | return 0; | 189 | return 0; |
190 | 190 | ||
191 | /* card number + user defined offset + device offset */ | ||
192 | minor = itv->num + ivtv_first_minor + minor_offset; | ||
193 | |||
194 | /* User explicitly selected 0 buffers for these streams, so don't | 191 | /* User explicitly selected 0 buffers for these streams, so don't |
195 | create them. */ | 192 | create them. */ |
196 | if (ivtv_stream_info[type].dma != PCI_DMA_NONE && | 193 | if (ivtv_stream_info[type].dma != PCI_DMA_NONE && |
@@ -211,7 +208,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) | |||
211 | snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s", | 208 | snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s", |
212 | itv->num, s->name); | 209 | itv->num, s->name); |
213 | 210 | ||
214 | s->v4l2dev->minor = minor; | 211 | s->v4l2dev->num = num; |
215 | s->v4l2dev->parent = &itv->dev->dev; | 212 | s->v4l2dev->parent = &itv->dev->dev; |
216 | s->v4l2dev->fops = ivtv_stream_info[type].fops; | 213 | s->v4l2dev->fops = ivtv_stream_info[type].fops; |
217 | s->v4l2dev->release = video_device_release; | 214 | s->v4l2dev->release = video_device_release; |
@@ -250,39 +247,46 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) | |||
250 | { | 247 | { |
251 | struct ivtv_stream *s = &itv->streams[type]; | 248 | struct ivtv_stream *s = &itv->streams[type]; |
252 | int vfl_type = ivtv_stream_info[type].vfl_type; | 249 | int vfl_type = ivtv_stream_info[type].vfl_type; |
253 | int minor; | 250 | int num; |
254 | 251 | ||
255 | if (s->v4l2dev == NULL) | 252 | if (s->v4l2dev == NULL) |
256 | return 0; | 253 | return 0; |
257 | 254 | ||
258 | minor = s->v4l2dev->minor; | 255 | num = s->v4l2dev->num; |
256 | /* card number + user defined offset + device offset */ | ||
257 | if (type != IVTV_ENC_STREAM_TYPE_MPG) { | ||
258 | struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; | ||
259 | |||
260 | if (s_mpg->v4l2dev) | ||
261 | num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset; | ||
262 | } | ||
263 | |||
259 | /* Register device. First try the desired minor, then any free one. */ | 264 | /* Register device. First try the desired minor, then any free one. */ |
260 | if (video_register_device(s->v4l2dev, vfl_type, minor) && | 265 | if (video_register_device(s->v4l2dev, vfl_type, num)) { |
261 | video_register_device(s->v4l2dev, vfl_type, -1)) { | 266 | IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n", |
262 | IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n", | 267 | s->name, num); |
263 | s->name, minor); | ||
264 | video_device_release(s->v4l2dev); | 268 | video_device_release(s->v4l2dev); |
265 | s->v4l2dev = NULL; | 269 | s->v4l2dev = NULL; |
266 | return -ENOMEM; | 270 | return -ENOMEM; |
267 | } | 271 | } |
272 | num = s->v4l2dev->num; | ||
268 | 273 | ||
269 | switch (vfl_type) { | 274 | switch (vfl_type) { |
270 | case VFL_TYPE_GRABBER: | 275 | case VFL_TYPE_GRABBER: |
271 | IVTV_INFO("Registered device video%d for %s (%d kB)\n", | 276 | IVTV_INFO("Registered device video%d for %s (%d kB)\n", |
272 | s->v4l2dev->minor, s->name, itv->options.kilobytes[type]); | 277 | num, s->name, itv->options.kilobytes[type]); |
273 | break; | 278 | break; |
274 | case VFL_TYPE_RADIO: | 279 | case VFL_TYPE_RADIO: |
275 | IVTV_INFO("Registered device radio%d for %s\n", | 280 | IVTV_INFO("Registered device radio%d for %s\n", |
276 | s->v4l2dev->minor - MINOR_VFL_TYPE_RADIO_MIN, s->name); | 281 | num, s->name); |
277 | break; | 282 | break; |
278 | case VFL_TYPE_VBI: | 283 | case VFL_TYPE_VBI: |
279 | if (itv->options.kilobytes[type]) | 284 | if (itv->options.kilobytes[type]) |
280 | IVTV_INFO("Registered device vbi%d for %s (%d kB)\n", | 285 | IVTV_INFO("Registered device vbi%d for %s (%d kB)\n", |
281 | s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, | 286 | num, s->name, itv->options.kilobytes[type]); |
282 | s->name, itv->options.kilobytes[type]); | ||
283 | else | 287 | else |
284 | IVTV_INFO("Registered device vbi%d for %s\n", | 288 | IVTV_INFO("Registered device vbi%d for %s\n", |
285 | s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, s->name); | 289 | num, s->name); |
286 | break; | 290 | break; |
287 | } | 291 | } |
288 | return 0; | 292 | return 0; |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 7addf2fd55de..ccd6566a515e 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -65,6 +65,7 @@ static struct device_attribute video_device_attrs[] = { | |||
65 | */ | 65 | */ |
66 | static struct video_device *video_device[VIDEO_NUM_DEVICES]; | 66 | static struct video_device *video_device[VIDEO_NUM_DEVICES]; |
67 | static DEFINE_MUTEX(videodev_lock); | 67 | static DEFINE_MUTEX(videodev_lock); |
68 | static DECLARE_BITMAP(video_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES); | ||
68 | 69 | ||
69 | struct video_device *video_device_alloc(void) | 70 | struct video_device *video_device_alloc(void) |
70 | { | 71 | { |
@@ -99,6 +100,7 @@ static void v4l2_chardev_release(struct kobject *kobj) | |||
99 | 100 | ||
100 | /* Free up this device for reuse */ | 101 | /* Free up this device for reuse */ |
101 | video_device[vfd->minor] = NULL; | 102 | video_device[vfd->minor] = NULL; |
103 | clear_bit(vfd->num, video_nums[vfd->vfl_type]); | ||
102 | mutex_unlock(&videodev_lock); | 104 | mutex_unlock(&videodev_lock); |
103 | 105 | ||
104 | /* Release the character device */ | 106 | /* Release the character device */ |
@@ -217,10 +219,10 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, | |||
217 | int index) | 219 | int index) |
218 | { | 220 | { |
219 | int i = 0; | 221 | int i = 0; |
220 | int base; | ||
221 | int end; | ||
222 | int ret; | 222 | int ret; |
223 | char *name_base; | 223 | int minor_offset = 0; |
224 | int minor_cnt = VIDEO_NUM_DEVICES; | ||
225 | const char *name_base; | ||
224 | void *priv = video_get_drvdata(vfd); | 226 | void *priv = video_get_drvdata(vfd); |
225 | 227 | ||
226 | /* the release callback MUST be present */ | 228 | /* the release callback MUST be present */ |
@@ -231,23 +233,15 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, | |||
231 | 233 | ||
232 | switch (type) { | 234 | switch (type) { |
233 | case VFL_TYPE_GRABBER: | 235 | case VFL_TYPE_GRABBER: |
234 | base = MINOR_VFL_TYPE_GRABBER_MIN; | ||
235 | end = MINOR_VFL_TYPE_GRABBER_MAX+1; | ||
236 | name_base = "video"; | 236 | name_base = "video"; |
237 | break; | 237 | break; |
238 | case VFL_TYPE_VTX: | 238 | case VFL_TYPE_VTX: |
239 | base = MINOR_VFL_TYPE_VTX_MIN; | ||
240 | end = MINOR_VFL_TYPE_VTX_MAX+1; | ||
241 | name_base = "vtx"; | 239 | name_base = "vtx"; |
242 | break; | 240 | break; |
243 | case VFL_TYPE_VBI: | 241 | case VFL_TYPE_VBI: |
244 | base = MINOR_VFL_TYPE_VBI_MIN; | ||
245 | end = MINOR_VFL_TYPE_VBI_MAX+1; | ||
246 | name_base = "vbi"; | 242 | name_base = "vbi"; |
247 | break; | 243 | break; |
248 | case VFL_TYPE_RADIO: | 244 | case VFL_TYPE_RADIO: |
249 | base = MINOR_VFL_TYPE_RADIO_MIN; | ||
250 | end = MINOR_VFL_TYPE_RADIO_MAX+1; | ||
251 | name_base = "radio"; | 245 | name_base = "radio"; |
252 | break; | 246 | break; |
253 | default: | 247 | default: |
@@ -256,31 +250,70 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, | |||
256 | return -EINVAL; | 250 | return -EINVAL; |
257 | } | 251 | } |
258 | 252 | ||
253 | vfd->vfl_type = type; | ||
254 | |||
255 | #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES | ||
256 | /* Keep the ranges for the first four types for historical | ||
257 | * reasons. | ||
258 | * Newer devices (not yet in place) should use the range | ||
259 | * of 128-191 and just pick the first free minor there | ||
260 | * (new style). */ | ||
261 | switch (type) { | ||
262 | case VFL_TYPE_GRABBER: | ||
263 | minor_offset = 0; | ||
264 | minor_cnt = 64; | ||
265 | break; | ||
266 | case VFL_TYPE_RADIO: | ||
267 | minor_offset = 64; | ||
268 | minor_cnt = 64; | ||
269 | break; | ||
270 | case VFL_TYPE_VTX: | ||
271 | minor_offset = 192; | ||
272 | minor_cnt = 32; | ||
273 | break; | ||
274 | case VFL_TYPE_VBI: | ||
275 | minor_offset = 224; | ||
276 | minor_cnt = 32; | ||
277 | break; | ||
278 | default: | ||
279 | minor_offset = 128; | ||
280 | minor_cnt = 64; | ||
281 | break; | ||
282 | } | ||
283 | #endif | ||
284 | |||
259 | /* Initialize the character device */ | 285 | /* Initialize the character device */ |
260 | cdev_init(&vfd->cdev, vfd->fops); | 286 | cdev_init(&vfd->cdev, vfd->fops); |
261 | vfd->cdev.owner = vfd->fops->owner; | 287 | vfd->cdev.owner = vfd->fops->owner; |
262 | /* pick a minor number */ | 288 | /* pick a minor number */ |
263 | mutex_lock(&videodev_lock); | 289 | mutex_lock(&videodev_lock); |
264 | if (nr >= 0 && nr < end-base) { | 290 | nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr); |
265 | /* use the one the driver asked for */ | 291 | if (nr == minor_cnt) |
266 | i = base + nr; | 292 | nr = find_first_zero_bit(video_nums[type], minor_cnt); |
267 | if (NULL != video_device[i]) { | 293 | if (nr == minor_cnt) { |
268 | mutex_unlock(&videodev_lock); | 294 | printk(KERN_ERR "could not get a free kernel number\n"); |
269 | return -ENFILE; | 295 | mutex_unlock(&videodev_lock); |
270 | } | 296 | return -ENFILE; |
271 | } else { | ||
272 | /* use first free */ | ||
273 | for (i = base; i < end; i++) | ||
274 | if (NULL == video_device[i]) | ||
275 | break; | ||
276 | if (i == end) { | ||
277 | mutex_unlock(&videodev_lock); | ||
278 | return -ENFILE; | ||
279 | } | ||
280 | } | 297 | } |
281 | video_device[i] = vfd; | 298 | #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES |
282 | vfd->vfl_type = type; | 299 | /* 1-on-1 mapping of kernel number to minor number */ |
283 | vfd->minor = i; | 300 | i = nr; |
301 | #else | ||
302 | /* The kernel number and minor numbers are independent */ | ||
303 | for (i = 0; i < VIDEO_NUM_DEVICES; i++) | ||
304 | if (video_device[i] == NULL) | ||
305 | break; | ||
306 | if (i == VIDEO_NUM_DEVICES) { | ||
307 | mutex_unlock(&videodev_lock); | ||
308 | printk(KERN_ERR "could not get a free minor\n"); | ||
309 | return -ENFILE; | ||
310 | } | ||
311 | #endif | ||
312 | vfd->minor = i + minor_offset; | ||
313 | vfd->num = nr; | ||
314 | set_bit(nr, video_nums[type]); | ||
315 | BUG_ON(video_device[vfd->minor]); | ||
316 | video_device[vfd->minor] = vfd; | ||
284 | 317 | ||
285 | ret = get_index(vfd, index); | 318 | ret = get_index(vfd, index); |
286 | vfd->index = ret; | 319 | vfd->index = ret; |
@@ -306,7 +339,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, | |||
306 | vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); | 339 | vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); |
307 | if (vfd->parent) | 340 | if (vfd->parent) |
308 | vfd->dev.parent = vfd->parent; | 341 | vfd->dev.parent = vfd->parent; |
309 | sprintf(vfd->dev.bus_id, "%s%d", name_base, i - base); | 342 | sprintf(vfd->dev.bus_id, "%s%d", name_base, nr); |
310 | ret = device_register(&vfd->dev); | 343 | ret = device_register(&vfd->dev); |
311 | if (ret < 0) { | 344 | if (ret < 0) { |
312 | printk(KERN_ERR "%s: device_register failed\n", __func__); | 345 | printk(KERN_ERR "%s: device_register failed\n", __func__); |
@@ -324,6 +357,7 @@ del_cdev: | |||
324 | fail_minor: | 357 | fail_minor: |
325 | mutex_lock(&videodev_lock); | 358 | mutex_lock(&videodev_lock); |
326 | video_device[vfd->minor] = NULL; | 359 | video_device[vfd->minor] = NULL; |
360 | clear_bit(vfd->num, video_nums[type]); | ||
327 | mutex_unlock(&videodev_lock); | 361 | mutex_unlock(&videodev_lock); |
328 | vfd->minor = -1; | 362 | vfd->minor = -1; |
329 | return ret; | 363 | return ret; |
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index d129b56e1a9f..a0a6b41c5e09 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h | |||
@@ -18,20 +18,11 @@ | |||
18 | 18 | ||
19 | #define VIDEO_MAJOR 81 | 19 | #define VIDEO_MAJOR 81 |
20 | 20 | ||
21 | /* Minor device allocation */ | ||
22 | #define MINOR_VFL_TYPE_GRABBER_MIN 0 | ||
23 | #define MINOR_VFL_TYPE_GRABBER_MAX 63 | ||
24 | #define MINOR_VFL_TYPE_RADIO_MIN 64 | ||
25 | #define MINOR_VFL_TYPE_RADIO_MAX 127 | ||
26 | #define MINOR_VFL_TYPE_VTX_MIN 192 | ||
27 | #define MINOR_VFL_TYPE_VTX_MAX 223 | ||
28 | #define MINOR_VFL_TYPE_VBI_MIN 224 | ||
29 | #define MINOR_VFL_TYPE_VBI_MAX 255 | ||
30 | |||
31 | #define VFL_TYPE_GRABBER 0 | 21 | #define VFL_TYPE_GRABBER 0 |
32 | #define VFL_TYPE_VBI 1 | 22 | #define VFL_TYPE_VBI 1 |
33 | #define VFL_TYPE_RADIO 2 | 23 | #define VFL_TYPE_RADIO 2 |
34 | #define VFL_TYPE_VTX 3 | 24 | #define VFL_TYPE_VTX 3 |
25 | #define VFL_TYPE_MAX 4 | ||
35 | 26 | ||
36 | struct v4l2_ioctl_callbacks; | 27 | struct v4l2_ioctl_callbacks; |
37 | 28 | ||
@@ -56,6 +47,7 @@ struct video_device | |||
56 | char name[32]; | 47 | char name[32]; |
57 | int vfl_type; | 48 | int vfl_type; |
58 | int minor; | 49 | int minor; |
50 | u16 num; | ||
59 | /* attribute to differentiate multiple indices on one physical device */ | 51 | /* attribute to differentiate multiple indices on one physical device */ |
60 | int index; | 52 | int index; |
61 | 53 | ||