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