aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-mailbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx18/cx18-mailbox.c')
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 4a1249a7d46a..f231dd09c720 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -131,13 +131,39 @@ static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
131 * Functions that run in a work_queue work handling context 131 * Functions that run in a work_queue work handling context
132 */ 132 */
133 133
134static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl)
135{
136 struct cx18_buffer *buf;
137
138 if (!s->dvb.enabled || mdl->bytesused == 0)
139 return;
140
141 /* We ignore mdl and buf readpos accounting here - it doesn't matter */
142
143 /* The likely case */
144 if (list_is_singular(&mdl->buf_list)) {
145 buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
146 list);
147 if (buf->bytesused)
148 dvb_dmx_swfilter(&s->dvb.demux,
149 buf->buf, buf->bytesused);
150 return;
151 }
152
153 list_for_each_entry(buf, &mdl->buf_list, list) {
154 if (buf->bytesused == 0)
155 break;
156 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused);
157 }
158}
159
134static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) 160static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
135{ 161{
136 u32 handle, mdl_ack_count, id; 162 u32 handle, mdl_ack_count, id;
137 struct cx18_mailbox *mb; 163 struct cx18_mailbox *mb;
138 struct cx18_mdl_ack *mdl_ack; 164 struct cx18_mdl_ack *mdl_ack;
139 struct cx18_stream *s; 165 struct cx18_stream *s;
140 struct cx18_buffer *buf; 166 struct cx18_mdl *mdl;
141 int i; 167 int i;
142 168
143 mb = &order->mb; 169 mb = &order->mb;
@@ -158,7 +184,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
158 id = mdl_ack->id; 184 id = mdl_ack->id;
159 /* 185 /*
160 * Simple integrity check for processing a stale (and possibly 186 * Simple integrity check for processing a stale (and possibly
161 * inconsistent mailbox): make sure the buffer id is in the 187 * inconsistent mailbox): make sure the MDL id is in the
162 * valid range for the stream. 188 * valid range for the stream.
163 * 189 *
164 * We go through the trouble of dealing with stale mailboxes 190 * We go through the trouble of dealing with stale mailboxes
@@ -169,44 +195,42 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order)
169 * There are occasions when we get a half changed mailbox, 195 * There are occasions when we get a half changed mailbox,
170 * which this check catches for a handle & id mismatch. If the 196 * which this check catches for a handle & id mismatch. If the
171 * handle and id do correspond, the worst case is that we 197 * handle and id do correspond, the worst case is that we
172 * completely lost the old buffer, but pick up the new buffer 198 * completely lost the old MDL, but pick up the new MDL
173 * early (but the new mdl_ack is guaranteed to be good in this 199 * early (but the new mdl_ack is guaranteed to be good in this
174 * case as the firmware wouldn't point us to a new mdl_ack until 200 * case as the firmware wouldn't point us to a new mdl_ack until
175 * it's filled in). 201 * it's filled in).
176 * 202 *
177 * cx18_queue_get buf() will detect the lost buffers 203 * cx18_queue_get_mdl() will detect the lost MDLs
178 * and send them back to q_free for fw rotation eventually. 204 * and send them back to q_free for fw rotation eventually.
179 */ 205 */
180 if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) && 206 if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
181 !(id >= s->mdl_base_idx && 207 !(id >= s->mdl_base_idx &&
182 id < (s->mdl_base_idx + s->buffers))) { 208 id < (s->mdl_base_idx + s->buffers))) {
183 CX18_WARN("Fell behind! Ignoring stale mailbox with " 209 CX18_WARN("Fell behind! Ignoring stale mailbox with "
184 " inconsistent data. Lost buffer for mailbox " 210 " inconsistent data. Lost MDL for mailbox "
185 "seq no %d\n", mb->request); 211 "seq no %d\n", mb->request);
186 break; 212 break;
187 } 213 }
188 buf = cx18_queue_get_buf(s, id, mdl_ack->data_used); 214 mdl = cx18_queue_get_mdl(s, id, mdl_ack->data_used);
189 215
190 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); 216 CX18_DEBUG_HI_DMA("DMA DONE for %s (MDL %d)\n", s->name, id);
191 if (buf == NULL) { 217 if (mdl == NULL) {
192 CX18_WARN("Could not find buf %d for stream %s\n", 218 CX18_WARN("Could not find MDL %d for stream %s\n",
193 id, s->name); 219 id, s->name);
194 continue; 220 continue;
195 } 221 }
196 222
197 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n", 223 CX18_DEBUG_HI_DMA("%s recv bytesused = %d\n",
198 s->name, buf->bytesused); 224 s->name, mdl->bytesused);
199 225
200 if (s->type != CX18_ENC_STREAM_TYPE_TS) 226 if (s->type != CX18_ENC_STREAM_TYPE_TS)
201 cx18_enqueue(s, buf, &s->q_full); 227 cx18_enqueue(s, mdl, &s->q_full);
202 else { 228 else {
203 if (s->dvb.enabled) 229 cx18_mdl_send_to_dvb(s, mdl);
204 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, 230 cx18_enqueue(s, mdl, &s->q_free);
205 buf->bytesused);
206 cx18_enqueue(s, buf, &s->q_free);
207 } 231 }
208 } 232 }
209 /* Put as many buffers as possible back into fw use */ 233 /* Put as many MDLs as possible back into fw use */
210 cx18_stream_load_fw_queue(s); 234 cx18_stream_load_fw_queue(s);
211 235
212 wake_up(&cx->dma_waitq); 236 wake_up(&cx->dma_waitq);
@@ -616,7 +640,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
616 640
617 /* 641 /*
618 * Wait for XPU to perform extra actions for the caller in some cases. 642 * Wait for XPU to perform extra actions for the caller in some cases.
619 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all buffers 643 * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all MDLs
620 * back in a burst shortly thereafter 644 * back in a burst shortly thereafter
621 */ 645 */
622 if (info->flags & API_SLOW) 646 if (info->flags & API_SLOW)