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 (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _SYS_USB_USBVC_VAR_H
  27 #define _SYS_USB_USBVC_VAR_H
  28 
  29 
  30 #ifdef  __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 #include <sys/list.h>
  35 #include <sys/sysmacros.h>
  36 #include <sys/usb/usba/usbai_private.h>
  37 #include <sys/videodev2.h>
  38 #include <sys/usb/clients/video/usbvc/usbvc.h>
  39 
  40 typedef struct usbvc_state usbvc_state_t;
  41 
  42 /*
  43  * Power Management support
  44  */
  45 typedef struct usbvc_power  {
  46 
  47         void            *usbvc_state;   /* points back to usbvc_state */
  48         uint8_t         usbvc_pwr_states; /* bit mask of device pwr states */
  49         int             usbvc_pm_busy;
  50 
  51         /* Wakeup and power transistion capabilites of an interface */
  52         uint8_t         usbvc_pm_capabilities;
  53 
  54         /* flag to indicate if driver is about to raise power level */
  55         boolean_t       usbvc_raise_power;
  56 
  57         uint8_t         usbvc_current_power;
  58         uint8_t         usbvc_wakeup_enabled;
  59 } usbvc_power_t;
  60 
  61 /* Raw data buf from the USB cam */
  62 typedef struct usbvc_buf
  63 {
  64         uchar_t *data;
  65         uint_t len;     /* the length of the allocated memory of data */
  66         uint_t filled;  /* number of bytes filled */
  67         uint_t len_read; /* bytes read */
  68         uchar_t status; /* empty, filling done, read done */
  69 
  70         /* cookie used for memory mapping */
  71         ddi_umem_cookie_t       umem_cookie;
  72         struct                  v4l2_buffer v4l2_buf;
  73         list_node_t             buf_node;       /* list */
  74 } usbvc_buf_t;
  75 
  76 /* Group data buf related lists and other elements */
  77 typedef struct usbvc_buf_grp
  78 {
  79     list_t              uv_buf_free;
  80         list_t          uv_buf_done;
  81         usbvc_buf_t     *buf_filling;
  82         uint_t          buf_cnt;
  83         usbvc_buf_t     *buf_head;
  84 } usbvc_buf_grp_t;
  85 
  86 /*
  87  * UVC Spec: one format descriptor may be followed by sererval frame
  88  * descriptors, one still image descriptor and one color matching descriptor.
  89  * It is called a format group. There might be several format groups follow
  90  * one input/output header.
  91  */
  92 typedef struct usbvc_format_group {
  93         usbvc_format_descr_t    *format;
  94         usbvc_frames_t          *frames;
  95         uint8_t                 frame_cnt;
  96 
  97         /* bytes per pix, used to calculate bytesperline */
  98         uint8_t                 v4l2_bpp;
  99 
 100         uint8_t                 v4l2_color;
 101         uint32_t                v4l2_pixelformat;       /* fcc, pixelformat */
 102         usbvc_still_image_frame_t       *still;
 103         usbvc_color_matching_descr_t    *color;
 104         usbvc_frames_t                  *cur_frame;
 105 } usbvc_format_group_t;
 106 
 107 /* A stream interface may have several format groups */
 108 typedef struct usbvc_stream_if {
 109 
 110         /* The actual format groups we parsed for the stream interface */
 111         uint8_t                 fmtgrp_cnt;
 112 
 113         usb_if_data_t           *if_descr;
 114         usbvc_input_header_t    *input_header;
 115         usbvc_output_header_t   *output_header;
 116         usbvc_format_group_t    *format_group;
 117         usbvc_format_group_t    *cur_format_group;
 118         usbvc_vs_probe_commit_t ctrl_pc;
 119         usb_ep_descr_t          *curr_ep;       /* current isoc ep descr */
 120         usb_pipe_handle_t       datain_ph;      /* current isoc pipe handle */
 121         uint_t                  curr_alt;       /* current alternate  */
 122 
 123         /* The max payload that the isoc data EPs can support */
 124         uint32_t        max_isoc_payload;
 125 
 126         uchar_t         start_polling;  /* indicate if isoc polling started */
 127 
 128         /*
 129          * To flag if VIDIOC_STREAMON is executed, only used by STREAM mode
 130          * for suspend/resume. If it's non-zero, we'll have to resume the
 131          * device's isoc polling operation after resume.
 132          */
 133         uint8_t         stream_on;
 134 
 135         uchar_t         fid;            /* the MJPEG FID bit */
 136         usbvc_buf_grp_t buf_read;       /* buf used for read I/O */
 137         uint8_t                 buf_read_num; /* desired buf num for read I/O */
 138         usbvc_buf_grp_t buf_map;        /* buf used for mmap I/O */
 139         list_node_t     stream_if_node;
 140 } usbvc_stream_if_t;
 141 
 142 /* video interface collection */
 143 typedef struct usbvc_vic {
 144 
 145         /* bFirstInterface, the video control infterface num of this VIC */
 146         uint8_t vctrl_if_num;
 147 
 148         /*
 149          * bInterfaceCount -1, the total number of stream interfaces
 150          * belong to this VIC
 151          */
 152         uint8_t vstrm_if_cnt;
 153 } usbvc_vic_t;
 154 
 155 /* Macros */
 156 #define USBVC_OPEN              0x00000001
 157 
 158 /* For serialization. */
 159 #define USBVC_SER_NOSIG B_FALSE
 160 #define USBVC_SER_SIG           B_TRUE
 161 
 162 /*
 163  * Masks for debug printing
 164  */
 165 #define PRINT_MASK_ATTA         0x00000001
 166 #define PRINT_MASK_OPEN         0x00000002
 167 #define PRINT_MASK_CLOSE        0x00000004
 168 #define PRINT_MASK_READ         0x00000008
 169 #define PRINT_MASK_IOCTL        0x00000010
 170 #define PRINT_MASK_PM   0x00000020
 171 #define PRINT_MASK_CB   0x00000040
 172 #define PRINT_MASK_HOTPLUG      0x00000080
 173 #define PRINT_MASK_DEVCTRL      0x00000100
 174 #define PRINT_MASK_DEVMAP       0x00000200
 175 #define PRINT_MASK_ALL          0xFFFFFFFF
 176 
 177 #define USBVC_MAX_PKTS 40
 178 
 179 #define USBVC_DEFAULT_READ_BUF_NUM 3
 180 #define USBVC_MAX_READ_BUF_NUM 40
 181 #define USBVC_MAX_MAP_BUF_NUM 40
 182 
 183 /* According to UVC specs, the frame interval is in 100ns unit */
 184 #define USBVC_FRAME_INTERVAL_DENOMINATOR        10000000
 185 
 186 /* Only D3...D0 are writable, Table 4-6, UVC Spec */
 187 #define USBVC_POWER_MODE_MASK   0xf0;
 188 
 189 enum usbvc_buf_status {
 190         USBVC_BUF_INIT          = 0,  /* Allocated, to be queued */
 191             USBVC_BUF_MAPPED    = 1,  /* For map I/O only. Memory is mapped. */
 192             USBVC_BUF_EMPTY             = 2, /* not initialized, to be filled */
 193 
 194         /*
 195          * buf is filled with a full frame without any errors,
 196          * it will be moved to full list.
 197          */
 198             USBVC_BUF_DONE              = 4,
 199 
 200         /*
 201          * buf is filled to full but no EOF bit is found at the end
 202          * of video data
 203          */
 204             USBVC_BUF_ERR               = 8
 205 };
 206 
 207 /*
 208  * This structure is used to map v4l2 controls to uvc controls. The structure
 209  * array is addressed by (V4L2_CID_BASE - V4L2_CID_*)
 210  */
 211 typedef struct usbvc_v4l2_ctrl_map {
 212         char    name[32];
 213         uint8_t selector; /* Control Selector */
 214         uint8_t len;    /* wLength, defined in uvc spec chp 4 for each ctrl */
 215 
 216         /* The xth bit in bmControls bitmap of processing unit descriptor */
 217         uint8_t bit;
 218 
 219         enum    v4l2_ctrl_type type;
 220 } usbvc_v4l2_ctrl_map_t;
 221 
 222 typedef struct usbvc_v4l2_ctrl {
 223         uint8_t                 entity_id;
 224         usbvc_v4l2_ctrl_map_t   *ctrl_map;
 225 } usbvc_v4l2_ctrl_t;
 226 
 227 
 228 /*
 229  * State structure
 230  */
 231 struct usbvc_state {
 232         dev_info_t              *usbvc_dip;     /* per-device info handle */
 233         usb_client_dev_data_t   *usbvc_reg;     /* registration data */
 234         int                     usbvc_dev_state; /* USB device states. */
 235         int                     usbvc_drv_state; /* driver states. */
 236         kmutex_t                usbvc_mutex;
 237         kcondvar_t              usbvc_serial_cv;
 238         boolean_t               usbvc_serial_inuse;
 239         boolean_t               usbvc_locks_initialized;
 240 
 241         usbvc_power_t           *usbvc_pm;
 242 
 243         usb_log_handle_t        usbvc_log_handle;       /* log handle */
 244         usb_pipe_handle_t       usbvc_default_ph; /* default pipe */
 245 
 246         /* Video ctrl interface header descriptor */
 247         usbvc_vc_header_t       *usbvc_vc_header;
 248         list_t                  usbvc_term_list;
 249         list_t                  usbvc_unit_list;
 250 
 251         list_t                  usbvc_stream_list;
 252         usbvc_stream_if_t       *usbvc_curr_strm;
 253         kcondvar_t              usbvc_read_cv;  /* wait for read buf done */
 254         kcondvar_t              usbvc_mapio_cv; /* wait for mmap I/O buf done */
 255 
 256         /* current I/O type: read or mmap. */
 257         uchar_t                 usbvc_io_type;
 258 };
 259 
 260 
 261 /*
 262  * Used in ioctl entry to copy an argument from kernel space (arg_name)
 263  * to USER space (arg)
 264  */
 265 #define USBVC_COPYOUT(arg_name) \
 266 if (ddi_copyout(&arg_name, (caddr_t)arg, sizeof (arg_name), mode)) { \
 267     rv = EFAULT; \
 268     break;      \
 269 }
 270 
 271 /*
 272  * Used in ioctl entry to copy an argument from USER space (arg) to
 273  * KERNEL space (arg_name)
 274  */
 275 #define USBVC_COPYIN(arg_name) \
 276 if (ddi_copyin((caddr_t)arg, &arg_name, sizeof (arg_name), mode)) { \
 277         rv = EFAULT; \
 278         break;  \
 279 }
 280 
 281 /* Turn a little endian byte array to a uint32_t */
 282 #define LE_TO_UINT32(src, off, des)     { \
 283                                 uint32_t tmp; \
 284                                 des = src[off + 3]; \
 285                                 des = des << 24; \
 286                                 tmp = src[off + 2]; \
 287                                 des |= tmp << 16; \
 288                                 tmp = src[off + 1]; \
 289                                 des |= tmp << 8; \
 290                                 des |= src[off]; \
 291                                 }
 292 
 293 /* Turn a uint32_t to a little endian byte array */
 294 #define UINT32_TO_LE(src, off, des)     { \
 295                                 des[off + 0] = 0xff & src; \
 296                                 des[off + 1] = 0xff & (src >> 8); \
 297                                 des[off + 2] = 0xff & (src >> 16); \
 298                                 des[off + 3] = 0xff & (src >> 24); \
 299                                 }
 300 
 301 /* Turn a little endian byte array to a uint16_t */
 302 #define LE_TO_UINT16(src, off, des)      \
 303                                 des = src[off + 1]; \
 304                                 des = des << 8; \
 305                                 des |= src[off];
 306 
 307 /* Turn a uint16_t to alittle endian byte array */
 308 #define UINT16_TO_LE(src, off, des)     { \
 309                                 des[off + 0] = 0xff & src; \
 310                                 des[off + 1] = 0xff & (src >> 8); \
 311                                 }
 312 
 313 #define NELEM(a)        (sizeof (a) / sizeof (*(a)))
 314 
 315 /* Minimum length of class specific descriptors */
 316 #define USBVC_C_HEAD_LEN_MIN    12      /* ctrl header */
 317 #define USBVC_I_TERM_LEN_MIN    8       /* input term */
 318 #define USBVC_O_TERM_LEN_MIN    9       /* output term */
 319 #define USBVC_P_UNIT_LEN_MIN    8       /* processing unit */
 320 #define USBVC_S_UNIT_LEN_MIN    5       /* selector unit */
 321 #define USBVC_E_UNIT_LEN_MIN    22      /* extension unit */
 322 #define USBVC_FRAME_LEN_MIN     26      /* Frame descriptor */
 323 
 324 /* Length of the Frame descriptor which has continuous frame intervals */
 325 #define USBVC_FRAME_LEN_CON     38
 326 
 327 
 328 /*
 329  * According to usb2.0 spec (table 9-13), for all ep, bits 10..0 specify the
 330  * max pkt size; for high speed ep, bits 12..11 specify the number of
 331  * additional transaction opportunities per microframe.
 332  */
 333 #define HS_PKT_SIZE(pktsize) (pktsize & 0x07ff) * (1 + ((pktsize >> 11) & 3))
 334 
 335 /*
 336  * warlock directives
 337  * _NOTE is an advice for locklint.  Locklint checks lock use for deadlocks.
 338  */
 339 _NOTE(MUTEX_PROTECTS_DATA(usbvc_state_t::usbvc_mutex, usbvc_state_t))
 340 _NOTE(DATA_READABLE_WITHOUT_LOCK(usbvc_state_t::{
 341         usbvc_dip
 342         usbvc_pm
 343         usbvc_log_handle
 344         usbvc_reg
 345         usbvc_default_ph
 346         usbvc_vc_header
 347         usbvc_term_list
 348         usbvc_unit_list
 349         usbvc_stream_list
 350 }))
 351 
 352 _NOTE(SCHEME_PROTECTS_DATA("stable data", usb_pipe_policy))
 353 _NOTE(SCHEME_PROTECTS_DATA("USBA", usbvc_stream_if::datain_ph))
 354 _NOTE(SCHEME_PROTECTS_DATA("USBA", usbvc_stream_if::curr_alt))
 355 _NOTE(SCHEME_PROTECTS_DATA("USBA", usbvc_stream_if::curr_ep))
 356 _NOTE(SCHEME_PROTECTS_DATA("unshared data", usbvc_buf::umem_cookie))
 357 _NOTE(SCHEME_PROTECTS_DATA("unshared data", usbvc_buf::data))
 358 _NOTE(SCHEME_PROTECTS_DATA("unshared data", usbvc_v4l2_ctrl))
 359 _NOTE(SCHEME_PROTECTS_DATA("unshared data", usbvc_v4l2_ctrl_map))
 360 _NOTE(SCHEME_PROTECTS_DATA("unshared data", mblk_t))
 361 _NOTE(SCHEME_PROTECTS_DATA("unshared data", buf))
 362 _NOTE(SCHEME_PROTECTS_DATA("unshared data", usb_isoc_req))
 363 _NOTE(SCHEME_PROTECTS_DATA("unshared data", v4l2_queryctrl))
 364 _NOTE(SCHEME_PROTECTS_DATA("unshared data", v4l2_format))
 365 _NOTE(SCHEME_PROTECTS_DATA("unshared data", v4l2_control))
 366 _NOTE(SCHEME_PROTECTS_DATA("unshared data", v4l2_streamparm))
 367 
 368 int     usbvc_open_isoc_pipe(usbvc_state_t *, usbvc_stream_if_t *);
 369 int     usbvc_start_isoc_polling(usbvc_state_t *, usbvc_stream_if_t *, uchar_t);
 370 int     usbvc_vc_set_ctrl(usbvc_state_t *, uint8_t,  uint8_t,
 371                 uint16_t, uint16_t, mblk_t *);
 372 int     usbvc_vc_get_ctrl(usbvc_state_t *, uint8_t,  uint8_t,
 373                 uint16_t, uint16_t, mblk_t *);
 374 int     usbvc_vs_set_probe_commit(usbvc_state_t *, usbvc_stream_if_t *,
 375         usbvc_vs_probe_commit_t *, uchar_t);
 376 void    usbvc_free_map_bufs(usbvc_state_t *, usbvc_stream_if_t *);
 377 int     usbvc_alloc_map_bufs(usbvc_state_t *, usbvc_stream_if_t *, int, int);
 378 int     usbvc_vs_get_probe(usbvc_state_t *, usbvc_stream_if_t *,
 379                 usbvc_vs_probe_commit_t *, uchar_t);
 380 
 381 /* Functions specific for V4L2 API */
 382 uint8_t         usbvc_v4l2_colorspace(uint8_t);
 383 uint32_t        usbvc_v4l2_guid2fcc(uint8_t *);
 384 int             usbvc_v4l2_ioctl(usbvc_state_t *, int, intptr_t, int);
 385 
 386 
 387 #ifdef __cplusplus
 388 }
 389 #endif
 390 
 391 #endif  /* _SYS_USB_USBVC_VAR_H */