aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c8
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.c78
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.h12
-rw-r--r--drivers/media/dvb/ttpci/av7110.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c2
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 110ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len)
111
112ssize_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
131void 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
141ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len) 149ssize_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
174ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, 182ssize_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
210ssize_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);
266EXPORT_SYMBOL(dvb_ringbuffer_free); 293EXPORT_SYMBOL(dvb_ringbuffer_free);
267EXPORT_SYMBOL(dvb_ringbuffer_avail); 294EXPORT_SYMBOL(dvb_ringbuffer_avail);
268EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup); 295EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
296EXPORT_SYMBOL(dvb_ringbuffer_read_user);
269EXPORT_SYMBOL(dvb_ringbuffer_read); 297EXPORT_SYMBOL(dvb_ringbuffer_read);
270EXPORT_SYMBOL(dvb_ringbuffer_write); 298EXPORT_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*/
117extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, 117extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf,
118 size_t len, int usermem); 118 u8 __user *buf, size_t len);
119extern 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 */
162extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
163 int offset, u8 __user *buf, size_t len);
160extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, 164extern 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
214static int dvb_ca_open(struct inode *inode, struct file *file) 214static int dvb_ca_open(struct inode *inode, struct file *file)