diff options
-rw-r--r-- | drivers/media/dvb/dvb-core/dmxdev.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_ca_en50221.c | 8 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_ringbuffer.c | 78 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_ringbuffer.h | 12 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110_av.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110_ca.c | 2 |
7 files changed, 69 insertions, 37 deletions
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index df5bef6a2517..1cf9fcb6f514 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c | |||
@@ -96,7 +96,7 @@ static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src, | |||
96 | if (avail > todo) | 96 | if (avail > todo) |
97 | avail = todo; | 97 | avail = todo; |
98 | 98 | ||
99 | ret = dvb_ringbuffer_read(src, (u8 *)buf, avail, 1); | 99 | ret = dvb_ringbuffer_read_user(src, buf, avail); |
100 | if (ret < 0) | 100 | if (ret < 0) |
101 | break; | 101 | break; |
102 | 102 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 588fbe105c27..8e5dd7b1f034 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c | |||
@@ -1357,7 +1357,7 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, | |||
1357 | 1357 | ||
1358 | idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen); | 1358 | idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen); |
1359 | while (idx != -1) { | 1359 | while (idx != -1) { |
1360 | dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0); | 1360 | dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2); |
1361 | if (connection_id == -1) | 1361 | if (connection_id == -1) |
1362 | connection_id = hdr[0]; | 1362 | connection_id = hdr[0]; |
1363 | if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) { | 1363 | if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) { |
@@ -1438,7 +1438,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, | |||
1438 | goto exit; | 1438 | goto exit; |
1439 | } | 1439 | } |
1440 | 1440 | ||
1441 | dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0); | 1441 | dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2); |
1442 | if (connection_id == -1) | 1442 | if (connection_id == -1) |
1443 | connection_id = hdr[0]; | 1443 | connection_id = hdr[0]; |
1444 | if (hdr[0] == connection_id) { | 1444 | if (hdr[0] == connection_id) { |
@@ -1449,8 +1449,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, | |||
1449 | fraglen -= 2; | 1449 | fraglen -= 2; |
1450 | } | 1450 | } |
1451 | 1451 | ||
1452 | if ((status = dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 2, | 1452 | if ((status = dvb_ringbuffer_pkt_read_user(&ca->slot_info[slot].rx_buffer, idx, 2, |
1453 | (u8 *)buf + pktlen, fraglen, 1)) < 0) { | 1453 | buf + pktlen, fraglen)) < 0) { |
1454 | goto exit; | 1454 | goto exit; |
1455 | } | 1455 | } |
1456 | pktlen += fraglen; | 1456 | pktlen += fraglen; |
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index 872985b7912d..584bbd194dc8 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c | |||
@@ -107,35 +107,43 @@ void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf) | |||
107 | wake_up(&rbuf->queue); | 107 | wake_up(&rbuf->queue); |
108 | } | 108 | } |
109 | 109 | ||
110 | 110 | ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len) | |
111 | |||
112 | ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem) | ||
113 | { | 111 | { |
114 | size_t todo = len; | 112 | size_t todo = len; |
115 | size_t split; | 113 | size_t split; |
116 | 114 | ||
117 | split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; | 115 | split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; |
118 | if (split > 0) { | 116 | if (split > 0) { |
119 | if (!usermem) | 117 | if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) |
120 | memcpy(buf, rbuf->data+rbuf->pread, split); | 118 | return -EFAULT; |
121 | else | ||
122 | if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) | ||
123 | return -EFAULT; | ||
124 | buf += split; | 119 | buf += split; |
125 | todo -= split; | 120 | todo -= split; |
126 | rbuf->pread = 0; | 121 | rbuf->pread = 0; |
127 | } | 122 | } |
128 | if (!usermem) | 123 | if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) |
129 | memcpy(buf, rbuf->data+rbuf->pread, todo); | 124 | return -EFAULT; |
130 | else | ||
131 | if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) | ||
132 | return -EFAULT; | ||
133 | 125 | ||
134 | rbuf->pread = (rbuf->pread + todo) % rbuf->size; | 126 | rbuf->pread = (rbuf->pread + todo) % rbuf->size; |
135 | 127 | ||
136 | return len; | 128 | return len; |
137 | } | 129 | } |
138 | 130 | ||
131 | void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len) | ||
132 | { | ||
133 | size_t todo = len; | ||
134 | size_t split; | ||
135 | |||
136 | split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; | ||
137 | if (split > 0) { | ||
138 | memcpy(buf, rbuf->data+rbuf->pread, split); | ||
139 | buf += split; | ||
140 | todo -= split; | ||
141 | rbuf->pread = 0; | ||
142 | } | ||
143 | memcpy(buf, rbuf->data+rbuf->pread, todo); | ||
144 | |||
145 | rbuf->pread = (rbuf->pread + todo) % rbuf->size; | ||
146 | } | ||
139 | 147 | ||
140 | 148 | ||
141 | ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len) | 149 | ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len) |
@@ -171,8 +179,8 @@ ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t le | |||
171 | return status; | 179 | return status; |
172 | } | 180 | } |
173 | 181 | ||
174 | ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | 182 | ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx, |
175 | int offset, u8* buf, size_t len, int usermem) | 183 | int offset, u8 __user *buf, size_t len) |
176 | { | 184 | { |
177 | size_t todo; | 185 | size_t todo; |
178 | size_t split; | 186 | size_t split; |
@@ -187,21 +195,40 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | |||
187 | todo = len; | 195 | todo = len; |
188 | split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; | 196 | split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; |
189 | if (split > 0) { | 197 | if (split > 0) { |
190 | if (!usermem) | 198 | if (copy_to_user(buf, rbuf->data+idx, split)) |
191 | memcpy(buf, rbuf->data+idx, split); | 199 | return -EFAULT; |
192 | else | ||
193 | if (copy_to_user(buf, rbuf->data+idx, split)) | ||
194 | return -EFAULT; | ||
195 | buf += split; | 200 | buf += split; |
196 | todo -= split; | 201 | todo -= split; |
197 | idx = 0; | 202 | idx = 0; |
198 | } | 203 | } |
199 | if (!usermem) | 204 | if (copy_to_user(buf, rbuf->data+idx, todo)) |
200 | memcpy(buf, rbuf->data+idx, todo); | 205 | return -EFAULT; |
201 | else | 206 | |
202 | if (copy_to_user(buf, rbuf->data+idx, todo)) | 207 | return len; |
203 | return -EFAULT; | 208 | } |
204 | 209 | ||
210 | ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | ||
211 | int offset, u8* buf, size_t len) | ||
212 | { | ||
213 | size_t todo; | ||
214 | size_t split; | ||
215 | size_t pktlen; | ||
216 | |||
217 | pktlen = rbuf->data[idx] << 8; | ||
218 | pktlen |= rbuf->data[(idx + 1) % rbuf->size]; | ||
219 | if (offset > pktlen) return -EINVAL; | ||
220 | if ((offset + len) > pktlen) len = pktlen - offset; | ||
221 | |||
222 | idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size; | ||
223 | todo = len; | ||
224 | split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; | ||
225 | if (split > 0) { | ||
226 | memcpy(buf, rbuf->data+idx, split); | ||
227 | buf += split; | ||
228 | todo -= split; | ||
229 | idx = 0; | ||
230 | } | ||
231 | memcpy(buf, rbuf->data+idx, todo); | ||
205 | return len; | 232 | return len; |
206 | } | 233 | } |
207 | 234 | ||
@@ -266,5 +293,6 @@ EXPORT_SYMBOL(dvb_ringbuffer_empty); | |||
266 | EXPORT_SYMBOL(dvb_ringbuffer_free); | 293 | EXPORT_SYMBOL(dvb_ringbuffer_free); |
267 | EXPORT_SYMBOL(dvb_ringbuffer_avail); | 294 | EXPORT_SYMBOL(dvb_ringbuffer_avail); |
268 | EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup); | 295 | EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup); |
296 | EXPORT_SYMBOL(dvb_ringbuffer_read_user); | ||
269 | EXPORT_SYMBOL(dvb_ringbuffer_read); | 297 | EXPORT_SYMBOL(dvb_ringbuffer_read); |
270 | EXPORT_SYMBOL(dvb_ringbuffer_write); | 298 | EXPORT_SYMBOL(dvb_ringbuffer_write); |
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h index 890826262966..41f04dae69b6 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h | |||
@@ -61,7 +61,7 @@ struct dvb_ringbuffer { | |||
61 | ** *** read min. 1000, max. <bufsize> bytes *** | 61 | ** *** read min. 1000, max. <bufsize> bytes *** |
62 | ** avail = dvb_ringbuffer_avail(rbuf); | 62 | ** avail = dvb_ringbuffer_avail(rbuf); |
63 | ** if (avail >= 1000) | 63 | ** if (avail >= 1000) |
64 | ** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize), 0); | 64 | ** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize)); |
65 | ** else | 65 | ** else |
66 | ** ... | 66 | ** ... |
67 | ** | 67 | ** |
@@ -114,8 +114,10 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); | |||
114 | ** <usermem> specifies whether <buf> resides in user space | 114 | ** <usermem> specifies whether <buf> resides in user space |
115 | ** returns number of bytes transferred or -EFAULT | 115 | ** returns number of bytes transferred or -EFAULT |
116 | */ | 116 | */ |
117 | extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, | 117 | extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, |
118 | size_t len, int usermem); | 118 | u8 __user *buf, size_t len); |
119 | extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, | ||
120 | u8 *buf, size_t len); | ||
119 | 121 | ||
120 | 122 | ||
121 | /* write routines & macros */ | 123 | /* write routines & macros */ |
@@ -157,8 +159,10 @@ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, | |||
157 | * <usermem> Set to 1 if <buf> is in userspace. | 159 | * <usermem> Set to 1 if <buf> is in userspace. |
158 | * returns Number of bytes read, or -EFAULT. | 160 | * returns Number of bytes read, or -EFAULT. |
159 | */ | 161 | */ |
162 | extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx, | ||
163 | int offset, u8 __user *buf, size_t len); | ||
160 | extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | 164 | extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, |
161 | int offset, u8* buf, size_t len, int usermem); | 165 | int offset, u8 *buf, size_t len); |
162 | 166 | ||
163 | /** | 167 | /** |
164 | * Dispose of a packet in the ring buffer. | 168 | * Dispose of a packet in the ring buffer. |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 6d7b9f6a6c75..dfe03cb42671 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -587,7 +587,7 @@ static void gpioirq(unsigned long data) | |||
587 | } | 587 | } |
588 | DVB_RINGBUFFER_SKIP(cibuf, 2); | 588 | DVB_RINGBUFFER_SKIP(cibuf, 2); |
589 | 589 | ||
590 | dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0); | 590 | dvb_ringbuffer_read(cibuf, av7110->debi_virt, len); |
591 | 591 | ||
592 | iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); | 592 | iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); |
593 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); | 593 | iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); |
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index ec55a968f204..184647ad1c7c 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -269,7 +269,7 @@ int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) | |||
269 | return -1; | 269 | return -1; |
270 | } | 270 | } |
271 | 271 | ||
272 | dvb_ringbuffer_read(buf, dest, (size_t) blen, 0); | 272 | dvb_ringbuffer_read(buf, dest, (size_t) blen); |
273 | 273 | ||
274 | dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n", | 274 | dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n", |
275 | (unsigned long) buf->pread, (unsigned long) buf->pwrite); | 275 | (unsigned long) buf->pread, (unsigned long) buf->pwrite); |
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c index c58e3fc509ed..261135ded481 100644 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ b/drivers/media/dvb/ttpci/av7110_ca.c | |||
@@ -208,7 +208,7 @@ static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, | |||
208 | return -EINVAL; | 208 | return -EINVAL; |
209 | DVB_RINGBUFFER_SKIP(cibuf, 2); | 209 | DVB_RINGBUFFER_SKIP(cibuf, 2); |
210 | 210 | ||
211 | return dvb_ringbuffer_read(cibuf, (u8 *)buf, len, 1); | 211 | return dvb_ringbuffer_read_user(cibuf, buf, len); |
212 | } | 212 | } |
213 | 213 | ||
214 | static int dvb_ca_open(struct inode *inode, struct file *file) | 214 | static int dvb_ca_open(struct inode *inode, struct file *file) |