d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/*
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * CDDL HEADER START
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro *
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * 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.
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro *
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * or http://www.opensolaris.org/os/licensing.
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * See the License for the specific language governing permissions
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * and limitations under the License.
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro *
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * When distributing Covered Code, include this CDDL HEADER in each
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * If applicable, add the following below this CDDL HEADER, with the
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * fields enclosed by brackets "[]" replaced with your own identifying
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * information: Portions Copyright [yyyy] [name of copyright owner]
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro *
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * CDDL HEADER END
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/*
193974072f41a843678abf5f61979c748687e66bSherry Moore * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * Use is subject to license terms.
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/*
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * Driver to control Alert and Power LEDs for the Seattle platform.
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * Alert LED is also known as Service (required).
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * Power LED is also known as Activity.
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/types.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/time.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/errno.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/cmn_err.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/param.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/modctl.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/conf.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/open.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/stat.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/clock.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/ddi.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/sunddi.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/file.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/note.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#include <sys/epic.h>
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/*
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * Some #defs that must be here as they differ for power.c
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * and epic.c
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#define EPIC_REGS_OFFSET 0x00
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#define EPIC_REGS_LEN 0x80
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#define EPIC_IND_DATA 0x40
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#define EPIC_IND_ADDR 0x41
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#define EPIC_WRITE_MASK 0x80
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/* dev_ops and cb_ops entry point function declarations */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int epic_attach(dev_info_t *, ddi_attach_cmd_t);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int epic_detach(dev_info_t *, ddi_detach_cmd_t);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int epic_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int epic_open(dev_t *, int, int, cred_t *);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int epic_close(dev_t, int, int, cred_t *);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int epic_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostruct cb_ops epic_cb_ops = {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro epic_open, /* open */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro epic_close, /* close */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nodev, /* strategy */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nodev, /* print */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nodev, /* dump */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nodev, /* read */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nodev, /* write */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro epic_ioctl, /* ioctl */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nodev, /* devmap */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nodev, /* mmap */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_segmap, /* segmap */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nochpoll, /* poll */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_prop_op, /* cb_prop_op */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro NULL, /* streamtab - for STREAMS drivers */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro D_NEW | D_MP /* driver compatibility flag */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro};
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic struct dev_ops epic_dev_ops = {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro DEVO_REV, /* driver build version */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro 0, /* device reference count */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro epic_getinfo,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nulldev,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nulldev, /* probe */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro epic_attach,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro epic_detach,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro nulldev, /* reset */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro &epic_cb_ops,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro (struct bus_ops *)NULL,
193974072f41a843678abf5f61979c748687e66bSherry Moore nulldev, /* power */
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_supported, /* devo_quiesce */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro};
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/*
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro * Soft state
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostruct epic_softc {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro dev_info_t *dip;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro kmutex_t mutex;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro uint8_t *cmd_reg;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_acc_handle_t cmd_handle;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro};
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro#define getsoftc(inst) ((struct epic_softc *)ddi_get_soft_state(statep, \
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro(inst)))
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/* module configuration stuff */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic void *statep;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroextern struct mod_ops mod_driverops;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic struct modldrv modldrv = {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro &mod_driverops,
193974072f41a843678abf5f61979c748687e66bSherry Moore "epic_client driver",
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro &epic_dev_ops
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro};
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic struct modlinkage modlinkage = {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro MODREV_1,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro &modldrv,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro 0
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro};
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroint
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro_init(void)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro{
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int e;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if ((e = ddi_soft_state_init(&statep,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro sizeof (struct epic_softc), 0)) != 0) {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (e);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro }
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if ((e = mod_install(&modlinkage)) != 0)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_soft_state_fini(&statep);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (e);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro}
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroint
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro_fini(void)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro{
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int e;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if ((e = mod_remove(&modlinkage)) != 0)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (e);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_soft_state_fini(&statep);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (DDI_SUCCESS);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro}
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroint
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro_info(struct modinfo *modinfop)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro{
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (mod_info(&modlinkage, modinfop));
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro}
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/*ARGSUSED*/
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroepic_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro{
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int inst;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int retval = DDI_SUCCESS;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro struct epic_softc *softc;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro inst = (getminor((dev_t)arg));
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro switch (cmd) {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case DDI_INFO_DEVT2DEVINFO:
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if ((softc = getsoftc(inst)) == NULL) {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro *result = (void *)NULL;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro retval = DDI_FAILURE;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro } else
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro *result = (void *)softc->dip;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case DDI_INFO_DEVT2INSTANCE:
bd9d7d01f0d32a91d43d2004867fc442f5c3ef98anovick *result = (void *)(uintptr_t)inst;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro default:
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro retval = DDI_FAILURE;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro }
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (retval);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro}
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroepic_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro{
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int inst;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro struct epic_softc *softc = NULL;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int minor;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro char name[MAXNAMELEN];
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_device_acc_attr_t dev_attr;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int res;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro switch (cmd) {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case DDI_ATTACH:
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro inst = ddi_get_instance(dip);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro (void) sprintf(name, "env-monitor%d", inst);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro minor = inst;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if (ddi_create_minor_node(dip, name, S_IFCHR, minor,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro DDI_PSEUDO, NULL) == DDI_FAILURE) {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro cmn_err(CE_WARN,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro "ddi_create_minor_node() failed for inst %d\n",
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro inst);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (DDI_FAILURE);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro }
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro /* Allocate a soft state structure for this instance */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if (ddi_soft_state_zalloc(statep, inst) != DDI_SUCCESS) {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro cmn_err(CE_WARN, " ddi_soft_state_zalloc() failed "
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro "for inst %d\n", inst);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro }
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro /* Setup soft state */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if ((softc = getsoftc(inst)) == NULL) {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro }
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro softc->dip = dip;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro mutex_init(&softc->mutex, NULL, MUTEX_DRIVER, NULL);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro /* Setup device attributes */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro res = ddi_regs_map_setup(dip, 0, (caddr_t *)&softc->cmd_reg,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_REGS_OFFSET, EPIC_REGS_LEN, &dev_attr,
193974072f41a843678abf5f61979c748687e66bSherry Moore &softc->cmd_handle);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if (res != DDI_SUCCESS) {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro cmn_err(CE_WARN, "ddi_regs_map_setup() failed\n");
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro }
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_report_dev(dip);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (DDI_SUCCESS);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case DDI_RESUME:
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (DDI_SUCCESS);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro default:
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (DDI_FAILURE);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro }
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro /* Attach failed */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro /* Free soft state, if allocated. remove minor node if added earlier */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if (softc)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_soft_state_free(statep, inst);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_remove_minor_node(dip, NULL);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (DDI_FAILURE);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro}
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroepic_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro{
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int inst;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro struct epic_softc *softc;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro switch (cmd) {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case DDI_DETACH:
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro inst = ddi_get_instance(dip);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if ((softc = getsoftc(inst)) == NULL)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (ENXIO);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro (void) ddi_regs_map_free(&softc->cmd_handle);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro /* Free the soft state and remove minor node added earlier */
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro mutex_destroy(&softc->mutex);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_soft_state_free(statep, inst);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro ddi_remove_minor_node(dip, NULL);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (DDI_SUCCESS);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case DDI_SUSPEND:
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (DDI_SUCCESS);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro default:
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (DDI_FAILURE);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro }
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro}
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/*ARGSUSED*/
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroepic_open(dev_t *devp, int flag, int otyp, cred_t *credp)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro{
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro _NOTE(ARGUNUSED(flag))
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro _NOTE(ARGUNUSED(otyp))
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro _NOTE(ARGUNUSED(credp))
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int inst = getminor(*devp);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (getsoftc(inst) == NULL ? ENXIO : 0);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro}
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/*ARGSUSED*/
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroepic_close(dev_t dev, int flag, int otyp, cred_t *credp)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro{
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro _NOTE(ARGUNUSED(flag))
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro _NOTE(ARGUNUSED(otyp))
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro _NOTE(ARGUNUSED(credp))
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int inst = getminor(dev);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (getsoftc(inst) == NULL ? ENXIO : 0);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro}
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro/*ARGSUSED*/
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbelorostatic int
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroepic_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloroint *rvalp)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro{
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro _NOTE(ARGUNUSED(credp))
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro int inst;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro struct epic_softc *softc;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro uint8_t in_command;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro inst = getminor(dev);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro if ((softc = getsoftc(inst)) == NULL)
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (ENXIO);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro mutex_enter(&softc->mutex);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro switch (cmd) {
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case EPIC_SET_POWER_LED:
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_WRITE(softc->cmd_handle, softc->cmd_reg,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_IND_LED_STATE0, EPIC_POWER_LED_MASK,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_POWER_LED_ON);
193974072f41a843678abf5f61979c748687e66bSherry Moore break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case EPIC_RESET_POWER_LED:
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_WRITE(softc->cmd_handle, softc->cmd_reg,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_IND_LED_STATE0, EPIC_POWER_LED_MASK,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_POWER_LED_OFF);
193974072f41a843678abf5f61979c748687e66bSherry Moore break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case EPIC_SB_BL_POWER_LED:
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_WRITE(softc->cmd_handle, softc->cmd_reg,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_IND_LED_STATE0, EPIC_POWER_LED_MASK,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_POWER_LED_SB_BLINK);
193974072f41a843678abf5f61979c748687e66bSherry Moore break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case EPIC_FAST_BL_POWER_LED:
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_WRITE(softc->cmd_handle, softc->cmd_reg,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_IND_LED_STATE0, EPIC_POWER_LED_MASK,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_POWER_LED_FAST_BLINK);
193974072f41a843678abf5f61979c748687e66bSherry Moore break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case EPIC_SET_ALERT_LED:
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_WRITE(softc->cmd_handle, softc->cmd_reg,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_IND_LED_STATE0, EPIC_ALERT_LED_MASK,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_ALERT_LED_ON);
193974072f41a843678abf5f61979c748687e66bSherry Moore break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case EPIC_RESET_ALERT_LED:
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_WRITE(softc->cmd_handle, softc->cmd_reg,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_IND_LED_STATE0, EPIC_ALERT_LED_MASK,
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_ALERT_LED_OFF);
193974072f41a843678abf5f61979c748687e66bSherry Moore break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro case EPIC_GET_FW:
193974072f41a843678abf5f61979c748687e66bSherry Moore EPIC_READ(softc->cmd_handle, softc->cmd_reg,
193974072f41a843678abf5f61979c748687e66bSherry Moore in_command, EPIC_IND_FW_VERSION);
193974072f41a843678abf5f61979c748687e66bSherry Moore if (ddi_copyout((void *)(&in_command), (void *)arg,
193974072f41a843678abf5f61979c748687e66bSherry Moore sizeof (in_command), mode) != DDI_SUCCESS) {
193974072f41a843678abf5f61979c748687e66bSherry Moore mutex_exit(&softc->mutex);
193974072f41a843678abf5f61979c748687e66bSherry Moore return (EFAULT);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore break;
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro default:
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro mutex_exit(&softc->mutex);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro cmn_err(CE_WARN, "epic: cmd %d is not valid", cmd);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (EINVAL);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro }
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro mutex_exit(&softc->mutex);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro return (0);
d58fda4376e4bf67072ce2e69f6f47036f9dbb68jbeloro}