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