/*
 * param_ring_buff_num_frames_ready_get()
 */
int
param_ring_buff_num_frames_ready_get(dcam_state_t *softc_p, uint_t *val_p)
{
	size_t read_pos, write_pos;

	/*
	 * note: currently we support only one read_ptr_id, so the
	 * following logic will work. If multiple read_ptr_id's are
	 * supported, this function call will need to receive a
	 * read_ptr_id
	 */

	if (softc_p->ring_buff_p == NULL) {
		return (1);
	}

	mutex_enter(&softc_p->dcam_frame_is_done_mutex);

	read_pos  = ring_buff_read_ptr_pos_get(softc_p->ring_buff_p, 0);
	write_pos = ring_buff_write_ptr_pos_get(softc_p->ring_buff_p);

	if (read_pos < write_pos) {
		*val_p = write_pos - read_pos;
	} else {
		*val_p = (softc_p->ring_buff_p->num_buffs + write_pos) -
		    read_pos;
	}

	mutex_exit(&softc_p->dcam_frame_is_done_mutex);

	return (0);
}
示例#2
0
/* ARGSUSED */
void
dcam_frame_is_done(void *ssp, ixl1394_callback_t *ixlp)
{
	dcam_state_t	*softc_p;
	int		 num_read_ptrs;
	int		 read_ptr_id;
	int		 vid_mode;
	size_t		 write_ptr_pos;
	ring_buff_t	*ring_buff_p;
	unsigned int	 seq_num;

	/*
	 * Store received frame in ring buffer position pointed to by
	 * write pointer (this routine is called after DMA engine has
	 * stored a single received frame in ring buffer position pointed
	 * to by write pointer; this routine marks the frame's vid mode,
	 * timestamp, and sequence number)
	 */

	if ((softc_p = (dcam_state_t *)ssp) == NULL) {
		return;
	}

	if ((ring_buff_p = softc_p->ring_buff_p) == NULL) {
		return;
	}

	mutex_enter(&softc_p->dcam_frame_is_done_mutex);

	write_ptr_pos = ring_buff_write_ptr_pos_get(ring_buff_p);

	/* mark vid mode */
	vid_mode =
	    softc_p->
		param_attr[DCAM1394_PARAM_VID_MODE][DCAM1394_SUBPARAM_NONE];
	ring_buff_p->buff_info_array_p[write_ptr_pos].vid_mode = vid_mode;


	/* update sequence counter overflow in param_status */
	if (softc_p->seq_count == 0xffffffff)
		softc_p->param_status |=
		    DCAM1394_STATUS_FRAME_SEQ_NUM_COUNT_OVERFLOW;


	/* mark frame's sequence number */
	ring_buff_p->buff_info_array_p[write_ptr_pos].seq_num =
	    softc_p->seq_count++;

	seq_num = ring_buff_p->buff_info_array_p[write_ptr_pos].seq_num;


	/* mark frame's timestamp */
	ring_buff_p->buff_info_array_p[write_ptr_pos].timestamp = gethrtime();


	/* increment write pointer */
	ring_buff_write_ptr_incr(ring_buff_p);

	num_read_ptrs = 1;

	for (read_ptr_id = 0; read_ptr_id < num_read_ptrs; read_ptr_id++) {

		/*
		 * if write pointer is pointing to the same position as
		 * read pointer
		 */

		if ((ring_buff_write_ptr_pos_get(ring_buff_p) ==
		    ring_buff_read_ptr_pos_get(ring_buff_p, read_ptr_id)) &&
		    (seq_num != 0)) {

			/* increment read pointer */
			ring_buff_read_ptr_incr(ring_buff_p, read_ptr_id);

			/*
			 * if device driver is processing a user
			 * process's read() request
			 */
			if (softc_p->reader_flags[read_ptr_id] &
			    DCAM1394_FLAG_READ_REQ_PROC) {

				/*
				 * invalidate the read() request processing
				 * operation
				 */
				softc_p->reader_flags[read_ptr_id] |=
				    DCAM1394_FLAG_READ_REQ_INVALID;
			}

			/* inform user app that we have lost one frame */
			softc_p->param_status |=
			    DCAM1394_STATUS_RING_BUFF_LOST_FRAME;
		}
	}

	/* inform user app that we have received one frame */
	softc_p->param_status |= DCAM1394_STATUS_FRAME_RCV_DONE;

	mutex_exit(&softc_p->dcam_frame_is_done_mutex);
}