/* * 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); }
/* 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); }