/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* The tphci driver can be used to exercise the mpxio framework together
*/
/* cb_ops entry points */
/* bus_ops entry points */
void *);
dev_info_t **);
void *);
static void *tphci_state;
struct tphci_state {
};
tphci_open, /* open */
tphci_close, /* close */
nodev, /* strategy */
nodev, /* print */
nodev, /* dump */
nodev, /* read */
nodev, /* write */
tphci_ioctl, /* ioctl */
nodev, /* devmap */
nodev, /* mmap */
nodev, /* segmap */
nochpoll, /* chpoll */
ddi_prop_op, /* cb_prop_op */
0, /* streamtab */
CB_REV, /* rev */
nodev, /* aread */
nodev /* awrite */
};
BUSO_REV, /* busops_rev */
nullbusmap, /* bus_map */
NULL, /* bus_get_intrspec */
NULL, /* bus_add_interspec */
NULL, /* bus_remove_interspec */
i_ddi_map_fault, /* bus_map_fault */
ddi_no_dma_map, /* bus_dma_map */
ddi_no_dma_allochdl, /* bus_dma_allochdl */
NULL, /* bus_dma_freehdl */
NULL, /* bus_dma_bindhdl */
NULL, /* bus_dma_unbindhdl */
NULL, /* bus_dma_flush */
NULL, /* bus_dma_win */
NULL, /* bus_dma_ctl */
tphci_ctl, /* bus_ctl */
ddi_bus_prop_op, /* bus_prop_op */
NULL, /* bus_get_eventcookie */
NULL, /* bus_add_eventcall */
NULL, /* bus_remove_event */
NULL, /* bus_post_event */
NULL, /* bus_intr_ctl */
tphci_bus_config, /* bus_config */
tphci_bus_unconfig, /* bus_unconfig */
NULL, /* bus_fm_init */
NULL, /* bus_fm_fini */
NULL, /* bus_fm_access_enter */
NULL, /* bus_fm_access_exit */
NULL, /* bus_power */
tphci_intr_op /* bus_intr_op */
};
0,
nulldev, /* identify */
nulldev, /* probe */
tphci_attach, /* attach and detach are mandatory */
nodev, /* reset */
&tphci_cb_ops, /* cb_ops */
&tphci_bus_ops, /* bus_ops */
NULL, /* power */
ddi_quiesce_not_needed, /* quiesce */
};
extern struct mod_ops mod_driverops;
"test phci driver",
};
&modldrv,
};
int
_init(void)
{
int rval;
sizeof (struct tphci_state), 2)) != 0) {
return (rval);
}
}
return (rval);
}
int
_fini(void)
{
int rval;
/*
* don't start cleaning up until we know that the module remove
* has worked -- if this works, then we know that each instance
* has successfully been detached
*/
return (rval);
}
return (rval);
}
int
{
}
/* ARGSUSED */
static int
{
return (EINVAL);
}
return (ENXIO);
}
return (0);
}
/* ARGSUSED */
static int
{
return (EINVAL);
}
return (ENXIO);
}
return (0);
}
/* ARGSUSED */
static int
{
return (0);
}
/*
* attach the module
*/
static int
{
char *vclass;
switch (cmd) {
case DDI_ATTACH:
break;
case DDI_RESUME:
case DDI_PM_RESUME:
return (0); /* nothing to do */
default:
return (DDI_FAILURE);
}
/*
* Allocate phci data structure.
*/
return (DDI_FAILURE);
}
/* bus_addr has the form #,<vhci_class> */
goto attach_fail;
}
/*
* Attach this instance with the mpxio framework
*/
ddi_node_name(dip));
goto attach_fail;
}
phci_regis++;
ddi_node_name(dip));
goto attach_fail;
}
return (DDI_SUCCESS);
if (phci_regis)
(void) mdi_phci_unregister(dip, 0);
return (DDI_FAILURE);
}
/*ARGSUSED*/
static int
{
switch (cmd) {
case DDI_DETACH:
break;
case DDI_SUSPEND:
case DDI_PM_SUSPEND:
return (0); /* nothing to do */
default:
return (DDI_FAILURE);
}
return (DDI_FAILURE);
return (DDI_SUCCESS);
}
/*
* tphci_getinfo()
* Given the device number, return the devinfo pointer or the
* instance number.
* Note: always succeed DDI_INFO_DEVT2INSTANCE, even before attach.
*/
/*ARGSUSED*/
static int
{
switch (cmd) {
case DDI_INFO_DEVT2DEVINFO:
else {
return (DDI_FAILURE);
}
break;
case DDI_INFO_DEVT2INSTANCE:
break;
default:
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*
* Interrupt stuff. NO OP for pseudo drivers.
*/
/*ARGSUSED*/
static int
{
return (DDI_FAILURE);
}
static int
{
switch (ctlop) {
case DDI_CTLOPS_REPORTDEV:
if (rdip == (dev_info_t *)0)
return (DDI_FAILURE);
return (DDI_SUCCESS);
case DDI_CTLOPS_INITCHILD:
{
}
case DDI_CTLOPS_UNINITCHILD:
{
}
case DDI_CTLOPS_DMAPMAPC:
case DDI_CTLOPS_REPORTINT:
case DDI_CTLOPS_REGSIZE:
case DDI_CTLOPS_NREGS:
case DDI_CTLOPS_SIDDEV:
case DDI_CTLOPS_SLAVEONLY:
case DDI_CTLOPS_AFFINITY:
case DDI_CTLOPS_POKE:
case DDI_CTLOPS_PEEK:
/*
* These ops correspond to functions that "shouldn't" be called
* by a pseudo driver. So we whine when we're called.
*/
return (DDI_FAILURE);
case DDI_CTLOPS_ATTACH:
case DDI_CTLOPS_BTOP:
case DDI_CTLOPS_BTOPR:
case DDI_CTLOPS_DETACH:
case DDI_CTLOPS_DVMAPAGESIZE:
case DDI_CTLOPS_IOMIN:
case DDI_CTLOPS_POWER:
case DDI_CTLOPS_PTOB:
default:
/*
* The ops that we pass up (default). We pass up memory
* allocation oriented ops that we receive - these may be
* associated with pseudo HBA drivers below us with target
* drivers below them that use ddi memory allocation
* interfaces like scsi_alloc_consistent_buf.
*/
}
}
static int
{
return (DDI_SUCCESS);
}
/*ARGSUSED*/
static int
{
return (DDI_SUCCESS);
}
static int
{
char *tmp;
return (-1);
return (-1);
return (0);
}
static int
{
switch (op) {
case BUS_CONFIG_ONE:
break;
case BUS_CONFIG_DRIVER: /* no direct children to configure */
case BUS_CONFIG_ALL:
return (NDI_SUCCESS);
default:
return (NDI_FAILURE);
}
/* only implement BUS_CONFIG_ONE */
/* caddr is hardcoded in the form *,<guid> */
(char *)arg);
return (NDI_FAILURE);
}
if (rval != MDI_SUCCESS) {
return (NDI_FAILURE);
}
/*
* Hold the path and exit the pHCI while calling mdi_pi_online
* to avoid deadlock with power management of pHCI.
*/
if (rval != MDI_SUCCESS) {
(void) mdi_pi_free(pip, 0);
return (NDI_FAILURE);
}
if (childp) {
}
return (NDI_SUCCESS);
}
static int
{
int circ;
switch (op) {
case BUS_UNCONFIG_ONE:
return (NDI_SUCCESS); /* no such device */
if (pip) {
if (rval == MDI_SUCCESS)
(void) mdi_pi_free(pip, 0);
}
case BUS_UNCONFIG_ALL:
if (flags & NDI_AUTODETACH)
return (NDI_FAILURE);
if (rval != MDI_SUCCESS)
break;
(void) mdi_pi_free(pip, 0);
}
case BUS_UNCONFIG_DRIVER: /* nothing to do */
return (NDI_SUCCESS);
default:
return (NDI_FAILURE);
}
/*NOTREACHED*/
}