Print this page
fixup .text where possible
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/1394/targets/dcam1394/dcam_frame.c
+++ new/usr/src/uts/common/io/1394/targets/dcam1394/dcam_frame.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 27
28 +
29 29 /*
30 30 * dcam_frame.c
31 31 *
32 32 * dcam1394 driver. Support for video frame access.
33 33 */
34 34
35 35 #include <sys/int_limits.h>
36 36 #include <sys/types.h>
37 37 #include <sys/kmem.h>
38 38 #include <sys/cmn_err.h>
39 39 #include <sys/1394/targets/dcam1394/dcam.h>
40 40 #include <sys/1394/targets/dcam1394/dcam_frame.h>
41 41 #include <sys/tnf_probe.h>
42 42 #include <sys/dcam/dcam1394_io.h>
43 43
44 44 #include <sys/1394/targets/dcam1394/dcam_reg.h>
45 45
46 46 static void dcam_free_resources(dcam_state_t *);
47 47
48 48 typedef struct dcam_mode_info_s {
49 49 int bytes_per_pkt;
50 50 int pkts_per_frame;
51 51 } dcam_mode_info_t;
52 52
53 53 /*
54 54 * packets per frame
55 55 *
56 56 * 30fps
57 57 * mode_0 1/2h, 60q, 240b
58 58 * mode_1 1h, 160q, 640
59 59 * mode_2 2h, 480q, 1920
60 60 * mode_3 2h, 640q, 2560
61 61 * mode_4 2h, 960q, 3840
62 62 * mode_5 2h, 320q, 1280
63 63 *
64 64 * 15fps
65 65 * mode_0 1/4h, 30q, 120
66 66 * mode_1 1/2h, 80q, 320
67 67 * mode_2 1h, 240q, 960
68 68 * mode_3 1h, 320q, 1280
69 69 * mode_4 1h, 480q, 1920
70 70 * mode_5 1h, 160q, 640
71 71 *
72 72 * 7.5fps
73 73 * mode_0 1/8h, 15q, 60
74 74 * mode_1 1/4h, 40q, 160
75 75 * mode_2 1/2h, 120q, 480
76 76 * mode_3 1/2h, 160q, 640
77 77 * mode_4 1/2h, 240q, 960
78 78 * mode_5 1/2h, 80q, 320
79 79 *
80 80 * 3.75fps
81 81 * mode_0 x
82 82 * mode_1 1/8h, 20q, 80
83 83 * mode_2 1/4h, 60q, 240
84 84 * mode_3 1/4h, 80q, 320
85 85 * mode_4 1/4h, 120q, 480
86 86 * mode_5 1/4h, 40q, 160
↓ open down ↓ |
48 lines elided |
↑ open up ↑ |
87 87 *
88 88 * 60fps
89 89 * mode_5 4H, 640q, 2560
90 90 *
91 91 */
92 92
93 93 /* indexed by vid mode, frame rate */
94 94 static int g_bytes_per_packet[6][5] = {
95 95
96 96 /* fps: 3.75 7.5 15 30 60 */
97 - /* vid mode 0 */ -1, 60, 120, 240, -1,
98 - /* vid mode 1 */ 80, 160, 320, 640, -1,
99 - /* vid mode 2 */ 240, 480, 960, 1920, -1,
100 - /* vid mode 3 */ 320, 640, 1280, 2560, -1,
101 - /* vid mode 4 */ 480, 960, 1920, 3840, -1,
102 - /* vid mode 5 */ 160, 320, 640, 1280, 2560
97 + /* vid mode 0 */ { -1, 60, 120, 240, -1 },
98 + /* vid mode 1 */ { 80, 160, 320, 640, -1 },
99 + /* vid mode 2 */ { 240, 480, 960, 1920, -1 },
100 + /* vid mode 3 */ { 320, 640, 1280, 2560, -1 },
101 + /* vid mode 4 */ { 480, 960, 1920, 3840, -1 },
102 + /* vid mode 5 */ { 160, 320, 640, 1280, 2560 }
103 103 };
104 104
105 105 /* indexed by vid mode */
106 106 static int g_bytes_per_frame[6] = {
107 107 57600,
108 108 153600,
109 109 460800,
110 110 614400,
111 111 921600,
112 112 307200
113 113 };
114 114
115 115
116 116 static
117 117 void dcam_rsrc_fail(t1394_isoch_single_handle_t t1394_single_hdl,
118 118 opaque_t single_evt_arg, t1394_isoch_rsrc_error_t fail_args);
119 119
120 120 /*
121 121 * dcam1394_ioctl_frame_rcv_start
122 122 */
123 123 int
124 124 dcam1394_ioctl_frame_rcv_start(dcam_state_t *softc_p)
125 125 {
126 126 if (!(softc_p->flags & DCAM1394_FLAG_FRAME_RCV_INIT)) {
127 127
128 128 if (dcam_frame_rcv_init(softc_p, softc_p->cur_vid_mode,
129 129 softc_p->cur_frame_rate, softc_p->cur_ring_buff_capacity)) {
130 130
131 131 dcam_free_resources(softc_p);
132 132 return (1);
133 133 }
134 134
135 135 softc_p->flags |= DCAM1394_FLAG_FRAME_RCV_INIT;
136 136 }
137 137
138 138 if (dcam_frame_rcv_start(softc_p)) {
139 139 return (1);
140 140 }
141 141
142 142 return (0);
143 143 }
144 144
145 145
146 146 /*
147 147 * dcam_frame_rcv_init
148 148 */
149 149 int
150 150 dcam_frame_rcv_init(dcam_state_t *softc_p, int vid_mode, int frame_rate,
151 151 int ring_buff_capacity)
152 152 {
153 153 int16_t bytes_per_pkt; /* # pkt bytes + overhead */
154 154 int bytes_per_frame;
155 155 size_t frame;
156 156 int cookie;
157 157 int failure;
158 158 id1394_isoch_dmainfo_t isoch_args; /* for alloc isoch call */
159 159 ixl1394_command_t *last_ixlp; /* last ixl in chain, */
160 160 /* used for appending ixls */
161 161 ixl1394_command_t *new_ixl_cmdp; /* new ixl command */
162 162 ixl1394_set_syncwait_t *new_ixl_sswp; /* new ixl set syncwait */
163 163 ixl1394_xfer_pkt_t *new_ixl_xfpp; /* new ixl xfer packet */
164 164 ixl1394_xfer_buf_t *new_ixl_xfbp; /* new ixl xfer buffer */
165 165 ixl1394_callback_t *new_ixl_cbp; /* new ixl callback */
166 166 ixl1394_jump_t *new_ixl_jmpp; /* new ixl jump */
167 167 int32_t result; /* errno from alloc_isoch_dma */
168 168 buff_info_t *buff_info_p;
169 169 dcam1394_reg_io_t reg_io;
170 170 uint_t data;
171 171 size_t num_bytes, num_bytes_left;
172 172 size_t num_xfer_cmds, xfer_cmd;
173 173 size_t max_ixl_buff_size;
174 174 uint64_t ixl_buff_kaddr;
175 175 caddr_t ixl_buff_vaddr;
176 176
177 177 bytes_per_pkt = g_bytes_per_packet[vid_mode][frame_rate];
178 178 if (bytes_per_pkt == -1) {
179 179 return (1);
180 180 }
181 181
182 182 bytes_per_frame = g_bytes_per_frame[vid_mode];
183 183
184 184 if ((softc_p->ring_buff_p = ring_buff_create(softc_p,
185 185 (size_t)ring_buff_capacity, (size_t)bytes_per_frame)) == NULL) {
186 186 return (1);
187 187 }
188 188
189 189 softc_p->ring_buff_p->read_ptr_pos[0] = 0;
190 190
191 191 /* allocate isoch channel */
192 192 softc_p->sii.si_channel_mask = 0xFFFF000000000000;
193 193 softc_p->sii.si_bandwidth = bytes_per_pkt;
194 194 softc_p->sii.rsrc_fail_target = dcam_rsrc_fail;
195 195 softc_p->sii.single_evt_arg = softc_p;
196 196 softc_p->sii.si_speed = softc_p->targetinfo.current_max_speed;
197 197
198 198 if (t1394_alloc_isoch_single(softc_p->sl_handle,
199 199 &softc_p->sii, 0, &softc_p->sii_output_args, &softc_p->sii_hdl,
200 200 &failure) != DDI_SUCCESS) {
201 201 return (1);
202 202 }
203 203
204 204 /*
205 205 * At this point, all buffer memory has been allocated and
206 206 * mapped, and is tracked on a linear linked list. Now need to
207 207 * build the IXL. Done on a frame-by-frame basis. Could
208 208 * theoretically have been done at the same time as the mem alloc
209 209 * above, but hey, no need to be so fancy here.
210 210 *
211 211 * ixl buff size is bound by SHRT_MAX and needs to
212 212 * be a multiple of packet size
213 213 */
214 214 max_ixl_buff_size = (SHRT_MAX / bytes_per_pkt) * bytes_per_pkt;
215 215
216 216 /* for each frame build frame's ixl list */
217 217 for (frame = 0; frame < softc_p->ring_buff_p->num_buffs; frame++) {
218 218
219 219 buff_info_p = &(softc_p->ring_buff_p->buff_info_array_p[frame]);
220 220
221 221 /*
222 222 * if this is the 1st frame, put a IXL label at the top so a
223 223 * loop can be created later
224 224 */
225 225 if (frame == 0) {
226 226 new_ixl_cmdp = kmem_zalloc(
227 227 sizeof (ixl1394_label_t), KM_SLEEP);
228 228 softc_p->ixlp = new_ixl_cmdp;
229 229
230 230 new_ixl_cmdp->ixl_opcode = IXL1394_OP_LABEL;
231 231
232 232 last_ixlp = softc_p->ixlp;
233 233 }
234 234
235 235 /* add wait-for-sync IXL command */
236 236 new_ixl_sswp = kmem_zalloc(
237 237 sizeof (ixl1394_set_syncwait_t), KM_SLEEP);
238 238
239 239 new_ixl_sswp->ixl_opcode = IXL1394_OP_SET_SYNCWAIT;
240 240
241 241 last_ixlp->next_ixlp = (ixl1394_command_t *)new_ixl_sswp;
242 242 last_ixlp = (ixl1394_command_t *)new_ixl_sswp;
243 243
244 244 /* add in each dma cookie */
245 245 for (cookie = 0; cookie < buff_info_p->dma_cookie_count;
246 246 cookie++) {
247 247
248 248 num_xfer_cmds = min(bytes_per_frame,
249 249 buff_info_p->dma_cookie.dmac_size) /
250 250 max_ixl_buff_size;
251 251
252 252 if (min(bytes_per_frame,
253 253 buff_info_p->dma_cookie.dmac_size) %
254 254 max_ixl_buff_size) {
255 255 num_xfer_cmds++;
256 256 }
257 257
258 258 num_bytes_left = min(bytes_per_frame,
259 259 buff_info_p->dma_cookie.dmac_size);
260 260
261 261 ixl_buff_kaddr =
262 262 buff_info_p->dma_cookie.dmac_laddress;
263 263
264 264 ixl_buff_vaddr = buff_info_p->kaddr_p;
265 265
266 266 for (xfer_cmd = 0; xfer_cmd < (num_xfer_cmds + 1);
267 267 xfer_cmd++) {
268 268 num_bytes = min(num_bytes_left,
269 269 max_ixl_buff_size);
270 270
271 271 if (xfer_cmd == 0) {
272 272 new_ixl_xfpp =
273 273 kmem_zalloc(
274 274 sizeof (ixl1394_xfer_pkt_t),
275 275 KM_SLEEP);
276 276
277 277 new_ixl_xfpp->ixl_opcode =
278 278 IXL1394_OP_RECV_PKT_ST;
279 279
280 280 new_ixl_xfpp->ixl_buf._dmac_ll =
281 281 ixl_buff_kaddr;
282 282 new_ixl_xfpp->size =
283 283 (uint16_t)bytes_per_pkt;
284 284 new_ixl_xfpp->mem_bufp =
285 285 ixl_buff_vaddr;
286 286
287 287 last_ixlp->next_ixlp =
288 288 (ixl1394_command_t *)new_ixl_xfpp;
289 289 last_ixlp =
290 290 (ixl1394_command_t *)new_ixl_xfpp;
291 291
292 292 num_bytes_left -= bytes_per_pkt;
293 293 ixl_buff_kaddr += bytes_per_pkt;
294 294 ixl_buff_vaddr += bytes_per_pkt;
295 295
296 296 continue;
297 297 }
298 298
299 299 /* allocate & init an IXL transfer command. */
300 300 new_ixl_xfbp =
301 301 kmem_zalloc(sizeof (ixl1394_xfer_buf_t),
302 302 KM_SLEEP);
303 303
304 304 new_ixl_xfbp->ixl_opcode = IXL1394_OP_RECV_BUF;
305 305
306 306 new_ixl_xfbp->ixl_buf._dmac_ll =
307 307 ixl_buff_kaddr;
308 308 new_ixl_xfbp->size = (uint16_t)num_bytes;
309 309 new_ixl_xfbp->pkt_size = bytes_per_pkt;
310 310 new_ixl_xfbp->mem_bufp = ixl_buff_vaddr;
311 311
312 312 last_ixlp->next_ixlp =
313 313 (ixl1394_command_t *)new_ixl_xfbp;
314 314 last_ixlp =
315 315 (ixl1394_command_t *)new_ixl_xfbp;
316 316
317 317 num_bytes_left -= num_bytes;
318 318 ixl_buff_kaddr += num_bytes;
319 319 ixl_buff_vaddr += num_bytes;
320 320 }
321 321
322 322 if (cookie > 0) {
323 323 ddi_dma_nextcookie(buff_info_p->dma_handle,
324 324 &(buff_info_p->dma_cookie));
325 325 }
326 326
327 327 }
328 328
329 329 /*
330 330 * at this point, have finished a frame. put in a callback
331 331 */
332 332 new_ixl_cbp = kmem_zalloc(
333 333 sizeof (ixl1394_callback_t), KM_SLEEP);
334 334
335 335 new_ixl_cbp->ixl_opcode = IXL1394_OP_CALLBACK;
336 336
337 337 new_ixl_cbp->callback = &dcam_frame_is_done;
338 338 new_ixl_cbp->callback_arg = NULL;
339 339
340 340 last_ixlp->next_ixlp = (ixl1394_command_t *)new_ixl_cbp;
341 341 last_ixlp = (ixl1394_command_t *)new_ixl_cbp;
342 342 }
343 343
344 344 /*
345 345 * for the final touch, put an IXL jump at the end to jump to the
346 346 * label at the top
347 347 */
348 348 new_ixl_jmpp = kmem_zalloc(sizeof (ixl1394_jump_t), KM_SLEEP);
349 349
350 350 new_ixl_jmpp->ixl_opcode = IXL1394_OP_JUMP;
351 351
352 352 new_ixl_jmpp->label = softc_p->ixlp;
353 353
354 354 last_ixlp->next_ixlp = (ixl1394_command_t *)new_ixl_jmpp;
355 355
356 356 /* don't need this, but it's neater */
357 357 last_ixlp = (ixl1394_command_t *)new_ixl_jmpp;
358 358
359 359 /* call fwim routine to alloc an isoch resource */
360 360 isoch_args.ixlp = softc_p->ixlp;
361 361 isoch_args.channel_num = softc_p->sii_output_args.channel_num;
362 362
363 363 /* other misc args. note speed doesn't matter for isoch receive */
364 364 isoch_args.idma_options = ID1394_LISTEN_PKT_MODE;
365 365 isoch_args.default_tag = 0;
366 366 isoch_args.default_sync = 1;
367 367 isoch_args.global_callback_arg = softc_p;
368 368
369 369 /* set the ISO channel number */
370 370 data = (softc_p->sii_output_args.channel_num & 0xF) << 28;
371 371
372 372 /* set the ISO speed */
373 373 data |= (softc_p->targetinfo.current_max_speed << 24);
374 374
375 375 reg_io.offs = DCAM1394_REG_OFFS_CUR_ISO_CHANNEL;
376 376 reg_io.val = data;
377 377
378 378 if (dcam_reg_write(softc_p, ®_io)) {
379 379 return (1);
380 380 }
381 381
382 382 result = 1234;
383 383
384 384 if (t1394_alloc_isoch_dma(softc_p->sl_handle, &isoch_args, 0,
385 385 &softc_p->isoch_handle, &result) != DDI_SUCCESS) {
386 386 return (1);
387 387 }
388 388
389 389 return (0);
390 390 }
391 391
392 392
393 393 /*
394 394 * dcam_frame_rcv_fini
395 395 */
396 396 int
397 397 dcam_frame_rcv_fini(dcam_state_t *softc_p)
398 398 {
399 399 t1394_free_isoch_dma(softc_p->sl_handle, 0, &softc_p->isoch_handle);
400 400
401 401 softc_p->isoch_handle = NULL;
402 402
403 403 t1394_free_isoch_single(softc_p->sl_handle, &softc_p->sii_hdl, 0);
404 404
405 405 return (0);
406 406 }
407 407
408 408
409 409 /*
410 410 * dcam_frame_rcv_start
411 411 */
412 412 int
413 413 dcam_frame_rcv_start(dcam_state_t *softc_p)
414 414 {
415 415 id1394_isoch_dma_ctrlinfo_t idma_ctrlinfo; /* currently not used */
416 416 int32_t result;
417 417 dcam1394_reg_io_t reg_io;
418 418
419 419 if ((t1394_start_isoch_dma(softc_p->sl_handle, softc_p->isoch_handle,
420 420 &idma_ctrlinfo, 0, &result)) != DDI_SUCCESS) {
421 421 return (1);
422 422 }
423 423
424 424 reg_io.offs = DCAM1394_REG_OFFS_ISO_EN;
425 425 reg_io.val = 0x80000000;
426 426
427 427 if (dcam_reg_write(softc_p, ®_io)) {
428 428 return (1);
429 429 }
430 430
431 431 softc_p->flags |= DCAM1394_FLAG_FRAME_RCVING;
432 432
433 433 return (0);
434 434 }
435 435
436 436
437 437 /*
438 438 * dcam_frame_rcv_stop
439 439 */
440 440 int
441 441 dcam_frame_rcv_stop(dcam_state_t *softc_p)
442 442 {
443 443 dcam1394_reg_io_t reg_io;
444 444
445 445 /* if resources have already been cleared, nothing to do */
446 446 if (!(softc_p->flags & DCAM1394_FLAG_FRAME_RCV_INIT)) {
447 447 return (0);
448 448 }
449 449
450 450 reg_io.offs = DCAM1394_REG_OFFS_ISO_EN;
451 451 reg_io.val = 0;
452 452
453 453 (void) dcam_reg_write(softc_p, ®_io);
454 454
455 455 t1394_stop_isoch_dma(softc_p->sl_handle, softc_p->isoch_handle, 0);
456 456 t1394_free_isoch_dma(softc_p->sl_handle, 0, &softc_p->isoch_handle);
457 457 t1394_free_isoch_single(softc_p->sl_handle, &softc_p->sii_hdl, 0);
458 458
459 459 dcam_free_resources(softc_p);
460 460
461 461 return (0);
462 462 }
463 463
464 464
465 465 void
466 466 dcam_free_resources(dcam_state_t *softc_p)
467 467 {
468 468 ixl1394_command_t *ptr;
469 469 ixl1394_command_t *tmp;
470 470
471 471 /*
472 472 * The following fixes a memory leak. See bug #4423667.
473 473 * The original code only released memory for the first frame.
474 474 */
475 475
476 476 /* free ixl opcode resources */
477 477 ptr = softc_p->ixlp;
478 478
479 479 while (ptr != NULL) {
480 480 tmp = ptr;
481 481 ptr = ptr->next_ixlp;
482 482
483 483 switch (tmp->ixl_opcode) {
484 484 case IXL1394_OP_LABEL:
485 485 kmem_free(tmp, sizeof (ixl1394_label_t));
486 486 break;
487 487
488 488 case IXL1394_OP_SET_SYNCWAIT:
489 489 kmem_free(tmp, sizeof (ixl1394_set_syncwait_t));
490 490 break;
491 491
492 492 case IXL1394_OP_RECV_PKT_ST:
493 493 kmem_free(tmp, sizeof (ixl1394_xfer_pkt_t));
494 494 break;
495 495
496 496 case IXL1394_OP_RECV_BUF:
497 497 kmem_free(tmp, sizeof (ixl1394_xfer_buf_t));
498 498 break;
499 499
500 500 case IXL1394_OP_CALLBACK:
501 501 kmem_free(tmp, sizeof (ixl1394_callback_t));
502 502 break;
503 503
504 504 case IXL1394_OP_JUMP:
505 505 kmem_free(tmp, sizeof (ixl1394_jump_t));
506 506 break;
507 507 }
508 508 }
509 509
510 510 /*
511 511 * free ring buff and indicate that the resources have been cleared
512 512 */
513 513 ring_buff_free(softc_p, softc_p->ring_buff_p);
514 514
515 515 softc_p->flags &= ~DCAM1394_FLAG_FRAME_RCV_INIT;
516 516 softc_p->ixlp = NULL;
517 517 }
518 518
519 519
520 520 /*
521 521 * dcam_frame_is_done
522 522 *
523 523 * This routine is called after DMA engine has stored a single received
524 524 * frame in ring buffer position pointed to by write pointer; this
525 525 * routine marks the frame's vid mode, timestamp, and sequence number
526 526 *
527 527 * Store received frame in ring buffer position pointed to by write pointer.
528 528 * Increment write pointer. If write pointer is pointing to the same
529 529 * position as read pointer, increment read pointer.
530 530 *
531 531 * If device driver is processing a user process's read() request
532 532 * invalidate the read() request processing operation.
533 533 *
534 534 */
535 535
536 536 /* ARGSUSED */
537 537 void
538 538 dcam_frame_is_done(void *ssp, ixl1394_callback_t *ixlp)
539 539 {
540 540 dcam_state_t *softc_p;
541 541 int num_read_ptrs;
542 542 int read_ptr_id;
543 543 int vid_mode;
544 544 size_t write_ptr_pos;
545 545 ring_buff_t *ring_buff_p;
546 546 unsigned int seq_num;
547 547
548 548 /*
549 549 * Store received frame in ring buffer position pointed to by
550 550 * write pointer (this routine is called after DMA engine has
551 551 * stored a single received frame in ring buffer position pointed
552 552 * to by write pointer; this routine marks the frame's vid mode,
553 553 * timestamp, and sequence number)
554 554 */
555 555
556 556 if ((softc_p = (dcam_state_t *)ssp) == NULL) {
557 557 return;
558 558 }
559 559
560 560 if ((ring_buff_p = softc_p->ring_buff_p) == NULL) {
561 561 return;
562 562 }
563 563
564 564 mutex_enter(&softc_p->dcam_frame_is_done_mutex);
565 565
566 566 write_ptr_pos = ring_buff_write_ptr_pos_get(ring_buff_p);
567 567
568 568 /* mark vid mode */
569 569 vid_mode =
570 570 softc_p->
571 571 param_attr[DCAM1394_PARAM_VID_MODE][DCAM1394_SUBPARAM_NONE];
572 572 ring_buff_p->buff_info_array_p[write_ptr_pos].vid_mode = vid_mode;
573 573
574 574
575 575 /* update sequence counter overflow in param_status */
576 576 if (softc_p->seq_count == 0xffffffff)
577 577 softc_p->param_status |=
578 578 DCAM1394_STATUS_FRAME_SEQ_NUM_COUNT_OVERFLOW;
579 579
580 580
581 581 /* mark frame's sequence number */
582 582 ring_buff_p->buff_info_array_p[write_ptr_pos].seq_num =
583 583 softc_p->seq_count++;
584 584
585 585 seq_num = ring_buff_p->buff_info_array_p[write_ptr_pos].seq_num;
586 586
587 587
588 588 /* mark frame's timestamp */
589 589 ring_buff_p->buff_info_array_p[write_ptr_pos].timestamp = gethrtime();
590 590
591 591
592 592 /* increment write pointer */
593 593 ring_buff_write_ptr_incr(ring_buff_p);
594 594
595 595 num_read_ptrs = 1;
596 596
597 597 for (read_ptr_id = 0; read_ptr_id < num_read_ptrs; read_ptr_id++) {
598 598
599 599 /*
600 600 * if write pointer is pointing to the same position as
601 601 * read pointer
602 602 */
603 603
604 604 if ((ring_buff_write_ptr_pos_get(ring_buff_p) ==
605 605 ring_buff_read_ptr_pos_get(ring_buff_p, read_ptr_id)) &&
606 606 (seq_num != 0)) {
607 607
608 608 /* increment read pointer */
609 609 ring_buff_read_ptr_incr(ring_buff_p, read_ptr_id);
610 610
611 611 /*
612 612 * if device driver is processing a user
613 613 * process's read() request
614 614 */
615 615 if (softc_p->reader_flags[read_ptr_id] &
616 616 DCAM1394_FLAG_READ_REQ_PROC) {
617 617
618 618 /*
619 619 * invalidate the read() request processing
620 620 * operation
621 621 */
622 622 softc_p->reader_flags[read_ptr_id] |=
623 623 DCAM1394_FLAG_READ_REQ_INVALID;
624 624 }
625 625
626 626 /* inform user app that we have lost one frame */
627 627 softc_p->param_status |=
628 628 DCAM1394_STATUS_RING_BUFF_LOST_FRAME;
629 629 }
630 630 }
631 631
632 632 /* inform user app that we have received one frame */
633 633 softc_p->param_status |= DCAM1394_STATUS_FRAME_RCV_DONE;
634 634
635 635 mutex_exit(&softc_p->dcam_frame_is_done_mutex);
636 636 }
637 637
638 638
639 639 /* ARGSUSED */
640 640 static void
641 641 dcam_rsrc_fail(t1394_isoch_single_handle_t t1394_single_hdl,
642 642 opaque_t single_evt_arg, t1394_isoch_rsrc_error_t fail_args)
643 643 {
644 644 cmn_err(CE_NOTE, "dcam_rsrc_fail(): unable to re-alloc resources\n");
645 645 }
↓ open down ↓ |
533 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX