diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 17:03:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 17:03:59 -0400 |
commit | cf2fa66055d718ae13e62451bb546505f63906a2 (patch) | |
tree | e206d3f04e74a34e9aa88d21af6c26eea21d4121 /drivers/media/video/ivtv | |
parent | 4501a466f28788485604ee42641d7a5fe7258d16 (diff) | |
parent | 57f51dbc45f65f7ee1e8c8f77200bb8000e3e271 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (313 commits)
V4L/DVB (9186): Added support for Prof 7300 DVB-S/S2 cards
V4L/DVB (9185): S2API: Ensure we have a reasonable ROLLOFF default
V4L/DVB (9184): cx24116: Change the default SNR units back to percentage by default.
V4L/DVB (9183): S2API: Return error of the caller provides 0 commands.
V4L/DVB (9182): S2API: Added support for DTV_HIERARCHY
V4L/DVB (9181): S2API: Add support fot DTV_GUARD_INTERVAL and DTV_TRANSMISSION_MODE
V4L/DVB (9180): S2API: Added support for DTV_CODE_RATE_HP/LP
V4L/DVB (9179): S2API: frontend.h cleanup
V4L/DVB (9178): cx24116: Add module parameter to return SNR as ESNO.
V4L/DVB (9177): S2API: Change _8PSK / _16APSK to PSK_8 and APSK_16
V4L/DVB (9176): Add support for DvbWorld USB cards with STV0288 demodulator.
V4L/DVB (9175): Remove NULL pointer in stb6000 driver.
V4L/DVB (9174): Allow custom inittab for ST STV0288 demodulator.
V4L/DVB (9173): S2API: Remove the hardcoded command limit during validation
V4L/DVB (9172): S2API: Bugfix related to DVB-S / DVB-S2 tuning for the legacy API.
V4L/DVB (9171): S2API: Stop an OOPS if illegal commands are dumped in S2API.
V4L/DVB (9170): cx24116: Sanity checking to data input via S2API to the cx24116 demod.
V4L/DVB (9169): uvcvideo: Support two new Bison Electronics webcams.
V4L/DVB (9168): Add support for MSI TV@nywhere Plus remote
V4L/DVB: v4l2-dev: remove duplicated #include
...
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-cards.h | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 12 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.h | 9 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 8 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.h | 5 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-gpio.c | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-gpio.h | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-i2c.c | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 58 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-irq.c | 9 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 42 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-vbi.c | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-yuv.c | 1 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtvfb.c | 78 |
14 files changed, 115 insertions, 117 deletions
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h index 381af1bceef8..0b8fe85fb697 100644 --- a/drivers/media/video/ivtv/ivtv-cards.h +++ b/drivers/media/video/ivtv/ivtv-cards.h | |||
@@ -154,7 +154,7 @@ | |||
154 | #define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ | 154 | #define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ |
155 | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \ | 155 | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \ |
156 | V4L2_CAP_SLICED_VBI_CAPTURE) | 156 | V4L2_CAP_SLICED_VBI_CAPTURE) |
157 | #define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \ | 157 | #define IVTV_CAP_DECODER (V4L2_CAP_VIDEO_OUTPUT | \ |
158 | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY) | 158 | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY) |
159 | 159 | ||
160 | struct ivtv_card_video_input { | 160 | struct ivtv_card_video_input { |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 4afc7ea07e86..aeaa13f6cb36 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"); |
@@ -655,9 +655,9 @@ done: | |||
655 | 655 | ||
656 | if (itv->card == NULL) { | 656 | if (itv->card == NULL) { |
657 | itv->card = ivtv_get_card(IVTV_CARD_PVR_150); | 657 | itv->card = ivtv_get_card(IVTV_CARD_PVR_150); |
658 | IVTV_ERR("Unknown card: vendor/device: %04x/%04x\n", | 658 | IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n", |
659 | itv->dev->vendor, itv->dev->device); | 659 | itv->dev->vendor, itv->dev->device); |
660 | IVTV_ERR(" subsystem vendor/device: %04x/%04x\n", | 660 | IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n", |
661 | itv->dev->subsystem_vendor, itv->dev->subsystem_device); | 661 | itv->dev->subsystem_vendor, itv->dev->subsystem_device); |
662 | IVTV_ERR(" %s based\n", chipname); | 662 | IVTV_ERR(" %s based\n", chipname); |
663 | IVTV_ERR("Defaulting to %s card\n", itv->card->name); | 663 | IVTV_ERR("Defaulting to %s card\n", itv->card->name); |
@@ -720,7 +720,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) | |||
720 | itv->speed = 1000; | 720 | itv->speed = 1000; |
721 | 721 | ||
722 | /* VBI */ | 722 | /* VBI */ |
723 | itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; | 723 | itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; |
724 | itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced; | 724 | itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced; |
725 | 725 | ||
726 | /* Init the sg table for osd/yuv output */ | 726 | /* Init the sg table for osd/yuv output */ |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 2ceb5227637c..bc29436e8a3c 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <linux/i2c-algo-bit.h> | 49 | #include <linux/i2c-algo-bit.h> |
50 | #include <linux/list.h> | 50 | #include <linux/list.h> |
51 | #include <linux/unistd.h> | 51 | #include <linux/unistd.h> |
52 | #include <linux/byteorder/swab.h> | ||
53 | #include <linux/pagemap.h> | 52 | #include <linux/pagemap.h> |
54 | #include <linux/scatterlist.h> | 53 | #include <linux/scatterlist.h> |
55 | #include <linux/workqueue.h> | 54 | #include <linux/workqueue.h> |
@@ -507,6 +506,8 @@ struct yuv_playback_info | |||
507 | struct v4l2_rect main_rect; | 506 | struct v4l2_rect main_rect; |
508 | u32 v4l2_src_w; | 507 | u32 v4l2_src_w; |
509 | u32 v4l2_src_h; | 508 | u32 v4l2_src_h; |
509 | |||
510 | u8 running; /* Have any frames been displayed */ | ||
510 | }; | 511 | }; |
511 | 512 | ||
512 | #define IVTV_VBI_FRAMES 32 | 513 | #define IVTV_VBI_FRAMES 32 |
@@ -751,6 +752,12 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv); | |||
751 | /* First-open initialization: load firmware, init cx25840, etc. */ | 752 | /* First-open initialization: load firmware, init cx25840, etc. */ |
752 | int ivtv_init_on_first_open(struct ivtv *itv); | 753 | int ivtv_init_on_first_open(struct ivtv *itv); |
753 | 754 | ||
755 | /* Test if the current VBI mode is raw (1) or sliced (0) */ | ||
756 | static inline int ivtv_raw_vbi(const struct ivtv *itv) | ||
757 | { | ||
758 | return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE; | ||
759 | } | ||
760 | |||
754 | /* This is a PCI post thing, where if the pci register is not read, then | 761 | /* This is a PCI post thing, where if the pci register is not read, then |
755 | the write doesn't always take effect right away. By reading back the | 762 | the write doesn't always take effect right away. By reading back the |
756 | register any pending PCI writes will be performed (in order), and so | 763 | register any pending PCI writes will be performed (in order), and so |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 7ec5c99f9ad1..b7457fc60ba5 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -39,7 +39,7 @@ | |||
39 | associated VBI streams are also automatically claimed. | 39 | associated VBI streams are also automatically claimed. |
40 | Possible error returns: -EBUSY if someone else has claimed | 40 | Possible error returns: -EBUSY if someone else has claimed |
41 | the stream or 0 on success. */ | 41 | the stream or 0 on success. */ |
42 | int ivtv_claim_stream(struct ivtv_open_id *id, int type) | 42 | static int ivtv_claim_stream(struct ivtv_open_id *id, int type) |
43 | { | 43 | { |
44 | struct ivtv *itv = id->itv; | 44 | struct ivtv *itv = id->itv; |
45 | struct ivtv_stream *s = &itv->streams[type]; | 45 | struct ivtv_stream *s = &itv->streams[type]; |
@@ -78,7 +78,7 @@ int ivtv_claim_stream(struct ivtv_open_id *id, int type) | |||
78 | if (type == IVTV_DEC_STREAM_TYPE_MPG) { | 78 | if (type == IVTV_DEC_STREAM_TYPE_MPG) { |
79 | vbi_type = IVTV_DEC_STREAM_TYPE_VBI; | 79 | vbi_type = IVTV_DEC_STREAM_TYPE_VBI; |
80 | } else if (type == IVTV_ENC_STREAM_TYPE_MPG && | 80 | } else if (type == IVTV_ENC_STREAM_TYPE_MPG && |
81 | itv->vbi.insert_mpeg && itv->vbi.sliced_in->service_set) { | 81 | itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) { |
82 | vbi_type = IVTV_ENC_STREAM_TYPE_VBI; | 82 | vbi_type = IVTV_ENC_STREAM_TYPE_VBI; |
83 | } else { | 83 | } else { |
84 | return 0; | 84 | return 0; |
@@ -305,7 +305,7 @@ static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *b | |||
305 | 305 | ||
306 | if (len > ucount) len = ucount; | 306 | if (len > ucount) len = ucount; |
307 | if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG && | 307 | if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG && |
308 | itv->vbi.sliced_in->service_set && buf != &itv->vbi.sliced_mpeg_buf) { | 308 | !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) { |
309 | const char *start = buf->buf + buf->readpos; | 309 | const char *start = buf->buf + buf->readpos; |
310 | const char *p = start + 1; | 310 | const char *p = start + 1; |
311 | const u8 *q; | 311 | const u8 *q; |
@@ -372,7 +372,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co | |||
372 | /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should | 372 | /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should |
373 | arrive one-by-one, so make sure we never output more than one VBI frame at a time */ | 373 | arrive one-by-one, so make sure we never output more than one VBI frame at a time */ |
374 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI || | 374 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI || |
375 | (s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set)) | 375 | (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv))) |
376 | single_frame = 1; | 376 | single_frame = 1; |
377 | 377 | ||
378 | for (;;) { | 378 | for (;;) { |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.h b/drivers/media/video/ivtv/ivtv-fileops.h index 2c8d5186c9c3..df81e790147f 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.h +++ b/drivers/media/video/ivtv/ivtv-fileops.h | |||
@@ -38,11 +38,6 @@ void ivtv_unmute(struct ivtv *itv); | |||
38 | 38 | ||
39 | /* Utilities */ | 39 | /* Utilities */ |
40 | 40 | ||
41 | /* Try to claim a stream for the filehandle. Return 0 on success, | ||
42 | -EBUSY if stream already claimed. Once a stream is claimed, it | ||
43 | remains claimed until the associated filehandle is closed. */ | ||
44 | int ivtv_claim_stream(struct ivtv_open_id *id, int type); | ||
45 | |||
46 | /* Release a previously claimed stream. */ | 41 | /* Release a previously claimed stream. */ |
47 | void ivtv_release_stream(struct ivtv_stream *s); | 42 | void ivtv_release_stream(struct ivtv_stream *s); |
48 | 43 | ||
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c index bc22905ea20f..74a44844ccaf 100644 --- a/drivers/media/video/ivtv/ivtv-gpio.c +++ b/drivers/media/video/ivtv/ivtv-gpio.c | |||
@@ -124,7 +124,7 @@ void ivtv_reset_ir_gpio(struct ivtv *itv) | |||
124 | } | 124 | } |
125 | 125 | ||
126 | /* Xceive tuner reset function */ | 126 | /* Xceive tuner reset function */ |
127 | int ivtv_reset_tuner_gpio(void *dev, int cmd, int value) | 127 | int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value) |
128 | { | 128 | { |
129 | struct i2c_algo_bit_data *algo = dev; | 129 | struct i2c_algo_bit_data *algo = dev; |
130 | struct ivtv *itv = algo->data; | 130 | struct ivtv *itv = algo->data; |
diff --git a/drivers/media/video/ivtv/ivtv-gpio.h b/drivers/media/video/ivtv/ivtv-gpio.h index 964a265d91a9..48b6291613a2 100644 --- a/drivers/media/video/ivtv/ivtv-gpio.h +++ b/drivers/media/video/ivtv/ivtv-gpio.h | |||
@@ -24,7 +24,7 @@ | |||
24 | /* GPIO stuff */ | 24 | /* GPIO stuff */ |
25 | void ivtv_gpio_init(struct ivtv *itv); | 25 | void ivtv_gpio_init(struct ivtv *itv); |
26 | void ivtv_reset_ir_gpio(struct ivtv *itv); | 26 | void ivtv_reset_ir_gpio(struct ivtv *itv); |
27 | int ivtv_reset_tuner_gpio(void *dev, int cmd, int value); | 27 | int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value); |
28 | int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg); | 28 | int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg); |
29 | 29 | ||
30 | #endif | 30 | #endif |
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index af154238fb9a..24700c211d52 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c | |||
@@ -64,8 +64,6 @@ | |||
64 | #include "ivtv-gpio.h" | 64 | #include "ivtv-gpio.h" |
65 | #include "ivtv-i2c.h" | 65 | #include "ivtv-i2c.h" |
66 | 66 | ||
67 | #include <media/ir-kbd-i2c.h> | ||
68 | |||
69 | /* i2c implementation for cx23415/6 chip, ivtv project. | 67 | /* i2c implementation for cx23415/6 chip, ivtv project. |
70 | * Author: Kevin Thayer (nufan_wfk at yahoo.com) | 68 | * Author: Kevin Thayer (nufan_wfk at yahoo.com) |
71 | */ | 69 | */ |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 61030309d0ad..8696527ab134 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -101,18 +101,15 @@ void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) | |||
101 | } | 101 | } |
102 | } | 102 | } |
103 | 103 | ||
104 | static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) | 104 | static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) |
105 | { | 105 | { |
106 | int f, l; | 106 | int f, l; |
107 | u16 set = 0; | ||
108 | 107 | ||
109 | for (f = 0; f < 2; f++) { | 108 | for (f = 0; f < 2; f++) { |
110 | for (l = 0; l < 24; l++) { | 109 | for (l = 0; l < 24; l++) { |
111 | fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal); | 110 | fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal); |
112 | set |= fmt->service_lines[f][l]; | ||
113 | } | 111 | } |
114 | } | 112 | } |
115 | return set != 0; | ||
116 | } | 113 | } |
117 | 114 | ||
118 | u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt) | 115 | u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt) |
@@ -474,7 +471,7 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format | |||
474 | int h = fmt->fmt.pix.height; | 471 | int h = fmt->fmt.pix.height; |
475 | 472 | ||
476 | w = min(w, 720); | 473 | w = min(w, 720); |
477 | w = max(w, 1); | 474 | w = max(w, 2); |
478 | h = min(h, itv->is_50hz ? 576 : 480); | 475 | h = min(h, itv->is_50hz ? 576 : 480); |
479 | h = max(h, 2); | 476 | h = max(h, 2); |
480 | ivtv_g_fmt_vid_cap(file, fh, fmt); | 477 | ivtv_g_fmt_vid_cap(file, fh, fmt); |
@@ -512,27 +509,20 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_ | |||
512 | static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) | 509 | static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) |
513 | { | 510 | { |
514 | struct ivtv_open_id *id = fh; | 511 | struct ivtv_open_id *id = fh; |
515 | s32 w, h; | 512 | struct ivtv *itv = id->itv; |
516 | int field; | 513 | s32 w = fmt->fmt.pix.width; |
517 | int ret; | 514 | s32 h = fmt->fmt.pix.height; |
515 | int field = fmt->fmt.pix.field; | ||
516 | int ret = ivtv_g_fmt_vid_out(file, fh, fmt); | ||
518 | 517 | ||
519 | w = fmt->fmt.pix.width; | 518 | w = min(w, 720); |
520 | h = fmt->fmt.pix.height; | 519 | w = max(w, 2); |
521 | field = fmt->fmt.pix.field; | 520 | h = min(h, itv->is_out_50hz ? 576 : 480); |
522 | ret = ivtv_g_fmt_vid_out(file, fh, fmt); | 521 | h = max(h, 2); |
522 | if (id->type == IVTV_DEC_STREAM_TYPE_YUV) | ||
523 | fmt->fmt.pix.field = field; | ||
523 | fmt->fmt.pix.width = w; | 524 | fmt->fmt.pix.width = w; |
524 | fmt->fmt.pix.height = h; | 525 | fmt->fmt.pix.height = h; |
525 | if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) { | ||
526 | fmt->fmt.pix.field = field; | ||
527 | if (fmt->fmt.pix.width < 2) | ||
528 | fmt->fmt.pix.width = 2; | ||
529 | if (fmt->fmt.pix.width > 720) | ||
530 | fmt->fmt.pix.width = 720; | ||
531 | if (fmt->fmt.pix.height < 2) | ||
532 | fmt->fmt.pix.height = 2; | ||
533 | if (fmt->fmt.pix.height > 576) | ||
534 | fmt->fmt.pix.height = 576; | ||
535 | } | ||
536 | return ret; | 526 | return ret; |
537 | } | 527 | } |
538 | 528 | ||
@@ -560,9 +550,9 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f | |||
560 | struct ivtv_open_id *id = fh; | 550 | struct ivtv_open_id *id = fh; |
561 | struct ivtv *itv = id->itv; | 551 | struct ivtv *itv = id->itv; |
562 | struct cx2341x_mpeg_params *p = &itv->params; | 552 | struct cx2341x_mpeg_params *p = &itv->params; |
553 | int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); | ||
563 | int w = fmt->fmt.pix.width; | 554 | int w = fmt->fmt.pix.width; |
564 | int h = fmt->fmt.pix.height; | 555 | int h = fmt->fmt.pix.height; |
565 | int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); | ||
566 | 556 | ||
567 | if (ret) | 557 | if (ret) |
568 | return ret; | 558 | return ret; |
@@ -585,8 +575,11 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f | |||
585 | { | 575 | { |
586 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | 576 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
587 | 577 | ||
578 | if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) | ||
579 | return -EBUSY; | ||
588 | itv->vbi.sliced_in->service_set = 0; | 580 | itv->vbi.sliced_in->service_set = 0; |
589 | itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); | 581 | itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; |
582 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); | ||
590 | return ivtv_g_fmt_vbi_cap(file, fh, fmt); | 583 | return ivtv_g_fmt_vbi_cap(file, fh, fmt); |
591 | } | 584 | } |
592 | 585 | ||
@@ -600,10 +593,10 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo | |||
600 | if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI) | 593 | if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI) |
601 | return ret; | 594 | return ret; |
602 | 595 | ||
603 | if (check_service_set(vbifmt, itv->is_50hz) == 0) | 596 | check_service_set(vbifmt, itv->is_50hz); |
604 | return -EINVAL; | 597 | if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) |
605 | if (atomic_read(&itv->capturing) > 0) | ||
606 | return -EBUSY; | 598 | return -EBUSY; |
599 | itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; | ||
607 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); | 600 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); |
608 | memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); | 601 | memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); |
609 | return 0; | 602 | return 0; |
@@ -651,8 +644,6 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f | |||
651 | itv->dma_data_req_size = | 644 | itv->dma_data_req_size = |
652 | 1080 * ((yi->v4l2_src_h + 31) & ~31); | 645 | 1080 * ((yi->v4l2_src_h + 31) & ~31); |
653 | 646 | ||
654 | /* Force update of yuv registers */ | ||
655 | yi->yuv_forced_update = 1; | ||
656 | return 0; | 647 | return 0; |
657 | } | 648 | } |
658 | 649 | ||
@@ -761,7 +752,7 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc | |||
761 | 752 | ||
762 | strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); | 753 | strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); |
763 | strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); | 754 | strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); |
764 | strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); | 755 | snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev)); |
765 | vcap->version = IVTV_DRIVER_VERSION; /* version */ | 756 | vcap->version = IVTV_DRIVER_VERSION; /* version */ |
766 | vcap->capabilities = itv->v4l2_cap; /* capabilities */ | 757 | vcap->capabilities = itv->v4l2_cap; /* capabilities */ |
767 | return 0; | 758 | return 0; |
@@ -1370,6 +1361,9 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | |||
1370 | if (itv->osd_global_alpha_state) | 1361 | if (itv->osd_global_alpha_state) |
1371 | fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; | 1362 | fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; |
1372 | 1363 | ||
1364 | if (yi->track_osd) | ||
1365 | fb->flags |= V4L2_FBUF_FLAG_OVERLAY; | ||
1366 | |||
1373 | pixfmt &= 7; | 1367 | pixfmt &= 7; |
1374 | 1368 | ||
1375 | /* no local alpha for RGB565 or unknown formats */ | 1369 | /* no local alpha for RGB565 or unknown formats */ |
@@ -1389,8 +1383,6 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | |||
1389 | else | 1383 | else |
1390 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; | 1384 | fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; |
1391 | } | 1385 | } |
1392 | if (yi->track_osd) | ||
1393 | fb->flags |= V4L2_FBUF_FLAG_OVERLAY; | ||
1394 | 1386 | ||
1395 | return 0; | 1387 | return 0; |
1396 | } | 1388 | } |
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 34f3ab827858..f5d00ec5da73 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c | |||
@@ -753,7 +753,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) | |||
753 | */ | 753 | */ |
754 | unsigned int frame = read_reg(0x28c0) & 1; | 754 | unsigned int frame = read_reg(0x28c0) & 1; |
755 | struct yuv_playback_info *yi = &itv->yuv_info; | 755 | struct yuv_playback_info *yi = &itv->yuv_info; |
756 | int last_dma_frame = atomic_read(&itv->yuv_info.next_dma_frame); | 756 | int last_dma_frame = atomic_read(&yi->next_dma_frame); |
757 | struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame]; | 757 | struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame]; |
758 | 758 | ||
759 | if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n"); | 759 | if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n"); |
@@ -772,6 +772,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) | |||
772 | next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS; | 772 | next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS; |
773 | atomic_set(&yi->next_dma_frame, next_dma_frame); | 773 | atomic_set(&yi->next_dma_frame, next_dma_frame); |
774 | yi->fields_lapsed = -1; | 774 | yi->fields_lapsed = -1; |
775 | yi->running = 1; | ||
775 | } | 776 | } |
776 | } | 777 | } |
777 | } | 778 | } |
@@ -804,9 +805,11 @@ static void ivtv_irq_vsync(struct ivtv *itv) | |||
804 | } | 805 | } |
805 | 806 | ||
806 | /* Check if we need to update the yuv registers */ | 807 | /* Check if we need to update the yuv registers */ |
807 | if ((yi->yuv_forced_update || f->update) && last_dma_frame != -1) { | 808 | if (yi->running && (yi->yuv_forced_update || f->update)) { |
808 | if (!f->update) { | 809 | if (!f->update) { |
809 | last_dma_frame = (u8)(last_dma_frame - 1) % IVTV_YUV_BUFFERS; | 810 | last_dma_frame = |
811 | (u8)(atomic_read(&yi->next_dma_frame) - | ||
812 | 1) % IVTV_YUV_BUFFERS; | ||
810 | f = &yi->new_frame_info[last_dma_frame]; | 813 | f = &yi->new_frame_info[last_dma_frame]; |
811 | } | 814 | } |
812 | 815 | ||
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 730e85d86fc8..5bbf31e39304 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; |
@@ -330,7 +334,7 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister) | |||
330 | 334 | ||
331 | static void ivtv_vbi_setup(struct ivtv *itv) | 335 | static void ivtv_vbi_setup(struct ivtv *itv) |
332 | { | 336 | { |
333 | int raw = itv->vbi.sliced_in->service_set == 0; | 337 | int raw = ivtv_raw_vbi(itv); |
334 | u32 data[CX2341X_MBOX_MAX_DATA]; | 338 | u32 data[CX2341X_MBOX_MAX_DATA]; |
335 | int lines; | 339 | int lines; |
336 | int i; | 340 | int i; |
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c index 1ce9deb1104f..4a37a7d2e69d 100644 --- a/drivers/media/video/ivtv/ivtv-vbi.c +++ b/drivers/media/video/ivtv/ivtv-vbi.c | |||
@@ -334,7 +334,7 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, | |||
334 | int y; | 334 | int y; |
335 | 335 | ||
336 | /* Raw VBI data */ | 336 | /* Raw VBI data */ |
337 | if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) { | 337 | if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) { |
338 | u8 type; | 338 | u8 type; |
339 | 339 | ||
340 | ivtv_buf_swap(buf); | 340 | ivtv_buf_swap(buf); |
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index 3092ff1d00a0..ee91107376c7 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c | |||
@@ -1147,6 +1147,7 @@ void ivtv_yuv_close(struct ivtv *itv) | |||
1147 | IVTV_DEBUG_YUV("ivtv_yuv_close\n"); | 1147 | IVTV_DEBUG_YUV("ivtv_yuv_close\n"); |
1148 | ivtv_waitq(&itv->vsync_waitq); | 1148 | ivtv_waitq(&itv->vsync_waitq); |
1149 | 1149 | ||
1150 | yi->running = 0; | ||
1150 | atomic_set(&yi->next_dma_frame, -1); | 1151 | atomic_set(&yi->next_dma_frame, -1); |
1151 | atomic_set(&yi->next_fill_frame, 0); | 1152 | atomic_set(&yi->next_fill_frame, 0); |
1152 | 1153 | ||
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index bdfda48e56bf..8a4a150b12fb 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c | |||
@@ -275,7 +275,6 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, | |||
275 | int size_in_bytes) | 275 | int size_in_bytes) |
276 | { | 276 | { |
277 | DEFINE_WAIT(wait); | 277 | DEFINE_WAIT(wait); |
278 | int ret = 0; | ||
279 | int got_sig = 0; | 278 | int got_sig = 0; |
280 | 279 | ||
281 | mutex_lock(&itv->udma.lock); | 280 | mutex_lock(&itv->udma.lock); |
@@ -316,7 +315,7 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, | |||
316 | return -EINTR; | 315 | return -EINTR; |
317 | } | 316 | } |
318 | 317 | ||
319 | return ret; | 318 | return 0; |
320 | } | 319 | } |
321 | 320 | ||
322 | static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, | 321 | static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, |
@@ -368,11 +367,12 @@ static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, | |||
368 | } | 367 | } |
369 | 368 | ||
370 | static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, | 369 | static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, |
371 | size_t count, loff_t *ppos) | 370 | size_t count, loff_t *ppos) |
372 | { | 371 | { |
373 | unsigned long p = *ppos; | 372 | unsigned long p = *ppos; |
374 | void *dst; | 373 | void *dst; |
375 | int err = 0; | 374 | int err = 0; |
375 | int dma_err; | ||
376 | unsigned long total_size; | 376 | unsigned long total_size; |
377 | struct ivtv *itv = (struct ivtv *) info->par; | 377 | struct ivtv *itv = (struct ivtv *) info->par; |
378 | unsigned long dma_offset = | 378 | unsigned long dma_offset = |
@@ -399,7 +399,6 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, | |||
399 | if (count + p > total_size) { | 399 | if (count + p > total_size) { |
400 | if (!err) | 400 | if (!err) |
401 | err = -ENOSPC; | 401 | err = -ENOSPC; |
402 | |||
403 | count = total_size - p; | 402 | count = total_size - p; |
404 | } | 403 | } |
405 | 404 | ||
@@ -408,39 +407,34 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, | |||
408 | if (info->fbops->fb_sync) | 407 | if (info->fbops->fb_sync) |
409 | info->fbops->fb_sync(info); | 408 | info->fbops->fb_sync(info); |
410 | 409 | ||
411 | if (!access_ok(VERIFY_READ, buf, count)) { | 410 | /* If transfer size > threshold and both src/dst |
412 | IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n", | 411 | addresses are aligned, use DMA */ |
413 | (unsigned long)buf); | 412 | if (count >= 4096 && |
414 | err = -EFAULT; | 413 | ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { |
415 | } | 414 | /* Odd address = can't DMA. Align */ |
416 | 415 | if ((unsigned long)dst & 3) { | |
417 | if (!err) { | 416 | lead = 4 - ((unsigned long)dst & 3); |
418 | /* If transfer size > threshold and both src/dst | 417 | if (copy_from_user(dst, buf, lead)) |
419 | addresses are aligned, use DMA */ | 418 | return -EFAULT; |
420 | if (count >= 4096 && | 419 | buf += lead; |
421 | ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { | 420 | dst += lead; |
422 | /* Odd address = can't DMA. Align */ | ||
423 | if ((unsigned long)dst & 3) { | ||
424 | lead = 4 - ((unsigned long)dst & 3); | ||
425 | memcpy(dst, buf, lead); | ||
426 | buf += lead; | ||
427 | dst += lead; | ||
428 | } | ||
429 | /* DMA resolution is 32 bits */ | ||
430 | if ((count - lead) & 3) | ||
431 | tail = (count - lead) & 3; | ||
432 | /* DMA the data */ | ||
433 | dma_size = count - lead - tail; | ||
434 | err = ivtvfb_prep_dec_dma_to_device(itv, | ||
435 | p + lead + dma_offset, (void *)buf, dma_size); | ||
436 | dst += dma_size; | ||
437 | buf += dma_size; | ||
438 | /* Copy any leftover data */ | ||
439 | if (tail) | ||
440 | memcpy(dst, buf, tail); | ||
441 | } else { | ||
442 | memcpy(dst, buf, count); | ||
443 | } | 421 | } |
422 | /* DMA resolution is 32 bits */ | ||
423 | if ((count - lead) & 3) | ||
424 | tail = (count - lead) & 3; | ||
425 | /* DMA the data */ | ||
426 | dma_size = count - lead - tail; | ||
427 | dma_err = ivtvfb_prep_dec_dma_to_device(itv, | ||
428 | p + lead + dma_offset, (void __user *)buf, dma_size); | ||
429 | if (dma_err) | ||
430 | return dma_err; | ||
431 | dst += dma_size; | ||
432 | buf += dma_size; | ||
433 | /* Copy any leftover data */ | ||
434 | if (tail && copy_from_user(dst, buf, tail)) | ||
435 | return -EFAULT; | ||
436 | } else if (copy_from_user(dst, buf, count)) { | ||
437 | return -EFAULT; | ||
444 | } | 438 | } |
445 | 439 | ||
446 | if (!err) | 440 | if (!err) |
@@ -463,9 +457,12 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar | |||
463 | vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | | 457 | vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | |
464 | FB_VBLANK_HAVE_VSYNC; | 458 | FB_VBLANK_HAVE_VSYNC; |
465 | trace = read_reg(0x028c0) >> 16; | 459 | trace = read_reg(0x028c0) >> 16; |
466 | if (itv->is_50hz && trace > 312) trace -= 312; | 460 | if (itv->is_50hz && trace > 312) |
467 | else if (itv->is_60hz && trace > 262) trace -= 262; | 461 | trace -= 312; |
468 | if (trace == 1) vblank.flags |= FB_VBLANK_VSYNCING; | 462 | else if (itv->is_60hz && trace > 262) |
463 | trace -= 262; | ||
464 | if (trace == 1) | ||
465 | vblank.flags |= FB_VBLANK_VSYNCING; | ||
469 | vblank.count = itv->last_vsync_field; | 466 | vblank.count = itv->last_vsync_field; |
470 | vblank.vcount = trace; | 467 | vblank.vcount = trace; |
471 | vblank.hcount = 0; | 468 | vblank.hcount = 0; |
@@ -476,7 +473,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar | |||
476 | 473 | ||
477 | case FBIO_WAITFORVSYNC: | 474 | case FBIO_WAITFORVSYNC: |
478 | prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); | 475 | prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); |
479 | if (!schedule_timeout(msecs_to_jiffies(50))) rc = -ETIMEDOUT; | 476 | if (!schedule_timeout(msecs_to_jiffies(50))) |
477 | rc = -ETIMEDOUT; | ||
480 | finish_wait(&itv->vsync_waitq, &wait); | 478 | finish_wait(&itv->vsync_waitq, &wait); |
481 | return rc; | 479 | return rc; |
482 | 480 | ||