diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-context.c | 55 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-context.h | 5 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | 4 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-debug.h | 39 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-debugifc.c | 177 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-encoder.c | 54 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-encoder.h | 1 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 64 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 1139 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.h | 135 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 2 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 6 | ||||
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-video-v4l.c | 4 |
13 files changed, 944 insertions, 741 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c index 22719ba861ac..9d94aed2e12d 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-context.c +++ b/drivers/media/video/pvrusb2/pvrusb2-context.c | |||
@@ -31,52 +31,32 @@ | |||
31 | 31 | ||
32 | static void pvr2_context_destroy(struct pvr2_context *mp) | 32 | static void pvr2_context_destroy(struct pvr2_context *mp) |
33 | { | 33 | { |
34 | if (mp->hdw) pvr2_hdw_destroy(mp->hdw); | ||
35 | pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr_main id=%p",mp); | 34 | pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr_main id=%p",mp); |
36 | if (mp->workqueue) { | 35 | if (mp->hdw) pvr2_hdw_destroy(mp->hdw); |
37 | flush_workqueue(mp->workqueue); | ||
38 | destroy_workqueue(mp->workqueue); | ||
39 | } | ||
40 | kfree(mp); | 36 | kfree(mp); |
41 | } | 37 | } |
42 | 38 | ||
43 | 39 | ||
44 | static void pvr2_context_trigger_poll(struct pvr2_context *mp) | 40 | static void pvr2_context_state_check(struct pvr2_context *mp) |
45 | { | ||
46 | queue_work(mp->workqueue,&mp->workpoll); | ||
47 | } | ||
48 | |||
49 | |||
50 | static void pvr2_context_poll(struct work_struct *work) | ||
51 | { | ||
52 | struct pvr2_context *mp = | ||
53 | container_of(work, struct pvr2_context, workpoll); | ||
54 | pvr2_context_enter(mp); do { | ||
55 | pvr2_hdw_poll(mp->hdw); | ||
56 | } while (0); pvr2_context_exit(mp); | ||
57 | } | ||
58 | |||
59 | |||
60 | static void pvr2_context_setup(struct work_struct *work) | ||
61 | { | 41 | { |
62 | struct pvr2_context *mp = | 42 | if (mp->init_flag) return; |
63 | container_of(work, struct pvr2_context, workinit); | 43 | |
44 | switch (pvr2_hdw_get_state(mp->hdw)) { | ||
45 | case PVR2_STATE_WARM: break; | ||
46 | case PVR2_STATE_ERROR: break; | ||
47 | case PVR2_STATE_READY: break; | ||
48 | case PVR2_STATE_RUN: break; | ||
49 | default: return; | ||
50 | } | ||
64 | 51 | ||
65 | pvr2_context_enter(mp); do { | 52 | pvr2_context_enter(mp); do { |
66 | if (!pvr2_hdw_dev_ok(mp->hdw)) break; | 53 | mp->init_flag = !0; |
67 | pvr2_hdw_setup(mp->hdw); | ||
68 | pvr2_hdw_setup_poll_trigger( | ||
69 | mp->hdw, | ||
70 | (void (*)(void *))pvr2_context_trigger_poll, | ||
71 | mp); | ||
72 | if (!pvr2_hdw_dev_ok(mp->hdw)) break; | ||
73 | if (!pvr2_hdw_init_ok(mp->hdw)) break; | ||
74 | mp->video_stream.stream = pvr2_hdw_get_video_stream(mp->hdw); | 54 | mp->video_stream.stream = pvr2_hdw_get_video_stream(mp->hdw); |
75 | if (mp->setup_func) { | 55 | if (mp->setup_func) { |
76 | mp->setup_func(mp); | 56 | mp->setup_func(mp); |
77 | } | 57 | } |
78 | } while (0); pvr2_context_exit(mp); | 58 | } while (0); pvr2_context_exit(mp); |
79 | } | 59 | } |
80 | 60 | ||
81 | 61 | ||
82 | struct pvr2_context *pvr2_context_create( | 62 | struct pvr2_context *pvr2_context_create( |
@@ -96,11 +76,10 @@ struct pvr2_context *pvr2_context_create( | |||
96 | mp = NULL; | 76 | mp = NULL; |
97 | goto done; | 77 | goto done; |
98 | } | 78 | } |
99 | 79 | pvr2_hdw_set_state_callback(mp->hdw, | |
100 | mp->workqueue = create_singlethread_workqueue("pvrusb2"); | 80 | (void (*)(void *))pvr2_context_state_check, |
101 | INIT_WORK(&mp->workinit, pvr2_context_setup); | 81 | mp); |
102 | INIT_WORK(&mp->workpoll, pvr2_context_poll); | 82 | pvr2_context_state_check(mp); |
103 | queue_work(mp->workqueue,&mp->workinit); | ||
104 | done: | 83 | done: |
105 | return mp; | 84 | return mp; |
106 | } | 85 | } |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h index 6327fa1f7e4f..a04187a93225 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-context.h +++ b/drivers/media/video/pvrusb2/pvrusb2-context.h | |||
@@ -45,14 +45,11 @@ struct pvr2_context { | |||
45 | struct pvr2_context_stream video_stream; | 45 | struct pvr2_context_stream video_stream; |
46 | struct mutex mutex; | 46 | struct mutex mutex; |
47 | int disconnect_flag; | 47 | int disconnect_flag; |
48 | int init_flag; | ||
48 | 49 | ||
49 | /* Called after pvr2_context initialization is complete */ | 50 | /* Called after pvr2_context initialization is complete */ |
50 | void (*setup_func)(struct pvr2_context *); | 51 | void (*setup_func)(struct pvr2_context *); |
51 | 52 | ||
52 | /* Work queue overhead for out-of-line processing */ | ||
53 | struct workqueue_struct *workqueue; | ||
54 | struct work_struct workinit; | ||
55 | struct work_struct workpoll; | ||
56 | }; | 53 | }; |
57 | 54 | ||
58 | struct pvr2_channel { | 55 | struct pvr2_channel { |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index e8a9252c7df6..2cca817e4144 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | |||
@@ -140,7 +140,7 @@ static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = { | |||
140 | static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt) | 140 | static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt) |
141 | { | 141 | { |
142 | ctxt->client->handler = NULL; | 142 | ctxt->client->handler = NULL; |
143 | ctxt->hdw->decoder_ctrl = NULL; | 143 | pvr2_hdw_set_decoder(ctxt->hdw,NULL); |
144 | kfree(ctxt); | 144 | kfree(ctxt); |
145 | } | 145 | } |
146 | 146 | ||
@@ -241,7 +241,7 @@ int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw, | |||
241 | ctxt->client = cp; | 241 | ctxt->client = cp; |
242 | ctxt->hdw = hdw; | 242 | ctxt->hdw = hdw; |
243 | ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1; | 243 | ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1; |
244 | hdw->decoder_ctrl = &ctxt->ctrl; | 244 | pvr2_hdw_set_decoder(hdw,&ctxt->ctrl); |
245 | cp->handler = &ctxt->handler; | 245 | cp->handler = &ctxt->handler; |
246 | { | 246 | { |
247 | /* | 247 | /* |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h index da6441b88f31..fca49d8a9311 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-debug.h +++ b/drivers/media/video/pvrusb2/pvrusb2-debug.h | |||
@@ -34,25 +34,26 @@ extern int pvrusb2_debug; | |||
34 | #define PVR2_TRACE_INIT (1 << 5) /* misc initialization steps */ | 34 | #define PVR2_TRACE_INIT (1 << 5) /* misc initialization steps */ |
35 | #define PVR2_TRACE_START_STOP (1 << 6) /* Streaming start / stop */ | 35 | #define PVR2_TRACE_START_STOP (1 << 6) /* Streaming start / stop */ |
36 | #define PVR2_TRACE_CTL (1 << 7) /* commit of control changes */ | 36 | #define PVR2_TRACE_CTL (1 << 7) /* commit of control changes */ |
37 | #define PVR2_TRACE_DEBUG (1 << 8) /* Temporary debug code */ | 37 | #define PVR2_TRACE_STATE (1 << 8) /* Device state changes */ |
38 | #define PVR2_TRACE_EEPROM (1 << 9) /* eeprom parsing / report */ | 38 | #define PVR2_TRACE_STBITS (1 << 9) /* Individual bit state changes */ |
39 | #define PVR2_TRACE_STRUCT (1 << 10) /* internal struct creation */ | 39 | #define PVR2_TRACE_EEPROM (1 << 10) /* eeprom parsing / report */ |
40 | #define PVR2_TRACE_OPEN_CLOSE (1 << 11) /* application open / close */ | 40 | #define PVR2_TRACE_STRUCT (1 << 11) /* internal struct creation */ |
41 | #define PVR2_TRACE_CREG (1 << 12) /* Main critical region entry / exit */ | 41 | #define PVR2_TRACE_OPEN_CLOSE (1 << 12) /* application open / close */ |
42 | #define PVR2_TRACE_SYSFS (1 << 13) /* Sysfs driven I/O */ | 42 | #define PVR2_TRACE_CREG (1 << 13) /* Main critical region entry / exit */ |
43 | #define PVR2_TRACE_FIRMWARE (1 << 14) /* firmware upload actions */ | 43 | #define PVR2_TRACE_SYSFS (1 << 14) /* Sysfs driven I/O */ |
44 | #define PVR2_TRACE_CHIPS (1 << 15) /* chip broadcast operation */ | 44 | #define PVR2_TRACE_FIRMWARE (1 << 15) /* firmware upload actions */ |
45 | #define PVR2_TRACE_I2C (1 << 16) /* I2C related stuff */ | 45 | #define PVR2_TRACE_CHIPS (1 << 16) /* chip broadcast operation */ |
46 | #define PVR2_TRACE_I2C_CMD (1 << 17) /* Software commands to I2C modules */ | 46 | #define PVR2_TRACE_I2C (1 << 17) /* I2C related stuff */ |
47 | #define PVR2_TRACE_I2C_CORE (1 << 18) /* I2C core debugging */ | 47 | #define PVR2_TRACE_I2C_CMD (1 << 18) /* Software commands to I2C modules */ |
48 | #define PVR2_TRACE_I2C_TRAF (1 << 19) /* I2C traffic through the adapter */ | 48 | #define PVR2_TRACE_I2C_CORE (1 << 19) /* I2C core debugging */ |
49 | #define PVR2_TRACE_V4LIOCTL (1 << 20) /* v4l ioctl details */ | 49 | #define PVR2_TRACE_I2C_TRAF (1 << 20) /* I2C traffic through the adapter */ |
50 | #define PVR2_TRACE_ENCODER (1 << 21) /* mpeg2 encoder operation */ | 50 | #define PVR2_TRACE_V4LIOCTL (1 << 21) /* v4l ioctl details */ |
51 | #define PVR2_TRACE_BUF_POOL (1 << 22) /* Track buffer pool management */ | 51 | #define PVR2_TRACE_ENCODER (1 << 22) /* mpeg2 encoder operation */ |
52 | #define PVR2_TRACE_BUF_FLOW (1 << 23) /* Track buffer flow in system */ | 52 | #define PVR2_TRACE_BUF_POOL (1 << 23) /* Track buffer pool management */ |
53 | #define PVR2_TRACE_DATA_FLOW (1 << 24) /* Track data flow */ | 53 | #define PVR2_TRACE_BUF_FLOW (1 << 24) /* Track buffer flow in system */ |
54 | #define PVR2_TRACE_DEBUGIFC (1 << 25) /* Debug interface actions */ | 54 | #define PVR2_TRACE_DATA_FLOW (1 << 25) /* Track data flow */ |
55 | #define PVR2_TRACE_GPIO (1 << 26) /* GPIO state bit changes */ | 55 | #define PVR2_TRACE_DEBUGIFC (1 << 26) /* Debug interface actions */ |
56 | #define PVR2_TRACE_GPIO (1 << 27) /* GPIO state bit changes */ | ||
56 | 57 | ||
57 | 58 | ||
58 | #endif /* __PVRUSB2_HDW_INTERNAL_H */ | 59 | #endif /* __PVRUSB2_HDW_INTERNAL_H */ |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index 6f135f4a2497..b0687430fdd4 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c | |||
@@ -31,14 +31,6 @@ struct debugifc_mask_item { | |||
31 | unsigned long msk; | 31 | unsigned long msk; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static struct debugifc_mask_item mask_items[] = { | ||
35 | {"ENC_FIRMWARE",(1<<PVR2_SUBSYS_B_ENC_FIRMWARE)}, | ||
36 | {"ENC_CFG",(1<<PVR2_SUBSYS_B_ENC_CFG)}, | ||
37 | {"DIG_RUN",(1<<PVR2_SUBSYS_B_DIGITIZER_RUN)}, | ||
38 | {"USB_RUN",(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)}, | ||
39 | {"ENC_RUN",(1<<PVR2_SUBSYS_B_ENC_RUN)}, | ||
40 | }; | ||
41 | |||
42 | 34 | ||
43 | static unsigned int debugifc_count_whitespace(const char *buf, | 35 | static unsigned int debugifc_count_whitespace(const char *buf, |
44 | unsigned int count) | 36 | unsigned int count) |
@@ -148,134 +140,14 @@ static int debugifc_match_keyword(const char *buf,unsigned int count, | |||
148 | } | 140 | } |
149 | 141 | ||
150 | 142 | ||
151 | static unsigned long debugifc_find_mask(const char *buf,unsigned int count) | ||
152 | { | ||
153 | struct debugifc_mask_item *mip; | ||
154 | unsigned int idx; | ||
155 | for (idx = 0; idx < ARRAY_SIZE(mask_items); idx++) { | ||
156 | mip = mask_items + idx; | ||
157 | if (debugifc_match_keyword(buf,count,mip->name)) { | ||
158 | return mip->msk; | ||
159 | } | ||
160 | } | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | |||
165 | static int debugifc_print_mask(char *buf,unsigned int sz, | ||
166 | unsigned long msk,unsigned long val) | ||
167 | { | ||
168 | struct debugifc_mask_item *mip; | ||
169 | unsigned int idx; | ||
170 | int bcnt = 0; | ||
171 | int ccnt; | ||
172 | for (idx = 0; idx < ARRAY_SIZE(mask_items); idx++) { | ||
173 | mip = mask_items + idx; | ||
174 | if (!(mip->msk & msk)) continue; | ||
175 | ccnt = scnprintf(buf,sz,"%s%c%s", | ||
176 | (bcnt ? " " : ""), | ||
177 | ((mip->msk & val) ? '+' : '-'), | ||
178 | mip->name); | ||
179 | sz -= ccnt; | ||
180 | buf += ccnt; | ||
181 | bcnt += ccnt; | ||
182 | } | ||
183 | return bcnt; | ||
184 | } | ||
185 | |||
186 | static unsigned int debugifc_parse_subsys_mask(const char *buf, | ||
187 | unsigned int count, | ||
188 | unsigned long *mskPtr, | ||
189 | unsigned long *valPtr) | ||
190 | { | ||
191 | const char *wptr; | ||
192 | unsigned int consume_cnt = 0; | ||
193 | unsigned int scnt; | ||
194 | unsigned int wlen; | ||
195 | int mode; | ||
196 | unsigned long m1,msk,val; | ||
197 | |||
198 | msk = 0; | ||
199 | val = 0; | ||
200 | |||
201 | while (count) { | ||
202 | scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); | ||
203 | if (!scnt) break; | ||
204 | consume_cnt += scnt; count -= scnt; buf += scnt; | ||
205 | if (!wptr) break; | ||
206 | |||
207 | mode = 0; | ||
208 | if (wlen) switch (wptr[0]) { | ||
209 | case '+': | ||
210 | wptr++; | ||
211 | wlen--; | ||
212 | break; | ||
213 | case '-': | ||
214 | mode = 1; | ||
215 | wptr++; | ||
216 | wlen--; | ||
217 | break; | ||
218 | } | ||
219 | if (!wlen) continue; | ||
220 | m1 = debugifc_find_mask(wptr,wlen); | ||
221 | if (!m1) break; | ||
222 | msk |= m1; | ||
223 | if (!mode) val |= m1; | ||
224 | } | ||
225 | *mskPtr = msk; | ||
226 | *valPtr = val; | ||
227 | return consume_cnt; | ||
228 | } | ||
229 | |||
230 | |||
231 | int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt) | 143 | int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt) |
232 | { | 144 | { |
233 | int bcnt = 0; | 145 | int bcnt = 0; |
234 | int ccnt; | 146 | int ccnt; |
235 | struct pvr2_hdw_debug_info dbg; | 147 | ccnt = scnprintf(buf,acnt,"Driver state info:\n"); |
236 | |||
237 | pvr2_hdw_get_debug_info(hdw,&dbg); | ||
238 | |||
239 | ccnt = scnprintf(buf,acnt,"big lock %s; ctl lock %s", | ||
240 | (dbg.big_lock_held ? "held" : "free"), | ||
241 | (dbg.ctl_lock_held ? "held" : "free")); | ||
242 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
243 | if (dbg.ctl_lock_held) { | ||
244 | ccnt = scnprintf(buf,acnt,"; cmd_state=%d cmd_code=%d" | ||
245 | " cmd_wlen=%d cmd_rlen=%d" | ||
246 | " wpend=%d rpend=%d tmout=%d rstatus=%d" | ||
247 | " wstatus=%d", | ||
248 | dbg.cmd_debug_state,dbg.cmd_code, | ||
249 | dbg.cmd_debug_write_len, | ||
250 | dbg.cmd_debug_read_len, | ||
251 | dbg.cmd_debug_write_pend, | ||
252 | dbg.cmd_debug_read_pend, | ||
253 | dbg.cmd_debug_timeout, | ||
254 | dbg.cmd_debug_rstatus, | ||
255 | dbg.cmd_debug_wstatus); | ||
256 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
257 | } | ||
258 | ccnt = scnprintf(buf,acnt,"\n"); | ||
259 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
260 | ccnt = scnprintf( | ||
261 | buf,acnt,"driver flags: %s %s %s\n", | ||
262 | (dbg.flag_init_ok ? "initialized" : "uninitialized"), | ||
263 | (dbg.flag_ok ? "ok" : "fail"), | ||
264 | (dbg.flag_disconnected ? "disconnected" : "connected")); | ||
265 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
266 | ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: "); | ||
267 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | 148 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; |
268 | ccnt = debugifc_print_mask(buf,acnt,dbg.subsys_flags,dbg.subsys_flags); | 149 | ccnt = pvr2_hdw_state_report(hdw,buf,acnt); |
269 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | 150 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; |
270 | ccnt = scnprintf(buf,acnt,"\n"); | ||
271 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
272 | ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: "); | ||
273 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
274 | ccnt = debugifc_print_mask(buf,acnt,~dbg.subsys_flags,dbg.subsys_flags); | ||
275 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
276 | ccnt = scnprintf(buf,acnt,"\n"); | ||
277 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
278 | |||
279 | ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n"); | 151 | ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n"); |
280 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | 152 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; |
281 | ccnt = pvr2_i2c_report(hdw,buf,acnt); | 153 | ccnt = pvr2_i2c_report(hdw,buf,acnt); |
@@ -290,7 +162,6 @@ int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, | |||
290 | { | 162 | { |
291 | int bcnt = 0; | 163 | int bcnt = 0; |
292 | int ccnt; | 164 | int ccnt; |
293 | unsigned long msk; | ||
294 | int ret; | 165 | int ret; |
295 | u32 gpio_dir,gpio_in,gpio_out; | 166 | u32 gpio_dir,gpio_in,gpio_out; |
296 | 167 | ||
@@ -311,28 +182,6 @@ int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, | |||
311 | pvr2_hdw_get_streaming(hdw) ? "on" : "off"); | 182 | pvr2_hdw_get_streaming(hdw) ? "on" : "off"); |
312 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | 183 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; |
313 | 184 | ||
314 | msk = pvr2_hdw_subsys_get(hdw); | ||
315 | ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: "); | ||
316 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
317 | ccnt = debugifc_print_mask(buf,acnt,msk,msk); | ||
318 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
319 | ccnt = scnprintf(buf,acnt,"\n"); | ||
320 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
321 | ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: "); | ||
322 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
323 | ccnt = debugifc_print_mask(buf,acnt,~msk,msk); | ||
324 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
325 | ccnt = scnprintf(buf,acnt,"\n"); | ||
326 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
327 | |||
328 | msk = pvr2_hdw_subsys_stream_get(hdw); | ||
329 | ccnt = scnprintf(buf,acnt,"Subsystems stopped on stream shutdown: "); | ||
330 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
331 | ccnt = debugifc_print_mask(buf,acnt,msk,msk); | ||
332 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
333 | ccnt = scnprintf(buf,acnt,"\n"); | ||
334 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
335 | |||
336 | return bcnt; | 185 | return bcnt; |
337 | } | 186 | } |
338 | 187 | ||
@@ -369,28 +218,10 @@ static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, | |||
369 | return pvr2_upload_firmware2(hdw); | 218 | return pvr2_upload_firmware2(hdw); |
370 | } else if (debugifc_match_keyword(wptr,wlen,"decoder")) { | 219 | } else if (debugifc_match_keyword(wptr,wlen,"decoder")) { |
371 | return pvr2_hdw_cmd_decoder_reset(hdw); | 220 | return pvr2_hdw_cmd_decoder_reset(hdw); |
221 | } else if (debugifc_match_keyword(wptr,wlen,"worker")) { | ||
222 | return pvr2_hdw_untrip(hdw); | ||
372 | } | 223 | } |
373 | return -EINVAL; | 224 | return -EINVAL; |
374 | } else if (debugifc_match_keyword(wptr,wlen,"subsys_flags")) { | ||
375 | unsigned long msk = 0; | ||
376 | unsigned long val = 0; | ||
377 | if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) { | ||
378 | pvr2_trace(PVR2_TRACE_DEBUGIFC, | ||
379 | "debugifc parse error on subsys mask"); | ||
380 | return -EINVAL; | ||
381 | } | ||
382 | pvr2_hdw_subsys_bit_chg(hdw,msk,val); | ||
383 | return 0; | ||
384 | } else if (debugifc_match_keyword(wptr,wlen,"stream_flags")) { | ||
385 | unsigned long msk = 0; | ||
386 | unsigned long val = 0; | ||
387 | if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) { | ||
388 | pvr2_trace(PVR2_TRACE_DEBUGIFC, | ||
389 | "debugifc parse error on stream mask"); | ||
390 | return -EINVAL; | ||
391 | } | ||
392 | pvr2_hdw_subsys_stream_bit_chg(hdw,msk,val); | ||
393 | return 0; | ||
394 | } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) { | 225 | } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) { |
395 | scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); | 226 | scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); |
396 | if (!scnt) return -EINVAL; | 227 | if (!scnt) return -EINVAL; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 205087a3e136..5ca548cc7e7f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c | |||
@@ -209,7 +209,7 @@ static int pvr2_encoder_cmd(void *ctxt, | |||
209 | 209 | ||
210 | LOCK_TAKE(hdw->ctl_lock); do { | 210 | LOCK_TAKE(hdw->ctl_lock); do { |
211 | 211 | ||
212 | if (!hdw->flag_encoder_ok) { | 212 | if (!hdw->state_encoder_ok) { |
213 | ret = -EIO; | 213 | ret = -EIO; |
214 | break; | 214 | break; |
215 | } | 215 | } |
@@ -278,7 +278,11 @@ static int pvr2_encoder_cmd(void *ctxt, | |||
278 | ret = -EBUSY; | 278 | ret = -EBUSY; |
279 | } | 279 | } |
280 | if (ret) { | 280 | if (ret) { |
281 | hdw->flag_encoder_ok = 0; | 281 | hdw->state_encoder_ok = 0; |
282 | pvr2_trace(PVR2_TRACE_STBITS, | ||
283 | "State bit %s <-- %s", | ||
284 | "state_encoder_ok", | ||
285 | (hdw->state_encoder_ok ? "true" : "false")); | ||
282 | pvr2_trace( | 286 | pvr2_trace( |
283 | PVR2_TRACE_ERROR_LEGS, | 287 | PVR2_TRACE_ERROR_LEGS, |
284 | "Giving up on command." | 288 | "Giving up on command." |
@@ -394,6 +398,24 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) | |||
394 | return ret; | 398 | return ret; |
395 | } | 399 | } |
396 | 400 | ||
401 | int pvr2_encoder_adjust(struct pvr2_hdw *hdw) | ||
402 | { | ||
403 | int ret; | ||
404 | ret = cx2341x_update(hdw,pvr2_encoder_cmd, | ||
405 | (hdw->enc_cur_valid ? &hdw->enc_cur_state : NULL), | ||
406 | &hdw->enc_ctl_state); | ||
407 | if (ret) { | ||
408 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
409 | "Error from cx2341x module code=%d",ret); | ||
410 | } else { | ||
411 | memcpy(&hdw->enc_cur_state,&hdw->enc_ctl_state, | ||
412 | sizeof(struct cx2341x_mpeg_params)); | ||
413 | hdw->enc_cur_valid = !0; | ||
414 | } | ||
415 | return ret; | ||
416 | } | ||
417 | |||
418 | |||
397 | int pvr2_encoder_configure(struct pvr2_hdw *hdw) | 419 | int pvr2_encoder_configure(struct pvr2_hdw *hdw) |
398 | { | 420 | { |
399 | int ret; | 421 | int ret; |
@@ -436,18 +458,10 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw) | |||
436 | return ret; | 458 | return ret; |
437 | } | 459 | } |
438 | 460 | ||
439 | ret = cx2341x_update(hdw,pvr2_encoder_cmd, | 461 | ret = pvr2_encoder_adjust(hdw); |
440 | (hdw->enc_cur_valid ? &hdw->enc_cur_state : NULL), | 462 | if (ret) return ret; |
441 | &hdw->enc_ctl_state); | ||
442 | if (ret) { | ||
443 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
444 | "Error from cx2341x module code=%d",ret); | ||
445 | return ret; | ||
446 | } | ||
447 | |||
448 | ret = 0; | ||
449 | 463 | ||
450 | if (!ret) ret = pvr2_encoder_vcmd( | 464 | ret = pvr2_encoder_vcmd( |
451 | hdw, CX2341X_ENC_INITIALIZE_INPUT, 0); | 465 | hdw, CX2341X_ENC_INITIALIZE_INPUT, 0); |
452 | 466 | ||
453 | if (ret) { | 467 | if (ret) { |
@@ -456,10 +470,6 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw) | |||
456 | return ret; | 470 | return ret; |
457 | } | 471 | } |
458 | 472 | ||
459 | hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); | ||
460 | memcpy(&hdw->enc_cur_state,&hdw->enc_ctl_state, | ||
461 | sizeof(struct cx2341x_mpeg_params)); | ||
462 | hdw->enc_cur_valid = !0; | ||
463 | return 0; | 473 | return 0; |
464 | } | 474 | } |
465 | 475 | ||
@@ -478,7 +488,7 @@ int pvr2_encoder_start(struct pvr2_hdw *hdw) | |||
478 | pvr2_encoder_vcmd(hdw,CX2341X_ENC_MUTE_VIDEO,1, | 488 | pvr2_encoder_vcmd(hdw,CX2341X_ENC_MUTE_VIDEO,1, |
479 | hdw->input_val == PVR2_CVAL_INPUT_RADIO ? 1 : 0); | 489 | hdw->input_val == PVR2_CVAL_INPUT_RADIO ? 1 : 0); |
480 | 490 | ||
481 | switch (hdw->config) { | 491 | switch (hdw->active_stream_type) { |
482 | case pvr2_config_vbi: | 492 | case pvr2_config_vbi: |
483 | status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, | 493 | status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, |
484 | 0x01,0x14); | 494 | 0x01,0x14); |
@@ -492,9 +502,6 @@ int pvr2_encoder_start(struct pvr2_hdw *hdw) | |||
492 | 0,0x13); | 502 | 0,0x13); |
493 | break; | 503 | break; |
494 | } | 504 | } |
495 | if (!status) { | ||
496 | hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN); | ||
497 | } | ||
498 | return status; | 505 | return status; |
499 | } | 506 | } |
500 | 507 | ||
@@ -505,7 +512,7 @@ int pvr2_encoder_stop(struct pvr2_hdw *hdw) | |||
505 | /* mask all interrupts */ | 512 | /* mask all interrupts */ |
506 | pvr2_write_register(hdw, 0x0048, 0xffffffff); | 513 | pvr2_write_register(hdw, 0x0048, 0xffffffff); |
507 | 514 | ||
508 | switch (hdw->config) { | 515 | switch (hdw->active_stream_type) { |
509 | case pvr2_config_vbi: | 516 | case pvr2_config_vbi: |
510 | status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, | 517 | status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, |
511 | 0x01,0x01,0x14); | 518 | 0x01,0x01,0x14); |
@@ -526,9 +533,6 @@ int pvr2_encoder_stop(struct pvr2_hdw *hdw) | |||
526 | pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401); | 533 | pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401); |
527 | pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); | 534 | pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); |
528 | 535 | ||
529 | if (!status) { | ||
530 | hdw->subsys_enabled_mask &= ~(1<<PVR2_SUBSYS_B_ENC_RUN); | ||
531 | } | ||
532 | return status; | 536 | return status; |
533 | } | 537 | } |
534 | 538 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.h b/drivers/media/video/pvrusb2/pvrusb2-encoder.h index 01b5a0b89c03..54caf2e3c428 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.h +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.h | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | struct pvr2_hdw; | 26 | struct pvr2_hdw; |
27 | 27 | ||
28 | int pvr2_encoder_adjust(struct pvr2_hdw *); | ||
28 | int pvr2_encoder_configure(struct pvr2_hdw *); | 29 | int pvr2_encoder_configure(struct pvr2_hdw *); |
29 | int pvr2_encoder_start(struct pvr2_hdw *); | 30 | int pvr2_encoder_start(struct pvr2_hdw *); |
30 | int pvr2_encoder_stop(struct pvr2_hdw *); | 31 | int pvr2_encoder_stop(struct pvr2_hdw *); |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index f873994b088c..8ee4549b7a9f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include <linux/videodev2.h> | 36 | #include <linux/videodev2.h> |
37 | #include <linux/i2c.h> | 37 | #include <linux/i2c.h> |
38 | #include <linux/workqueue.h> | ||
38 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
39 | #include "pvrusb2-hdw.h" | 40 | #include "pvrusb2-hdw.h" |
40 | #include "pvrusb2-io.h" | 41 | #include "pvrusb2-io.h" |
@@ -179,6 +180,12 @@ struct pvr2_hdw { | |||
179 | /* Device type, one of PVR2_HDW_TYPE_xxxxx */ | 180 | /* Device type, one of PVR2_HDW_TYPE_xxxxx */ |
180 | unsigned int hdw_type; | 181 | unsigned int hdw_type; |
181 | 182 | ||
183 | /* Kernel worker thread handling */ | ||
184 | struct workqueue_struct *workqueue; | ||
185 | struct work_struct workpoll; /* Update driver state */ | ||
186 | struct work_struct worki2csync; /* Update i2c clients */ | ||
187 | struct work_struct workinit; /* Driver initialization sequence */ | ||
188 | |||
182 | /* Video spigot */ | 189 | /* Video spigot */ |
183 | struct pvr2_stream *vid_stream; | 190 | struct pvr2_stream *vid_stream; |
184 | 191 | ||
@@ -186,9 +193,6 @@ struct pvr2_hdw { | |||
186 | struct mutex big_lock_mutex; | 193 | struct mutex big_lock_mutex; |
187 | int big_lock_held; /* For debugging */ | 194 | int big_lock_held; /* For debugging */ |
188 | 195 | ||
189 | void (*poll_trigger_func)(void *); | ||
190 | void *poll_trigger_data; | ||
191 | |||
192 | char name[32]; | 196 | char name[32]; |
193 | 197 | ||
194 | /* I2C stuff */ | 198 | /* I2C stuff */ |
@@ -225,14 +229,48 @@ struct pvr2_hdw { | |||
225 | unsigned int cmd_debug_write_len; // | 229 | unsigned int cmd_debug_write_len; // |
226 | unsigned int cmd_debug_read_len; // | 230 | unsigned int cmd_debug_read_len; // |
227 | 231 | ||
232 | /* Bits of state that describe what is going on with various parts | ||
233 | of the driver. */ | ||
234 | volatile int state_encoder_ok; /* Encoder is operational */ | ||
235 | volatile int state_encoder_run; /* Encoder is running */ | ||
236 | volatile int state_encoder_config; /* Encoder is configured */ | ||
237 | volatile int state_encoder_waitok; /* Encoder pre-wait done */ | ||
238 | volatile int state_decoder_run; /* Decoder is running */ | ||
239 | volatile int state_usbstream_run; /* FX2 is streaming */ | ||
240 | volatile int state_decoder_quiescent; /* Decoder idle for > 50msec */ | ||
241 | volatile int state_pipeline_config; /* Pipeline is configured */ | ||
242 | int state_pipeline_req; /* Somebody wants to stream */ | ||
243 | int state_pipeline_pause; /* Pipeline must be paused */ | ||
244 | int state_pipeline_idle; /* Pipeline not running */ | ||
245 | |||
246 | /* This is the master state of the driver. It is the combined | ||
247 | result of other bits of state. Examining this will indicate the | ||
248 | overall state of the driver. Values here are one of | ||
249 | PVR2_STATE_xxxx */ | ||
250 | unsigned int master_state; | ||
251 | |||
252 | /* True if states must be re-evaluated */ | ||
253 | int state_stale; | ||
254 | |||
255 | void (*state_func)(void *); | ||
256 | void *state_data; | ||
257 | |||
258 | /* Timer for measuring decoder settling time */ | ||
259 | struct timer_list quiescent_timer; | ||
260 | |||
261 | /* Timer for measuring encoder pre-wait time */ | ||
262 | struct timer_list encoder_wait_timer; | ||
263 | |||
264 | /* Place to block while waiting for state changes */ | ||
265 | wait_queue_head_t state_wait_data; | ||
266 | |||
267 | |||
228 | int flag_ok; /* device in known good state */ | 268 | int flag_ok; /* device in known good state */ |
229 | int flag_disconnected; /* flag_ok == 0 due to disconnect */ | 269 | int flag_disconnected; /* flag_ok == 0 due to disconnect */ |
230 | int flag_init_ok; /* true if structure is fully initialized */ | 270 | int flag_init_ok; /* true if structure is fully initialized */ |
231 | int flag_streaming_enabled; /* true if streaming should be on */ | ||
232 | int fw1_state; /* current situation with fw1 */ | 271 | int fw1_state; /* current situation with fw1 */ |
233 | int flag_encoder_ok; /* True if encoder is healthy */ | 272 | int flag_decoder_missed;/* We've noticed missing decoder */ |
234 | 273 | int flag_tripped; /* Indicates overall failure to start */ | |
235 | int flag_decoder_is_tuned; | ||
236 | 274 | ||
237 | struct pvr2_decoder_ctrl *decoder_ctrl; | 275 | struct pvr2_decoder_ctrl *decoder_ctrl; |
238 | 276 | ||
@@ -241,12 +279,6 @@ struct pvr2_hdw { | |||
241 | unsigned int fw_size; | 279 | unsigned int fw_size; |
242 | int fw_cpu_flag; /* True if we are dealing with the CPU */ | 280 | int fw_cpu_flag; /* True if we are dealing with the CPU */ |
243 | 281 | ||
244 | // Which subsystem pieces have been enabled / configured | ||
245 | unsigned long subsys_enabled_mask; | ||
246 | |||
247 | // Which subsystems are manipulated to enable streaming | ||
248 | unsigned long subsys_stream_mask; | ||
249 | |||
250 | // True if there is a request to trigger logging of state in each | 282 | // True if there is a request to trigger logging of state in each |
251 | // module. | 283 | // module. |
252 | int log_requested; | 284 | int log_requested; |
@@ -296,13 +328,16 @@ struct pvr2_hdw { | |||
296 | /* Location of eeprom or a negative number if none */ | 328 | /* Location of eeprom or a negative number if none */ |
297 | int eeprom_addr; | 329 | int eeprom_addr; |
298 | 330 | ||
299 | enum pvr2_config config; | 331 | enum pvr2_config active_stream_type; |
332 | enum pvr2_config desired_stream_type; | ||
300 | 333 | ||
301 | /* Control state needed for cx2341x module */ | 334 | /* Control state needed for cx2341x module */ |
302 | struct cx2341x_mpeg_params enc_cur_state; | 335 | struct cx2341x_mpeg_params enc_cur_state; |
303 | struct cx2341x_mpeg_params enc_ctl_state; | 336 | struct cx2341x_mpeg_params enc_ctl_state; |
304 | /* True if an encoder attribute has changed */ | 337 | /* True if an encoder attribute has changed */ |
305 | int enc_stale; | 338 | int enc_stale; |
339 | /* True if an unsafe encoder attribute has changed */ | ||
340 | int enc_unsafe_stale; | ||
306 | /* True if enc_cur_state is valid */ | 341 | /* True if enc_cur_state is valid */ |
307 | int enc_cur_valid; | 342 | int enc_cur_valid; |
308 | 343 | ||
@@ -332,6 +367,7 @@ struct pvr2_hdw { | |||
332 | 367 | ||
333 | /* This function gets the current frequency */ | 368 | /* This function gets the current frequency */ |
334 | unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *); | 369 | unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *); |
370 | void pvr2_hdw_set_decoder(struct pvr2_hdw *,struct pvr2_decoder_ctrl *); | ||
335 | 371 | ||
336 | #endif /* __PVRUSB2_HDW_INTERNAL_H */ | 372 | #endif /* __PVRUSB2_HDW_INTERNAL_H */ |
337 | 373 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 402c59488253..4e55a2a84073 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -246,32 +246,46 @@ static const char *control_values_hsm[] = { | |||
246 | }; | 246 | }; |
247 | 247 | ||
248 | 248 | ||
249 | static const char *control_values_subsystem[] = { | 249 | static const char *pvr2_state_names[] = { |
250 | [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware", | 250 | [PVR2_STATE_NONE] = "none", |
251 | [PVR2_SUBSYS_B_ENC_CFG] = "enc_config", | 251 | [PVR2_STATE_DEAD] = "dead", |
252 | [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run", | 252 | [PVR2_STATE_COLD] = "cold", |
253 | [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run", | 253 | [PVR2_STATE_WARM] = "warm", |
254 | [PVR2_SUBSYS_B_ENC_RUN] = "enc_run", | 254 | [PVR2_STATE_ERROR] = "error", |
255 | [PVR2_STATE_READY] = "ready", | ||
256 | [PVR2_STATE_RUN] = "run", | ||
255 | }; | 257 | }; |
256 | 258 | ||
259 | |||
260 | static void pvr2_hdw_state_sched(struct pvr2_hdw *); | ||
261 | static int pvr2_hdw_state_eval(struct pvr2_hdw *); | ||
257 | static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); | 262 | static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); |
263 | static void pvr2_hdw_worker_i2c(struct work_struct *work); | ||
264 | static void pvr2_hdw_worker_poll(struct work_struct *work); | ||
265 | static void pvr2_hdw_worker_init(struct work_struct *work); | ||
266 | static int pvr2_hdw_wait(struct pvr2_hdw *,int state); | ||
267 | static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *); | ||
268 | static void pvr2_hdw_state_log_state(struct pvr2_hdw *); | ||
258 | static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); | 269 | static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); |
259 | static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw); | 270 | static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw); |
260 | static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw); | 271 | static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw); |
261 | static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); | 272 | static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); |
262 | static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); | 273 | static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); |
263 | static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw); | 274 | static void pvr2_hdw_quiescent_timeout(unsigned long); |
264 | static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, | 275 | static void pvr2_hdw_encoder_wait_timeout(unsigned long); |
265 | unsigned long msk, | ||
266 | unsigned long val); | ||
267 | static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw, | ||
268 | unsigned long msk, | ||
269 | unsigned long val); | ||
270 | static int pvr2_send_request_ex(struct pvr2_hdw *hdw, | 276 | static int pvr2_send_request_ex(struct pvr2_hdw *hdw, |
271 | unsigned int timeout,int probe_fl, | 277 | unsigned int timeout,int probe_fl, |
272 | void *write_data,unsigned int write_len, | 278 | void *write_data,unsigned int write_len, |
273 | void *read_data,unsigned int read_len); | 279 | void *read_data,unsigned int read_len); |
274 | 280 | ||
281 | |||
282 | static void trace_stbit(const char *name,int val) | ||
283 | { | ||
284 | pvr2_trace(PVR2_TRACE_STBITS, | ||
285 | "State bit %s <-- %s", | ||
286 | name,(val ? "true" : "false")); | ||
287 | } | ||
288 | |||
275 | static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) | 289 | static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) |
276 | { | 290 | { |
277 | struct pvr2_hdw *hdw = cptr->hdw; | 291 | struct pvr2_hdw *hdw = cptr->hdw; |
@@ -480,6 +494,7 @@ static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr) | |||
480 | static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr) | 494 | static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr) |
481 | { | 495 | { |
482 | cptr->hdw->enc_stale = 0; | 496 | cptr->hdw->enc_stale = 0; |
497 | cptr->hdw->enc_unsafe_stale = 0; | ||
483 | } | 498 | } |
484 | 499 | ||
485 | static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp) | 500 | static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp) |
@@ -502,6 +517,7 @@ static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp) | |||
502 | static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v) | 517 | static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v) |
503 | { | 518 | { |
504 | int ret; | 519 | int ret; |
520 | struct pvr2_hdw *hdw = cptr->hdw; | ||
505 | struct v4l2_ext_controls cs; | 521 | struct v4l2_ext_controls cs; |
506 | struct v4l2_ext_control c1; | 522 | struct v4l2_ext_control c1; |
507 | memset(&cs,0,sizeof(cs)); | 523 | memset(&cs,0,sizeof(cs)); |
@@ -510,10 +526,22 @@ static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v) | |||
510 | cs.count = 1; | 526 | cs.count = 1; |
511 | c1.id = cptr->info->v4l_id; | 527 | c1.id = cptr->info->v4l_id; |
512 | c1.value = v; | 528 | c1.value = v; |
513 | ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs, | 529 | ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state, |
530 | hdw->state_encoder_run, &cs, | ||
514 | VIDIOC_S_EXT_CTRLS); | 531 | VIDIOC_S_EXT_CTRLS); |
532 | if (ret == -EBUSY) { | ||
533 | /* Oops. cx2341x is telling us it's not safe to change | ||
534 | this control while we're capturing. Make a note of this | ||
535 | fact so that the pipeline will be stopped the next time | ||
536 | controls are committed. Then go on ahead and store this | ||
537 | change anyway. */ | ||
538 | ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state, | ||
539 | 0, &cs, | ||
540 | VIDIOC_S_EXT_CTRLS); | ||
541 | if (!ret) hdw->enc_unsafe_stale = !0; | ||
542 | } | ||
515 | if (ret) return ret; | 543 | if (ret) return ret; |
516 | cptr->hdw->enc_stale = !0; | 544 | hdw->enc_stale = !0; |
517 | return 0; | 545 | return 0; |
518 | } | 546 | } |
519 | 547 | ||
@@ -544,7 +572,13 @@ static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr) | |||
544 | 572 | ||
545 | static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp) | 573 | static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp) |
546 | { | 574 | { |
547 | *vp = cptr->hdw->flag_streaming_enabled; | 575 | *vp = cptr->hdw->state_pipeline_req; |
576 | return 0; | ||
577 | } | ||
578 | |||
579 | static int ctrl_masterstate_get(struct pvr2_ctrl *cptr,int *vp) | ||
580 | { | ||
581 | *vp = cptr->hdw->master_state; | ||
548 | return 0; | 582 | return 0; |
549 | } | 583 | } |
550 | 584 | ||
@@ -657,29 +691,6 @@ static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp) | |||
657 | return 0; | 691 | return 0; |
658 | } | 692 | } |
659 | 693 | ||
660 | static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp) | ||
661 | { | ||
662 | *vp = cptr->hdw->subsys_enabled_mask; | ||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v) | ||
667 | { | ||
668 | pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v); | ||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp) | ||
673 | { | ||
674 | *vp = cptr->hdw->subsys_stream_mask; | ||
675 | return 0; | ||
676 | } | ||
677 | |||
678 | static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v) | ||
679 | { | ||
680 | pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v); | ||
681 | return 0; | ||
682 | } | ||
683 | 694 | ||
684 | static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v) | 695 | static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v) |
685 | { | 696 | { |
@@ -915,6 +926,11 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
915 | .get_value = ctrl_hsm_get, | 926 | .get_value = ctrl_hsm_get, |
916 | DEFENUM(control_values_hsm), | 927 | DEFENUM(control_values_hsm), |
917 | },{ | 928 | },{ |
929 | .desc = "Master State", | ||
930 | .name = "master_state", | ||
931 | .get_value = ctrl_masterstate_get, | ||
932 | DEFENUM(pvr2_state_names), | ||
933 | },{ | ||
918 | .desc = "Signal Present", | 934 | .desc = "Signal Present", |
919 | .name = "signal_present", | 935 | .name = "signal_present", |
920 | .get_value = ctrl_signal_get, | 936 | .get_value = ctrl_signal_get, |
@@ -955,20 +971,6 @@ static const struct pvr2_ctl_info control_defs[] = { | |||
955 | .sym_to_val = ctrl_std_sym_to_val, | 971 | .sym_to_val = ctrl_std_sym_to_val, |
956 | .type = pvr2_ctl_bitmask, | 972 | .type = pvr2_ctl_bitmask, |
957 | },{ | 973 | },{ |
958 | .desc = "Subsystem enabled mask", | ||
959 | .name = "debug_subsys_mask", | ||
960 | .skip_init = !0, | ||
961 | .get_value = ctrl_subsys_get, | ||
962 | .set_value = ctrl_subsys_set, | ||
963 | DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), | ||
964 | },{ | ||
965 | .desc = "Subsystem stream mask", | ||
966 | .name = "debug_subsys_stream_mask", | ||
967 | .skip_init = !0, | ||
968 | .get_value = ctrl_subsys_stream_get, | ||
969 | .set_value = ctrl_subsys_stream_set, | ||
970 | DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), | ||
971 | },{ | ||
972 | .desc = "Video Standard Name", | 974 | .desc = "Video Standard Name", |
973 | .name = "video_standard", | 975 | .name = "video_standard", |
974 | .internal_id = PVR2_CID_STDENUM, | 976 | .internal_id = PVR2_CID_STDENUM, |
@@ -1248,8 +1250,6 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1248 | time we configure the encoder, then we'll fully configure it. */ | 1250 | time we configure the encoder, then we'll fully configure it. */ |
1249 | hdw->enc_cur_valid = 0; | 1251 | hdw->enc_cur_valid = 0; |
1250 | 1252 | ||
1251 | hdw->flag_encoder_ok = 0; | ||
1252 | |||
1253 | /* First prepare firmware loading */ | 1253 | /* First prepare firmware loading */ |
1254 | ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ | 1254 | ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ |
1255 | ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/ | 1255 | ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/ |
@@ -1347,293 +1347,129 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1347 | if (ret) { | 1347 | if (ret) { |
1348 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1348 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
1349 | "firmware2 upload post-proc failure"); | 1349 | "firmware2 upload post-proc failure"); |
1350 | } else { | ||
1351 | hdw->flag_encoder_ok = !0; | ||
1352 | hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE); | ||
1353 | } | 1350 | } |
1354 | return ret; | 1351 | return ret; |
1355 | } | 1352 | } |
1356 | 1353 | ||
1357 | 1354 | ||
1358 | #define FIRMWARE_RECOVERY_BITS \ | 1355 | static const char *pvr2_get_state_name(unsigned int st) |
1359 | ((1<<PVR2_SUBSYS_B_ENC_CFG) | \ | 1356 | { |
1360 | (1<<PVR2_SUBSYS_B_ENC_RUN) | \ | 1357 | if (st < ARRAY_SIZE(pvr2_state_names)) { |
1361 | (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \ | 1358 | return pvr2_state_names[st]; |
1362 | (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) | ||
1363 | |||
1364 | /* | ||
1365 | |||
1366 | This single function is key to pretty much everything. The pvrusb2 | ||
1367 | device can logically be viewed as a series of subsystems which can be | ||
1368 | stopped / started or unconfigured / configured. To get things streaming, | ||
1369 | one must configure everything and start everything, but there may be | ||
1370 | various reasons over time to deconfigure something or stop something. | ||
1371 | This function handles all of this activity. Everything EVERYWHERE that | ||
1372 | must affect a subsystem eventually comes here to do the work. | ||
1373 | |||
1374 | The current state of all subsystems is represented by a single bit mask, | ||
1375 | known as subsys_enabled_mask. The bit positions are defined by the | ||
1376 | PVR2_SUBSYS_xxxx macros, with one subsystem per bit position. At any | ||
1377 | time the set of configured or active subsystems can be queried just by | ||
1378 | looking at that mask. To change bits in that mask, this function here | ||
1379 | must be called. The "msk" argument indicates which bit positions to | ||
1380 | change, and the "val" argument defines the new values for the positions | ||
1381 | defined by "msk". | ||
1382 | |||
1383 | There is a priority ordering of starting / stopping things, and for | ||
1384 | multiple requested changes, this function implements that ordering. | ||
1385 | (Thus we will act on a request to load encoder firmware before we | ||
1386 | configure the encoder.) In addition to priority ordering, there is a | ||
1387 | recovery strategy implemented here. If a particular step fails and we | ||
1388 | detect that failure, this function will clear the affected subsystem bits | ||
1389 | and restart. Thus we have a means for recovering from a dead encoder: | ||
1390 | Clear all bits that correspond to subsystems that we need to restart / | ||
1391 | reconfigure and start over. | ||
1392 | |||
1393 | */ | ||
1394 | static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, | ||
1395 | unsigned long msk, | ||
1396 | unsigned long val) | ||
1397 | { | ||
1398 | unsigned long nmsk; | ||
1399 | unsigned long vmsk; | ||
1400 | int ret; | ||
1401 | unsigned int tryCount = 0; | ||
1402 | |||
1403 | if (!hdw->flag_ok) return; | ||
1404 | |||
1405 | msk &= PVR2_SUBSYS_ALL; | ||
1406 | nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk); | ||
1407 | nmsk &= PVR2_SUBSYS_ALL; | ||
1408 | |||
1409 | for (;;) { | ||
1410 | tryCount++; | ||
1411 | if (!((nmsk ^ hdw->subsys_enabled_mask) & | ||
1412 | PVR2_SUBSYS_ALL)) break; | ||
1413 | if (tryCount > 4) { | ||
1414 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1415 | "Too many retries when configuring device;" | ||
1416 | " giving up"); | ||
1417 | pvr2_hdw_render_useless(hdw); | ||
1418 | break; | ||
1419 | } | ||
1420 | if (tryCount > 1) { | ||
1421 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1422 | "Retrying device reconfiguration"); | ||
1423 | } | ||
1424 | pvr2_trace(PVR2_TRACE_INIT, | ||
1425 | "subsys mask changing 0x%lx:0x%lx" | ||
1426 | " from 0x%lx to 0x%lx", | ||
1427 | msk,val,hdw->subsys_enabled_mask,nmsk); | ||
1428 | |||
1429 | vmsk = (nmsk ^ hdw->subsys_enabled_mask) & | ||
1430 | hdw->subsys_enabled_mask; | ||
1431 | if (vmsk) { | ||
1432 | if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) { | ||
1433 | pvr2_trace(PVR2_TRACE_CTL, | ||
1434 | "/*---TRACE_CTL----*/" | ||
1435 | " pvr2_encoder_stop"); | ||
1436 | ret = pvr2_encoder_stop(hdw); | ||
1437 | if (ret) { | ||
1438 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1439 | "Error recovery initiated"); | ||
1440 | hdw->subsys_enabled_mask &= | ||
1441 | ~FIRMWARE_RECOVERY_BITS; | ||
1442 | continue; | ||
1443 | } | ||
1444 | } | ||
1445 | if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) { | ||
1446 | pvr2_trace(PVR2_TRACE_CTL, | ||
1447 | "/*---TRACE_CTL----*/" | ||
1448 | " pvr2_hdw_cmd_usbstream(0)"); | ||
1449 | pvr2_hdw_cmd_usbstream(hdw,0); | ||
1450 | } | ||
1451 | if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) { | ||
1452 | pvr2_trace(PVR2_TRACE_CTL, | ||
1453 | "/*---TRACE_CTL----*/" | ||
1454 | " decoder disable"); | ||
1455 | if (hdw->decoder_ctrl) { | ||
1456 | hdw->decoder_ctrl->enable( | ||
1457 | hdw->decoder_ctrl->ctxt,0); | ||
1458 | } else { | ||
1459 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1460 | "WARNING:" | ||
1461 | " No decoder present"); | ||
1462 | } | ||
1463 | hdw->subsys_enabled_mask &= | ||
1464 | ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN); | ||
1465 | } | ||
1466 | if (vmsk & PVR2_SUBSYS_CFG_ALL) { | ||
1467 | hdw->subsys_enabled_mask &= | ||
1468 | ~(vmsk & PVR2_SUBSYS_CFG_ALL); | ||
1469 | } | ||
1470 | } | ||
1471 | vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk; | ||
1472 | if (vmsk) { | ||
1473 | if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) { | ||
1474 | pvr2_trace(PVR2_TRACE_CTL, | ||
1475 | "/*---TRACE_CTL----*/" | ||
1476 | " pvr2_upload_firmware2"); | ||
1477 | ret = pvr2_upload_firmware2(hdw); | ||
1478 | if (ret) { | ||
1479 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1480 | "Failure uploading encoder" | ||
1481 | " firmware"); | ||
1482 | pvr2_hdw_render_useless(hdw); | ||
1483 | break; | ||
1484 | } | ||
1485 | } | ||
1486 | if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) { | ||
1487 | pvr2_trace(PVR2_TRACE_CTL, | ||
1488 | "/*---TRACE_CTL----*/" | ||
1489 | " pvr2_encoder_configure"); | ||
1490 | ret = pvr2_encoder_configure(hdw); | ||
1491 | if (ret) { | ||
1492 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1493 | "Error recovery initiated"); | ||
1494 | hdw->subsys_enabled_mask &= | ||
1495 | ~FIRMWARE_RECOVERY_BITS; | ||
1496 | continue; | ||
1497 | } | ||
1498 | } | ||
1499 | if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) { | ||
1500 | pvr2_trace(PVR2_TRACE_CTL, | ||
1501 | "/*---TRACE_CTL----*/" | ||
1502 | " decoder enable"); | ||
1503 | if (hdw->decoder_ctrl) { | ||
1504 | hdw->decoder_ctrl->enable( | ||
1505 | hdw->decoder_ctrl->ctxt,!0); | ||
1506 | } else { | ||
1507 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1508 | "WARNING:" | ||
1509 | " No decoder present"); | ||
1510 | } | ||
1511 | hdw->subsys_enabled_mask |= | ||
1512 | (1<<PVR2_SUBSYS_B_DIGITIZER_RUN); | ||
1513 | } | ||
1514 | if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) { | ||
1515 | pvr2_trace(PVR2_TRACE_CTL, | ||
1516 | "/*---TRACE_CTL----*/" | ||
1517 | " pvr2_hdw_cmd_usbstream(1)"); | ||
1518 | pvr2_hdw_cmd_usbstream(hdw,!0); | ||
1519 | } | ||
1520 | if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) { | ||
1521 | pvr2_trace(PVR2_TRACE_CTL, | ||
1522 | "/*---TRACE_CTL----*/" | ||
1523 | " pvr2_encoder_start"); | ||
1524 | ret = pvr2_encoder_start(hdw); | ||
1525 | if (ret) { | ||
1526 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1527 | "Error recovery initiated"); | ||
1528 | hdw->subsys_enabled_mask &= | ||
1529 | ~FIRMWARE_RECOVERY_BITS; | ||
1530 | continue; | ||
1531 | } | ||
1532 | } | ||
1533 | } | ||
1534 | } | 1359 | } |
1360 | return "???"; | ||
1535 | } | 1361 | } |
1536 | 1362 | ||
1537 | 1363 | static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl) | |
1538 | void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw, | ||
1539 | unsigned long msk,unsigned long val) | ||
1540 | { | 1364 | { |
1541 | LOCK_TAKE(hdw->big_lock); do { | 1365 | if (!hdw->decoder_ctrl) { |
1542 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val); | 1366 | if (!hdw->flag_decoder_missed) { |
1543 | } while (0); LOCK_GIVE(hdw->big_lock); | 1367 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
1368 | "WARNING: No decoder present"); | ||
1369 | hdw->flag_decoder_missed = !0; | ||
1370 | trace_stbit("flag_decoder_missed", | ||
1371 | hdw->flag_decoder_missed); | ||
1372 | } | ||
1373 | return -EIO; | ||
1374 | } | ||
1375 | hdw->decoder_ctrl->enable(hdw->decoder_ctrl->ctxt,enablefl); | ||
1376 | return 0; | ||
1544 | } | 1377 | } |
1545 | 1378 | ||
1546 | 1379 | ||
1547 | unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw) | 1380 | void pvr2_hdw_set_decoder(struct pvr2_hdw *hdw,struct pvr2_decoder_ctrl *ptr) |
1548 | { | 1381 | { |
1549 | return hdw->subsys_enabled_mask; | 1382 | if (hdw->decoder_ctrl == ptr) return; |
1383 | hdw->decoder_ctrl = ptr; | ||
1384 | if (hdw->decoder_ctrl && hdw->flag_decoder_missed) { | ||
1385 | hdw->flag_decoder_missed = 0; | ||
1386 | trace_stbit("flag_decoder_missed", | ||
1387 | hdw->flag_decoder_missed); | ||
1388 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | ||
1389 | "Decoder has appeared"); | ||
1390 | pvr2_hdw_state_sched(hdw); | ||
1391 | } | ||
1550 | } | 1392 | } |
1551 | 1393 | ||
1552 | 1394 | ||
1553 | unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw) | 1395 | int pvr2_hdw_get_state(struct pvr2_hdw *hdw) |
1554 | { | 1396 | { |
1555 | return hdw->subsys_stream_mask; | 1397 | return hdw->master_state; |
1556 | } | 1398 | } |
1557 | 1399 | ||
1558 | 1400 | ||
1559 | static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw, | 1401 | static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *hdw) |
1560 | unsigned long msk, | ||
1561 | unsigned long val) | ||
1562 | { | 1402 | { |
1563 | unsigned long val2; | 1403 | if (!hdw->flag_tripped) return 0; |
1564 | msk &= PVR2_SUBSYS_ALL; | 1404 | hdw->flag_tripped = 0; |
1565 | val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk)); | 1405 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
1566 | pvr2_trace(PVR2_TRACE_INIT, | 1406 | "Clearing driver error statuss"); |
1567 | "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx", | 1407 | return !0; |
1568 | msk,val,hdw->subsys_stream_mask,val2); | ||
1569 | hdw->subsys_stream_mask = val2; | ||
1570 | } | 1408 | } |
1571 | 1409 | ||
1572 | 1410 | ||
1573 | void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, | 1411 | int pvr2_hdw_untrip(struct pvr2_hdw *hdw) |
1574 | unsigned long msk, | ||
1575 | unsigned long val) | ||
1576 | { | 1412 | { |
1413 | int fl; | ||
1577 | LOCK_TAKE(hdw->big_lock); do { | 1414 | LOCK_TAKE(hdw->big_lock); do { |
1578 | pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val); | 1415 | fl = pvr2_hdw_untrip_unlocked(hdw); |
1579 | } while (0); LOCK_GIVE(hdw->big_lock); | 1416 | } while (0); LOCK_GIVE(hdw->big_lock); |
1417 | if (fl) pvr2_hdw_state_sched(hdw); | ||
1418 | return 0; | ||
1580 | } | 1419 | } |
1581 | 1420 | ||
1582 | 1421 | ||
1583 | static int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl) | 1422 | const char *pvr2_hdw_get_state_name(unsigned int id) |
1584 | { | 1423 | { |
1585 | if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0; | 1424 | if (id >= ARRAY_SIZE(pvr2_state_names)) return NULL; |
1586 | if (enableFl) { | 1425 | return pvr2_state_names[id]; |
1587 | pvr2_trace(PVR2_TRACE_START_STOP, | ||
1588 | "/*--TRACE_STREAM--*/ enable"); | ||
1589 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0); | ||
1590 | } else { | ||
1591 | pvr2_trace(PVR2_TRACE_START_STOP, | ||
1592 | "/*--TRACE_STREAM--*/ disable"); | ||
1593 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0); | ||
1594 | } | ||
1595 | if (!hdw->flag_ok) return -EIO; | ||
1596 | hdw->flag_streaming_enabled = enableFl != 0; | ||
1597 | return 0; | ||
1598 | } | 1426 | } |
1599 | 1427 | ||
1600 | 1428 | ||
1601 | int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw) | 1429 | int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw) |
1602 | { | 1430 | { |
1603 | return hdw->flag_streaming_enabled != 0; | 1431 | return hdw->state_pipeline_req != 0; |
1604 | } | 1432 | } |
1605 | 1433 | ||
1606 | 1434 | ||
1607 | int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag) | 1435 | int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag) |
1608 | { | 1436 | { |
1609 | int ret; | 1437 | int ret,st; |
1610 | LOCK_TAKE(hdw->big_lock); do { | 1438 | LOCK_TAKE(hdw->big_lock); do { |
1611 | ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag); | 1439 | pvr2_hdw_untrip_unlocked(hdw); |
1440 | if ((!enable_flag) != !(hdw->state_pipeline_req)) { | ||
1441 | hdw->state_pipeline_req = enable_flag != 0; | ||
1442 | pvr2_trace(PVR2_TRACE_START_STOP, | ||
1443 | "/*--TRACE_STREAM--*/ %s", | ||
1444 | enable_flag ? "enable" : "disable"); | ||
1445 | } | ||
1446 | pvr2_hdw_state_sched(hdw); | ||
1612 | } while (0); LOCK_GIVE(hdw->big_lock); | 1447 | } while (0); LOCK_GIVE(hdw->big_lock); |
1613 | return ret; | 1448 | if ((ret = pvr2_hdw_wait(hdw,0)) < 0) return ret; |
1614 | } | 1449 | if (enable_flag) { |
1615 | 1450 | while ((st = hdw->master_state) != PVR2_STATE_RUN) { | |
1616 | 1451 | if (st != PVR2_STATE_READY) return -EIO; | |
1617 | static int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw, | 1452 | if ((ret = pvr2_hdw_wait(hdw,st)) < 0) return ret; |
1618 | enum pvr2_config config) | 1453 | } |
1619 | { | 1454 | } |
1620 | unsigned long sm = hdw->subsys_enabled_mask; | ||
1621 | if (!hdw->flag_ok) return -EIO; | ||
1622 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0); | ||
1623 | hdw->config = config; | ||
1624 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm); | ||
1625 | return 0; | 1455 | return 0; |
1626 | } | 1456 | } |
1627 | 1457 | ||
1628 | 1458 | ||
1629 | int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config) | 1459 | int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config) |
1630 | { | 1460 | { |
1631 | int ret; | 1461 | int fl; |
1632 | if (!hdw->flag_ok) return -EIO; | ||
1633 | LOCK_TAKE(hdw->big_lock); | 1462 | LOCK_TAKE(hdw->big_lock); |
1634 | ret = pvr2_hdw_set_stream_type_no_lock(hdw,config); | 1463 | if ((fl = (hdw->desired_stream_type != config)) != 0) { |
1464 | hdw->desired_stream_type = config; | ||
1465 | hdw->state_pipeline_config = 0; | ||
1466 | trace_stbit("state_pipeline_config", | ||
1467 | hdw->state_pipeline_config); | ||
1468 | pvr2_hdw_state_sched(hdw); | ||
1469 | } | ||
1635 | LOCK_GIVE(hdw->big_lock); | 1470 | LOCK_GIVE(hdw->big_lock); |
1636 | return ret; | 1471 | if (fl) return 0; |
1472 | return pvr2_hdw_wait(hdw,0); | ||
1637 | } | 1473 | } |
1638 | 1474 | ||
1639 | 1475 | ||
@@ -1866,12 +1702,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) | |||
1866 | (hdw->hdw_type == PVR2_HDW_TYPE_24XXX)) { | 1702 | (hdw->hdw_type == PVR2_HDW_TYPE_24XXX)) { |
1867 | pvr2_hdw_cmd_powerup(hdw); | 1703 | pvr2_hdw_cmd_powerup(hdw); |
1868 | if (!pvr2_hdw_dev_ok(hdw)) return; | 1704 | if (!pvr2_hdw_dev_ok(hdw)) return; |
1869 | |||
1870 | if (pvr2_upload_firmware2(hdw)){ | ||
1871 | pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!"); | ||
1872 | pvr2_hdw_render_useless(hdw); | ||
1873 | return; | ||
1874 | } | ||
1875 | } | 1705 | } |
1876 | 1706 | ||
1877 | // This step MUST happen after the earlier powerup step. | 1707 | // This step MUST happen after the earlier powerup step. |
@@ -1924,8 +1754,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) | |||
1924 | 1754 | ||
1925 | if (!pvr2_hdw_dev_ok(hdw)) return; | 1755 | if (!pvr2_hdw_dev_ok(hdw)) return; |
1926 | 1756 | ||
1927 | pvr2_hdw_commit_ctl_internal(hdw); | 1757 | pvr2_hdw_commit_setup(hdw); |
1928 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1929 | 1758 | ||
1930 | hdw->vid_stream = pvr2_stream_create(); | 1759 | hdw->vid_stream = pvr2_stream_create(); |
1931 | if (!pvr2_hdw_dev_ok(hdw)) return; | 1760 | if (!pvr2_hdw_dev_ok(hdw)) return; |
@@ -1945,25 +1774,25 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) | |||
1945 | 1774 | ||
1946 | if (!pvr2_hdw_dev_ok(hdw)) return; | 1775 | if (!pvr2_hdw_dev_ok(hdw)) return; |
1947 | 1776 | ||
1948 | /* Make sure everything is up to date */ | ||
1949 | pvr2_i2c_core_sync(hdw); | ||
1950 | |||
1951 | if (!pvr2_hdw_dev_ok(hdw)) return; | ||
1952 | |||
1953 | hdw->flag_init_ok = !0; | 1777 | hdw->flag_init_ok = !0; |
1778 | |||
1779 | pvr2_hdw_state_sched(hdw); | ||
1954 | } | 1780 | } |
1955 | 1781 | ||
1956 | 1782 | ||
1957 | int pvr2_hdw_setup(struct pvr2_hdw *hdw) | 1783 | /* Set up the structure and attempt to put the device into a usable state. |
1784 | This can be a time-consuming operation, which is why it is not done | ||
1785 | internally as part of the create() step. */ | ||
1786 | static void pvr2_hdw_setup(struct pvr2_hdw *hdw) | ||
1958 | { | 1787 | { |
1959 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw); | 1788 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw); |
1960 | LOCK_TAKE(hdw->big_lock); do { | 1789 | do { |
1961 | pvr2_hdw_setup_low(hdw); | 1790 | pvr2_hdw_setup_low(hdw); |
1962 | pvr2_trace(PVR2_TRACE_INIT, | 1791 | pvr2_trace(PVR2_TRACE_INIT, |
1963 | "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d", | 1792 | "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d", |
1964 | hdw,hdw->flag_ok,hdw->flag_init_ok); | 1793 | hdw,pvr2_hdw_dev_ok(hdw),hdw->flag_init_ok); |
1965 | if (pvr2_hdw_dev_ok(hdw)) { | 1794 | if (pvr2_hdw_dev_ok(hdw)) { |
1966 | if (pvr2_hdw_init_ok(hdw)) { | 1795 | if (hdw->flag_init_ok) { |
1967 | pvr2_trace( | 1796 | pvr2_trace( |
1968 | PVR2_TRACE_INFO, | 1797 | PVR2_TRACE_INFO, |
1969 | "Device initialization" | 1798 | "Device initialization" |
@@ -2013,9 +1842,8 @@ int pvr2_hdw_setup(struct pvr2_hdw *hdw) | |||
2013 | " the pvrusb2 device" | 1842 | " the pvrusb2 device" |
2014 | " in order to recover."); | 1843 | " in order to recover."); |
2015 | } | 1844 | } |
2016 | } while (0); LOCK_GIVE(hdw->big_lock); | 1845 | } while (0); |
2017 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw); | 1846 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw); |
2018 | return hdw->flag_init_ok; | ||
2019 | } | 1847 | } |
2020 | 1848 | ||
2021 | 1849 | ||
@@ -2044,6 +1872,19 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2044 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", | 1872 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", |
2045 | hdw,pvr2_device_names[hdw_type]); | 1873 | hdw,pvr2_device_names[hdw_type]); |
2046 | if (!hdw) goto fail; | 1874 | if (!hdw) goto fail; |
1875 | |||
1876 | init_timer(&hdw->quiescent_timer); | ||
1877 | hdw->quiescent_timer.data = (unsigned long)hdw; | ||
1878 | hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout; | ||
1879 | |||
1880 | init_timer(&hdw->encoder_wait_timer); | ||
1881 | hdw->encoder_wait_timer.data = (unsigned long)hdw; | ||
1882 | hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout; | ||
1883 | |||
1884 | hdw->master_state = PVR2_STATE_DEAD; | ||
1885 | |||
1886 | init_waitqueue_head(&hdw->state_wait_data); | ||
1887 | |||
2047 | hdw->tuner_signal_stale = !0; | 1888 | hdw->tuner_signal_stale = !0; |
2048 | cx2341x_fill_defaults(&hdw->enc_ctl_state); | 1889 | cx2341x_fill_defaults(&hdw->enc_ctl_state); |
2049 | 1890 | ||
@@ -2184,18 +2025,16 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2184 | if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1; | 2025 | if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1; |
2185 | hdw->name[cnt1] = 0; | 2026 | hdw->name[cnt1] = 0; |
2186 | 2027 | ||
2028 | hdw->workqueue = create_singlethread_workqueue(hdw->name); | ||
2029 | INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll); | ||
2030 | INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c); | ||
2031 | INIT_WORK(&hdw->workinit,pvr2_hdw_worker_init); | ||
2032 | |||
2187 | pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", | 2033 | pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", |
2188 | hdw->unit_number,hdw->name); | 2034 | hdw->unit_number,hdw->name); |
2189 | 2035 | ||
2190 | hdw->tuner_type = -1; | 2036 | hdw->tuner_type = -1; |
2191 | hdw->flag_ok = !0; | 2037 | hdw->flag_ok = !0; |
2192 | /* Initialize the mask of subsystems that we will shut down when we | ||
2193 | stop streaming. */ | ||
2194 | hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL; | ||
2195 | hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); | ||
2196 | |||
2197 | pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx", | ||
2198 | hdw->subsys_stream_mask); | ||
2199 | 2038 | ||
2200 | hdw->usb_intf = intf; | 2039 | hdw->usb_intf = intf; |
2201 | hdw->usb_dev = interface_to_usbdev(intf); | 2040 | hdw->usb_dev = interface_to_usbdev(intf); |
@@ -2211,15 +2050,25 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
2211 | mutex_init(&hdw->ctl_lock_mutex); | 2050 | mutex_init(&hdw->ctl_lock_mutex); |
2212 | mutex_init(&hdw->big_lock_mutex); | 2051 | mutex_init(&hdw->big_lock_mutex); |
2213 | 2052 | ||
2053 | queue_work(hdw->workqueue,&hdw->workinit); | ||
2214 | return hdw; | 2054 | return hdw; |
2215 | fail: | 2055 | fail: |
2216 | if (hdw) { | 2056 | if (hdw) { |
2057 | del_timer_sync(&hdw->quiescent_timer); | ||
2058 | del_timer_sync(&hdw->encoder_wait_timer); | ||
2059 | if (hdw->workqueue) { | ||
2060 | flush_workqueue(hdw->workqueue); | ||
2061 | destroy_workqueue(hdw->workqueue); | ||
2062 | hdw->workqueue = NULL; | ||
2063 | } | ||
2217 | usb_free_urb(hdw->ctl_read_urb); | 2064 | usb_free_urb(hdw->ctl_read_urb); |
2218 | usb_free_urb(hdw->ctl_write_urb); | 2065 | usb_free_urb(hdw->ctl_write_urb); |
2219 | kfree(hdw->ctl_read_buffer); | 2066 | kfree(hdw->ctl_read_buffer); |
2220 | kfree(hdw->ctl_write_buffer); | 2067 | kfree(hdw->ctl_write_buffer); |
2221 | kfree(hdw->controls); | 2068 | kfree(hdw->controls); |
2222 | kfree(hdw->mpeg_ctrl_info); | 2069 | kfree(hdw->mpeg_ctrl_info); |
2070 | kfree(hdw->std_defs); | ||
2071 | kfree(hdw->std_enum_names); | ||
2223 | kfree(hdw); | 2072 | kfree(hdw); |
2224 | } | 2073 | } |
2225 | return NULL; | 2074 | return NULL; |
@@ -2250,10 +2099,10 @@ static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw) | |||
2250 | kfree(hdw->ctl_write_buffer); | 2099 | kfree(hdw->ctl_write_buffer); |
2251 | hdw->ctl_write_buffer = NULL; | 2100 | hdw->ctl_write_buffer = NULL; |
2252 | } | 2101 | } |
2253 | pvr2_hdw_render_useless_unlocked(hdw); | ||
2254 | hdw->flag_disconnected = !0; | 2102 | hdw->flag_disconnected = !0; |
2255 | hdw->usb_dev = NULL; | 2103 | hdw->usb_dev = NULL; |
2256 | hdw->usb_intf = NULL; | 2104 | hdw->usb_intf = NULL; |
2105 | pvr2_hdw_render_useless(hdw); | ||
2257 | } | 2106 | } |
2258 | 2107 | ||
2259 | 2108 | ||
@@ -2262,6 +2111,13 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) | |||
2262 | { | 2111 | { |
2263 | if (!hdw) return; | 2112 | if (!hdw) return; |
2264 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw); | 2113 | pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw); |
2114 | del_timer_sync(&hdw->quiescent_timer); | ||
2115 | del_timer_sync(&hdw->encoder_wait_timer); | ||
2116 | if (hdw->workqueue) { | ||
2117 | flush_workqueue(hdw->workqueue); | ||
2118 | destroy_workqueue(hdw->workqueue); | ||
2119 | hdw->workqueue = NULL; | ||
2120 | } | ||
2265 | if (hdw->fw_buffer) { | 2121 | if (hdw->fw_buffer) { |
2266 | kfree(hdw->fw_buffer); | 2122 | kfree(hdw->fw_buffer); |
2267 | hdw->fw_buffer = NULL; | 2123 | hdw->fw_buffer = NULL; |
@@ -2290,12 +2146,6 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) | |||
2290 | } | 2146 | } |
2291 | 2147 | ||
2292 | 2148 | ||
2293 | int pvr2_hdw_init_ok(struct pvr2_hdw *hdw) | ||
2294 | { | ||
2295 | return hdw->flag_init_ok; | ||
2296 | } | ||
2297 | |||
2298 | |||
2299 | int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw) | 2149 | int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw) |
2300 | { | 2150 | { |
2301 | return (hdw && hdw->flag_ok); | 2151 | return (hdw && hdw->flag_ok); |
@@ -2473,17 +2323,11 @@ static const char *get_ctrl_typename(enum pvr2_ctl_type tp) | |||
2473 | } | 2323 | } |
2474 | 2324 | ||
2475 | 2325 | ||
2476 | /* Commit all control changes made up to this point. Subsystems can be | 2326 | /* Figure out if we need to commit control changes. If so, mark internal |
2477 | indirectly affected by these changes. For a given set of things being | 2327 | state flags to indicate this fact and return true. Otherwise do nothing |
2478 | committed, we'll clear the affected subsystem bits and then once we're | 2328 | else and return false. */ |
2479 | done committing everything we'll make a request to restore the subsystem | 2329 | static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw) |
2480 | state(s) back to their previous value before this function was called. | ||
2481 | Thus we can automatically reconfigure affected pieces of the driver as | ||
2482 | controls are changed. */ | ||
2483 | static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) | ||
2484 | { | 2330 | { |
2485 | unsigned long saved_subsys_mask = hdw->subsys_enabled_mask; | ||
2486 | unsigned long stale_subsys_mask = 0; | ||
2487 | unsigned int idx; | 2331 | unsigned int idx; |
2488 | struct pvr2_ctrl *cptr; | 2332 | struct pvr2_ctrl *cptr; |
2489 | int value; | 2333 | int value; |
@@ -2518,6 +2362,25 @@ static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) | |||
2518 | return 0; | 2362 | return 0; |
2519 | } | 2363 | } |
2520 | 2364 | ||
2365 | hdw->state_pipeline_config = 0; | ||
2366 | trace_stbit("state_pipeline_config",hdw->state_pipeline_config); | ||
2367 | pvr2_hdw_state_sched(hdw); | ||
2368 | |||
2369 | return !0; | ||
2370 | } | ||
2371 | |||
2372 | |||
2373 | /* Perform all operations needed to commit all control changes. This must | ||
2374 | be performed in synchronization with the pipeline state and is thus | ||
2375 | expected to be called as part of the driver's worker thread. Return | ||
2376 | true if commit successful, otherwise return false to indicate that | ||
2377 | commit isn't possible at this time. */ | ||
2378 | static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) | ||
2379 | { | ||
2380 | unsigned int idx; | ||
2381 | struct pvr2_ctrl *cptr; | ||
2382 | int disruptive_change; | ||
2383 | |||
2521 | /* When video standard changes, reset the hres and vres values - | 2384 | /* When video standard changes, reset the hres and vres values - |
2522 | but if the user has pending changes there, then let the changes | 2385 | but if the user has pending changes there, then let the changes |
2523 | take priority. */ | 2386 | take priority. */ |
@@ -2536,24 +2399,26 @@ static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) | |||
2536 | } | 2399 | } |
2537 | } | 2400 | } |
2538 | 2401 | ||
2539 | if (hdw->std_dirty || | 2402 | /* If any of the below has changed, then we can't do the update |
2540 | hdw->enc_stale || | 2403 | while the pipeline is running. Pipeline must be paused first |
2541 | hdw->srate_dirty || | 2404 | and decoder -> encoder connection be made quiescent before we |
2542 | hdw->res_ver_dirty || | 2405 | can proceed. */ |
2543 | hdw->res_hor_dirty || | 2406 | disruptive_change = |
2544 | 0) { | 2407 | (hdw->std_dirty || |
2545 | /* If any of this changes, then the encoder needs to be | 2408 | hdw->enc_unsafe_stale || |
2546 | reconfigured, and we need to reset the stream. */ | 2409 | hdw->srate_dirty || |
2547 | stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); | 2410 | hdw->res_ver_dirty || |
2548 | } | 2411 | hdw->res_hor_dirty || |
2549 | 2412 | hdw->input_dirty || | |
2550 | if (hdw->input_dirty) { | 2413 | (hdw->active_stream_type != hdw->desired_stream_type)); |
2551 | /* pk: If input changes to or from radio, then the encoder | 2414 | if (disruptive_change && !hdw->state_pipeline_idle) { |
2552 | needs to be restarted (for ENC_MUTE_VIDEO to work) */ | 2415 | /* Pipeline is not idle; we can't proceed. Arrange to |
2553 | stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN); | 2416 | cause pipeline to stop so that we can try this again |
2417 | later.... */ | ||
2418 | hdw->state_pipeline_pause = !0; | ||
2419 | return 0; | ||
2554 | } | 2420 | } |
2555 | 2421 | ||
2556 | |||
2557 | if (hdw->srate_dirty) { | 2422 | if (hdw->srate_dirty) { |
2558 | /* Write new sample rate into control structure since | 2423 | /* Write new sample rate into control structure since |
2559 | * the master copy is stale. We must track srate | 2424 | * the master copy is stale. We must track srate |
@@ -2582,51 +2447,88 @@ static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) | |||
2582 | cptr->info->clear_dirty(cptr); | 2447 | cptr->info->clear_dirty(cptr); |
2583 | } | 2448 | } |
2584 | 2449 | ||
2450 | if (hdw->active_stream_type != hdw->desired_stream_type) { | ||
2451 | /* Handle any side effects of stream config here */ | ||
2452 | hdw->active_stream_type = hdw->desired_stream_type; | ||
2453 | } | ||
2454 | |||
2585 | /* Now execute i2c core update */ | 2455 | /* Now execute i2c core update */ |
2586 | pvr2_i2c_core_sync(hdw); | 2456 | pvr2_i2c_core_sync(hdw); |
2587 | 2457 | ||
2588 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0); | 2458 | if (hdw->state_encoder_run) { |
2589 | pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask); | 2459 | /* If encoder isn't running, then this will get worked out |
2460 | later when we start the encoder. */ | ||
2461 | if (pvr2_encoder_adjust(hdw) < 0) return !0; | ||
2462 | } | ||
2590 | 2463 | ||
2591 | return 0; | 2464 | hdw->state_pipeline_config = !0; |
2465 | trace_stbit("state_pipeline_config",hdw->state_pipeline_config); | ||
2466 | return !0; | ||
2592 | } | 2467 | } |
2593 | 2468 | ||
2594 | 2469 | ||
2595 | int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw) | 2470 | int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw) |
2596 | { | 2471 | { |
2472 | int fl; | ||
2473 | LOCK_TAKE(hdw->big_lock); | ||
2474 | fl = pvr2_hdw_commit_setup(hdw); | ||
2475 | LOCK_GIVE(hdw->big_lock); | ||
2476 | if (!fl) return 0; | ||
2477 | return pvr2_hdw_wait(hdw,0); | ||
2478 | } | ||
2479 | |||
2480 | |||
2481 | static void pvr2_hdw_worker_i2c(struct work_struct *work) | ||
2482 | { | ||
2483 | struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,worki2csync); | ||
2597 | LOCK_TAKE(hdw->big_lock); do { | 2484 | LOCK_TAKE(hdw->big_lock); do { |
2598 | pvr2_hdw_commit_ctl_internal(hdw); | 2485 | pvr2_i2c_core_sync(hdw); |
2599 | } while (0); LOCK_GIVE(hdw->big_lock); | 2486 | } while (0); LOCK_GIVE(hdw->big_lock); |
2600 | return 0; | ||
2601 | } | 2487 | } |
2602 | 2488 | ||
2603 | 2489 | ||
2604 | void pvr2_hdw_poll(struct pvr2_hdw *hdw) | 2490 | static void pvr2_hdw_worker_poll(struct work_struct *work) |
2605 | { | 2491 | { |
2492 | int fl = 0; | ||
2493 | struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,workpoll); | ||
2606 | LOCK_TAKE(hdw->big_lock); do { | 2494 | LOCK_TAKE(hdw->big_lock); do { |
2607 | pvr2_i2c_core_sync(hdw); | 2495 | fl = pvr2_hdw_state_eval(hdw); |
2608 | } while (0); LOCK_GIVE(hdw->big_lock); | 2496 | } while (0); LOCK_GIVE(hdw->big_lock); |
2497 | if (fl && hdw->state_func) { | ||
2498 | hdw->state_func(hdw->state_data); | ||
2499 | } | ||
2609 | } | 2500 | } |
2610 | 2501 | ||
2611 | 2502 | ||
2612 | void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw, | 2503 | static void pvr2_hdw_worker_init(struct work_struct *work) |
2613 | void (*func)(void *), | ||
2614 | void *data) | ||
2615 | { | 2504 | { |
2505 | struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,workinit); | ||
2616 | LOCK_TAKE(hdw->big_lock); do { | 2506 | LOCK_TAKE(hdw->big_lock); do { |
2617 | hdw->poll_trigger_func = func; | 2507 | pvr2_hdw_setup(hdw); |
2618 | hdw->poll_trigger_data = data; | ||
2619 | } while (0); LOCK_GIVE(hdw->big_lock); | 2508 | } while (0); LOCK_GIVE(hdw->big_lock); |
2620 | } | 2509 | } |
2621 | 2510 | ||
2622 | 2511 | ||
2623 | void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw) | 2512 | static int pvr2_hdw_wait(struct pvr2_hdw *hdw,int state) |
2624 | { | 2513 | { |
2625 | if (hdw->poll_trigger_func) { | 2514 | return wait_event_interruptible( |
2626 | hdw->poll_trigger_func(hdw->poll_trigger_data); | 2515 | hdw->state_wait_data, |
2627 | } | 2516 | (hdw->state_stale == 0) && |
2517 | (!state || (hdw->master_state != state))); | ||
2518 | } | ||
2519 | |||
2520 | |||
2521 | void pvr2_hdw_set_state_callback(struct pvr2_hdw *hdw, | ||
2522 | void (*callback_func)(void *), | ||
2523 | void *callback_data) | ||
2524 | { | ||
2525 | LOCK_TAKE(hdw->big_lock); do { | ||
2526 | hdw->state_data = callback_data; | ||
2527 | hdw->state_func = callback_func; | ||
2528 | } while (0); LOCK_GIVE(hdw->big_lock); | ||
2628 | } | 2529 | } |
2629 | 2530 | ||
2531 | |||
2630 | /* Return name for this driver instance */ | 2532 | /* Return name for this driver instance */ |
2631 | const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) | 2533 | const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) |
2632 | { | 2534 | { |
@@ -2689,6 +2591,7 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) | |||
2689 | pvr2_i2c_core_sync(hdw); | 2591 | pvr2_i2c_core_sync(hdw); |
2690 | pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); | 2592 | pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); |
2691 | cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2"); | 2593 | cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2"); |
2594 | pvr2_hdw_state_log_state(hdw); | ||
2692 | printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); | 2595 | printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); |
2693 | } while (0); LOCK_GIVE(hdw->big_lock); | 2596 | } while (0); LOCK_GIVE(hdw->big_lock); |
2694 | } | 2597 | } |
@@ -2959,7 +2862,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, | |||
2959 | " without lock!!"); | 2862 | " without lock!!"); |
2960 | return -EDEADLK; | 2863 | return -EDEADLK; |
2961 | } | 2864 | } |
2962 | if ((!hdw->flag_ok) && !probe_fl) { | 2865 | if (!hdw->flag_ok && !probe_fl) { |
2963 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 2866 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
2964 | "Attempted to execute control transfer" | 2867 | "Attempted to execute control transfer" |
2965 | " when device not ok"); | 2868 | " when device not ok"); |
@@ -3167,7 +3070,7 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw, | |||
3167 | 3070 | ||
3168 | hdw->cmd_debug_state = 0; | 3071 | hdw->cmd_debug_state = 0; |
3169 | if ((status < 0) && (!probe_fl)) { | 3072 | if ((status < 0) && (!probe_fl)) { |
3170 | pvr2_hdw_render_useless_unlocked(hdw); | 3073 | pvr2_hdw_render_useless(hdw); |
3171 | } | 3074 | } |
3172 | return status; | 3075 | return status; |
3173 | } | 3076 | } |
@@ -3227,24 +3130,17 @@ static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data) | |||
3227 | } | 3130 | } |
3228 | 3131 | ||
3229 | 3132 | ||
3230 | static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw) | 3133 | void pvr2_hdw_render_useless(struct pvr2_hdw *hdw) |
3231 | { | 3134 | { |
3232 | if (!hdw->flag_ok) return; | 3135 | if (!hdw->flag_ok) return; |
3233 | pvr2_trace(PVR2_TRACE_INIT,"render_useless"); | 3136 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
3234 | hdw->flag_ok = 0; | 3137 | "Device being rendered inoperable"); |
3235 | if (hdw->vid_stream) { | 3138 | if (hdw->vid_stream) { |
3236 | pvr2_stream_setup(hdw->vid_stream,NULL,0,0); | 3139 | pvr2_stream_setup(hdw->vid_stream,NULL,0,0); |
3237 | } | 3140 | } |
3238 | hdw->flag_streaming_enabled = 0; | 3141 | hdw->flag_ok = 0; |
3239 | hdw->subsys_enabled_mask = 0; | 3142 | trace_stbit("flag_ok",hdw->flag_ok); |
3240 | } | 3143 | pvr2_hdw_state_sched(hdw); |
3241 | |||
3242 | |||
3243 | void pvr2_hdw_render_useless(struct pvr2_hdw *hdw) | ||
3244 | { | ||
3245 | LOCK_TAKE(hdw->ctl_lock); | ||
3246 | pvr2_hdw_render_useless_unlocked(hdw); | ||
3247 | LOCK_GIVE(hdw->ctl_lock); | ||
3248 | } | 3144 | } |
3249 | 3145 | ||
3250 | 3146 | ||
@@ -3299,7 +3195,6 @@ int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) | |||
3299 | int status; | 3195 | int status; |
3300 | LOCK_TAKE(hdw->ctl_lock); do { | 3196 | LOCK_TAKE(hdw->ctl_lock); do { |
3301 | pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset"); | 3197 | pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset"); |
3302 | hdw->flag_ok = !0; | ||
3303 | hdw->cmd_buffer[0] = FX2CMD_DEEP_RESET; | 3198 | hdw->cmd_buffer[0] = FX2CMD_DEEP_RESET; |
3304 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | 3199 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); |
3305 | } while (0); LOCK_GIVE(hdw->ctl_lock); | 3200 | } while (0); LOCK_GIVE(hdw->ctl_lock); |
@@ -3349,26 +3244,473 @@ static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) | |||
3349 | (runFl ? FX2CMD_STREAMING_ON : FX2CMD_STREAMING_OFF); | 3244 | (runFl ? FX2CMD_STREAMING_ON : FX2CMD_STREAMING_OFF); |
3350 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | 3245 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); |
3351 | } while (0); LOCK_GIVE(hdw->ctl_lock); | 3246 | } while (0); LOCK_GIVE(hdw->ctl_lock); |
3352 | if (!status) { | ||
3353 | hdw->subsys_enabled_mask = | ||
3354 | ((hdw->subsys_enabled_mask & | ||
3355 | ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) | | ||
3356 | (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0)); | ||
3357 | } | ||
3358 | return status; | 3247 | return status; |
3359 | } | 3248 | } |
3360 | 3249 | ||
3361 | 3250 | ||
3362 | void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw, | 3251 | /* Evaluate whether or not state_encoder_ok can change */ |
3363 | struct pvr2_hdw_debug_info *ptr) | 3252 | static int state_eval_encoder_ok(struct pvr2_hdw *hdw) |
3253 | { | ||
3254 | if (hdw->state_encoder_ok) return 0; | ||
3255 | if (hdw->flag_tripped) return 0; | ||
3256 | if (hdw->state_encoder_run) return 0; | ||
3257 | if (hdw->state_encoder_config) return 0; | ||
3258 | if (hdw->state_decoder_run) return 0; | ||
3259 | if (hdw->state_usbstream_run) return 0; | ||
3260 | if (pvr2_upload_firmware2(hdw) < 0) { | ||
3261 | hdw->flag_tripped = !0; | ||
3262 | trace_stbit("flag_tripped",hdw->flag_tripped); | ||
3263 | return !0; | ||
3264 | } | ||
3265 | hdw->state_encoder_ok = !0; | ||
3266 | trace_stbit("state_encoder_ok",hdw->state_encoder_ok); | ||
3267 | return !0; | ||
3268 | } | ||
3269 | |||
3270 | |||
3271 | /* Evaluate whether or not state_encoder_config can change */ | ||
3272 | static int state_eval_encoder_config(struct pvr2_hdw *hdw) | ||
3273 | { | ||
3274 | if (hdw->state_encoder_config) { | ||
3275 | if (hdw->state_encoder_ok) { | ||
3276 | if (hdw->state_pipeline_req && | ||
3277 | !hdw->state_pipeline_pause) return 0; | ||
3278 | } | ||
3279 | hdw->state_encoder_config = 0; | ||
3280 | hdw->state_encoder_waitok = 0; | ||
3281 | trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok); | ||
3282 | /* paranoia - solve race if timer just completed */ | ||
3283 | del_timer_sync(&hdw->encoder_wait_timer); | ||
3284 | } else { | ||
3285 | if (!hdw->state_encoder_ok || | ||
3286 | !hdw->state_pipeline_idle || | ||
3287 | hdw->state_pipeline_pause || | ||
3288 | !hdw->state_pipeline_req || | ||
3289 | !hdw->state_pipeline_config) { | ||
3290 | /* We must reset the enforced wait interval if | ||
3291 | anything has happened that might have disturbed | ||
3292 | the encoder. This should be a rare case. */ | ||
3293 | if (timer_pending(&hdw->encoder_wait_timer)) { | ||
3294 | del_timer_sync(&hdw->encoder_wait_timer); | ||
3295 | } | ||
3296 | if (hdw->state_encoder_waitok) { | ||
3297 | /* Must clear the state - therefore we did | ||
3298 | something to a state bit and must also | ||
3299 | return true. */ | ||
3300 | hdw->state_encoder_waitok = 0; | ||
3301 | trace_stbit("state_encoder_waitok", | ||
3302 | hdw->state_encoder_waitok); | ||
3303 | return !0; | ||
3304 | } | ||
3305 | return 0; | ||
3306 | } | ||
3307 | if (!hdw->state_encoder_waitok) { | ||
3308 | if (!timer_pending(&hdw->encoder_wait_timer)) { | ||
3309 | /* waitok flag wasn't set and timer isn't | ||
3310 | running. Check flag once more to avoid | ||
3311 | a race then start the timer. This is | ||
3312 | the point when we measure out a minimal | ||
3313 | quiet interval before doing something to | ||
3314 | the encoder. */ | ||
3315 | if (!hdw->state_encoder_waitok) { | ||
3316 | hdw->encoder_wait_timer.expires = | ||
3317 | jiffies + (HZ*50/1000); | ||
3318 | add_timer(&hdw->encoder_wait_timer); | ||
3319 | } | ||
3320 | } | ||
3321 | /* We can't continue until we know we have been | ||
3322 | quiet for the interval measured by this | ||
3323 | timer. */ | ||
3324 | return 0; | ||
3325 | } | ||
3326 | pvr2_encoder_configure(hdw); | ||
3327 | if (hdw->state_encoder_ok) hdw->state_encoder_config = !0; | ||
3328 | } | ||
3329 | trace_stbit("state_encoder_config",hdw->state_encoder_config); | ||
3330 | return !0; | ||
3331 | } | ||
3332 | |||
3333 | |||
3334 | /* Evaluate whether or not state_encoder_run can change */ | ||
3335 | static int state_eval_encoder_run(struct pvr2_hdw *hdw) | ||
3336 | { | ||
3337 | if (hdw->state_encoder_run) { | ||
3338 | if (hdw->state_encoder_ok) { | ||
3339 | if (hdw->state_decoder_run) return 0; | ||
3340 | if (pvr2_encoder_stop(hdw) < 0) return !0; | ||
3341 | } | ||
3342 | hdw->state_encoder_run = 0; | ||
3343 | } else { | ||
3344 | if (!hdw->state_encoder_ok) return 0; | ||
3345 | if (!hdw->state_decoder_run) return 0; | ||
3346 | if (pvr2_encoder_start(hdw) < 0) return !0; | ||
3347 | hdw->state_encoder_run = !0; | ||
3348 | } | ||
3349 | trace_stbit("state_encoder_run",hdw->state_encoder_run); | ||
3350 | return !0; | ||
3351 | } | ||
3352 | |||
3353 | |||
3354 | /* Timeout function for quiescent timer. */ | ||
3355 | static void pvr2_hdw_quiescent_timeout(unsigned long data) | ||
3356 | { | ||
3357 | struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; | ||
3358 | hdw->state_decoder_quiescent = !0; | ||
3359 | trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent); | ||
3360 | hdw->state_stale = !0; | ||
3361 | queue_work(hdw->workqueue,&hdw->workpoll); | ||
3362 | } | ||
3363 | |||
3364 | |||
3365 | /* Timeout function for encoder wait timer. */ | ||
3366 | static void pvr2_hdw_encoder_wait_timeout(unsigned long data) | ||
3367 | { | ||
3368 | struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; | ||
3369 | hdw->state_encoder_waitok = !0; | ||
3370 | trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok); | ||
3371 | hdw->state_stale = !0; | ||
3372 | queue_work(hdw->workqueue,&hdw->workpoll); | ||
3373 | } | ||
3374 | |||
3375 | |||
3376 | /* Evaluate whether or not state_decoder_run can change */ | ||
3377 | static int state_eval_decoder_run(struct pvr2_hdw *hdw) | ||
3378 | { | ||
3379 | if (hdw->state_decoder_run) { | ||
3380 | if (hdw->state_encoder_ok) { | ||
3381 | if (hdw->state_pipeline_req && | ||
3382 | !hdw->state_pipeline_pause) return 0; | ||
3383 | } | ||
3384 | if (!hdw->flag_decoder_missed) { | ||
3385 | pvr2_decoder_enable(hdw,0); | ||
3386 | } | ||
3387 | hdw->state_decoder_quiescent = 0; | ||
3388 | hdw->state_decoder_run = 0; | ||
3389 | /* paranoia - solve race if timer just completed */ | ||
3390 | del_timer_sync(&hdw->quiescent_timer); | ||
3391 | } else { | ||
3392 | if (!hdw->state_decoder_quiescent) { | ||
3393 | if (!timer_pending(&hdw->quiescent_timer)) { | ||
3394 | /* We don't do something about the | ||
3395 | quiescent timer until right here because | ||
3396 | we also want to catch cases where the | ||
3397 | decoder was already not running (like | ||
3398 | after initialization) as opposed to | ||
3399 | knowing that we had just stopped it. | ||
3400 | The second flag check is here to cover a | ||
3401 | race - the timer could have run and set | ||
3402 | this flag just after the previous check | ||
3403 | but before we did the pending check. */ | ||
3404 | if (!hdw->state_decoder_quiescent) { | ||
3405 | hdw->quiescent_timer.expires = | ||
3406 | jiffies + (HZ*50/1000); | ||
3407 | add_timer(&hdw->quiescent_timer); | ||
3408 | } | ||
3409 | } | ||
3410 | /* Don't allow decoder to start again until it has | ||
3411 | been quiesced first. This little detail should | ||
3412 | hopefully further stabilize the encoder. */ | ||
3413 | return 0; | ||
3414 | } | ||
3415 | if (!hdw->state_pipeline_req || | ||
3416 | hdw->state_pipeline_pause || | ||
3417 | !hdw->state_pipeline_config || | ||
3418 | !hdw->state_encoder_config || | ||
3419 | !hdw->state_encoder_ok) return 0; | ||
3420 | del_timer_sync(&hdw->quiescent_timer); | ||
3421 | if (hdw->flag_decoder_missed) return 0; | ||
3422 | if (pvr2_decoder_enable(hdw,!0) < 0) return 0; | ||
3423 | hdw->state_decoder_quiescent = 0; | ||
3424 | hdw->state_decoder_run = !0; | ||
3425 | } | ||
3426 | trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent); | ||
3427 | trace_stbit("state_decoder_run",hdw->state_decoder_run); | ||
3428 | return !0; | ||
3429 | } | ||
3430 | |||
3431 | |||
3432 | /* Evaluate whether or not state_usbstream_run can change */ | ||
3433 | static int state_eval_usbstream_run(struct pvr2_hdw *hdw) | ||
3434 | { | ||
3435 | if (hdw->state_usbstream_run) { | ||
3436 | if (hdw->state_encoder_ok) { | ||
3437 | if (hdw->state_encoder_run) return 0; | ||
3438 | } | ||
3439 | pvr2_hdw_cmd_usbstream(hdw,0); | ||
3440 | hdw->state_usbstream_run = 0; | ||
3441 | } else { | ||
3442 | if (!hdw->state_encoder_ok || | ||
3443 | !hdw->state_encoder_run || | ||
3444 | !hdw->state_pipeline_req || | ||
3445 | hdw->state_pipeline_pause) return 0; | ||
3446 | if (pvr2_hdw_cmd_usbstream(hdw,!0) < 0) return 0; | ||
3447 | hdw->state_usbstream_run = !0; | ||
3448 | } | ||
3449 | trace_stbit("state_usbstream_run",hdw->state_usbstream_run); | ||
3450 | return !0; | ||
3451 | } | ||
3452 | |||
3453 | |||
3454 | /* Attempt to configure pipeline, if needed */ | ||
3455 | static int state_eval_pipeline_config(struct pvr2_hdw *hdw) | ||
3456 | { | ||
3457 | if (hdw->state_pipeline_config || | ||
3458 | hdw->state_pipeline_pause) return 0; | ||
3459 | pvr2_hdw_commit_execute(hdw); | ||
3460 | return !0; | ||
3461 | } | ||
3462 | |||
3463 | |||
3464 | /* Update pipeline idle and pipeline pause tracking states based on other | ||
3465 | inputs. This must be called whenever the other relevant inputs have | ||
3466 | changed. */ | ||
3467 | static int state_update_pipeline_state(struct pvr2_hdw *hdw) | ||
3468 | { | ||
3469 | unsigned int st; | ||
3470 | int updatedFl = 0; | ||
3471 | /* Update pipeline state */ | ||
3472 | st = !(hdw->state_encoder_run || | ||
3473 | hdw->state_decoder_run || | ||
3474 | hdw->state_usbstream_run || | ||
3475 | (!hdw->state_decoder_quiescent)); | ||
3476 | if (!st != !hdw->state_pipeline_idle) { | ||
3477 | hdw->state_pipeline_idle = st; | ||
3478 | updatedFl = !0; | ||
3479 | } | ||
3480 | if (hdw->state_pipeline_idle && hdw->state_pipeline_pause) { | ||
3481 | hdw->state_pipeline_pause = 0; | ||
3482 | updatedFl = !0; | ||
3483 | } | ||
3484 | return updatedFl; | ||
3485 | } | ||
3486 | |||
3487 | |||
3488 | typedef int (*state_eval_func)(struct pvr2_hdw *); | ||
3489 | |||
3490 | /* Set of functions to be run to evaluate various states in the driver. */ | ||
3491 | const static state_eval_func eval_funcs[] = { | ||
3492 | state_eval_pipeline_config, | ||
3493 | state_eval_encoder_ok, | ||
3494 | state_eval_encoder_config, | ||
3495 | state_eval_decoder_run, | ||
3496 | state_eval_encoder_run, | ||
3497 | state_eval_usbstream_run, | ||
3498 | }; | ||
3499 | |||
3500 | |||
3501 | /* Process various states and return true if we did anything interesting. */ | ||
3502 | static int pvr2_hdw_state_update(struct pvr2_hdw *hdw) | ||
3503 | { | ||
3504 | unsigned int i; | ||
3505 | int state_updated = 0; | ||
3506 | int check_flag; | ||
3507 | |||
3508 | if (!hdw->state_stale) return 0; | ||
3509 | if ((hdw->fw1_state != FW1_STATE_OK) || | ||
3510 | !hdw->flag_ok) { | ||
3511 | hdw->state_stale = 0; | ||
3512 | return !0; | ||
3513 | } | ||
3514 | /* This loop is the heart of the entire driver. It keeps trying to | ||
3515 | evaluate various bits of driver state until nothing changes for | ||
3516 | one full iteration. Each "bit of state" tracks some global | ||
3517 | aspect of the driver, e.g. whether decoder should run, if | ||
3518 | pipeline is configured, usb streaming is on, etc. We separately | ||
3519 | evaluate each of those questions based on other driver state to | ||
3520 | arrive at the correct running configuration. */ | ||
3521 | do { | ||
3522 | check_flag = 0; | ||
3523 | state_update_pipeline_state(hdw); | ||
3524 | /* Iterate over each bit of state */ | ||
3525 | for (i = 0; (i<ARRAY_SIZE(eval_funcs)) && hdw->flag_ok; i++) { | ||
3526 | if ((*eval_funcs[i])(hdw)) { | ||
3527 | check_flag = !0; | ||
3528 | state_updated = !0; | ||
3529 | state_update_pipeline_state(hdw); | ||
3530 | } | ||
3531 | } | ||
3532 | } while (check_flag && hdw->flag_ok); | ||
3533 | hdw->state_stale = 0; | ||
3534 | trace_stbit("state_stale",hdw->state_stale); | ||
3535 | return state_updated; | ||
3536 | } | ||
3537 | |||
3538 | |||
3539 | static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which, | ||
3540 | char *buf,unsigned int acnt) | ||
3541 | { | ||
3542 | switch (which) { | ||
3543 | case 0: | ||
3544 | return scnprintf( | ||
3545 | buf,acnt, | ||
3546 | "driver:%s%s%s%s%s", | ||
3547 | (hdw->flag_ok ? " <ok>" : " <fail>"), | ||
3548 | (hdw->flag_init_ok ? " <init>" : " <uninitialized>"), | ||
3549 | (hdw->flag_disconnected ? " <disconnected>" : | ||
3550 | " <connected>"), | ||
3551 | (hdw->flag_tripped ? " <tripped>" : ""), | ||
3552 | (hdw->flag_decoder_missed ? " <no decoder>" : "")); | ||
3553 | case 1: | ||
3554 | return scnprintf( | ||
3555 | buf,acnt, | ||
3556 | "pipeline:%s%s%s%s", | ||
3557 | (hdw->state_pipeline_idle ? " <idle>" : ""), | ||
3558 | (hdw->state_pipeline_config ? | ||
3559 | " <configok>" : " <stale>"), | ||
3560 | (hdw->state_pipeline_req ? " <req>" : ""), | ||
3561 | (hdw->state_pipeline_pause ? " <pause>" : "")); | ||
3562 | case 2: | ||
3563 | return scnprintf( | ||
3564 | buf,acnt, | ||
3565 | "worker:%s%s%s%s%s%s", | ||
3566 | (hdw->state_decoder_run ? | ||
3567 | " <decode:run>" : | ||
3568 | (hdw->state_decoder_quiescent ? | ||
3569 | "" : " <decode:stop>")), | ||
3570 | (hdw->state_decoder_quiescent ? | ||
3571 | " <decode:quiescent>" : ""), | ||
3572 | (hdw->state_encoder_ok ? | ||
3573 | "" : " <encode:init>"), | ||
3574 | (hdw->state_encoder_run ? | ||
3575 | " <encode:run>" : " <encode:stop>"), | ||
3576 | (hdw->state_encoder_config ? | ||
3577 | " <encode:configok>" : | ||
3578 | (hdw->state_encoder_waitok ? | ||
3579 | "" : " <encode:wait>")), | ||
3580 | (hdw->state_usbstream_run ? | ||
3581 | " <usb:run>" : " <usb:stop>")); | ||
3582 | break; | ||
3583 | case 3: | ||
3584 | return scnprintf( | ||
3585 | buf,acnt, | ||
3586 | "state: %s", | ||
3587 | pvr2_get_state_name(hdw->master_state)); | ||
3588 | break; | ||
3589 | default: break; | ||
3590 | } | ||
3591 | return 0; | ||
3592 | } | ||
3593 | |||
3594 | |||
3595 | unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw, | ||
3596 | char *buf,unsigned int acnt) | ||
3597 | { | ||
3598 | unsigned int bcnt,ccnt,idx; | ||
3599 | bcnt = 0; | ||
3600 | LOCK_TAKE(hdw->big_lock); | ||
3601 | for (idx = 0; ; idx++) { | ||
3602 | ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,acnt); | ||
3603 | if (!ccnt) break; | ||
3604 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
3605 | if (!acnt) break; | ||
3606 | buf[0] = '\n'; ccnt = 1; | ||
3607 | bcnt += ccnt; acnt -= ccnt; buf += ccnt; | ||
3608 | } | ||
3609 | LOCK_GIVE(hdw->big_lock); | ||
3610 | return bcnt; | ||
3611 | } | ||
3612 | |||
3613 | |||
3614 | static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw) | ||
3615 | { | ||
3616 | char buf[128]; | ||
3617 | unsigned int idx,ccnt; | ||
3618 | |||
3619 | for (idx = 0; ; idx++) { | ||
3620 | ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf)); | ||
3621 | if (!ccnt) break; | ||
3622 | printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf); | ||
3623 | } | ||
3624 | } | ||
3625 | |||
3626 | |||
3627 | /* Evaluate and update the driver's current state, taking various actions | ||
3628 | as appropriate for the update. */ | ||
3629 | static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw) | ||
3630 | { | ||
3631 | unsigned int st; | ||
3632 | int state_updated = 0; | ||
3633 | int callback_flag = 0; | ||
3634 | |||
3635 | pvr2_trace(PVR2_TRACE_STBITS, | ||
3636 | "Drive state check START"); | ||
3637 | if (pvrusb2_debug & PVR2_TRACE_STBITS) { | ||
3638 | pvr2_hdw_state_log_state(hdw); | ||
3639 | } | ||
3640 | |||
3641 | /* Process all state and get back over disposition */ | ||
3642 | state_updated = pvr2_hdw_state_update(hdw); | ||
3643 | |||
3644 | /* Update master state based upon all other states. */ | ||
3645 | if (!hdw->flag_ok) { | ||
3646 | st = PVR2_STATE_DEAD; | ||
3647 | } else if (hdw->fw1_state != FW1_STATE_OK) { | ||
3648 | st = PVR2_STATE_COLD; | ||
3649 | } else if (!hdw->state_encoder_ok) { | ||
3650 | st = PVR2_STATE_WARM; | ||
3651 | } else if (hdw->flag_tripped || hdw->flag_decoder_missed) { | ||
3652 | st = PVR2_STATE_ERROR; | ||
3653 | } else if (hdw->state_encoder_run && | ||
3654 | hdw->state_decoder_run && | ||
3655 | hdw->state_usbstream_run) { | ||
3656 | st = PVR2_STATE_RUN; | ||
3657 | } else { | ||
3658 | st = PVR2_STATE_READY; | ||
3659 | } | ||
3660 | if (hdw->master_state != st) { | ||
3661 | pvr2_trace(PVR2_TRACE_STATE, | ||
3662 | "Device state change from %s to %s", | ||
3663 | pvr2_get_state_name(hdw->master_state), | ||
3664 | pvr2_get_state_name(st)); | ||
3665 | hdw->master_state = st; | ||
3666 | state_updated = !0; | ||
3667 | callback_flag = !0; | ||
3668 | } | ||
3669 | if (state_updated) { | ||
3670 | /* Trigger anyone waiting on any state changes here. */ | ||
3671 | wake_up(&hdw->state_wait_data); | ||
3672 | } | ||
3673 | |||
3674 | if (pvrusb2_debug & PVR2_TRACE_STBITS) { | ||
3675 | pvr2_hdw_state_log_state(hdw); | ||
3676 | } | ||
3677 | pvr2_trace(PVR2_TRACE_STBITS, | ||
3678 | "Drive state check DONE callback=%d",callback_flag); | ||
3679 | |||
3680 | return callback_flag; | ||
3681 | } | ||
3682 | |||
3683 | |||
3684 | /* Cause kernel thread to check / update driver state */ | ||
3685 | static void pvr2_hdw_state_sched(struct pvr2_hdw *hdw) | ||
3686 | { | ||
3687 | if (hdw->state_stale) return; | ||
3688 | hdw->state_stale = !0; | ||
3689 | trace_stbit("state_stale",hdw->state_stale); | ||
3690 | queue_work(hdw->workqueue,&hdw->workpoll); | ||
3691 | } | ||
3692 | |||
3693 | |||
3694 | void pvr2_hdw_get_debug_info_unlocked(const struct pvr2_hdw *hdw, | ||
3695 | struct pvr2_hdw_debug_info *ptr) | ||
3364 | { | 3696 | { |
3365 | ptr->big_lock_held = hdw->big_lock_held; | 3697 | ptr->big_lock_held = hdw->big_lock_held; |
3366 | ptr->ctl_lock_held = hdw->ctl_lock_held; | 3698 | ptr->ctl_lock_held = hdw->ctl_lock_held; |
3367 | ptr->flag_ok = hdw->flag_ok; | ||
3368 | ptr->flag_disconnected = hdw->flag_disconnected; | 3699 | ptr->flag_disconnected = hdw->flag_disconnected; |
3369 | ptr->flag_init_ok = hdw->flag_init_ok; | 3700 | ptr->flag_init_ok = hdw->flag_init_ok; |
3370 | ptr->flag_streaming_enabled = hdw->flag_streaming_enabled; | 3701 | ptr->flag_ok = hdw->flag_ok; |
3371 | ptr->subsys_flags = hdw->subsys_enabled_mask; | 3702 | ptr->fw1_state = hdw->fw1_state; |
3703 | ptr->flag_decoder_missed = hdw->flag_decoder_missed; | ||
3704 | ptr->flag_tripped = hdw->flag_tripped; | ||
3705 | ptr->state_encoder_ok = hdw->state_encoder_ok; | ||
3706 | ptr->state_encoder_run = hdw->state_encoder_run; | ||
3707 | ptr->state_decoder_run = hdw->state_decoder_run; | ||
3708 | ptr->state_usbstream_run = hdw->state_usbstream_run; | ||
3709 | ptr->state_decoder_quiescent = hdw->state_decoder_quiescent; | ||
3710 | ptr->state_pipeline_config = hdw->state_pipeline_config; | ||
3711 | ptr->state_pipeline_req = hdw->state_pipeline_req; | ||
3712 | ptr->state_pipeline_pause = hdw->state_pipeline_pause; | ||
3713 | ptr->state_pipeline_idle = hdw->state_pipeline_idle; | ||
3372 | ptr->cmd_debug_state = hdw->cmd_debug_state; | 3714 | ptr->cmd_debug_state = hdw->cmd_debug_state; |
3373 | ptr->cmd_code = hdw->cmd_debug_code; | 3715 | ptr->cmd_code = hdw->cmd_debug_code; |
3374 | ptr->cmd_debug_write_len = hdw->cmd_debug_write_len; | 3716 | ptr->cmd_debug_write_len = hdw->cmd_debug_write_len; |
@@ -3381,6 +3723,15 @@ void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw, | |||
3381 | } | 3723 | } |
3382 | 3724 | ||
3383 | 3725 | ||
3726 | void pvr2_hdw_get_debug_info_locked(struct pvr2_hdw *hdw, | ||
3727 | struct pvr2_hdw_debug_info *ptr) | ||
3728 | { | ||
3729 | LOCK_TAKE(hdw->ctl_lock); do { | ||
3730 | pvr2_hdw_get_debug_info_unlocked(hdw,ptr); | ||
3731 | } while(0); LOCK_GIVE(hdw->ctl_lock); | ||
3732 | } | ||
3733 | |||
3734 | |||
3384 | int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp) | 3735 | int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp) |
3385 | { | 3736 | { |
3386 | return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp); | 3737 | return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp); |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index e2f9d5e4cb65..383685f7c81f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h | |||
@@ -44,27 +44,6 @@ | |||
44 | #define PVR2_CVAL_INPUT_COMPOSITE 2 | 44 | #define PVR2_CVAL_INPUT_COMPOSITE 2 |
45 | #define PVR2_CVAL_INPUT_RADIO 3 | 45 | #define PVR2_CVAL_INPUT_RADIO 3 |
46 | 46 | ||
47 | /* Subsystem definitions - these are various pieces that can be | ||
48 | independently stopped / started. Usually you don't want to mess with | ||
49 | this directly (let the driver handle things itself), but it is useful | ||
50 | for debugging. */ | ||
51 | #define PVR2_SUBSYS_B_ENC_FIRMWARE 0 | ||
52 | #define PVR2_SUBSYS_B_ENC_CFG 1 | ||
53 | #define PVR2_SUBSYS_B_DIGITIZER_RUN 2 | ||
54 | #define PVR2_SUBSYS_B_USBSTREAM_RUN 3 | ||
55 | #define PVR2_SUBSYS_B_ENC_RUN 4 | ||
56 | |||
57 | #define PVR2_SUBSYS_CFG_ALL ( \ | ||
58 | (1 << PVR2_SUBSYS_B_ENC_FIRMWARE) | \ | ||
59 | (1 << PVR2_SUBSYS_B_ENC_CFG) ) | ||
60 | #define PVR2_SUBSYS_RUN_ALL ( \ | ||
61 | (1 << PVR2_SUBSYS_B_DIGITIZER_RUN) | \ | ||
62 | (1 << PVR2_SUBSYS_B_USBSTREAM_RUN) | \ | ||
63 | (1 << PVR2_SUBSYS_B_ENC_RUN) ) | ||
64 | #define PVR2_SUBSYS_ALL ( \ | ||
65 | PVR2_SUBSYS_CFG_ALL | \ | ||
66 | PVR2_SUBSYS_RUN_ALL ) | ||
67 | |||
68 | enum pvr2_config { | 47 | enum pvr2_config { |
69 | pvr2_config_empty, /* No configuration */ | 48 | pvr2_config_empty, /* No configuration */ |
70 | pvr2_config_mpeg, /* Encoded / compressed video */ | 49 | pvr2_config_mpeg, /* Encoded / compressed video */ |
@@ -79,8 +58,41 @@ enum pvr2_v4l_type { | |||
79 | pvr2_v4l_type_radio, | 58 | pvr2_v4l_type_radio, |
80 | }; | 59 | }; |
81 | 60 | ||
61 | /* Major states that we can be in: | ||
62 | * | ||
63 | * DEAD - Device is in an unusable state and cannot be recovered. This | ||
64 | * can happen if we completely lose the ability to communicate with it | ||
65 | * (but it might still on the bus). In this state there's nothing we can | ||
66 | * do; it must be replugged in order to recover. | ||
67 | * | ||
68 | * COLD - Device is in an unusuable state, needs microcontroller firmware. | ||
69 | * | ||
70 | * WARM - We can communicate with the device and the proper | ||
71 | * microcontroller firmware is running, but other device initialization is | ||
72 | * still needed (e.g. encoder firmware). | ||
73 | * | ||
74 | * ERROR - A problem prevents capture operation (e.g. encoder firmware | ||
75 | * missing). | ||
76 | * | ||
77 | * READY - Device is operational, but not streaming. | ||
78 | * | ||
79 | * RUN - Device is streaming. | ||
80 | * | ||
81 | */ | ||
82 | #define PVR2_STATE_NONE 0 | ||
83 | #define PVR2_STATE_DEAD 1 | ||
84 | #define PVR2_STATE_COLD 2 | ||
85 | #define PVR2_STATE_WARM 3 | ||
86 | #define PVR2_STATE_ERROR 4 | ||
87 | #define PVR2_STATE_READY 5 | ||
88 | #define PVR2_STATE_RUN 6 | ||
89 | |||
90 | /* Translate configuration enum to a string label */ | ||
82 | const char *pvr2_config_get_name(enum pvr2_config); | 91 | const char *pvr2_config_get_name(enum pvr2_config); |
83 | 92 | ||
93 | /* Translate a master state enum to a string label */ | ||
94 | const char *pvr2_hdw_get_state_name(unsigned int); | ||
95 | |||
84 | struct pvr2_hdw; | 96 | struct pvr2_hdw; |
85 | 97 | ||
86 | /* Create and return a structure for interacting with the underlying | 98 | /* Create and return a structure for interacting with the underlying |
@@ -88,28 +100,13 @@ struct pvr2_hdw; | |||
88 | struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | 100 | struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, |
89 | const struct usb_device_id *devid); | 101 | const struct usb_device_id *devid); |
90 | 102 | ||
91 | /* Poll for background activity (if any) */ | ||
92 | void pvr2_hdw_poll(struct pvr2_hdw *); | ||
93 | |||
94 | /* Trigger a poll to take place later at a convenient time */ | ||
95 | void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *); | ||
96 | |||
97 | /* Register a callback used to trigger a future poll */ | ||
98 | void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *, | ||
99 | void (*func)(void *), | ||
100 | void *data); | ||
101 | |||
102 | /* Destroy hardware interaction structure */ | 103 | /* Destroy hardware interaction structure */ |
103 | void pvr2_hdw_destroy(struct pvr2_hdw *); | 104 | void pvr2_hdw_destroy(struct pvr2_hdw *); |
104 | 105 | ||
105 | /* Set up the structure and attempt to put the device into a usable state. | 106 | /* Register a function to be called whenever the master state changes. */ |
106 | This can be a time-consuming operation, which is why it is not done | 107 | void pvr2_hdw_set_state_callback(struct pvr2_hdw *, |
107 | internally as part of the create() step. Return value is exactly the | 108 | void (*callback_func)(void *), |
108 | same as pvr2_hdw_init_ok(). */ | 109 | void *callback_data); |
109 | int pvr2_hdw_setup(struct pvr2_hdw *); | ||
110 | |||
111 | /* Initialization succeeded */ | ||
112 | int pvr2_hdw_init_ok(struct pvr2_hdw *); | ||
113 | 110 | ||
114 | /* Return true if in the ready (normal) state */ | 111 | /* Return true if in the ready (normal) state */ |
115 | int pvr2_hdw_dev_ok(struct pvr2_hdw *); | 112 | int pvr2_hdw_dev_ok(struct pvr2_hdw *); |
@@ -167,6 +164,9 @@ int pvr2_hdw_set_streaming(struct pvr2_hdw *,int); | |||
167 | /* Find out if streaming is on */ | 164 | /* Find out if streaming is on */ |
168 | int pvr2_hdw_get_streaming(struct pvr2_hdw *); | 165 | int pvr2_hdw_get_streaming(struct pvr2_hdw *); |
169 | 166 | ||
167 | /* Retrieve driver overall state */ | ||
168 | int pvr2_hdw_get_state(struct pvr2_hdw *); | ||
169 | |||
170 | /* Configure the type of stream to generate */ | 170 | /* Configure the type of stream to generate */ |
171 | int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config); | 171 | int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config); |
172 | 172 | ||
@@ -177,26 +177,6 @@ struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *); | |||
177 | int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std, | 177 | int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std, |
178 | unsigned int idx); | 178 | unsigned int idx); |
179 | 179 | ||
180 | /* Enable / disable various pieces of hardware. Items to change are | ||
181 | identified by bit positions within msk, and new state for each item is | ||
182 | identified by corresponding bit positions within val. */ | ||
183 | void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw, | ||
184 | unsigned long msk,unsigned long val); | ||
185 | |||
186 | /* Retrieve mask indicating which pieces of hardware are currently enabled | ||
187 | / configured. */ | ||
188 | unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *); | ||
189 | |||
190 | /* Adjust mask of what get shut down when streaming is stopped. This is a | ||
191 | debugging aid. */ | ||
192 | void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, | ||
193 | unsigned long msk,unsigned long val); | ||
194 | |||
195 | /* Retrieve mask indicating which pieces of hardware are disabled when | ||
196 | streaming is turned off. */ | ||
197 | unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *); | ||
198 | |||
199 | |||
200 | /* Enable / disable retrieval of CPU firmware or prom contents. This must | 180 | /* Enable / disable retrieval of CPU firmware or prom contents. This must |
201 | be enabled before pvr2_hdw_cpufw_get() will function. Note that doing | 181 | be enabled before pvr2_hdw_cpufw_get() will function. Note that doing |
202 | this may prevent the device from running (and leaving this mode may | 182 | this may prevent the device from running (and leaving this mode may |
@@ -253,6 +233,9 @@ void pvr2_hdw_cpureset_assert(struct pvr2_hdw *,int); | |||
253 | /* Execute a USB-commanded device reset */ | 233 | /* Execute a USB-commanded device reset */ |
254 | void pvr2_hdw_device_reset(struct pvr2_hdw *); | 234 | void pvr2_hdw_device_reset(struct pvr2_hdw *); |
255 | 235 | ||
236 | /* Reset worker's error trapping circuit breaker */ | ||
237 | int pvr2_hdw_untrip(struct pvr2_hdw *); | ||
238 | |||
256 | /* Execute hard reset command (after this point it's likely that the | 239 | /* Execute hard reset command (after this point it's likely that the |
257 | encoder will have to be reconfigured). This also clears the "useless" | 240 | encoder will have to be reconfigured). This also clears the "useless" |
258 | state. */ | 241 | state. */ |
@@ -275,11 +258,21 @@ int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val); | |||
275 | struct pvr2_hdw_debug_info { | 258 | struct pvr2_hdw_debug_info { |
276 | int big_lock_held; | 259 | int big_lock_held; |
277 | int ctl_lock_held; | 260 | int ctl_lock_held; |
278 | int flag_ok; | ||
279 | int flag_disconnected; | 261 | int flag_disconnected; |
280 | int flag_init_ok; | 262 | int flag_init_ok; |
281 | int flag_streaming_enabled; | 263 | int flag_ok; |
282 | unsigned long subsys_flags; | 264 | int fw1_state; |
265 | int flag_decoder_missed; | ||
266 | int flag_tripped; | ||
267 | int state_encoder_ok; | ||
268 | int state_encoder_run; | ||
269 | int state_decoder_run; | ||
270 | int state_usbstream_run; | ||
271 | int state_decoder_quiescent; | ||
272 | int state_pipeline_config; | ||
273 | int state_pipeline_req; | ||
274 | int state_pipeline_pause; | ||
275 | int state_pipeline_idle; | ||
283 | int cmd_debug_state; | 276 | int cmd_debug_state; |
284 | int cmd_debug_write_len; | 277 | int cmd_debug_write_len; |
285 | int cmd_debug_read_len; | 278 | int cmd_debug_read_len; |
@@ -295,8 +288,20 @@ struct pvr2_hdw_debug_info { | |||
295 | diagnosing lockups. Note that this operation is completed without any | 288 | diagnosing lockups. Note that this operation is completed without any |
296 | kind of locking and so it is not atomic and may yield inconsistent | 289 | kind of locking and so it is not atomic and may yield inconsistent |
297 | results. This is *purely* a debugging aid. */ | 290 | results. This is *purely* a debugging aid. */ |
298 | void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw, | 291 | void pvr2_hdw_get_debug_info_unlocked(const struct pvr2_hdw *hdw, |
299 | struct pvr2_hdw_debug_info *); | 292 | struct pvr2_hdw_debug_info *); |
293 | |||
294 | /* Intrusively retrieve internal state info - this is useful for | ||
295 | diagnosing overall driver state. This operation synchronizes against | ||
296 | the overall driver mutex - so if there are locking problems this will | ||
297 | likely hang! This is *purely* a debugging aid. */ | ||
298 | void pvr2_hdw_get_debug_info_locked(struct pvr2_hdw *hdw, | ||
299 | struct pvr2_hdw_debug_info *); | ||
300 | |||
301 | /* Report out several lines of text that describes driver internal state. | ||
302 | Results are written into the passed-in buffer. */ | ||
303 | unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw, | ||
304 | char *buf_ptr,unsigned int buf_size); | ||
300 | 305 | ||
301 | /* Cause modules to log their state once */ | 306 | /* Cause modules to log their state once */ |
302 | void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw); | 307 | void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw); |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index c817c864e6a0..f8b7bd1e0d89 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | |||
@@ -895,7 +895,7 @@ static int pvr2_i2c_attach_inform(struct i2c_client *client) | |||
895 | list_add_tail(&cp->list,&hdw->i2c_clients); | 895 | list_add_tail(&cp->list,&hdw->i2c_clients); |
896 | hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT; | 896 | hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT; |
897 | } while (0); mutex_unlock(&hdw->i2c_list_lock); | 897 | } while (0); mutex_unlock(&hdw->i2c_list_lock); |
898 | if (fl) pvr2_hdw_poll_trigger_unlocked(hdw); | 898 | if (fl) queue_work(hdw->workqueue,&hdw->worki2csync); |
899 | return 0; | 899 | return 0; |
900 | } | 900 | } |
901 | 901 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 7a596ea7cfe6..6f06f595b86c 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | |||
@@ -1015,10 +1015,8 @@ static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh) | |||
1015 | sp = fh->dev_info->stream->stream; | 1015 | sp = fh->dev_info->stream->stream; |
1016 | pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh); | 1016 | pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh); |
1017 | pvr2_hdw_set_stream_type(hdw,fh->dev_info->config); | 1017 | pvr2_hdw_set_stream_type(hdw,fh->dev_info->config); |
1018 | pvr2_hdw_set_streaming(hdw,!0); | 1018 | if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret; |
1019 | ret = pvr2_ioread_set_enabled(fh->rhp,!0); | 1019 | return pvr2_ioread_set_enabled(fh->rhp,!0); |
1020 | |||
1021 | return ret; | ||
1022 | } | 1020 | } |
1023 | 1021 | ||
1024 | 1022 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c index 61efa6f02200..767e49022f9b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c | |||
@@ -129,7 +129,7 @@ static const struct pvr2_v4l_decoder_ops decoder_ops[] = { | |||
129 | static void decoder_detach(struct pvr2_v4l_decoder *ctxt) | 129 | static void decoder_detach(struct pvr2_v4l_decoder *ctxt) |
130 | { | 130 | { |
131 | ctxt->client->handler = NULL; | 131 | ctxt->client->handler = NULL; |
132 | ctxt->hdw->decoder_ctrl = NULL; | 132 | pvr2_hdw_set_decoder(ctxt->hdw,NULL); |
133 | kfree(ctxt); | 133 | kfree(ctxt); |
134 | } | 134 | } |
135 | 135 | ||
@@ -217,7 +217,7 @@ int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw, | |||
217 | ctxt->client = cp; | 217 | ctxt->client = cp; |
218 | ctxt->hdw = hdw; | 218 | ctxt->hdw = hdw; |
219 | ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1; | 219 | ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1; |
220 | hdw->decoder_ctrl = &ctxt->ctrl; | 220 | pvr2_hdw_set_decoder(hdw,&ctxt->ctrl); |
221 | cp->handler = &ctxt->handler; | 221 | cp->handler = &ctxt->handler; |
222 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up", | 222 | pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up", |
223 | cp->client->addr); | 223 | cp->client->addr); |