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