8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * CDDL HEADER START
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * The contents of this file are subject to the terms of the
193974072f41a843678abf5f61979c748687e66bSherry Moore * Common Development and Distribution License (the "License").
193974072f41a843678abf5f61979c748687e66bSherry Moore * You may not use this file except in compliance with the License.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * or http://www.opensolaris.org/os/licensing.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * See the License for the specific language governing permissions
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * and limitations under the License.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * When distributing Covered Code, include this CDDL HEADER in each
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * If applicable, add the following below this CDDL HEADER, with the
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * fields enclosed by brackets "[]" replaced with your own identifying
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * information: Portions Copyright [yyyy] [name of copyright owner]
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * CDDL HEADER END
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
193974072f41a843678abf5f61979c748687e66bSherry Moore * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * Use is subject to license terms.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam.c
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam1394 driver. Controls IIDC compliant devices attached through a
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * IEEE-1394 bus.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/conf.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/ddi.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/modctl.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/sunndi.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/types.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/ddi.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/sunddi.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/file.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/errno.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/open.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/cred.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/mkdev.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/kmem.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/stat.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/cmn_err.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/stream.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/buf.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/uio.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/devops.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/1394/t1394.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/tnf_probe.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/dcam/dcam1394_io.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/1394/targets/dcam1394/dcam.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/1394/targets/dcam1394/dcam_reg.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/1394/targets/dcam1394/dcam_param.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#include <sys/1394/targets/dcam1394/dcam_frame.h>
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#ifndef NPROBE
8eea8e29cc4374d1ee24c25a07f45af132db3499apextern int tnf_mod_load(void);
8eea8e29cc4374d1ee24c25a07f45af132db3499apextern int tnf_mod_unload(struct modlinkage *mlp);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#endif /* ! NPROBE */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* for power management (we have only one component) */
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic char *dcam_pmc[] = {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap "NAME=dcam1394",
8eea8e29cc4374d1ee24c25a07f45af132db3499ap "0=Off",
8eea8e29cc4374d1ee24c25a07f45af132db3499ap "1=On"
8eea8e29cc4374d1ee24c25a07f45af132db3499ap};
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apint g_vid_mode_frame_num_bytes[] =
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap 57600, /* vid mode 0 */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap 153600, /* vid mode 1 */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap 460800, /* vid mode 2 */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap 614400, /* vid mode 3 */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap 921600, /* vid mode 4 */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap 307200 /* vid mode 5 */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap};
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic int byte_copy_to_user_buff(uchar_t *src_addr_p, struct uio *uio_p,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap size_t num_bytes, int start_index, int *end_index);
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic int byte_copy_from_user_buff(uchar_t *dst_addr_p, struct uio *uio_p,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap size_t num_bytes, int start_index, int *end_index);
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic int dcam_reset(dcam_state_t *softc_p);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* opaque state structure head */
8eea8e29cc4374d1ee24c25a07f45af132db3499apvoid *dcam_state_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic struct cb_ops dcam_cb_ops = {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_open, /* open */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_close, /* close */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nodev, /* strategy */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nodev, /* print */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nodev, /* dump */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_read, /* read */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nodev, /* write */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_ioctl, /* ioctl */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nodev, /* devmap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nodev, /* mmap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nodev, /* segmap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_chpoll, /* chpoll */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_prop_op, /* prop_op */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap NULL, /* streams */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /* flags */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap D_NEW | D_MP | D_64BIT | D_HOTPLUG,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap CB_REV, /* rev */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nodev, /* aread */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nodev /* awrite */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap};
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic struct dev_ops dcam_dev_ops = {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap DEVO_REV, /* DEVO_REV indicated by manual */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap 0, /* device reference count */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_getinfo, /* getinfo */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nulldev, /* identify */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nulldev, /* probe */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_attach, /* attach */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_detach, /* detach */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap nodev, /* reset */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap &dcam_cb_ops, /* ptr to cb_ops struct */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap NULL, /* ptr to bus_ops struct; none */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_power, /* power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_supported, /* devo_quiesce */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap};
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apextern struct mod_ops mod_driverops;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic struct modldrv modldrv = {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap &mod_driverops,
193974072f41a843678abf5f61979c748687e66bSherry Moore "SUNW 1394-based Digital Camera driver",
8eea8e29cc4374d1ee24c25a07f45af132db3499ap &dcam_dev_ops,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap};
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic struct modlinkage modlinkage = {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap MODREV_1,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void *)&modldrv,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap NULL,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap};
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499ap_init(void)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int err;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap err = ddi_soft_state_init(&dcam_state_p, sizeof (dcam_state_t), 2);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (err) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (err);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#ifndef NPROBE
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) tnf_mod_load();
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#endif /* ! NPROBE */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (err = mod_install(&modlinkage)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#ifndef NPROBE
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) tnf_mod_unload(&modlinkage);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#endif /* ! NPROBE */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_fini(&dcam_state_p);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (err);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499ap_info(struct modinfo *modinfop)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int err;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap err = mod_info(&modlinkage, modinfop);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (err);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499ap_fini(void)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int err;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if ((err = mod_remove(&modlinkage)) != 0) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (err);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#ifndef NPROBE
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) tnf_mod_unload(&modlinkage);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#endif /* ! NPROBE */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_fini(&dcam_state_p);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (err);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_attach
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* ARGSUSED */
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap char tmp_str[MAX_STR_LEN];
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_state_t *softc_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_eventcookie_t ev_cookie;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int instance;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int ret_val;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap switch (cmd) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DDI_ATTACH:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = ddi_get_instance(dip);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_soft_state_zalloc(dcam_state_p, instance) !=
8eea8e29cc4374d1ee24c25a07f45af132db3499ap DDI_SUCCESS) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if ((softc_p = ddi_get_soft_state(dcam_state_p, instance)) ==
8eea8e29cc4374d1ee24c25a07f45af132db3499ap NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_free(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * Initialize soft state
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->dip = dip;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->instance = instance;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->usr_model = -1;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->ixlp = NULL;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->seq_count = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->param_status = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * set default vid_mode, frame_rate and ring_buff_capacity
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->cur_vid_mode = 1;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->cur_frame_rate = 3;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->cur_ring_buff_capacity = 10;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->camera_online = 1;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) sprintf(tmp_str, "dcam%d", instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_create_minor_node(dip, tmp_str, S_IFCHR, instance,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap DDI_PSEUDO, 0) != DDI_SUCCESS) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_free(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) sprintf(tmp_str, "dcamctl%d", instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_create_minor_node(dip, tmp_str, S_IFCHR,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance + DCAM1394_MINOR_CTRL, "ddi_dcam1394", 0) !=
8eea8e29cc4374d1ee24c25a07f45af132db3499ap DDI_SUCCESS) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_free(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (t1394_attach(dip, T1394_VERSION_V1, 0,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap &(softc_p->attachinfo),
8eea8e29cc4374d1ee24c25a07f45af132db3499ap &(softc_p->sl_handle)) != DDI_SUCCESS) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_free(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_remove_minor_node(dip, NULL);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (t1394_get_targetinfo(softc_p->sl_handle,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->attachinfo.localinfo.bus_generation, 0,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap &(softc_p->targetinfo)) != DDI_SUCCESS) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap cmn_err(CE_WARN,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap "dcam_attach: t1394_get_targetinfo failed\n");
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_get_eventcookie(dip, DDI_DEVI_BUS_RESET_EVENT,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap &ev_cookie) != DDI_SUCCESS) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) t1394_detach(&softc_p->sl_handle, 0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_free(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_remove_minor_node(dip, NULL);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_add_event_handler(dip, ev_cookie, dcam_bus_reset_notify,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p, &softc_p->event_id) != DDI_SUCCESS) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) t1394_detach(&softc_p->sl_handle, 0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_free(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_remove_minor_node(dip, NULL);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_init(&softc_p->softc_mutex, NULL, MUTEX_DRIVER,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->attachinfo.iblock_cookie);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_init(&softc_p->dcam_frame_is_done_mutex, NULL,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap MUTEX_DRIVER, softc_p->attachinfo.iblock_cookie);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * init the soft state's parameter attribute structure
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (param_attr_init(softc_p, softc_p->param_attr) !=
8eea8e29cc4374d1ee24c25a07f45af132db3499ap DDI_SUCCESS) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) ddi_remove_event_handler(softc_p->event_id);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) t1394_detach(&softc_p->sl_handle, 0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_free(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_remove_minor_node(dip, NULL);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * power management stuff
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_prop_update_string_array(DDI_DEV_T_NONE,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dip, "pm-components", dcam_pmc,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap sizeof (dcam_pmc)/sizeof (char *)) == DDI_PROP_SUCCESS) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) pm_raise_power(dip, 0, 1);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_prop_exists(DDI_DEV_T_ANY, dip, 0,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap "power-managed?")) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) pm_idle_component(dip, 0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap } else {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) pm_busy_component(dip, 0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->flags |= DCAM1394_FLAG_ATTACH_COMPLETE;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_report_dev(dip);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ret_val = DDI_SUCCESS;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DDI_RESUME:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = ddi_get_instance(dip);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if ((softc_p = ddi_get_soft_state(dcam_state_p, instance)) ==
8eea8e29cc4374d1ee24c25a07f45af132db3499ap NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_free(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_enter(&softc_p->softc_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p->flags & DCAM1394_FLAG_FRAME_RCV_INIT) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) dcam1394_ioctl_frame_rcv_start(softc_p);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->suspended = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->softc_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ret_val = DDI_SUCCESS;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap default:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ret_val = DDI_FAILURE;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (ret_val);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_power: perform dcam power management
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* ARGSUSED */
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_power(dev_info_t *dip, int component, int level)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_state_t *softc_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int instance;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = ddi_get_instance(dip);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p = (dcam_state_t *)ddi_get_soft_state(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p == NULL)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->pm_cable_power = level;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_SUCCESS);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_getinfo
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* ARGSUSED */
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dev_t dev;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_state_t *softc_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int status;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int instance;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap switch (cmd) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DDI_INFO_DEVT2DEVINFO:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dev = (dev_t)arg;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = DEV_TO_INSTANCE(dev);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p = (dcam_state_t *)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_get_soft_state(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p == NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *result = (void *)softc_p->dip;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap status = DDI_SUCCESS;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DDI_INFO_DEVT2INSTANCE:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dev = (dev_t)arg;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = DEV_TO_INSTANCE(dev);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *result = (void *)(uintptr_t)instance;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap status = DDI_SUCCESS;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap default:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap status = DDI_FAILURE;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (status);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_detach
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* ARGSUSED */
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int instance;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_state_t *softc_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = ddi_get_instance(dip);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p = (dcam_state_t *)ddi_get_soft_state(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p == NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap switch (cmd) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DDI_SUSPEND:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_enter(&softc_p->softc_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->suspended = 1;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p->flags & DCAM1394_FLAG_FRAME_RCV_INIT) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) dcam_frame_rcv_stop(softc_p);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->softc_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_SUCCESS);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DDI_DETACH:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * power management stuff
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) pm_lower_power(dip, 0, 0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components");
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * deregister with 1394 DDI framework
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (t1394_detach(&softc_p->sl_handle, 0) != DDI_SUCCESS) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) ddi_remove_event_handler(softc_p->event_id);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * free state structures, mutexes, condvars;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * deregister interrupts
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_destroy(&softc_p->softc_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_destroy(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * Remove all minor nodes, all dev_t's properties
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_remove_minor_node(dip, NULL);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_soft_state_free(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ddi_prop_remove_all(dip);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_SUCCESS);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap default:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_FAILURE);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_open
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* ARGSUSED */
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_state_t *softc_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int instance;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int is_ctrl_file;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap uint_t new_flags;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = (int)DEV_TO_INSTANCE(*dev_p);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if ((softc_p = ddi_get_soft_state(dcam_state_p, instance)) == NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (ENXIO);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * if dcam_attach hasn't completed, return error
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * XXX: Check this out
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (!(softc_p->flags & DCAM1394_FLAG_ATTACH_COMPLETE)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (ENXIO);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /* disallow block, mount, and layered opens */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (otyp != OTYP_CHR) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (EINVAL);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap new_flags = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap is_ctrl_file = (getminor(*dev_p) & DCAM1394_MINOR_CTRL) ? 1 : 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_enter(&softc_p->softc_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * The open is either for the capture file or the control file.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * If it's the control file construct new flags.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * If it's the capture file return busy if it's already open,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * otherwise construct new flags.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (is_ctrl_file) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap new_flags |= DCAM1394_FLAG_OPEN_CONTROL;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap } else {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p->flags & DCAM1394_FLAG_OPEN_CAPTURE) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->softc_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (EBUSY);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap new_flags |= DCAM1394_FLAG_OPEN_CAPTURE;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap new_flags |= DCAM1394_FLAG_OPEN;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->flags |= new_flags;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->softc_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * power management stuff
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p->pm_open_count == 0) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_prop_exists(DDI_DEV_T_ANY, softc_p->dip, 0,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap "power-managed?")) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) pm_busy_component(softc_p->dip, 0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p->pm_cable_power == 0) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int i;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) pm_raise_power(softc_p->dip, 0, 1);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * Wait for the power to be up and stable
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * before proceeding. 100 msecs should
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * certainly be enough, and if we check
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * every msec we'll probably loop just a
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * few times.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap for (i = 0; i < 100; i++) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (param_power_set(softc_p, 1) == 0) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap delay((clock_t)drv_usectohz(1000));
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->pm_open_count++;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_close
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* ARGSUSED */
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_close(dev_t dev, int flags, int otyp, cred_t *cred_p)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int instance;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_state_t *softc;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = DEV_TO_INSTANCE(dev);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc = (dcam_state_t *)ddi_get_soft_state(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * power management stuff
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc->pm_open_count = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_prop_exists(DDI_DEV_T_ANY, softc->dip, 0, "power-managed?")) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) pm_idle_component(softc->dip, 0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_enter(&softc->softc_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (getminor(dev) & DCAM1394_MINOR_CTRL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc->flags &= ~DCAM1394_FLAG_OPEN_CONTROL;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap } else {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * If an application which has opened the camera capture
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * device exits without calling DCAM1394_CMD_FRAME_RCV_STOP
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * ioctl, then we need to release resources.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc->flags & DCAM1394_FLAG_FRAME_RCV_INIT) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) dcam_frame_rcv_stop(softc);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc->flags &= ~DCAM1394_FLAG_FRAME_RCV_INIT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (void) param_power_set(softc, 0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc->flags &= ~DCAM1394_FLAG_OPEN_CAPTURE;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * If driver is completely closed, then stabilize the camera
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * and turn off transient flags
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (!(softc->flags &
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (DCAM1394_FLAG_OPEN_CONTROL | DCAM1394_FLAG_OPEN_CAPTURE))) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc->flags &= DCAM1394_FLAG_ATTACH_COMPLETE;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc->softc_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (DDI_SUCCESS);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_read
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * If read pointer is not pointing to the same position as write pointer
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * copy frame data from ring buffer position pointed to by read pointer.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * If during the course of copying frame data, the device driver
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * invalidated this read() request processing operation, restart
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * this operation.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * Increment read pointer and return frame data to user process.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * Else return error
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* ARGSUSED */
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_read(dev_t dev, struct uio *uio_p, cred_t *cred_p)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap buff_info_t *buff_info_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_state_t *softc_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap hrtime_t timestamp;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int index, instance;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int read_ptr_id;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap size_t read_ptr_pos, write_ptr_pos;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int read_req_invalid;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ring_buff_t *ring_buff_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap uchar_t *frame_data_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap uint_t seq_num;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap unsigned long user_frame_buff_addr;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap uint_t vid_mode;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int gotten_addr_flag;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = DEV_TO_INSTANCE(dev);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p = (dcam_state_t *)ddi_get_soft_state(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p == NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (ENXIO);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if ((ring_buff_p = softc_p->ring_buff_p) == NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (EAGAIN);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap read_ptr_id = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_enter(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->reader_flags[read_ptr_id] |= DCAM1394_FLAG_READ_REQ_PROC;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap user_frame_buff_addr = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap gotten_addr_flag = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap do {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap read_ptr_pos = ring_buff_read_ptr_pos_get(ring_buff_p,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap read_ptr_id);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap write_ptr_pos = ring_buff_write_ptr_pos_get(ring_buff_p);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (read_ptr_pos != write_ptr_pos) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * Since the app wants realtime video, set the read
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * pointer to the newest data.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (write_ptr_pos == 0) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap read_ptr_pos = ring_buff_p->num_buffs - 1;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap } else {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap read_ptr_pos = write_ptr_pos - 1;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * copy frame data from ring buffer position pointed
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * to by read pointer
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap index = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap buff_info_p =
193974072f41a843678abf5f61979c748687e66bSherry Moore &(ring_buff_p->buff_info_array_p[read_ptr_pos]);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap vid_mode = softc_p->cur_vid_mode;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap seq_num = buff_info_p->seq_num;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap timestamp = buff_info_p->timestamp;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap frame_data_p = (uchar_t *)buff_info_p->kaddr_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * Fix for bug #4424042
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * don't lock this section
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (byte_copy_to_user_buff((uchar_t *)&vid_mode,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap uio_p, sizeof (uint_t), index, &index)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (EFAULT);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (byte_copy_to_user_buff((uchar_t *)&seq_num,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap uio_p, sizeof (unsigned int), index, &index)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (EFAULT);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (byte_copy_to_user_buff((uchar_t *)&timestamp,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap uio_p, sizeof (hrtime_t), index, &index)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (EFAULT);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * get buff pointer; do ddi_copyout()
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * get user buffer address only once
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (!gotten_addr_flag) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (byte_copy_from_user_buff(
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (uchar_t *)&user_frame_buff_addr, uio_p,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->usr_model, index, &index)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (EFAULT);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#ifdef _MULTI_DATAMODEL
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p->usr_model == ILP32_PTR_SIZE) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap user_frame_buff_addr =
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ((user_frame_buff_addr >> 32) &
8eea8e29cc4374d1ee24c25a07f45af132db3499ap 0xffffffffULL) |
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ((user_frame_buff_addr << 32) &
8eea8e29cc4374d1ee24c25a07f45af132db3499ap 0xffffffff00000000ULL);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap#endif /* _MULTI_DATAMODEL */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap gotten_addr_flag = 1;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_copyout(
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (caddr_t)frame_data_p,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (caddr_t)user_frame_buff_addr,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap g_vid_mode_frame_num_bytes[softc_p->cur_vid_mode],
8eea8e29cc4374d1ee24c25a07f45af132db3499ap 0)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (EFAULT);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * if during the course of copying frame data,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * the device driver invalidated this read()
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * request processing operation; restart this
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * operation
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_enter(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap read_req_invalid = softc_p->reader_flags[read_ptr_id] &
8eea8e29cc4374d1ee24c25a07f45af132db3499ap DCAM1394_FLAG_READ_REQ_INVALID;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->reader_flags[read_ptr_id] &=
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ~(DCAM1394_FLAG_READ_REQ_INVALID);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap } else {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (EAGAIN);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_enter(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap } while (read_req_invalid);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * return number of bytes actually written to user space
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap uio_p->uio_resid -= g_vid_mode_frame_num_bytes[softc_p->cur_vid_mode];
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->reader_flags[read_ptr_id] &= ~(DCAM1394_FLAG_READ_REQ_PROC);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /* increment read pointer */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ring_buff_read_ptr_incr(ring_buff_p, read_ptr_id);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_ioctl
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* ARGSUSED */
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int *rvalp)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_state_t *softc_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam1394_param_list_t *param_list;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam1394_reg_io_t dcam_reg_io;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int instance, is_ctrl_file, rc, i;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap param_list = (dcam1394_param_list_t *)0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = DEV_TO_INSTANCE(dev);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if ((softc_p = ddi_get_soft_state(dcam_state_p, instance)) == NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = ENXIO;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * determine user applications data model
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->usr_model = ILP32_PTR_SIZE;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap else
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->usr_model = LP64_PTR_SIZE;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap switch (cmd) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DCAM1394_CMD_REG_READ:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_copyin((caddr_t)arg, &dcam_reg_io,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap sizeof (dcam1394_reg_io_t), mode)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EFAULT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (dcam_reg_read(softc_p, &dcam_reg_io)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EFAULT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_copyout(&dcam_reg_io, (caddr_t)arg,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap sizeof (dcam1394_reg_io_t), mode)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EFAULT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DCAM1394_CMD_REG_WRITE:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_copyin((caddr_t)arg, &dcam_reg_io,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap sizeof (dcam1394_reg_io_t), mode)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EFAULT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (dcam_reg_write(softc_p, &dcam_reg_io)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EFAULT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_copyout(&dcam_reg_io, (caddr_t)arg,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap sizeof (dcam1394_reg_io_t), mode)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EFAULT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DCAM1394_CMD_CAM_RESET:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (dcam_reset(softc_p)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EIO;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DCAM1394_CMD_PARAM_GET:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap param_list = (dcam1394_param_list_t *)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap kmem_alloc(sizeof (dcam1394_param_list_t), KM_SLEEP);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_copyin((caddr_t)arg, (caddr_t)param_list,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap sizeof (dcam1394_param_list_t), mode)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EFAULT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (dcam1394_ioctl_param_get(softc_p, *param_list)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EINVAL;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_copyout((caddr_t)param_list, (caddr_t)arg,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap sizeof (dcam1394_param_list_t), mode)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EFAULT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DCAM1394_CMD_PARAM_SET:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap param_list = (dcam1394_param_list_t *)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap kmem_alloc((size_t)sizeof (dcam1394_param_list_t),
8eea8e29cc4374d1ee24c25a07f45af132db3499ap KM_SLEEP);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_copyin((caddr_t)arg, (caddr_t)param_list,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap sizeof (dcam1394_param_list_t), mode)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EFAULT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap is_ctrl_file = (getminor(dev) & DCAM1394_MINOR_CTRL) ? 1:0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (dcam1394_ioctl_param_set(softc_p, is_ctrl_file,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *param_list)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EINVAL;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (is_ctrl_file) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_enter(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->param_status |= DCAM1394_STATUS_PARAM_CHANGE;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (ddi_copyout(param_list, (caddr_t)arg,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap sizeof (dcam1394_param_list_t), mode)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EFAULT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap goto done;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DCAM1394_CMD_FRAME_RCV_START:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (dcam1394_ioctl_frame_rcv_start(softc_p)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = ENXIO;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DCAM1394_CMD_FRAME_RCV_STOP:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (dcam_frame_rcv_stop(softc_p)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = ENXIO;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DCAM1394_CMD_RING_BUFF_FLUSH:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p->ring_buff_p == NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EAGAIN;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * the simplest way to flush ring_buff is to empty it
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap for (i = 0; i < softc_p->ring_buff_p->num_read_ptrs; i++) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->ring_buff_p->read_ptr_pos[i] =
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->ring_buff_p->write_ptr_pos;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * if device driver is processing a user
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * process's read() request
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p->reader_flags[i] &
8eea8e29cc4374d1ee24c25a07f45af132db3499ap DCAM1394_FLAG_READ_REQ_PROC) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * invalidate the read() request processing
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * operation
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->reader_flags[i] |=
8eea8e29cc4374d1ee24c25a07f45af132db3499ap DCAM1394_FLAG_READ_REQ_INVALID;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap case DCAM1394_CMD_FRAME_SEQ_NUM_COUNT_RESET:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_enter(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->seq_count = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap default:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap rc = EIO;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap break;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499apdone:
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (param_list)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap kmem_free(param_list, sizeof (dcam1394_param_list_t));
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (rc);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_chpoll
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* ARGSUSED */
8eea8e29cc4374d1ee24c25a07f45af132db3499apint
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_chpoll(dev_t dev, short events, int anyyet, short *reventsp,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap struct pollhead **phpp)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_state_t *softc_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int instance, ring_buff_has_data, read_ptr_id;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap size_t read_ptr_pos, write_ptr_pos;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap short revent;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap instance = DEV_TO_INSTANCE(dev);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p = (dcam_state_t *)ddi_get_soft_state(dcam_state_p, instance);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p == NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (ENXIO);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap read_ptr_id = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap revent = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (softc_p->ring_buff_p == NULL) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ring_buff_has_data = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap } else {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_enter(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap read_ptr_pos =
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ring_buff_read_ptr_pos_get(softc_p->ring_buff_p,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap read_ptr_id);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap write_ptr_pos =
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ring_buff_write_ptr_pos_get(softc_p->ring_buff_p);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (read_ptr_pos != write_ptr_pos) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ring_buff_has_data = 1;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap } else {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap ring_buff_has_data = 0;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap mutex_exit(&softc_p->dcam_frame_is_done_mutex);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * now check for events
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if ((events & POLLRDNORM) && ring_buff_has_data) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap revent |= POLLRDNORM;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if ((events & POLLPRI) && softc_p->param_status) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap revent |= POLLPRI;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /* if no events have occurred */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (revent == 0) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (!anyyet) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *phpp = &softc_p->dcam_pollhead;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *reventsp = revent;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_bus_reset_notify
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/* ARGSUSED */
8eea8e29cc4374d1ee24c25a07f45af132db3499apvoid
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_bus_reset_notify(dev_info_t *dip, ddi_eventcookie_t ev_cookie, void *arg,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap void *impl_data)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_state_t *softc_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap t1394_localinfo_t *localinfo = impl_data;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap t1394_targetinfo_t targetinfo;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p = arg;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * this is needed to handle LG camera "changing GUID" bug
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * XXX: What's this about?
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if ((dip == NULL) || (arg == NULL) || (impl_data == NULL) ||
8eea8e29cc4374d1ee24c25a07f45af132db3499ap (softc_p->sl_handle == NULL)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap localinfo = impl_data;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * simply return if no target info
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (t1394_get_targetinfo(softc_p->sl_handle,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap localinfo->bus_generation, 0, &targetinfo) != DDI_SUCCESS)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (localinfo->local_nodeID == softc_p->targetinfo.target_nodeID) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->param_status |= DCAM1394_STATUS_CAM_UNPLUG;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap } else {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->param_status &= ~DCAM1394_STATUS_CAM_UNPLUG;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /* struct copies */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->attachinfo.localinfo = *localinfo;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (targetinfo.target_nodeID != T1394_INVALID_NODEID) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->targetinfo.current_max_payload =
8eea8e29cc4374d1ee24c25a07f45af132db3499ap targetinfo.current_max_payload;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->targetinfo.current_max_speed =
8eea8e29cc4374d1ee24c25a07f45af132db3499ap targetinfo.current_max_speed;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap softc_p->targetinfo.target_nodeID =
8eea8e29cc4374d1ee24c25a07f45af132db3499ap targetinfo.target_nodeID;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * byte_copy_to_user_buff
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic int
8eea8e29cc4374d1ee24c25a07f45af132db3499apbyte_copy_to_user_buff(uchar_t *src_addr_p, struct uio *uio_p, size_t num_bytes,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int start_index, int *end_index_p)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int index;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap size_t len;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap uchar_t *u8_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap index = start_index;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap u8_p = (uchar_t *)src_addr_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap while (num_bytes) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap len = num_bytes;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (uiomove(u8_p, len, UIO_READ, uio_p)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (-1);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap index++;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap u8_p += len;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap num_bytes -= len;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *end_index_p = index;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * byte_copy_from_user_buff
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic int
8eea8e29cc4374d1ee24c25a07f45af132db3499apbyte_copy_from_user_buff(uchar_t *dst_addr_p, struct uio *uio_p,
8eea8e29cc4374d1ee24c25a07f45af132db3499ap size_t num_bytes, int start_index, int *end_index_p)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap int index;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap size_t len;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap uchar_t *u8_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap index = start_index;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap u8_p = (uchar_t *)dst_addr_p;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap while (num_bytes) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap len = num_bytes;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (uiomove(u8_p, len, UIO_WRITE, uio_p)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (-1);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap index++;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap u8_p += len;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap num_bytes -= len;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap *end_index_p = index;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap/*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * dcam_reset()
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499apstatic int
8eea8e29cc4374d1ee24c25a07f45af132db3499apdcam_reset(dcam_state_t *softc_p)
8eea8e29cc4374d1ee24c25a07f45af132db3499ap{
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam1394_reg_io_t dcam_reg_io;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_reg_io.offs = DCAM1394_REG_OFFS_INITIALIZE;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_reg_io.val = DCAM1394_REG_VAL_INITIALIZE_ASSERT;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (dcam_reg_write(softc_p, &dcam_reg_io)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (-1);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap /*
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * If the camera has a TI VSP, tweak the iris feature
8eea8e29cc4374d1ee24c25a07f45af132db3499ap * to "on" and value 4.
8eea8e29cc4374d1ee24c25a07f45af132db3499ap */
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_reg_io.offs = DCAM1394_REG_OFFS_FEATURE_CSR_BASE +
193974072f41a843678abf5f61979c748687e66bSherry Moore DCAM1394_REG_OFFS_IRIS_CSR;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap dcam_reg_io.val = 0x82000004;
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap if (dcam_reg_write(softc_p, &dcam_reg_io)) {
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (-1);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap }
8eea8e29cc4374d1ee24c25a07f45af132db3499ap
8eea8e29cc4374d1ee24c25a07f45af132db3499ap return (0);
8eea8e29cc4374d1ee24c25a07f45af132db3499ap}