diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-mailbox.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-mailbox.c | 58 |
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 | ||
134 | static 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 | |||
134 | static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) | 160 | static 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) |