17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*47cd5876SAlan Perry  * Common Development and Distribution License (the "License").
6*47cd5876SAlan Perry  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*47cd5876SAlan Perry  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef _SYS_1394_TARGETS_AV1394_ISOCH_H
277c478bd9Sstevel@tonic-gate #define	_SYS_1394_TARGETS_AV1394_ISOCH_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * isoch module definitions
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <sys/note.h>
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #ifdef __cplusplus
367c478bd9Sstevel@tonic-gate extern "C" {
377c478bd9Sstevel@tonic-gate #endif
387c478bd9Sstevel@tonic-gate 
39*47cd5876SAlan Perry #define	COOKIES		100
40*47cd5876SAlan Perry 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * isoch DMA memory management: segments and pools
437c478bd9Sstevel@tonic-gate  *
447c478bd9Sstevel@tonic-gate  * isoch segment - a contiguous chunk of kernel memory
457c478bd9Sstevel@tonic-gate  */
467c478bd9Sstevel@tonic-gate typedef struct av1394_isoch_seg_s {
477c478bd9Sstevel@tonic-gate 	caddr_t			is_kaddr;	/* segment kernel virt addr */
487c478bd9Sstevel@tonic-gate 	int			is_size;	/* segment size */
497c478bd9Sstevel@tonic-gate 	ddi_umem_cookie_t	is_umem_cookie;	/* umem cookie */
507c478bd9Sstevel@tonic-gate 	size_t			is_umem_size;	/* umem size (page-aligned) */
517c478bd9Sstevel@tonic-gate 	ddi_dma_handle_t	is_dma_hdl;	/* bind handle */
52*47cd5876SAlan Perry 	ddi_dma_cookie_t	is_dma_cookie[COOKIES];
53*47cd5876SAlan Perry 						/* dma cookie */
54*47cd5876SAlan Perry 	uint_t			is_dma_ncookies;
55*47cd5876SAlan Perry 						/* # of cookies */
567c478bd9Sstevel@tonic-gate } av1394_isoch_seg_t;
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate /*
597c478bd9Sstevel@tonic-gate  * isoch pool - a set of one or more isoch segments
607c478bd9Sstevel@tonic-gate  */
617c478bd9Sstevel@tonic-gate typedef struct av1394_isoch_pool_s {
627c478bd9Sstevel@tonic-gate 	av1394_isoch_seg_t	*ip_seg;	/* array of segments */
637c478bd9Sstevel@tonic-gate 	int			ip_nsegs;	/* # of valid segments */
647c478bd9Sstevel@tonic-gate 	int			ip_alloc_size;	/* array alloc'd size */
657c478bd9Sstevel@tonic-gate 	int			ip_size;	/* total pool size */
667c478bd9Sstevel@tonic-gate 	int			ip_umem_size;	/* total alloc'd memory size */
677c478bd9Sstevel@tonic-gate } av1394_isoch_pool_t;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate  * many members are protected because they are modified during channel
717c478bd9Sstevel@tonic-gate  * initialization or/and during isoch transfer, both of which are
727c478bd9Sstevel@tonic-gate  * single-threaded processes. after that these members remain read-only.
737c478bd9Sstevel@tonic-gate  */
747c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_isoch_seg_s))
757c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_isoch_pool_s))
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate  * IXL receive data block (one or more RECV_BUF commands will follow the label)
797c478bd9Sstevel@tonic-gate  */
807c478bd9Sstevel@tonic-gate typedef struct av1394_ir_ixl_data_s {
817c478bd9Sstevel@tonic-gate 	ixl1394_label_t		rd_label;
827c478bd9Sstevel@tonic-gate 	ixl1394_callback_t	rd_cb;		/* buffer completion callback */
837c478bd9Sstevel@tonic-gate 	ixl1394_jump_t		rd_jump;	/* next command */
847c478bd9Sstevel@tonic-gate } av1394_ir_ixl_data_t;
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_ir_ixl_data_s))
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate /*
897c478bd9Sstevel@tonic-gate  * isoch receive structure
907c478bd9Sstevel@tonic-gate  */
917c478bd9Sstevel@tonic-gate typedef struct av1394_ir_s {
927c478bd9Sstevel@tonic-gate 	av1394_isoch_pool_t	ir_data_pool;	/* pool for data packets */
937c478bd9Sstevel@tonic-gate 	/* IXL */
947c478bd9Sstevel@tonic-gate 	ixl1394_command_t	*ir_ixlp;	/* IXL chain */
957c478bd9Sstevel@tonic-gate 	av1394_ir_ixl_data_t	*ir_ixl_data;	/* data block array */
967c478bd9Sstevel@tonic-gate 	ixl1394_xfer_buf_t	*ir_ixl_buf;	/* RECV_BUF command array */
977c478bd9Sstevel@tonic-gate 	int			ir_ixl_nbufs;	/* # of commands in array */
987c478bd9Sstevel@tonic-gate 	size_t			ir_ixl_bpf;	/* # of buffers per frame - 1 */
997c478bd9Sstevel@tonic-gate 	size_t			ir_ixl_bufsz;	/* buffer size */
1007c478bd9Sstevel@tonic-gate 	size_t			ir_ixl_tailsz;	/* tail buffer size */
1017c478bd9Sstevel@tonic-gate 	/* xfer */
1027c478bd9Sstevel@tonic-gate 	int			ir_nfull;	/* # of full frames */
1037c478bd9Sstevel@tonic-gate 	int			ir_first_full;	/* first full frame */
1047c478bd9Sstevel@tonic-gate 	int			ir_nempty;	/* # of empty frames */
1057c478bd9Sstevel@tonic-gate 	int			ir_last_empty;	/* last produced frame */
1067c478bd9Sstevel@tonic-gate 	int			ir_hiwat;	/* high water mark */
1077c478bd9Sstevel@tonic-gate 	int			ir_lowat;	/* low water mark */
1087c478bd9Sstevel@tonic-gate 	int			ir_overflow_idx; /* overflow frame index */
1097c478bd9Sstevel@tonic-gate 	/* read() support */
1107c478bd9Sstevel@tonic-gate 	int			ir_read_idx;	/* first full frame */
1117c478bd9Sstevel@tonic-gate 	int			ir_read_cnt;	/* number of full frames */
1127c478bd9Sstevel@tonic-gate 	off_t			ir_read_off;	/* offset into the frame */
1137c478bd9Sstevel@tonic-gate } av1394_ir_t;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_ir_s::{
1167c478bd9Sstevel@tonic-gate 	ir_ixlp
1177c478bd9Sstevel@tonic-gate 	ir_ixl_buf
1187c478bd9Sstevel@tonic-gate 	ir_ixl_nbufs
1197c478bd9Sstevel@tonic-gate 	ir_ixl_bpf
1207c478bd9Sstevel@tonic-gate 	ir_ixl_bufsz
1217c478bd9Sstevel@tonic-gate 	ir_ixl_tailsz
1227c478bd9Sstevel@tonic-gate }))
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate /*
1257c478bd9Sstevel@tonic-gate  * IXL transmit begin block, used to get a starting point for timestamping
1267c478bd9Sstevel@tonic-gate  */
1277c478bd9Sstevel@tonic-gate enum { AV1394_IT_IXL_BEGIN_NPOST = 3 };
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate typedef struct av1394_it_ixl_begin_s {
1307c478bd9Sstevel@tonic-gate 	ixl1394_label_t		be_label;
1317c478bd9Sstevel@tonic-gate 	ixl1394_xfer_pkt_t	be_empty_pre;	/* needed for next command */
1327c478bd9Sstevel@tonic-gate 	ixl1394_store_timestamp_t be_store_ts;	/* store timestamp */
1337c478bd9Sstevel@tonic-gate 	ixl1394_callback_t	be_cb;		/* timestamp handling */
1347c478bd9Sstevel@tonic-gate 	ixl1394_xfer_pkt_t	be_empty_post[AV1394_IT_IXL_BEGIN_NPOST];
1357c478bd9Sstevel@tonic-gate 	ixl1394_jump_t		be_jump;	/* next command */
1367c478bd9Sstevel@tonic-gate } av1394_it_ixl_begin_t;
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_it_ixl_begin_s))
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate /*
1417c478bd9Sstevel@tonic-gate  * common part of transmit commands that are in a linked list
1427c478bd9Sstevel@tonic-gate  */
1437c478bd9Sstevel@tonic-gate typedef struct av1394_it_ixl_common_s {
1447c478bd9Sstevel@tonic-gate 	struct av1394_it_ixl_common_s	*tc_next;	/* next in the list */
1457c478bd9Sstevel@tonic-gate 	int				tc_size;	/* structure size */
1467c478bd9Sstevel@tonic-gate } av1394_it_ixl_common_t;
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate /*
1497c478bd9Sstevel@tonic-gate  * IXL transmit data block
1507c478bd9Sstevel@tonic-gate  */
1517c478bd9Sstevel@tonic-gate typedef struct av1394_it_ixl_buf_s {
1527c478bd9Sstevel@tonic-gate 	av1394_it_ixl_common_t	tb_common;
1537c478bd9Sstevel@tonic-gate 	int			tb_flags;
1547c478bd9Sstevel@tonic-gate 	int			tb_framenum;	/* frame number */
1557c478bd9Sstevel@tonic-gate 	struct av1394_ic_s	*tb_icp;
1567c478bd9Sstevel@tonic-gate 	ixl1394_label_t		tb_label;
1577c478bd9Sstevel@tonic-gate 	ixl1394_xfer_buf_t	tb_buf;		/* transmit packets */
1587c478bd9Sstevel@tonic-gate 	ixl1394_store_timestamp_t tb_store_ts;	/* cycle time feedback */
1597c478bd9Sstevel@tonic-gate 	ixl1394_callback_t	tb_cb;		/* callback */
1607c478bd9Sstevel@tonic-gate 	ixl1394_jump_t		tb_jump;	/* next command */
1617c478bd9Sstevel@tonic-gate } av1394_it_ixl_buf_t;
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_it_ixl_buf_s))
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate /* tb_flags */
1667c478bd9Sstevel@tonic-gate enum {
1677c478bd9Sstevel@tonic-gate 	AV1394_IT_IXL_BUF_NEXT_EMPTY	= 0x01,	/* followed by empty CIP */
1687c478bd9Sstevel@tonic-gate 	AV1394_IT_IXL_BUF_SOF		= 0x02,	/* start of frame */
1697c478bd9Sstevel@tonic-gate 	AV1394_IT_IXL_BUF_EOF		= 0x04	/* end of frame */
1707c478bd9Sstevel@tonic-gate };
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate /*
1737c478bd9Sstevel@tonic-gate  * empty CIP
1747c478bd9Sstevel@tonic-gate  */
1757c478bd9Sstevel@tonic-gate typedef struct av1394_it_ixl_empty_cip_s {
1767c478bd9Sstevel@tonic-gate 	av1394_it_ixl_common_t	te_common;
1777c478bd9Sstevel@tonic-gate 	ixl1394_label_t		te_label;
1787c478bd9Sstevel@tonic-gate 	ixl1394_xfer_pkt_t	te_pkt;
1797c478bd9Sstevel@tonic-gate 	ixl1394_jump_t		te_jump;	/* next command */
1807c478bd9Sstevel@tonic-gate } av1394_it_ixl_empty_cip_t;
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_it_ixl_empty_cip_s))
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate  * per-frame information
1867c478bd9Sstevel@tonic-gate  */
1877c478bd9Sstevel@tonic-gate typedef struct av1394_it_frame_info_s {
1887c478bd9Sstevel@tonic-gate 	caddr_t			fi_ts_off;	/* where to put a timestamp */
1897c478bd9Sstevel@tonic-gate 	int			fi_ncycs;	/* # of bus cycles */
1907c478bd9Sstevel@tonic-gate 	av1394_it_ixl_buf_t	*fi_first_buf;	/* first IXL buffer */
1917c478bd9Sstevel@tonic-gate 	av1394_it_ixl_buf_t	*fi_last_buf;	/* last IXL buffer */
1927c478bd9Sstevel@tonic-gate } av1394_it_frame_info_t;
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_it_frame_info_s))
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate /*
1977c478bd9Sstevel@tonic-gate  * timestamp type
1987c478bd9Sstevel@tonic-gate  */
1997c478bd9Sstevel@tonic-gate typedef union av1394_it_ts {
2007c478bd9Sstevel@tonic-gate 	uint16_t	ts_syt;		/* SYT timestamp */
2017c478bd9Sstevel@tonic-gate } av1394_it_ts_t;
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate /*
2047c478bd9Sstevel@tonic-gate  * isoch transmit structure
2057c478bd9Sstevel@tonic-gate  */
2067c478bd9Sstevel@tonic-gate typedef struct av1394_it_s {
2077c478bd9Sstevel@tonic-gate 	av1394_isoch_pool_t	it_data_pool;	/* pool for data packets */
2087c478bd9Sstevel@tonic-gate 	/* IXL */
2097c478bd9Sstevel@tonic-gate 	ixl1394_command_t	*it_ixlp;	/* IXL chain */
2107c478bd9Sstevel@tonic-gate 	av1394_it_ixl_begin_t	it_ixl_begin;	/* begin block */
2117c478bd9Sstevel@tonic-gate 	av1394_it_ixl_common_t	*it_ixl_data;	/* data block */
2127c478bd9Sstevel@tonic-gate 	av1394_it_frame_info_t	*it_frame_info;	/* frame info array */
2137c478bd9Sstevel@tonic-gate 	av1394_it_ixl_empty_cip_t *it_skipped_cip; /* last skipped CIP */
2147c478bd9Sstevel@tonic-gate 	/* xfer */
2157c478bd9Sstevel@tonic-gate 	int			it_first_empty; /* first empty frame # */
2167c478bd9Sstevel@tonic-gate 	int			it_nempty;	/* # of empty frames */
2177c478bd9Sstevel@tonic-gate 	int			it_last_full;	/* last full frame # */
2187c478bd9Sstevel@tonic-gate 	int			it_nfull;	/* # of full frames */
2197c478bd9Sstevel@tonic-gate 	int			it_hiwat;	/* high water mark */
2207c478bd9Sstevel@tonic-gate 	int			it_lowat;	/* low water mark */
2217c478bd9Sstevel@tonic-gate 	int			it_start_thre;	/* xfer start threshold */
2227c478bd9Sstevel@tonic-gate 	av1394_it_ts_t		it_ts_init;	/* initial timestamp */
2237c478bd9Sstevel@tonic-gate 	/* underrun data */
2247c478bd9Sstevel@tonic-gate 	int			it_underrun_idx; /* underrun frame index */
2257c478bd9Sstevel@tonic-gate 	ixl1394_command_t	*it_saved_label; /* saved buffer label */
2267c478bd9Sstevel@tonic-gate 	/* write() support */
2277c478bd9Sstevel@tonic-gate 	int			it_write_idx;	/* first empty frame */
2287c478bd9Sstevel@tonic-gate 	int			it_write_cnt;	/* # of empty frames */
2297c478bd9Sstevel@tonic-gate 	off_t			it_write_off;	/* offset into the frame */
2307c478bd9Sstevel@tonic-gate } av1394_it_t;
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_it_s::{
2337c478bd9Sstevel@tonic-gate 	it_ixlp
2347c478bd9Sstevel@tonic-gate 	it_ixl_begin
2357c478bd9Sstevel@tonic-gate 	it_ixl_data
2367c478bd9Sstevel@tonic-gate 	it_frame_info
2377c478bd9Sstevel@tonic-gate 	it_ts_init
2387c478bd9Sstevel@tonic-gate 	it_skipped_cip
2397c478bd9Sstevel@tonic-gate }))
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate /* misc channel parameters */
2427c478bd9Sstevel@tonic-gate typedef struct av1394_ic_param_s {
2437c478bd9Sstevel@tonic-gate 	int		cp_bus_speed;	/* bus speed */
2447c478bd9Sstevel@tonic-gate 	int		cp_dbs;		/* DBS */
2457c478bd9Sstevel@tonic-gate 	int		cp_fn;		/* FN */
2467c478bd9Sstevel@tonic-gate 	int		cp_n;		/* rate numerator */
2477c478bd9Sstevel@tonic-gate 	int		cp_d;		/* rate denominator */
2487c478bd9Sstevel@tonic-gate 	int		cp_ts_mode;	/* timestamp mode */
2497c478bd9Sstevel@tonic-gate } av1394_ic_param_t;
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate /* channel state */
2527c478bd9Sstevel@tonic-gate typedef enum {
2537c478bd9Sstevel@tonic-gate 	AV1394_IC_IDLE,		/* nothing happens */
2547c478bd9Sstevel@tonic-gate 	AV1394_IC_STARTED,	/* channel has been started */
2557c478bd9Sstevel@tonic-gate 	AV1394_IC_DMA,		/* DMA transfer is in progress */
2567c478bd9Sstevel@tonic-gate 	AV1394_IC_SUSPENDED	/* transfer on the channel suspended */
2577c478bd9Sstevel@tonic-gate } av1394_ic_state_t;
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate /*
2607c478bd9Sstevel@tonic-gate  * isoch channel structure, common for both recv and xmit
2617c478bd9Sstevel@tonic-gate  */
2627c478bd9Sstevel@tonic-gate typedef struct av1394_ic_s {
2637c478bd9Sstevel@tonic-gate 	kmutex_t		ic_mutex;	/* structure mutex */
2647c478bd9Sstevel@tonic-gate 	struct av1394_inst_s	*ic_avp;	/* backpointer to instance */
2657c478bd9Sstevel@tonic-gate 	int			ic_num;		/* channel # */
2667c478bd9Sstevel@tonic-gate 	int			ic_dir;		/* xfer direction */
2677c478bd9Sstevel@tonic-gate 	av1394_ic_state_t	ic_state;	/* state */
2687c478bd9Sstevel@tonic-gate 	int			ic_pktsz;	/* packet size */
2697c478bd9Sstevel@tonic-gate 	int			ic_npkts;	/* # of packets/frame */
2707c478bd9Sstevel@tonic-gate 	size_t			ic_framesz;	/* frame size (pktsz * npkts) */
2717c478bd9Sstevel@tonic-gate 	int			ic_nframes;	/* # of frames */
2727c478bd9Sstevel@tonic-gate 	av1394_ic_param_t	ic_param;	/* misc parameters */
2737c478bd9Sstevel@tonic-gate 	size_t			ic_mmap_sz;	/* mmap size */
2747c478bd9Sstevel@tonic-gate 	off_t			ic_mmap_off;	/* mmap offset */
2757c478bd9Sstevel@tonic-gate 	t1394_isoch_single_handle_t ic_sii_hdl;	/* isoch single handle */
2767c478bd9Sstevel@tonic-gate 	t1394_isoch_dma_handle_t ic_isoch_hdl;	/* 1394 isoch handle */
2777c478bd9Sstevel@tonic-gate 	kcondvar_t		ic_xfer_cv;	/* xfer cv */
2787c478bd9Sstevel@tonic-gate 	int			ic_preq;	/* postponed request */
2797c478bd9Sstevel@tonic-gate 	av1394_ir_t		ic_ir;		/* recv */
2807c478bd9Sstevel@tonic-gate 	av1394_it_t		ic_it;		/* xmit */
2817c478bd9Sstevel@tonic-gate } av1394_ic_t;
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(av1394_ic_s::ic_mutex, av1394_ic_s))
2847c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_ic_s::{
2857c478bd9Sstevel@tonic-gate 	ic_avp
2867c478bd9Sstevel@tonic-gate 	ic_num
2877c478bd9Sstevel@tonic-gate 	ic_dir
2887c478bd9Sstevel@tonic-gate 	ic_sii_hdl
2897c478bd9Sstevel@tonic-gate 	ic_isoch_hdl
2907c478bd9Sstevel@tonic-gate 	ic_pktsz
2917c478bd9Sstevel@tonic-gate 	ic_npkts
2927c478bd9Sstevel@tonic-gate 	ic_framesz
2937c478bd9Sstevel@tonic-gate 	ic_nframes
2947c478bd9Sstevel@tonic-gate 	ic_param
2957c478bd9Sstevel@tonic-gate 	ic_mmap_sz
2967c478bd9Sstevel@tonic-gate 	ic_mmap_off
2977c478bd9Sstevel@tonic-gate }))
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate /* xfer directions */
3007c478bd9Sstevel@tonic-gate enum {
3017c478bd9Sstevel@tonic-gate 	AV1394_IR,
3027c478bd9Sstevel@tonic-gate 	AV1394_IT
3037c478bd9Sstevel@tonic-gate };
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate /* CIP type */
3067c478bd9Sstevel@tonic-gate enum {
3077c478bd9Sstevel@tonic-gate 	AV1394_CIP_FULL,
3087c478bd9Sstevel@tonic-gate 	AV1394_CIP_EMPTY
3097c478bd9Sstevel@tonic-gate };
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate /* misc constants */
3127c478bd9Sstevel@tonic-gate enum {
3137c478bd9Sstevel@tonic-gate 	AV1394_IC_FRAME_SIZE_MAX = 1024 * 1024,	/* max frame size */
3147c478bd9Sstevel@tonic-gate 	AV1394_MEM_MAX_PERCENT	= (100/10),	/* max percent of physmem */
3157c478bd9Sstevel@tonic-gate 	AV1394_SEGSZ_MAX_SHIFT	= 16,		/* maximum segment size */
3167c478bd9Sstevel@tonic-gate 	AV1394_SEGSZ_MAX	= (1UL << AV1394_SEGSZ_MAX_SHIFT),
3177c478bd9Sstevel@tonic-gate 	AV1394_SEGSZ_MAX_OFFSET	= AV1394_SEGSZ_MAX - 1,
3187c478bd9Sstevel@tonic-gate 	AV1394_IXL_BUFSZ_MAX	= 57344,	/* max buf size (uint16_t) */
3197c478bd9Sstevel@tonic-gate 						/* 57344 is ptob(btop(65535)) */
3207c478bd9Sstevel@tonic-gate 	AV1394_IR_NFRAMES_MIN	= 3,		/* minimum frame count */
3217c478bd9Sstevel@tonic-gate 	AV1394_IT_NFRAMES_MIN	= 3,		/* minimum frame count */
3227c478bd9Sstevel@tonic-gate 	AV1394_CIPSZ		= 8,		/* CIP header size */
3237c478bd9Sstevel@tonic-gate 	AV1394_DV_NTSC_FRAMESZ	= 250,		/* DV-NTSC frame size in pkts */
3247c478bd9Sstevel@tonic-gate 	AV1394_DV_PAL_FRAMESZ	= 300		/* DV-PAL frame size in pkts */
3257c478bd9Sstevel@tonic-gate };
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate #define	AV1394_TS_MODE_GET_OFF(mode)	((mode) & 0xff)
3287c478bd9Sstevel@tonic-gate #define	AV1394_TS_MODE_GET_SIZE(mode)	(((mode) >> 8) & 0xff)
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate /* private ISOCH_INIT flag */
3317c478bd9Sstevel@tonic-gate #define	IEC61883_PRIV_ISOCH_NOALLOC	0x40000000
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate /*
3347c478bd9Sstevel@tonic-gate  * autoxmit (isoch xmit via write(2)) support
3357c478bd9Sstevel@tonic-gate  */
3367c478bd9Sstevel@tonic-gate typedef struct av1394_isoch_autoxmit_s {
3377c478bd9Sstevel@tonic-gate 	uchar_t			ax_ciph[AV1394_CIPSZ];	/* first CIP hdr */
3387c478bd9Sstevel@tonic-gate 	boolean_t		ax_copy_ciph;		/* need to copy hdr */
3397c478bd9Sstevel@tonic-gate 	int			ax_fmt;			/* data format */
3407c478bd9Sstevel@tonic-gate } av1394_isoch_autoxmit_t;
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate /* autoxmit formats */
3437c478bd9Sstevel@tonic-gate enum {
3447c478bd9Sstevel@tonic-gate 	AV1394_ISOCH_AUTOXMIT_DV	= 0x10,
3457c478bd9Sstevel@tonic-gate 	AV1394_ISOCH_AUTOXMIT_UNKNOWN	= 0,
3467c478bd9Sstevel@tonic-gate 	AV1394_ISOCH_AUTOXMIT_DV_NTSC	= 1 | AV1394_ISOCH_AUTOXMIT_DV,
3477c478bd9Sstevel@tonic-gate 	AV1394_ISOCH_AUTOXMIT_DV_PAL	= 2 | AV1394_ISOCH_AUTOXMIT_DV
3487c478bd9Sstevel@tonic-gate };
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate /*
3527c478bd9Sstevel@tonic-gate  * User processes calling mmap(2) pass the 'offset' and 'len' arguments,
3537c478bd9Sstevel@tonic-gate  * returned by IEC61883_ISOCH_INIT ioctl. These arguments uniquely identify
3547c478bd9Sstevel@tonic-gate  * the DMA buffer associated with a channel. For each isochronous channel
3557c478bd9Sstevel@tonic-gate  * a part of this "address space" should be allocated to prevent conflicts
3567c478bd9Sstevel@tonic-gate  * with other channels.
3577c478bd9Sstevel@tonic-gate  */
3587c478bd9Sstevel@tonic-gate typedef struct av1394_as_s {
3597c478bd9Sstevel@tonic-gate 	off_t		as_end;		/* address space end */
3607c478bd9Sstevel@tonic-gate } av1394_as_t;
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate /*
3647c478bd9Sstevel@tonic-gate  * CMP (Connection Management Procedures)
3657c478bd9Sstevel@tonic-gate  *
3667c478bd9Sstevel@tonic-gate  * PCR address map (Ref: IEC 61883-1 Fig 14)
3677c478bd9Sstevel@tonic-gate  */
3687c478bd9Sstevel@tonic-gate #define	AV1394_PCR_ADDR_START		0xFFFFF0000900
3697c478bd9Sstevel@tonic-gate #define	AV1394_PCR_ADDR_OMPR		0xFFFFF0000900
3707c478bd9Sstevel@tonic-gate #define	AV1394_PCR_ADDR_OPCR0		0xFFFFF0000904
3717c478bd9Sstevel@tonic-gate #define	AV1394_PCR_ADDR_NOPCR		31
3727c478bd9Sstevel@tonic-gate #define	AV1394_PCR_ADDR_IMPR		0xFFFFF0000980
3737c478bd9Sstevel@tonic-gate #define	AV1394_PCR_ADDR_IPCR0		0xFFFFF0000984
3747c478bd9Sstevel@tonic-gate #define	AV1394_PCR_ADDR_NIPCR		31
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate /* initial values and bus reset masks (Ref: IEC 61883-1 Fig 10-13) */
3777c478bd9Sstevel@tonic-gate #define	AV1394_OMPR_INIT_VAL		0xBFFFFF00
3787c478bd9Sstevel@tonic-gate #define	AV1394_IMPR_INIT_VAL		0x80FFFF00
3797c478bd9Sstevel@tonic-gate #define	AV1394_PCR_INIT_VAL		0x00000000	/* both iPCR and oPCR */
3807c478bd9Sstevel@tonic-gate #define	AV1394_OPCR_BR_CLEAR_MASK	0x7FC03C00
3817c478bd9Sstevel@tonic-gate #define	AV1394_IPCR_BR_CLEAR_MASK	0x7FC0FFFF
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate /*
3847c478bd9Sstevel@tonic-gate  * local plug control register
3857c478bd9Sstevel@tonic-gate  */
3867c478bd9Sstevel@tonic-gate typedef struct av1394_pcr_s {
3877c478bd9Sstevel@tonic-gate 	uint32_t		pcr_val;	/* value */
3887c478bd9Sstevel@tonic-gate 	t1394_addr_handle_t	pcr_addr_hdl;	/* address handle */
3897c478bd9Sstevel@tonic-gate } av1394_pcr_t;
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate enum {
3927c478bd9Sstevel@tonic-gate 	AV1394_OMPR_IDX		= 0,	/* oMPR index */
3937c478bd9Sstevel@tonic-gate 	AV1394_OPCR0_IDX	= 1,	/* oPCR0 index */
3947c478bd9Sstevel@tonic-gate 	AV1394_IMPR_IDX		= 32,	/* iMPR index */
3957c478bd9Sstevel@tonic-gate 	AV1394_IPCR0_IDX	= 33,	/* iPCR0 index */
3967c478bd9Sstevel@tonic-gate 	AV1394_NPCR		= 64	/* total number of PCRs */
3977c478bd9Sstevel@tonic-gate };
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate /* plug handle manipulation */
4007c478bd9Sstevel@tonic-gate enum {
4017c478bd9Sstevel@tonic-gate 	AV1394_PCR_REMOTE	= 0x40000000
4027c478bd9Sstevel@tonic-gate };
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate /*
4057c478bd9Sstevel@tonic-gate  * per-instance CMP structure
4067c478bd9Sstevel@tonic-gate  */
4077c478bd9Sstevel@tonic-gate typedef struct av1394_cmp_s {
4087c478bd9Sstevel@tonic-gate 	krwlock_t	cmp_pcr_rwlock;		/* rwlock for PCRs */
4097c478bd9Sstevel@tonic-gate 	av1394_pcr_t	*cmp_pcr[AV1394_NPCR];	/* array of PCRs */
4107c478bd9Sstevel@tonic-gate } av1394_cmp_t;
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("cmp_pcr_rwlock", av1394_cmp_s::cmp_pcr))
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate /*
4167c478bd9Sstevel@tonic-gate  * per-instance soft state structure
4177c478bd9Sstevel@tonic-gate  */
4187c478bd9Sstevel@tonic-gate typedef struct av1394_isoch_s {
4197c478bd9Sstevel@tonic-gate 	kmutex_t		i_mutex;	/* structure mutex */
4207c478bd9Sstevel@tonic-gate 	int			i_nopen;	/* number of opens */
4217c478bd9Sstevel@tonic-gate 	av1394_cmp_t		i_cmp;		/* CMP information */
4227c478bd9Sstevel@tonic-gate 	av1394_ic_t		*i_ic[64];	/* array of channels */
4237c478bd9Sstevel@tonic-gate 	av1394_as_t		i_mmap_as;	/* mmap virtual addr space */
4247c478bd9Sstevel@tonic-gate 	ddi_softintr_t		i_softintr_id;	/* soft interrupt id */
4257c478bd9Sstevel@tonic-gate 	uint64_t		i_softintr_ch;	/* channels to service */
4267c478bd9Sstevel@tonic-gate 	av1394_isoch_autoxmit_t	i_autoxmit;	/* autoxmit support */
4277c478bd9Sstevel@tonic-gate } av1394_isoch_t;
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(av1394_isoch_s::i_mutex, av1394_isoch_s))
4307c478bd9Sstevel@tonic-gate _NOTE(DATA_READABLE_WITHOUT_LOCK(av1394_isoch_s::{
4317c478bd9Sstevel@tonic-gate 	i_ic
4327c478bd9Sstevel@tonic-gate 	i_softintr_id
4337c478bd9Sstevel@tonic-gate }))
4347c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("single-threaded", av1394_isoch_autoxmit_s))
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate _NOTE(LOCK_ORDER(av1394_isoch_s::i_mutex av1394_ic_s::ic_mutex))
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate /* postponed request types */
4397c478bd9Sstevel@tonic-gate enum {
4407c478bd9Sstevel@tonic-gate 	AV1394_PREQ_IR_OVERFLOW		= 0x01,
4417c478bd9Sstevel@tonic-gate 	AV1394_PREQ_IT_UNDERRUN		= 0x02
4427c478bd9Sstevel@tonic-gate };
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate /* isoch channel */
4457c478bd9Sstevel@tonic-gate int	av1394_ic_open(struct av1394_inst_s *, int);
4467c478bd9Sstevel@tonic-gate int	av1394_ic_close(struct av1394_inst_s *, int);
4477c478bd9Sstevel@tonic-gate int	av1394_ic_init(struct av1394_inst_s *avp, iec61883_isoch_init_t *ii,
4487c478bd9Sstevel@tonic-gate 	av1394_ic_t **icpp);
4497c478bd9Sstevel@tonic-gate void	av1394_ic_fini(av1394_ic_t *icp);
4507c478bd9Sstevel@tonic-gate int	av1394_ic_alloc_pool(av1394_isoch_pool_t *pool, size_t segsz, int cnt,
4517c478bd9Sstevel@tonic-gate 	int mincnt);
4527c478bd9Sstevel@tonic-gate void	av1394_ic_free_pool(av1394_isoch_pool_t *pool);
4537c478bd9Sstevel@tonic-gate int	av1394_ic_dma_setup(av1394_ic_t *icp, av1394_isoch_pool_t *pool);
4547c478bd9Sstevel@tonic-gate void	av1394_ic_dma_cleanup(av1394_ic_t *icp, av1394_isoch_pool_t *pool);
4557c478bd9Sstevel@tonic-gate int	av1394_ic_ixl_seg_decomp(size_t segsz, size_t pktsz, size_t *bufszp,
4567c478bd9Sstevel@tonic-gate 	size_t *tailszp);
4577c478bd9Sstevel@tonic-gate void	av1394_ic_dma_sync_frames(av1394_ic_t *icp, int idx, int cnt,
4587c478bd9Sstevel@tonic-gate 		av1394_isoch_pool_t *pool, uint_t type);
4597c478bd9Sstevel@tonic-gate int	av1394_ic_start(av1394_ic_t *icp);
4607c478bd9Sstevel@tonic-gate int	av1394_ic_stop(av1394_ic_t *icp);
4617c478bd9Sstevel@tonic-gate void	av1394_ic_ixl_dump(ixl1394_command_t *cmd);
4627c478bd9Sstevel@tonic-gate void	av1394_ic_trigger_softintr(av1394_ic_t *icp, int num, int preq);
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate /* isoch receive */
4657c478bd9Sstevel@tonic-gate int	av1394_ir_init(av1394_ic_t *icp, int *error);
4667c478bd9Sstevel@tonic-gate void	av1394_ir_fini(av1394_ic_t *icp);
4677c478bd9Sstevel@tonic-gate int	av1394_ir_start(av1394_ic_t *icp);
4687c478bd9Sstevel@tonic-gate int	av1394_ir_stop(av1394_ic_t *icp);
4697c478bd9Sstevel@tonic-gate int	av1394_ir_recv(av1394_ic_t *icp, iec61883_recv_t *recv);
4707c478bd9Sstevel@tonic-gate int	av1394_ir_read(av1394_ic_t *icp, struct uio *uiop);
4717c478bd9Sstevel@tonic-gate void	av1394_ir_overflow(av1394_ic_t *icp);
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate /* isoch transmit */
4747c478bd9Sstevel@tonic-gate int	av1394_it_init(av1394_ic_t *icp, int *error);
4757c478bd9Sstevel@tonic-gate void	av1394_it_fini(av1394_ic_t *icp);
4767c478bd9Sstevel@tonic-gate int	av1394_it_start(av1394_ic_t *icp);
4777c478bd9Sstevel@tonic-gate int	av1394_it_stop(av1394_ic_t *icp);
4787c478bd9Sstevel@tonic-gate int	av1394_it_xmit(av1394_ic_t *icp, iec61883_xmit_t *xmit);
4797c478bd9Sstevel@tonic-gate int	av1394_it_write(av1394_ic_t *icp, struct uio *uiop);
4807c478bd9Sstevel@tonic-gate void	av1394_it_underrun(av1394_ic_t *icp);
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate /* address space for mmap(2) */
4837c478bd9Sstevel@tonic-gate void av1394_as_init(av1394_as_t *as);
4847c478bd9Sstevel@tonic-gate void av1394_as_fini(av1394_as_t *as);
4857c478bd9Sstevel@tonic-gate off_t	av1394_as_alloc(av1394_as_t *as, size_t size);
4867c478bd9Sstevel@tonic-gate void av1394_as_free(av1394_as_t *as, off_t);
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate /* CMP */
4897c478bd9Sstevel@tonic-gate int	av1394_cmp_init(struct av1394_inst_s *avp);
4907c478bd9Sstevel@tonic-gate void	av1394_cmp_fini(struct av1394_inst_s *avp);
4917c478bd9Sstevel@tonic-gate void	av1394_cmp_bus_reset(struct av1394_inst_s *avp);
4927c478bd9Sstevel@tonic-gate void	av1394_cmp_close(struct av1394_inst_s *avp);
4937c478bd9Sstevel@tonic-gate int	av1394_ioctl_plug_init(struct av1394_inst_s *, void *, int);
4947c478bd9Sstevel@tonic-gate int	av1394_ioctl_plug_fini(struct av1394_inst_s *, void *, int);
4957c478bd9Sstevel@tonic-gate int	av1394_ioctl_plug_reg_read(struct av1394_inst_s *, void *, int);
4967c478bd9Sstevel@tonic-gate int	av1394_ioctl_plug_reg_cas(struct av1394_inst_s *, void *, int);
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate /* isoch common */
4997c478bd9Sstevel@tonic-gate int	av1394_isoch_attach(struct av1394_inst_s *);
5007c478bd9Sstevel@tonic-gate void	av1394_isoch_detach(struct av1394_inst_s *);
5017c478bd9Sstevel@tonic-gate int	av1394_isoch_cpr_suspend(struct av1394_inst_s *);
5027c478bd9Sstevel@tonic-gate int	av1394_isoch_cpr_resume(struct av1394_inst_s *);
5037c478bd9Sstevel@tonic-gate void	av1394_isoch_bus_reset(struct av1394_inst_s *);
5047c478bd9Sstevel@tonic-gate void	av1394_isoch_disconnect(struct av1394_inst_s *);
5057c478bd9Sstevel@tonic-gate void	av1394_isoch_reconnect(struct av1394_inst_s *);
5067c478bd9Sstevel@tonic-gate int	av1394_isoch_open(struct av1394_inst_s *, int);
5077c478bd9Sstevel@tonic-gate int	av1394_isoch_close(struct av1394_inst_s *, int);
5087c478bd9Sstevel@tonic-gate int	av1394_isoch_read(struct av1394_inst_s *, struct uio *);
5097c478bd9Sstevel@tonic-gate int	av1394_isoch_write(struct av1394_inst_s *, struct uio *);
5107c478bd9Sstevel@tonic-gate int	av1394_isoch_ioctl(struct av1394_inst_s *, int, intptr_t, int, int *);
5117c478bd9Sstevel@tonic-gate int	av1394_isoch_devmap(struct av1394_inst_s *, devmap_cookie_t, offset_t,
5127c478bd9Sstevel@tonic-gate 		size_t, size_t *, uint_t);
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate #ifdef __cplusplus
5157c478bd9Sstevel@tonic-gate }
5167c478bd9Sstevel@tonic-gate #endif
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate #endif /* _SYS_1394_TARGETS_AV1394_ISOCH_H */
519