3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * CDDL HEADER START
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The contents of this file are subject to the terms of the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Common Development and Distribution License (the "License").
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * You may not use this file except in compliance with the License.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * or http://www.opensolaris.org/os/licensing.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * See the License for the specific language governing permissions
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and limitations under the License.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * When distributing Covered Code, include this CDDL HEADER in each
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If applicable, add the following below this CDDL HEADER, with the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * fields enclosed by brackets "[]" replaced with your own identifying
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * information: Portions Copyright [yyyy] [name of copyright owner]
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * CDDL HEADER END
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Use is subject to license terms.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Copyright (c) * Copyright (c) 2001 Tadpole Technology plc
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * All rights reserved.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * From "@(#)pcicfg.c 1.31 99/06/18 SMI"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Cardbus hotplug module
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/open.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/file.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/stat.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/ddi.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/sunndi.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/note.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pci.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/hotplug/hpcsvc.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/hotplug/pci/pcicfg.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pcic_reg.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include "cardbus.h"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include "cardbus_hp.h"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include "cardbus_cfg.h"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * ************************************************************************
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * *** Implementation specific data structures/definitions. ***
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * ************************************************************************
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifndef HPC_MAX_OCCUPANTS
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define HPC_MAX_OCCUPANTS 8
3db86aab554edbb4244c8d1a1c90f152eee768afsteveltypedef struct hpc_occupant_info {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *id[HPC_MAX_OCCUPANTS];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel} hpc_occupant_info_t;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define PCICFG_FLAGS_CONTINUE 0x1
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define PCICFG_OP_ONLINE 0x1
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define PCICFG_OP_OFFLINE 0x0
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define CBHP_DEVCTL_MINOR 255
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define AP_MINOR_NUM_TO_CB_INSTANCE(x) ((x) & 0xFF)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define AP_MINOR_NUM(x) (((uint_t)(3) << 8) | ((x) & 0xFF))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define AP_IS_CB_MINOR(x) (((x)>>8) == (3))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern int cardbus_debug;
0d282d1376eb7ba06504448622a6d65726e4bd3erwextern int number_of_cardbus_cards;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_autocfg_enabled = 1; /* auto config is enabled by default */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* static functions */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_event_handler(caddr_t slot_arg, uint_t event_mask);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_pci_control(caddr_t ops_arg, hpc_slot_t slot_hdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int request, caddr_t arg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_new_slot_state(dev_info_t *dip, hpc_slot_t hdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_slot_info_t *slot_info, int slot_state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_list_occupants(dev_info_t *dip, void *hdl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void create_occupant_props(dev_info_t *self, dev_t dev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void delete_occupant_props(dev_info_t *dip, dev_t dev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_configure_ap(cbus_t *cbp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_unconfigure_ap(cbus_t *cbp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cbus_unconfigure(dev_info_t *devi, int prim_bus);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid cardbus_dump_pci_config(dev_info_t *dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid cardbus_dump_pci_node(dev_info_t *dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_init_hotplug(cbus_t *cbp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char tbuf[MAXNAMELEN];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_slot_info_t slot_info;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_slot_ops_t *slot_ops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_slot_t slhandle; /* HPS slot handle */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * register the bus instance with the HPS framework.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hpc_nexus_register_bus(cbp->cb_dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_new_slot_state, 0) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: failed to register the bus with HPS\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(cbp->ap_id, "slot%d", cbp->cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_pathname(cbp->cb_dip, tbuf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->nexus_path = kmem_alloc(strlen(tbuf) + 1, KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) strcpy(cbp->nexus_path, tbuf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_init_hotplug: nexus_path set to %s", cbp->nexus_path);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_ops = hpc_alloc_slot_ops(KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->slot_ops = slot_ops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Fill in the slot information structure that
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * describes the slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_info.version = HPC_SLOT_INFO_VERSION;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_info.slot_type = HPC_SLOT_TYPE_PCI;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_info.slot.pci.device_number = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_info.slot.pci.slot_capabilities = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) strcpy(slot_info.slot.pci.slot_logical_name, cbp->ap_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_ops->hpc_version = HPC_SLOT_OPS_VERSION;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_ops->hpc_op_connect = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_ops->hpc_op_disconnect = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_ops->hpc_op_insert = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_ops->hpc_op_remove = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_ops->hpc_op_control = cardbus_pci_control;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hpc_slot_register(cbp->cb_dip, cbp->nexus_path, &slot_info,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &slhandle, slot_ops, (caddr_t)cbp, 0) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If the slot can not be registered,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * then the slot_ops need to be freed.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cbp%d Unable to Register Slot %s", cbp->cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_info.slot.pci.slot_logical_name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_nexus_unregister_bus(cbp->cb_dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_free_slot_ops(slot_ops);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->slot_ops = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(slhandle == cbp->slot_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_init_hotplug: slot_handle 0x%p", cbp->slot_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_event_handler(caddr_t slot_arg, uint_t event_mask)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ap_minor = (int)((uintptr_t)slot_arg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cb_instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rv = HPC_EVENT_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cb_instance = AP_MINOR_NUM_TO_CB_INSTANCE(ap_minor);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(cb_instance >= 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (event_mask) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_EVENT_SLOT_INSERTION:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * A card is inserted in the slot. Just report this
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * event and return.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_event_handler(%s%d): card is inserted",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_EVENT_SLOT_CONFIGURE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Configure the occupant that is just inserted in the slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The receptacle may or may not be in the connected state. If
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the receptacle is not connected and the auto configuration
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is enabled on this slot then connect the slot. If auto
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * configuration is enabled then configure the card.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(cbp->auto_config)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * auto configuration is disabled.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_event_handler(%s%d): "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "SLOT_CONFIGURE event occured (slot %s)",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_event_handler(%s%d): configure event",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->ostate != AP_OSTATE_UNCONFIGURED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "!slot%d already configured\n",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam cbp->cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Auto configuration is enabled. First, make sure the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * receptacle is in the CONNECTED state.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((rv = hpc_nexus_connect(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, 0)) == HPC_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->rstate = AP_RSTATE_CONNECTED; /* record rstate */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_configure_ap(cbp) == HPC_SUCCESS)
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam create_occupant_props(cbp->cb_dip, makedevice(
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ddi_driver_major((cbp->cb_dip)), ap_minor));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = HPC_ERR_FAILED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_EVENT_SLOT_UNCONFIGURE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Unconfigure the occupant in this slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(cbp->auto_config)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * auto configuration is disabled.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_event_handler(%s%d): "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "SLOT_UNCONFIGURE event"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " occured - auto-conf disabled (slot %s)",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_event_handler(%s%d): SLOT_UNCONFIGURE event"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " occured (slot %s)",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_unconfigure_ap(cbp) != HPC_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = HPC_ERR_FAILED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
0d282d1376eb7ba06504448622a6d65726e4bd3erw DEVI(cbp->cb_dip)->devi_ops->devo_bus_ops = cbp->orig_bopsp;
0d282d1376eb7ba06504448622a6d65726e4bd3erw --number_of_cardbus_cards;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_EVENT_SLOT_REMOVAL:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Card is removed from the slot. The card must have been
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * unconfigured before this event.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->ostate != AP_OSTATE_UNCONFIGURED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_event_handler(%s%d): "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "card is removed from"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " the slot %s before doing unconfigure!!",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_event_handler(%s%d): "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "card is removed from the slot %s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_EVENT_SLOT_POWER_ON:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Slot is connected to the bus. i.e the card is powered
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * on.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_event_handler(%s%d): "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "card is powered on in the slot %s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->rstate = AP_RSTATE_CONNECTED; /* record rstate */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_EVENT_SLOT_POWER_OFF:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Slot is disconnected from the bus. i.e the card is powered
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * off.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_event_handler(%s%d): "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "card is powered off in the slot %s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->rstate = AP_RSTATE_DISCONNECTED; /* record rstate */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 4,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_event_handler(%s%d): "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "unknown event %x for this slot %s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip), cbp->cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel event_mask, cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_pci_control(caddr_t ops_arg, hpc_slot_t slot_hdl, int request,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel caddr_t arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rval = HPC_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_led_info_t *hpc_led_info;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _NOTE(ARGUNUSED(slot_hdl))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ops_arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(mutex_owned(&cbp->cb_mutex));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (request) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam case HPC_CTRL_GET_SLOT_STATE: {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_slot_state_t *hpc_slot_state;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_slot_state = (hpc_slot_state_t *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_pci_control() - "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "HPC_CTRL_GET_SLOT_STATE hpc_slot_state=0x%p",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) hpc_slot_state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->card_present)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *hpc_slot_state = HPC_SLOT_CONNECTED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *hpc_slot_state = HPC_SLOT_EMPTY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam case HPC_CTRL_GET_BOARD_TYPE: {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_board_type_t *hpc_board_type;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_board_type = (hpc_board_type_t *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_pci_control() - HPC_CTRL_GET_BOARD_TYPE");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The HPC driver does not know what board type
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is plugged in.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *hpc_board_type = HPC_BOARD_PCI_HOTPLUG;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_DEV_CONFIGURED:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_DEV_UNCONFIGURED:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 5,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_pci_control() - HPC_CTRL_DEV_%sCONFIGURED",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel request == HPC_CTRL_DEV_UNCONFIGURED ? "UN" : "");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_GET_LED_STATE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_led_info = (hpc_led_info_t *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 5,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_pci_control() - HPC_CTRL_GET_LED_STATE "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "led %d is %d",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_led_info->led, cbp->leds[hpc_led_info->led]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_led_info->state = cbp->leds[hpc_led_info->led];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_SET_LED_STATE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_led_info = (hpc_led_info_t *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 4,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_pci_control() - HPC_CTRL_SET_LED_STATE "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "led %d to %d",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_led_info->led, hpc_led_info->state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->leds[hpc_led_info->led] = hpc_led_info->state;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_ENABLE_AUTOCFG:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 5,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_pci_control() - HPC_CTRL_ENABLE_AUTOCFG");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Cardbus ALWAYS does auto config, from the slots point of
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * view this is turning on the card and making sure it's ok.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This is all done by the bridge driver before we see any
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * indication.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_DISABLE_AUTOCFG:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 5,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_pci_control() - HPC_CTRL_DISABLE_AUTOCFG");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_DISABLE_ENUM:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_ENABLE_ENUM:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = HPC_ERR_NOTSUPPORTED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rval);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * cardbus_new_slot_state()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This function is called by the HPS when it finds a hot plug
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * slot is added or being removed from the hot plug framework.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * It returns 0 for success and HPC_ERR_FAILED for errors.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_new_slot_state(dev_info_t *dip, hpc_slot_t hdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_slot_info_t *slot_info, int slot_state)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cb_instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ap_minor;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rv = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_new_slot_state: slot_handle 0x%p", hdl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * get the soft state structure for the bus instance.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cb_instance = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_DONTPASS, "cbus-instance", -1);
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ASSERT(cb_instance >= 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (slot_state) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_SLOT_ONLINE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Make sure the slot is not already ONLINE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->slot_handle != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 4,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_new_slot_state: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus already ONLINE!!");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = HPC_ERR_FAILED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Add the hot plug slot to the bus.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* create the AP minor node */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ap_minor = AP_MINOR_NUM(cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_create_minor_node(dip, slot_info->pci_slot_name,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel S_IFCHR, ap_minor,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_NT_PCI_ATTACHMENT_POINT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0) == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 4,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_new_slot_state: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "ddi_create_minor_node failed");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = HPC_ERR_FAILED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* save the slot handle */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->slot_handle = hdl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* setup event handler for all hardware events on the slot */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hpc_install_event_handler(hdl, -1, cardbus_event_handler,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)((long)ap_minor)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 4,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_new_slot_state: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "install event handler failed");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = HPC_ERR_FAILED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->event_mask = (uint32_t)0xFFFFFFFF;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel create_occupant_props(dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel makedevice(ddi_name_to_major(ddi_get_name(dip)),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ap_minor));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* set default auto configuration enabled flag for this slot */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->auto_config = cardbus_autocfg_enabled;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* copy the slot information */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->name = (char *)kmem_alloc(strlen(slot_info->pci_slot_name)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel + 1, KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) strcpy(cbp->name, slot_info->pci_slot_name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 10,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_new_slot_state: cbp->name set to %s", cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 4,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Cardbus slot \"%s\" ONLINE\n", slot_info->pci_slot_name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->ostate = AP_OSTATE_UNCONFIGURED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->rstate = AP_RSTATE_EMPTY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_SLOT_OFFLINE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * A hot plug slot is being removed from the bus.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Make sure there is no occupant configured on the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * slot before removing the AP minor node.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->ostate != AP_OSTATE_UNCONFIGURED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus: Card is still in configured state");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = HPC_ERR_FAILED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If the AP device is in open state then return
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * error.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->soft_state != PCIHP_SOFT_STATE_CLOSED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = HPC_ERR_FAILED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* remove the minor node */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_remove_minor_node(dip, cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* free up the memory for the name string */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(cbp->name, strlen(cbp->name) + 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* update the slot info data */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->name = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->slot_handle = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_new_slot_state: Cardbus slot OFFLINE");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_new_slot_state: unknown slot_state %d\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = HPC_ERR_FAILED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_list_occupants(dev_info_t *dip, void *hdl)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_occupant_info_t *occupant = (hpc_occupant_info_t *)hdl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char pn[MAXPATHLEN];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Ignore the attachment point and pcs.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp(ddi_binding_name(dip), "pcs") == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_CONTINUE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_pathname(dip, pn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel occupant->id[occupant->i] = kmem_alloc(strlen(pn) + 1, KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) strcpy(occupant->id[occupant->i], pn);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel occupant->i++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * continue the walk to the next sibling to look for a match
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * or to find other nodes if this card is a multi-function card.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_PRUNECHILD);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcreate_occupant_props(dev_info_t *self, dev_t dev)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_occupant_info_t occupant;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int circular;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel occupant.i = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_devi_enter(self, &circular);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_walk_devs(ddi_get_child(self), cardbus_list_occupants,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *)&occupant);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_devi_exit(self, circular);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (occupant.i == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *c[] = { "" };
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(self, 1, "create_occupant_props: no occupant\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_prop_update_string_array(dev, self, "pci-occupant",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel c, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(self, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "create_occupant_props: %d occupant\n", occupant.i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_prop_update_string_array(dev, self, "pci-occupant",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel occupant.id, occupant.i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < occupant.i; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(occupant.id[i], strlen(occupant.id[i]) + 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afsteveldelete_occupant_props(dev_info_t *dip, dev_t dev)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_remove(dev, dip, "pci-occupant")
3db86aab554edbb4244c8d1a1c90f152eee768afstevel != DDI_PROP_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return; /* add error handling */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * **************************************
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * CONFIGURE the occupant in the slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * **************************************
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_configure_ap(cbus_t *cbp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *self = cbp->cb_dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rv = HPC_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_slot_state_t rstate;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct cardbus_config_ctrl ctrl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int circular_count;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * check for valid request:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 1. It is a hotplug slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 2. The receptacle is in the CONNECTED state.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->slot_handle == NULL || cbp->disabled) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If the occupant is already in (partially) configured
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * state then call the ndi_devi_online() on the device
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * subtree(s) for this attachment point.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->ostate == AP_OSTATE_CONFIGURED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.flags = PCICFG_FLAGS_CONTINUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.busno = cardbus_primary_busno(self);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.rv = NDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.dip = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.op = PCICFG_OP_ONLINE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_devi_enter(self, &circular_count);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_walk_devs(ddi_get_child(self),
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam cbus_configure, (void *)&ctrl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_devi_exit(self, circular_count);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dump_pci_config(self);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dump_pci_node(self);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ctrl.rv != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * one or more of the devices are not
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * onlined.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "cardbus(%s%d): failed to attach "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "one or more drivers for the card in the slot %s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(self), cbp->cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* tell HPC driver that the occupant is configured */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_DEV_CONFIGURED, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Occupant is in the UNCONFIGURED state.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Check if the receptacle is in the CONNECTED state. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_GET_SLOT_STATE, (caddr_t)&rstate) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rstate != HPC_SLOT_CONNECTED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* error. either the slot is empty or connect failed */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->rstate = AP_RSTATE_CONNECTED; /* record rstate */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Call the configurator to configure the card.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_configure(cbp) != PCICFG_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* record the occupant state as CONFIGURED */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->ostate = AP_OSTATE_CONFIGURED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->condition = AP_COND_OK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* now, online all the devices in the AP */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.flags = PCICFG_FLAGS_CONTINUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.busno = cardbus_primary_busno(self);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.rv = NDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.dip = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.op = PCICFG_OP_ONLINE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_devi_enter(self, &circular_count);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_walk_devs(ddi_get_child(self), cbus_configure, (void *)&ctrl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_devi_exit(self, circular_count);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dump_pci_config(self);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dump_pci_node(self);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ctrl.rv != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * one or more of the devices are not
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * ONLINE'd.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "cbhp (%s%d): failed to attach one or"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " more drivers for the card in the slot %s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(cbp->cb_dip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->cb_instance, cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* rv = EFAULT; */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* tell HPC driver that the occupant is configured */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_nexus_control(cbp->slot_handle,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam HPC_CTRL_DEV_CONFIGURED, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * **************************************
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * UNCONFIGURE the occupant in the slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * **************************************
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_unconfigure_ap(cbus_t *cbp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *self = cbp->cb_dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rv = HPC_SUCCESS, nrv;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * check for valid request:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 1. It is a hotplug slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 2. The occupant is in the CONFIGURED state.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->slot_handle == NULL || cbp->disabled) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If the occupant is in the CONFIGURED state then
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * call the configurator to unconfigure the slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->ostate == AP_OSTATE_CONFIGURED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Detach all the drivers for the devices in the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nrv = cardbus_unconfigure_node(self,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_primary_busno(self),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel B_TRUE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (nrv != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Failed to detach one or more drivers.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Restore the status for the drivers
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * which are offlined during this step.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cbhp (%s%d): Failed to offline all devices"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " (slot %s)", ddi_driver_name(cbp->cb_dip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->cb_instance, cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = EBUSY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_unconfigure(cbp) == PCICFG_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Now that resources are freed,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * clear EXT and Turn LED ON.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->ostate = AP_OSTATE_UNCONFIGURED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->condition = AP_COND_UNKNOWN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * send the notification of state change
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to the HPC driver.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_DEV_UNCONFIGURED, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = EIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcbus_configure(dev_info_t *dip, void *hdl)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_regspec_t *pci_rp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int length, rc;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct cardbus_config_ctrl *ctrl = (struct cardbus_config_ctrl *)hdl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t bus, device, function;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Ignore the attachment point and pcs.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp(ddi_binding_name(dip), "hp_attachment") == 0 ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel strcmp(ddi_binding_name(dip), "pcs") == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8, "cbus_configure: Ignoring\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_CONTINUE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6, "cbus_configure\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(ctrl->op == PCICFG_OP_ONLINE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get the PCI device number information from the devinfo
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * node. Since the node may not have the address field
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * setup (this is done in the DDI_INITCHILD of the parent)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we look up the 'reg' property to decode that information.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_DONTPASS, "reg", (int **)&pci_rp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint_t *)&length) != DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Porbably not a real device, like PCS for example */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_get_child(dip) == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_PRUNECHILD);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cubs_configure: Don't configure device\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl->rv = DDI_FAILURE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl->dip = dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_TERMINATE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pci_rp->pci_phys_hi == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_CONTINUE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* get the pci device id information */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel device = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel function = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * free the memory allocated by ddi_prop_lookup_int_array
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_free(pci_rp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (bus <= ctrl->busno)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_CONTINUE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cbus_configure on-line device at: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "[0x%x][0x%x][0x%x]\n", bus, device, function);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rc = ndi_devi_online(dip, NDI_ONLINE_ATTACH|NDI_CONFIG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cbus_configure %s\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rc == NDI_SUCCESS ? "Success": "Failure");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rc != NDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_PRUNECHILD);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_CONTINUE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_unconfigure_node(dev_info_t *dip, int prim_bus, boolean_t top_bridge)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *child, *next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6, "cardbus_unconfigure_node\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Ignore pcs.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp(ddi_binding_name(dip), "pcs") == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8, "cardbus_unconfigure_node: Ignoring\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * bottom up off-line
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (child = ddi_get_child(dip); child; child = next) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rc;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel next = ddi_get_next_sibling(child);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rc = cardbus_unconfigure_node(child, prim_bus, B_FALSE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rc != NDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rc);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Don't unconfigure the bridge itself.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (top_bridge)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbus_unconfigure(dip, prim_bus) != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_unconfigure_node: cardbus_unconfigure failed\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This will turn resources allocated by cbus_configure()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and remove the device tree from the attachment point
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and below. The routine assumes the devices have their
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * drivers detached.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcbus_unconfigure(dev_info_t *devi, int prim_bus)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_regspec_t *pci_rp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t bus, device, func, length;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ndi_flags = NDI_UNCONFIG;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, devi,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_DONTPASS, "reg", (int **)&pci_rp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &length) != DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This cannot be one of our devices. If it's something like a
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SCSI device then the attempt to offline the HBA
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * (which probably is one of our devices)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * will also do bottom up offlining. That
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * will fail if this device is busy. So always
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * return success here
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * so that the walk will continue.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pci_rp->pci_phys_hi == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (bus <= prim_bus)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel device = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_free(pci_rp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(devi, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cbus_unconfigure: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "offline bus [0x%x] device [0x%x] function [%x]\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus, device, func);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_devi_offline(devi, ndi_flags) != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(devi, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Device [0x%x] function [%x] is busy\n", device, func);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(devi, 9,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Tearing down device [0x%x] function [0x%x]\n", device, func);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_teardown_device(devi) != PCICFG_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(devi, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Failed to tear down "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "device [0x%x] function [0x%x]\n", device, func);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelboolean_t
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_is_cb_minor(dev_t dev)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (AP_IS_CB_MINOR(getminor(dev)) ? B_TRUE : B_FALSE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_open(dev_t *devp, int flags, int otyp, cred_t *credp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int minor;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _NOTE(ARGUNUSED(credp))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel minor = getminor(*devp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Make sure the open is for the right file type.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (otyp != OTYP_CHR)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EINVAL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get the soft state structure for the 'devctl' device.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam AP_MINOR_NUM_TO_CB_INSTANCE(minor));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Handle the open by tracking the device state.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Note: Needs review w.r.t exclusive access to AP or the bus.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Currently in the pci plug-in we don't use EXCL open at all
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * so the code below implements EXCL access on the bus.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* enforce exclusive access to the bus */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((cbp->soft_state == PCIHP_SOFT_STATE_OPEN_EXCL) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ((flags & FEXCL) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (cbp->soft_state != PCIHP_SOFT_STATE_CLOSED))) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EBUSY);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (flags & FEXCL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->soft_state = PCIHP_SOFT_STATE_OPEN_EXCL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->soft_state = PCIHP_SOFT_STATE_OPEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_close(dev_t dev, int flags, int otyp, cred_t *credp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int minor;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _NOTE(ARGUNUSED(credp))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel minor = getminor(dev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (otyp != OTYP_CHR)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EINVAL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel AP_MINOR_NUM_TO_CB_INSTANCE(minor));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->soft_state = PCIHP_SOFT_STATE_CLOSED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * cardbus_ioctl: devctl hotplug controls
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int *rvalp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *self;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *child_dip = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct devctl_iocdata *dcp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t bus_state;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rv = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int nrv = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ap_minor;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_slot_state_t rstate;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel devctl_ap_state_t ap_state;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct hpc_control_data hpc_ctrldata;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct hpc_led_info led_info;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _NOTE(ARGUNUSED(credp))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ap_minor = getminor(dev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel AP_MINOR_NUM_TO_CB_INSTANCE(ap_minor));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ENXIO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel self = cbp->cb_dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * read devctl ioctl data
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((cmd != DEVCTL_AP_CONTROL) && ndi_dc_allochdl((void *)arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &dcp) != NDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EFAULT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *cmd_name;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_DEVICE_GETSTATE: cmd_name = "DEVCTL_DEVICE_GETSTATE"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_DEVICE_ONLINE: cmd_name = "DEVCTL_DEVICE_ONLINE"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_DEVICE_OFFLINE: cmd_name = "DEVCTL_DEVICE_OFFLINE"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_DEVICE_RESET: cmd_name = "DEVCTL_DEVICE_RESET"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_BUS_QUIESCE: cmd_name = "DEVCTL_BUS_QUIESCE"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_BUS_UNQUIESCE: cmd_name = "DEVCTL_BUS_UNQUIESCE"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_BUS_RESET: cmd_name = "DEVCTL_BUS_RESET"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_BUS_RESETALL: cmd_name = "DEVCTL_BUS_RESETALL"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_BUS_GETSTATE: cmd_name = "DEVCTL_BUS_GETSTATE"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_CONNECT: cmd_name = "DEVCTL_AP_CONNECT"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_DISCONNECT: cmd_name = "DEVCTL_AP_DISCONNECT"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_INSERT: cmd_name = "DEVCTL_AP_INSERT"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_REMOVE: cmd_name = "DEVCTL_AP_REMOVE"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_CONFIGURE: cmd_name = "DEVCTL_AP_CONFIGURE"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_UNCONFIGURE: cmd_name = "DEVCTL_AP_UNCONFIGURE"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_GETSTATE: cmd_name = "DEVCTL_AP_GETSTATE"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_CONTROL: cmd_name = "DEVCTL_AP_CONTROL"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default: cmd_name = "Unknown"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_ioctl: cmd = 0x%x, \"%s\"", cmd, cmd_name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_DEVICE_GETSTATE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_DEVICE_ONLINE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_DEVICE_OFFLINE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_BUS_GETSTATE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ndi_devctl_ioctl(self, cmd, arg, mode, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_dc_freehdl(dcp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_DEVICE_RESET:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENOTSUP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_BUS_QUIESCE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (bus_state == BUS_QUIESCED)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_set_bus_state(self, BUS_QUIESCED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_BUS_UNQUIESCE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (bus_state == BUS_ACTIVE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_set_bus_state(self, BUS_ACTIVE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_BUS_RESET:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENOTSUP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_BUS_RESETALL:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENOTSUP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_CONNECT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_DISCONNECT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * CONNECT(DISCONNECT) the hot plug slot to(from) the bus.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_INSERT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_REMOVE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Prepare the slot for INSERT/REMOVE operation.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * check for valid request:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 1. It is a hotplug slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 2. The slot has no occupant that is in
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the 'configured' state.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The lower 8 bits of the minor number is the PCI
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * device number for the slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((cbp->slot_handle == NULL) || cbp->disabled) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* the slot occupant must be in the UNCONFIGURED state */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->ostate != AP_OSTATE_UNCONFIGURED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Call the HPC driver to perform the operation on the slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_INSERT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = hpc_nexus_insert(cbp->slot_handle, NULL, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_REMOVE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = hpc_nexus_remove(cbp->slot_handle, NULL, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_CONNECT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((rv = hpc_nexus_connect(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, 0)) == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->rstate = AP_RSTATE_CONNECTED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_DISCONNECT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((rv = hpc_nexus_disconnect(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, 0)) == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->rstate = AP_RSTATE_DISCONNECTED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (rv) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_ERR_INVALID:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_ERR_NOTSUPPORTED:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENOTSUP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_ERR_FAILED:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = EIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_CONFIGURE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * **************************************
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * CONFIGURE the occupant in the slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * **************************************
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((nrv = cardbus_configure_ap(cbp)) == HPC_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel create_occupant_props(cbp->cb_dip, dev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = nrv;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_UNCONFIGURE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * **************************************
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * UNCONFIGURE the occupant in the slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * **************************************
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((nrv = cardbus_unconfigure_ap(cbp)) == HPC_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delete_occupant_props(cbp->cb_dip, dev);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = nrv;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_GETSTATE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int mutex_held;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * return the state of Attachment Point.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If the occupant is in UNCONFIGURED state then
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we should get the receptacle state from the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * HPC driver because the receptacle state
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * maintained in the nexus may not be accurate.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * check for valid request:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 1. It is a hotplug slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->slot_handle == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* try to acquire the slot mutex */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_held = mutex_tryenter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->ostate == AP_OSTATE_UNCONFIGURED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_GET_SLOT_STATE,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&rstate) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (mutex_held)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->rstate = (ap_rstate_t)rstate;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ap_state.ap_rstate = cbp->rstate;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ap_state.ap_ostate = cbp->ostate;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ap_state.ap_condition = cbp->condition;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ap_state.ap_last_change = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ap_state.ap_error_code = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (mutex_held)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ap_state.ap_in_transition = 0; /* AP is not busy */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ap_state.ap_in_transition = 1; /* AP is busy */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (mutex_held)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* copy the return-AP-state information to the user space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_dc_return_ap_state(&ap_state, dcp) != NDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DEVCTL_AP_CONTROL:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * HPC control functions:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * HPC_CTRL_ENABLE_SLOT/HPC_CTRL_DISABLE_SLOT
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Changes the state of the slot and preserves
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the state across the reboot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * HPC_CTRL_ENABLE_AUTOCFG/HPC_CTRL_DISABLE_AUTOCFG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Enables or disables the auto configuration
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * of hot plugged occupant if the hardware
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * supports notification of the hot plug
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * events.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * HPC_CTRL_GET_LED_STATE/HPC_CTRL_SET_LED_STATE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Controls the state of an LED.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * HPC_CTRL_GET_SLOT_INFO
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get slot information data structure
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * (hpc_slot_info_t).
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * HPC_CTRL_GET_BOARD_TYPE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get board type information (hpc_board_type_t).
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * HPC_CTRL_GET_CARD_INFO
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get card information (hpc_card_info_t).
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * These control functions are used by the cfgadm plug-in
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to implement "-x" and "-v" options.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* copy user ioctl data first */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef _MULTI_DATAMODEL
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct hpc_control32_data hpc_ctrldata32;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (copyin((void *)arg, (void *)&hpc_ctrldata32,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct hpc_control32_data)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_ctrldata.cmd = hpc_ctrldata32.cmd;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_ctrldata.data =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *)(intptr_t)hpc_ctrldata32.data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (copyin((void *)arg, (void *)&hpc_ctrldata,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct hpc_control_data)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = EFAULT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *hpc_name;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (hpc_ctrldata.cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_GET_LED_STATE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_name = "HPC_CTRL_GET_LED_STATE";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_SET_LED_STATE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_name = "HPC_CTRL_SET_LED_STATE";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_ENABLE_SLOT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_name = "HPC_CTRL_ENABLE_SLOT";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_DISABLE_SLOT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_name = "HPC_CTRL_DISABLE_SLOT";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_ENABLE_AUTOCFG:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_name = "HPC_CTRL_ENABLE_AUTOCFG";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_DISABLE_AUTOCFG:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_name = "HPC_CTRL_DISABLE_AUTOCFG";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_GET_BOARD_TYPE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_name = "HPC_CTRL_GET_BOARD_TYPE";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_GET_SLOT_INFO:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_name = "HPC_CTRL_GET_SLOT_INFO";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_GET_CARD_INFO:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_name = "HPC_CTRL_GET_CARD_INFO";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default: hpc_name = "Unknown"; break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_ioctl: HP Control cmd 0x%x - \"%s\"",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_ctrldata.cmd, hpc_name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * check for valid request:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 1. It is a hotplug slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->slot_handle == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (hpc_ctrldata.cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_GET_LED_STATE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* copy the led info from the user space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (copyin(hpc_ctrldata.data, (void *)&led_info,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (hpc_led_info_t)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* get the state of LED information */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_GET_LED_STATE,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&led_info) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* copy the led info to the user space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (copyout((void *)&led_info, hpc_ctrldata.data,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (hpc_led_info_t)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_SET_LED_STATE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* copy the led info from the user space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (copyin(hpc_ctrldata.data, (void *)&led_info,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (hpc_led_info_t)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* set the state of an LED */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_SET_LED_STATE,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&led_info) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_ENABLE_SLOT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Enable the slot for hotplug operations.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->disabled = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* tell the HPC driver also */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_ENABLE_SLOT, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_DISABLE_SLOT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Disable the slot for hotplug operations.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->disabled = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* tell the HPC driver also */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_DISABLE_SLOT, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_ENABLE_AUTOCFG:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Enable auto configuration on this slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->auto_config = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* tell the HPC driver also */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_ENABLE_AUTOCFG, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_DISABLE_AUTOCFG:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Disable auto configuration on this slot.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->auto_config = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* tell the HPC driver also */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_DISABLE_AUTOCFG, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_GET_BOARD_TYPE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_board_type_t board_type;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get board type data structure, hpc_board_type_t.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hpc_nexus_control(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_CTRL_GET_BOARD_TYPE,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&board_type) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* copy the board type info to the user space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (copyout((void *)&board_type, hpc_ctrldata.data,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (hpc_board_type_t)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_GET_SLOT_INFO:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_slot_info_t slot_info;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get slot information structure, hpc_slot_info_t.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_info.version = HPC_SLOT_INFO_VERSION;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_info.slot_type = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_info.pci_slot_capabilities = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel slot_info.pci_dev_num =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint16_t)AP_MINOR_NUM_TO_CB_INSTANCE(ap_minor);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) strcpy(slot_info.pci_slot_name, cbp->name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* copy the slot info structure to the user space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (copyout((void *)&slot_info, hpc_ctrldata.data,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (hpc_slot_info_t)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case HPC_CTRL_GET_CARD_INFO:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hpc_card_info_t card_info;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_acc_handle_t handle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get card information structure, hpc_card_info_t.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
0d282d1376eb7ba06504448622a6d65726e4bd3erw if (cbp->card_present == B_FALSE) {
0d282d1376eb7ba06504448622a6d65726e4bd3erw rv = ENXIO;
0d282d1376eb7ba06504448622a6d65726e4bd3erw break;
0d282d1376eb7ba06504448622a6d65726e4bd3erw }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* verify that the card is configured */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->ostate != AP_OSTATE_CONFIGURED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* either the card is not present or */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* it is not configured. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* get the information from the PCI config header */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* for the function 0. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (child_dip = ddi_get_child(cbp->cb_dip); child_dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel child_dip = ddi_get_next_sibling(child_dip))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp("pcs", ddi_get_name(child_dip)))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!child_dip) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pci_config_setup(child_dip, &handle)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = EIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel card_info.prog_class = pci_config_get8(handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_CONF_PROGCLASS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel card_info.base_class = pci_config_get8(handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_CONF_BASCLASS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel card_info.sub_class = pci_config_get8(handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_CONF_SUBCLASS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel card_info.header_type = pci_config_get8(handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_CONF_HEADER);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_teardown(&handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* copy the card info structure to the user space */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (copyout((void *)&card_info, hpc_ctrldata.data,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (hpc_card_info_t)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENXIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = EINVAL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rv = ENOTTY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cmd != DEVCTL_AP_CONTROL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_dc_freehdl(dcp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(cbp->cb_dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_ioctl: rv = 0x%x", rv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstruct cardbus_pci_desc {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *name;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ushort_t offset;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int (*cfg_get_func)();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *fmt;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct cardbus_pci_desc generic_pci_cfg[] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "VendorId =", 0, (int(*)())pci_config_get16, "%s 0x%04x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "DeviceId =", 2, (int(*)())pci_config_get16, "%s 0x%04x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Command =", 4, (int(*)())pci_config_get16, "%s 0x%04x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Status =", 6, (int(*)())pci_config_get16, "%s 0x%04x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Latency =", 0xd, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "BASE0 =", 0x10, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "BASE1 =", 0x14, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "BASE2 =", 0x18, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "BASE3 =", 0x1c, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "BASE4 =", 0x20, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "CIS Pointer =", 0x28, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "ILINE =", 0x3c, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "IPIN =", 0x3d, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { NULL, 0, NULL, NULL }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct cardbus_pci_desc cardbus_pci_cfg[] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "VendorId =", 0, (int(*)())pci_config_get16, "%s 0x%04x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "DeviceId =", 2, (int(*)())pci_config_get16, "%s 0x%04x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Command =", 4, (int(*)())pci_config_get16, "%s 0x%04x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Status =", 6, (int(*)())pci_config_get16, "%s 0x%04x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "CacheLineSz =", 0xc, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Latency =", 0xd, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "MemBase Addr=", 0x10, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Pri Bus =", 0x18, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Sec Bus =", 0x19, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Sub Bus =", 0x1a, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "CBus Latency=", 0x1b, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Mem0 Base =", 0x1c, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Mem0 Limit =", 0x20, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Mem1 Base =", 0x24, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Mem1 Limit =", 0x28, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "I/O0 Base =", 0x2c, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "I/O0 Limit =", 0x30, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "I/O1 Base =", 0x34, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "I/O1 Limit =", 0x38, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "ILINE =", 0x3c, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "IPIN =", 0x3d, (int(*)())pci_config_get8, "%s 0x%02x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Bridge Ctrl =", 0x3e, (int(*)())pci_config_get16, "%s 0x%04x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { "Legacy Addr =", 0x44, (int(*)())pci_config_get32, "%s 0x%08x" },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { NULL, 0, NULL, NULL }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dump(struct cardbus_pci_desc *spcfg, ddi_acc_handle_t handle)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; spcfg[i].name; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE, spcfg[i].fmt, spcfg[i].name,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam spcfg[i].cfg_get_func(handle, spcfg[i].offset));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dump_pci_node(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct cardbus_pci_desc *spcfg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_acc_handle_t config_handle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t VendorId;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE, "\nPCI leaf node of dip 0x%p:\n", (void *)dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (next = ddi_get_child(dip); next;
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam next = ddi_get_next_sibling(next)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel VendorId = ddi_getprop(DDI_DEV_T_ANY, next,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam DDI_PROP_CANSLEEP|DDI_PROP_DONTPASS,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam "vendor-id", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (VendorId == -1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* not a pci device */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pci_config_setup(next, &config_handle) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "!pcic child: non pci device\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel spcfg = generic_pci_cfg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dump(spcfg, config_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_teardown(&config_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dump_pci_config(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct cardbus_pci_desc *spcfg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_acc_handle_t config_handle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam cmn_err(CE_WARN,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam "!pci_config_setup() failed on 0x%p", (void *)dip);
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel spcfg = cardbus_pci_cfg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dump(spcfg, config_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_teardown(&config_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dump_socket(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_acc_handle_t iohandle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel caddr_t ioaddr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_device_acc_attr_t attr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_regs_map_setup(dip, 1,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam (caddr_t *)&ioaddr,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam 0,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam 4096,
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam &attr, &iohandle) != DDI_SUCCESS) {
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam cmn_err(CE_WARN, "Failed to map address for 0x%p", (void *)dip);
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE, "////////////////////////////////////////");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE, "SOCKET_EVENT = [0x%x]",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ddi_get32(iohandle, (uint32_t *)(ioaddr+CB_STATUS_EVENT)));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE, "SOCKET_MASK = [0x%x]",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ddi_get32(iohandle, (uint32_t *)(ioaddr+CB_STATUS_MASK)));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE, "SOCKET_STATE = [0x%x]",
5c066ec28ea93f3a7c93082611a61747f255290aJerry Gilliam ddi_get32(iohandle, (uint32_t *)(ioaddr+CB_PRESENT_STATE)));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE, "////////////////////////////////////////");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&iohandle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}