cardbus.c revision 903a11ebdc8df157c4700150f41f1f262f4a8ae8
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/*
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw * 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#pragma ident "%Z%%M% %I% %E% SMI"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Cardbus module
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/conf.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/modctl.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pci.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/ddi.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/sunndi.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/ddi_impldefs.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/hotplug/hpcsvc.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pctypes.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pcmcia.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/sservice.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/note.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pci/pci_types.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pci/pci_sc.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pcic_reg.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pcic_var.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pcmcia.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef sparc
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/ddi_subrdefs.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#elif defined(__x86) || defined(__amd64)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pci_intr_lib.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/mach_intr.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include "cardbus.h"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include "cardbus_parse.h"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include "cardbus_hp.h"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include "cardbus_cfg.h"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_command_default = PCI_COMM_SERR_ENABLE |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_COMM_WAIT_CYC_ENAB |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_COMM_PARITY_DETECT |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_COMM_ME | PCI_COMM_MAE |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_COMM_IO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_next_instance = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_count = 0;
0d282d1376eb7ba06504448622a6d65726e4bd3erwint number_of_cardbus_cards = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_bus_map(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_map_req_t *mp, off_t offset, off_t len, caddr_t *vaddrp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcirp2rp(const pci_regspec_t *pci_rp, struct regspec *rp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_ctlops(dev_info_t *, dev_info_t *,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_ctl_enum_t, void *arg, void *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_init_child_regs(dev_info_t *child);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_initchild(dev_info_t *, dev_info_t *,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *, void *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_name_child(dev_info_t *, char *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_removechild(dev_info_t *dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_dma_allochdl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_attr_t *attr, int (*waitfp)(caddr_t), caddr_t arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t *handlep);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_dma_freehdl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t handle, struct ddi_dma_req *dmareq,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_cookie_t *cp, uint_t *ccountp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_dma_flush(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t handle, off_t off, size_t len,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t cache_flags);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_dma_win(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t handle, uint_t win, off_t *offp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel size_t *lenp, ddi_dma_cookie_t *cookiep, uint_t *ccountp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_dma_map(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct ddi_dma_req *dmareqp, ddi_dma_handle_t *handlep);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_prop_op(dev_t dev, dev_info_t *dip, dev_info_t *ch_dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_op_t prop_op, int mod_flags,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *name, caddr_t valuep, int *lengthp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_get_eventcookie(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *eventname, ddi_eventcookie_t *cookiep);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_eventcookie_t cookie, void (*callback)(dev_info_t *dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_eventcookie_t cookie, void *arg, void *bus_impldata),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel void *arg, ddi_callback_id_t *cb_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_post_event(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_eventcookie_t cookie, void *bus_impldata);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_intr_ops(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_intr_op_t intr_op,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_intr_handle_impl_t *hdlp, void *result);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int check_token(char *token, int *len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic char *find_token(char **cp, int *l, char *endc);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int parse_token(char *token);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int token_to_hex(char *token, unsigned *val, int len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int token_to_dec(char *token, unsigned *val, int len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_add_prop(struct cb_deviceset_props *cdsp, int type,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *name, caddr_t vp, int len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_add_stringprop(struct cb_deviceset_props *cdsp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *name, char *vp, int len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_prop_free(ddi_prop_t *propp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_devprops_free(struct cb_deviceset_props *cbdp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_parse_devprop(cbus_t *cbp, char *cp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_device_props(cbus_t *cbp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_expand_busrange(dev_info_t *dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_convert_properties(dev_info_t *dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_revert_properties(dev_info_t *dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * driver global data
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelkmutex_t cardbus_list_mutex; /* Protects the probe handle list */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid *cardbus_state;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint cardbus_latency_timer = 0x40;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint cardbus_debug = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Module linkage information for the kernel.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern struct mod_ops mod_miscops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct modlmisc modlmisc = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &mod_miscops,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh "Cardbus Configurator support",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct modlinkage modlinkage = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel MODREV_1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &modlmisc,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel_init(void)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int error;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel error = ddi_soft_state_init(&cardbus_state, sizeof (cbus_t), 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (error != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (error);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_init(&cardbus_list_mutex, NULL, MUTEX_DRIVER, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((error = mod_install(&modlinkage)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (error);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel_fini(void)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int error;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((error = mod_remove(&modlinkage)) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_soft_state_fini(&cardbus_state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (error);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel_info(struct modinfo *modinfop)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (mod_info(&modlinkage, modinfop));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstruct bus_ops cardbusbus_ops = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel BUSO_REV,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_bus_map,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel i_ddi_map_fault,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dma_map,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dma_allochdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dma_freehdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dma_bindhdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dma_unbindhdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dma_flush,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dma_win,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_mctl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_ctlops, /* (*bus_ctl)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_prop_op,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_get_eventcookie, /* (*bus_get_eventcookie)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_add_eventcall, /* (*bus_add_eventcall)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_remove_eventcall, /* (*bus_remove_eventcall)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_post_event, /* (*bus_post_event)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_intr_ctl)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_config)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_unconfig)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_fm_init)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_fm_fini)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_enter)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_exit)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_power)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_intr_ops /* (*bus_intr_op)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define CB_EVENT_TAG_INSERT 0
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define CB_EVENT_TAG_REMOVE 1
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic ndi_event_definition_t cb_ndi_event_defs[] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { CB_EVENT_TAG_INSERT, DDI_DEVI_INSERT_EVENT, EPL_INTERRUPT, 0 },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { CB_EVENT_TAG_REMOVE, DDI_DEVI_REMOVE_EVENT, EPL_INTERRUPT, 0 }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define CB_N_NDI_EVENTS \
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (sizeof (cb_ndi_event_defs) / sizeof (cb_ndi_event_defs[0]))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef sparc
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstruct busnum_ctrl {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rv;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_bus_range_t *range;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_claim_pci_busnum(dev_info_t *dip, void *arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_bus_range_t pci_bus_range;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct busnum_ctrl *ctrl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_ra_request_t req;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char bus_type[16] = "(unknown)";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t retlen;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl = (struct busnum_ctrl *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* check if this is a PCI bus node */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel len = sizeof (bus_type);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_op(DDI_DEV_T_ANY, dip, PROP_LEN_AND_VAL_BUF,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "device_type",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&bus_type, &len) != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0); /* (DDI_WALK_PRUNECHILD); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((strcmp(bus_type, "pci") != 0) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (strcmp(bus_type, "pciex") != 0)) /* it is not a pci bus type */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0); /* (DDI_WALK_PRUNECHILD); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* look for the bus-range property */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel len = sizeof (struct cardbus_bus_range);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getlongprop_buf(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "bus-range", (caddr_t)&pci_bus_range, &len) == DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_claim_pci_busnum: %u -> %u \n",
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh pci_bus_range.lo, pci_bus_range.hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((pci_bus_range.lo >= ctrl->range->lo) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (pci_bus_range.hi <= ctrl->range->hi)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_claim_pci_busnum: claim %u -> %u \n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_bus_range.lo, pci_bus_range.hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* claim the bus range from the bus resource map */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bzero((caddr_t)&req, sizeof (req));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_addr = (uint64_t)pci_bus_range.lo;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_flags |= NDI_RA_ALLOC_SPECIFIED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_len = (uint64_t)pci_bus_range.hi -
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint64_t)pci_bus_range.lo + 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_ra_alloc(ctrl->dip, &req, &base, &retlen,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NDI_RA_TYPE_PCI_BUSNUM, 0) == NDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0); /* (DDI_WALK_PRUNECHILD); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * never Error return.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl->rv = DDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_WALK_TERMINATE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_walk_node_child(dev_info_t *parent,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int (*f)(dev_info_t *, void *), void *arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ret;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (dip = ddi_get_child(parent); dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dip = ddi_get_next_sibling(dip)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = (*f) (dip, arg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ret)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_fix_hostbridge_busrange(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_bus_range_t bus_range;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct busnum_ctrl ctrl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t next_bus;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t blen;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_ra_request_t req;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_fix_hostbridge_busrange\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_len = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_ra_alloc(dip, &req,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &next_bus, &blen, NDI_RA_TYPE_PCI_BUSNUM,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0) != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_ra_map_destroy(dip, NDI_RA_TYPE_PCI_BUSNUM);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_ra_map_setup(dip, NDI_RA_TYPE_PCI_BUSNUM)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel == NDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_fix_hostbridge_busrange "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "NDI_RA_TYPE_PCI_BUSNUM setup fail\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus_range.lo = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_getlongprop_buf(DDI_DEV_T_NONE, dip,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus_range, &len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus_range.hi = 255;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_ra_free(dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint64_t)bus_range.lo + 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint64_t)bus_range.hi - (uint64_t)bus_range.lo,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NDI_RA_TYPE_PCI_BUSNUM, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.rv = DDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.dip = dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.range = &bus_range;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_walk_node_child(dip, cardbus_claim_pci_busnum,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void*)&ctrl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ctrl.rv != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_fix_hostbridge_busrange "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_walk_node_child fails\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh "bus-range", (int *)&bus_range, 2);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_fix_hostbridge_busrange "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "already set up %x\n", (int)next_bus);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_ra_free(dip, next_bus, (uint64_t)1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NDI_RA_TYPE_PCI_BUSNUM, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic dev_info_t *
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_find_hsbridge_dip(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (pdip) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_get_parent(pdip) == ddi_root_node())
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pdip = ddi_get_parent(pdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (pdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif /* sparc */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Attach a device to the cardbus infrastructure.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_attach(dev_info_t *dip, cb_nexus_cb_t *nex_ops)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cb_instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = (anp_t *)ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct dev_info *devi = DEVI(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Make sure that it is not already initialized.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_exists(DDI_DEV_T_ANY, dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_NOTPROM | DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cbus-instance") == 1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%s%d: cardbus instance already initialized!\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(dip), ddi_get_instance(dip));
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh mutex_exit(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * initialize soft state structure for the bus instance.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cb_instance = cardbus_next_instance++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_soft_state_zalloc(cardbus_state, cb_instance) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s%d: can't allocate cardbus soft state\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(dip), ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->cb_instance = cb_instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->cb_dip = dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_init(&cbp->cb_mutex, NULL, MUTEX_DRIVER, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Save the instance number of the soft state structure for
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this bus as a devinfo property.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cbus-instance", (caddr_t)&cb_instance,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (cb_instance)) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%s%d: failed to add the property 'cbus-instance'",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(dip), ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_soft_state_free(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->cb_nex_ops = nex_ops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * TODO - Should probably be some sort of locking on the devinfo here.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->orig_dopsp = devi->devi_ops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->orig_bopsp = devi->devi_ops->devo_bus_ops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->cb_dops = *devi->devi_ops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel devi->devi_ops = &cbp->cb_dops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_event_alloc_hdl(dip, *anp->an_iblock, &cbp->cb_ndi_event_hdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NDI_SLEEP) == NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->cb_ndi_events.ndi_n_events = CB_N_NDI_EVENTS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->cb_ndi_events.ndi_events_version = NDI_EVENTS_REV1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->cb_ndi_events.ndi_event_defs = cb_ndi_event_defs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_event_bind_set(cbp->cb_ndi_event_hdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &cbp->cb_ndi_events,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NDI_SLEEP) != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_attach: ndi_event_bind_set failed\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Check for device initialization property.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_device_props(cbp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_init_hotplug(cbp) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_soft_state_free(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef sparc
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* a hack to fix the bus-range problem on pci root nodes */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *hs_dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hs_dip = cardbus_find_hsbridge_dip(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_fix_hostbridge_busrange(hs_dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_expand_busrange(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_count++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef TODO
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_detach(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cb_instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* get the instance number for the cardbus soft state data */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cb_instance = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh DDI_PROP_DONTPASS, "cbus-instance", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cb_instance < 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE); /* no instance is setup for this bus */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->cb_dsp) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct cb_deviceset_props *cbdp, *ncbdp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbdp = cbp->cb_dsp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (cbdp) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ncbdp = cbdp->next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_devprops_free(cbdp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbdp = ncbdp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Unregister the bus with the HPS.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * (Note: It is assumed that the HPS framework uninstalls
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * event handlers for all the hot plug slots on this bus.)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_nexus_unregister_bus(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->cb_ndi_event_hdl != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_event_unbind_set(cbp->cb_ndi_event_hdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &cbp->cb_ndi_events, NDI_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_event_free_hdl(cbp->cb_ndi_event_hdl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->nexus_path)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(cbp->nexus_path, strlen(cbp->nexus_path) + 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->name)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(cbp->name, strlen(cbp->name) + 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_soft_state_free(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* remove the 'cbus-instance' property from the devinfo node */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_prop_remove(DDI_DEV_T_ANY, dip, "cbus-instance");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(cardbus_count != 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel --cardbus_count;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cardbus_list_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelboolean_t
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_load_cardbus(dev_info_t *dip, uint_t socket, uint32_t pc_base)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifndef HOTPLUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct cardbus_config_ctrl ctrl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int circular_count;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cb_instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct dev_info *devi = DEVI(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _NOTE(ARGUNUSED(socket, pc_base))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6, "cardbus_load_cardbus\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cb_instance = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh DDI_PROP_DONTPASS, "cbus-instance", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(cb_instance >= 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->fatal_problem)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (B_FALSE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_convert_properties(dip) == DDI_FAILURE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (B_FALSE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel number_of_cardbus_cards++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel devi->devi_ops->devo_bus_ops = &cardbusbus_ops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef HOTPLUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->card_present = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_slot_event_notify(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_EVENT_SLOT_INSERTION, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_slot_event_notify(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_EVENT_SLOT_POWER_ON, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_slot_event_notify(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_EVENT_SLOT_CONFIGURE, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_configure(cbp) != PCICFG_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6, "cardbus_configure failed\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (B_FALSE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.rv = NDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.busno = cardbus_primary_busno(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.op = PCICFG_OP_ONLINE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.dip = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.flags = PCICFG_FLAGS_CONTINUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The child of the dip is the cardbus dip. The child of the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * cardbus dip is the device itself
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8, "cardbus_load_cardbus: calling cbus_configure\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_devi_enter(dip, &circular_count);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_walk_devs(ddi_get_child(dip), cbus_configure, (void *)&ctrl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_devi_exit(dip, circular_count);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ctrl.rv != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_load_cardbus (%s%d): failed to attach (%d)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.dip ? ddi_driver_name(ctrl.dip) : "Unknown",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.dip ? ddi_get_instance(ctrl.dip) : 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctrl.rv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Returning error here will cause the pcic_load_cardbus() call
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to fail. This will invoke pcic_unload_cardbus() which calls
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * cardbus_unload_cardbus() below.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (B_FALSE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 7, "cardbus_load_cardbus: returning TRUE\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (B_TRUE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Unload the cardbus module
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_unload_cardbus(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cb_instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifndef HOTPLUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int prim_bus = cardbus_primary_busno(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6, "cardbus_unload_cardbus\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cb_instance = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_DONTPASS, "cbus-instance", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(cb_instance >= 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (number_of_cardbus_cards == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef HOTPLUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->card_present = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_slot_event_notify(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_EVENT_SLOT_POWER_OFF, 0);
0d282d1376eb7ba06504448622a6d65726e4bd3erw (void) hpc_slot_event_notify(cbp->slot_handle,
0d282d1376eb7ba06504448622a6d65726e4bd3erw HPC_EVENT_SLOT_UNCONFIGURE, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) hpc_slot_event_notify(cbp->slot_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel HPC_EVENT_SLOT_REMOVAL, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&cbp->cb_mutex);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_unload_cardbus: calling cardbus_unconfigure_node\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rval = cardbus_unconfigure_node(dip, prim_bus, B_TRUE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rval != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 4,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_unload_cardbus: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_unconfigure_node failed\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel number_of_cardbus_cards--;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->fatal_problem = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus(%s%d): Failed to remove device tree: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Slot disabled",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_name(dip), ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) cardbus_unconfigure(cbp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Inform the lower drivers that the card has been removed
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->cb_ndi_event_hdl != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_eventcookie_t cookie;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_event_retrieve_cookie(cbp->cb_ndi_event_hdl, dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_DEVI_REMOVE_EVENT, &cookie, 0) == NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_event_run_callbacks(cbp->cb_ndi_event_hdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dip, cookie, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_revert_properties(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwstatic boolean_t
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwis_32bit_pccard(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw int len;
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw char bus_type[16];
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw len = sizeof (bus_type);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (ddi_prop_op(DDI_DEV_T_ANY, ddi_get_parent(dip),
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw PROP_LEN_AND_VAL_BUF,
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw "device_type",
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw (caddr_t)&bus_type, &len) != DDI_SUCCESS)
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw return (B_FALSE);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if ((strcmp(bus_type, "pci") != 0) &&
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw (strcmp(bus_type, "pciex") != 0) &&
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw (strcmp(bus_type, "cardbus") != 0)) /* not of pci type */
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw return (B_FALSE);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw return (B_TRUE);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw}
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwvoid
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwcardbus_save_children(dev_info_t *dip)
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw{
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw for (; dip != NULL; dip = ddi_get_next_sibling(dip)) {
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw cardbus_save_children(ddi_get_child(dip));
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (strcmp("pcs", ddi_node_name(dip)) == 0)
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw continue;
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (!is_32bit_pccard(dip))
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw continue;
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw cardbus_err(dip, 1, "Saving device\n");
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw (void) pci_save_config_regs(dip);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw }
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw}
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwvoid
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwcardbus_restore_children(dev_info_t *dip)
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw{
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw for (; dip != NULL; dip = ddi_get_next_sibling(dip)) {
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw cardbus_restore_children(ddi_get_child(dip));
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (strcmp("pcs", ddi_node_name(dip)) == 0)
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw continue;
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (!is_32bit_pccard(dip))
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw continue;
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw cardbus_err(dip, 1, "restoring device\n");
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw (void) pci_restore_config_regs(dip);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_convert_properties(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct pcm_regs *pcic_avail_p, *old_avail_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_regspec_t *cb_avail_p, *new_avail_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_ranges_t *pcic_range_p, *old_range_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_range_t *cb_range_p, *new_range_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int range_len, range_entries, i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int avail_len, avail_entries;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6, "cardbus_convert_properties\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "#address-cells", 3) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_convert_properties: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "failed to update #address-cells property\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "#size-cells", 2) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_convert_properties: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "failed to update #size-cells property\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, "available",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&pcic_avail_p, &avail_len) != DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_convert_properties: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "no available property for pcmcia\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel avail_entries = avail_len / sizeof (struct pcm_regs);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cb_avail_p = kmem_alloc(sizeof (pci_regspec_t) * avail_entries,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel old_avail_p = pcic_avail_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_avail_p = cb_avail_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < avail_entries;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel i++, old_avail_p++, new_avail_p++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_avail_p->pci_phys_hi = old_avail_p->phys_hi;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_avail_p->pci_phys_mid = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_avail_p->pci_phys_low = old_avail_p->phys_lo;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_avail_p->pci_size_hi = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_avail_p->pci_size_low = old_avail_p->phys_len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "available",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (int *)cb_avail_p,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (sizeof (pci_regspec_t) * avail_entries)/sizeof (int));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic_avail_p, avail_len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(cb_avail_p, sizeof (pci_regspec_t) * avail_entries);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, "ranges",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&pcic_range_p, &range_len) != DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_convert_properties: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "no ranges property for pcmcia\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel range_entries = range_len / sizeof (pcic_ranges_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cb_range_p = kmem_alloc(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (cardbus_range_t) * range_entries, KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel old_range_p = pcic_range_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_range_p = cb_range_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < range_entries;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel i++, old_range_p++, new_range_p++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_range_p->child_hi =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel old_range_p->pcic_range_caddrhi;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_range_p->child_mid = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_range_p->child_lo =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel old_range_p->pcic_range_caddrlo;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_range_p->parent_hi =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel old_range_p->pcic_range_paddrhi;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_range_p->parent_mid =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel old_range_p->pcic_range_paddrmid;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_range_p->parent_lo =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel old_range_p->pcic_range_paddrlo;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_range_p->size_hi = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new_range_p->size_lo = old_range_p->pcic_range_size;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "ranges",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (int *)cb_range_p,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (sizeof (cardbus_range_t) * range_entries)/sizeof (int));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic_range_p, range_len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(cb_range_p, sizeof (cardbus_range_t) * range_entries);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_revert_properties(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6, "cardbus_revert_properties\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "#address-cells");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "#size-cells");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "available");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_prop_op(dev_t dev, dev_info_t *dip, dev_info_t *ch_dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_op_t prop_op, int mod_flags,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *name, caddr_t valuep, int *lengthp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((ch_dip != dip) || (cardbus_debug >= 9))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_prop_op(%s) (dip=0x%p, op=%d, name=%s)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(ch_dip), (void *) dip, prop_op, name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (impl_ddi_bus_prop_op(dev, dip, ch_dip, prop_op,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mod_flags, name, valuep, lengthp));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_ctlops(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_ctl_enum_t ctlop, void *arg, void *result)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_regspec_t *regs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int totreg, reglen;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel const char *dname = ddi_driver_name(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(number_of_cardbus_cards != 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_ctlops(%p, %p, %d, %p, %p)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *)dip, (void *)rdip, ctlop, (void *)arg, (void *)result);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (ctlop) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_CTLOPS_UNINITCHILD:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_removechild((dev_info_t *)arg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw case DDI_CTLOPS_POWER:
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Do Nothing
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_ctlops: Unsupported DDI_CTLOP %d\n", ctlop);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ddi_ctlops(dip, rdip, ctlop, arg, result));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_CTLOPS_SIDDEV: /* see ddi_dev_is_sid(9F) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_CTLOPS_SLAVEONLY: /* see ddi_slaveonly(9F) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE); /* cardbus */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_CTLOPS_REGSIZE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_CTLOPS_NREGS:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rdip == (dev_info_t *)NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *(int *)result = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_CTLOPS_IOMIN:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If we are using the streaming cache, align at
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * least on a cache line boundary. Otherwise use
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * whatever alignment is passed in.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (arg) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int val = *((int *)result);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCI_SBUF_LINE_SIZE
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = maxbit(val, PCI_SBUF_LINE_SIZE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = maxbit(val, 64);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *((int *)result) = val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_CTLOPS_INITCHILD:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (cardbus_initchild(rdip, dip, (dev_info_t *)arg,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh result));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_CTLOPS_REPORTDEV:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rdip == (dev_info_t *)0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp("pcs", ddi_node_name(rdip)) == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_ctlops: PCCard socket %d at %s@%s\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_instance(rdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dname, ddi_get_name_addr(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_regspec_t *pci_rp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int length;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_DONTPASS, "reg", (int **)&pci_rp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint_t *)&length) != DDI_PROP_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pci_rp->pci_phys_hi == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "%s%d at %s@%s\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(rdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_instance(rdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dname, ddi_get_name_addr(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t bus, device, function;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int32_t val32;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *ptr, buf[128];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
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 ptr = buf;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(ptr, " "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "Bus %3d Device %2d Function %2d",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus, device, function);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ptr = &ptr[strlen(ptr)];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val32 = ddi_getprop(DDI_DEV_T_ANY, rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "vendor-id", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (val32 != -1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(ptr, " Vendor 0x%04x",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val32);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ptr = &ptr[strlen(ptr)];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val32 = ddi_getprop(DDI_DEV_T_ANY, rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "device-id", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (val32 != -1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(ptr, " Device 0x%04x",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val32);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ptr = &ptr[strlen(ptr)];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val32 = ddi_getprop(DDI_DEV_T_ANY, rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "class-code", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (val32 != -1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel const char *name;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((name = ddi_get_name(rdip)) !=
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(ptr, " Name %s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(ptr,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " Class 0x%x", val32 >> 8);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ptr = &ptr[strlen(ptr)];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *ptr++ = '\n';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(((caddr_t)ptr - (caddr_t)buf) <
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh sizeof (buf));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *ptr = '\0';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, buf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_free(pci_rp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (next = ddi_get_child(rdip); next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel next = ddi_get_next_sibling(next))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) cardbus_ctlops(next, next,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_CTLOPS_REPORTDEV, arg, result);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *(int *)result = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getlongprop(DDI_DEV_T_NONE, rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "reg",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&regs, &reglen) != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel totreg = reglen / sizeof (pci_regspec_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ctlop == DDI_CTLOPS_NREGS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_ctlops, returning NREGS = %d\n", totreg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *(int *)result = totreg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (ctlop == DDI_CTLOPS_REGSIZE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel const int rn = *(int *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rn > totreg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_ctlops, returning REGSIZE(%d) = %d\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rn, regs[rn].pci_size_low);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *(off_t *)result = regs[rn].pci_size_low;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(regs, reglen);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_init_child_regs(dev_info_t *child)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_acc_handle_t config_handle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint16_t command_preserve, command;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if !defined(__i386) && !defined(__amd64)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t bcr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t header_type;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t min_gnt, latency_timer;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t n;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Map the child configuration space to for initialization.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Set the latency-timer register to values appropriate
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * for the devices on the bus (based on other devices
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * MIN_GNT and MAX_LAT registers.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Set the fast back-to-back enable bit in the command
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * register if it's supported and all devices on the bus
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * have the capability.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pci_config_setup(child, &config_handle) != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(child, 6, "cardbus_init_child_regs()\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Determine the configuration header type.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Support for "command-preserve" property. Note that we
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * add PCI_COMM_BACK2BACK_ENAB to the bits to be preserved
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * since the obp will set this if the device supports and
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * all targets on the same bus support it. Since psycho
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * doesn't support PCI_COMM_BACK2BACK_ENAB, it will never
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * be set. This is just here in case future revs do support
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * PCI_COMM_BACK2BACK_ENAB.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "command-preserve", 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel command = pci_config_get16(config_handle, PCI_CONF_COMM);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel command |= (cardbus_command_default & ~command_preserve);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_put16(config_handle, PCI_CONF_COMM, command);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel command = pci_config_get16(config_handle, PCI_CONF_COMM);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if !defined(__i386) && !defined(__amd64)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If the device has a bus control register then program it
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * based on the settings in the command register.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcr = pci_config_get8(config_handle, PCI_BCNF_BCNTRL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_command_default & PCI_COMM_PARITY_DETECT)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_command_default & PCI_COMM_SERR_ENABLE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Initialize cache-line-size configuration register if needed.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cache-line-size", 0) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_CACHE_LINE_SIZE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel n = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (n != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh "cache-line-size", n);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Initialize latency timer registers if needed.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "latency-timer", 0) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel latency_timer = cardbus_latency_timer;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh latency_timer);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel min_gnt = pci_config_get8(config_handle,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh PCI_CONF_MIN_G);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Cardbus os only 33Mhz
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (min_gnt != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel latency_timer = min_gnt * 8;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh latency_timer);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel n = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (n != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh "latency-timer", n);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_teardown(&config_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_initchild(dev_info_t *rdip, dev_info_t *dip, dev_info_t *child,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel void *result)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char name[MAXNAMELEN];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel const char *dname = ddi_driver_name(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel const struct cb_ops *cop;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _NOTE(ARGUNUSED(rdip, result))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(child, 6, "cardbus_initchild\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Name the child
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_set_name_addr(child, name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_set_parent_data(child, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_dev_is_persistent_node(child) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Try to merge the properties from this prototype
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * node into real h/w nodes.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_merge_node(child, cardbus_name_child) == DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Merged ok - return failure to remove the node.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_removechild(child);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The child was not merged into a h/w node,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * but there's not much we can do with it other
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * than return failure to cause the node to be removed.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(child), ddi_get_name_addr(child),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(child));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_removechild(child);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_NOT_WELL_FORMED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cop = DEVI(dip)->devi_ops->devo_cb_ops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((cop == NULL) || (!(cop->cb_flag & D_HOTPLUG))) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s: driver doesn't support HOTPLUG\n", dname);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_init_child_regs(child);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Create ppd if needed.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_get_parent_data(child) == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct cardbus_parent_private_data *ppd;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef sparc
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppd = (struct cardbus_parent_private_data *)
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh kmem_zalloc(sizeof (struct cardbus_parent_private_data),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#elif defined(__x86) || defined(__amd64)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppd = (struct cardbus_parent_private_data *)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_zalloc(sizeof (struct cardbus_parent_private_data)
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh + sizeof (struct intrspec), KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppd->ppd.par_intr = (struct intrspec *)(ppd + 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (ppd->ppd.par_intr)->intrspec_pri = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (ppd->ppd.par_intr)->intrspec_vec = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (ppd->ppd.par_intr)->intrspec_func = (uint_t (*)()) 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getprop(DDI_DEV_T_NONE, child, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "interrupts", -1) != -1)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppd->ppd.par_nintr = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppd->code = CB_PPD_CODE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(child, 5,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_initchild: Creating empty ppd\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppd->ppd.par_nreg = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppd->ppd.par_reg = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_set_parent_data(child, (caddr_t)ppd);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_name_child(dev_info_t *child, char *name, int namelen)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_regspec_t *pci_rp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char **unit_addr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t n;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int bus, device, func;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Pseudo nodes indicate a prototype node with per-instance
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * properties to be merged into the real h/w device node.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The interpretation of the unit-address is DD[,F]
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * where DD is the device id and F is the function.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_dev_is_persistent_node(child) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, child,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "unit-address", &unit_addr, &n) != DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "cannot name node from %s.conf",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(child));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (n != 1 || *unit_addr == NULL || **unit_addr == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "unit-address property in %s.conf"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " not well-formed", ddi_driver_name(child));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_free(unit_addr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) snprintf(name, namelen, "%s", *unit_addr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_free(unit_addr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get the address portion of the node name based on
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the function and device number.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "reg", (int **)&pci_rp, &n) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
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 if (func != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) snprintf(name, namelen, "%x,%x", device, func);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) snprintf(name, namelen, "%x", device);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(child, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_name_child: system init done [%x][%x][%x]"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " for %s [%s] nodeid: %x @%s\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus, device, func,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_name(child), ddi_get_name_addr(child),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DEVI(child)->devi_nodeid, name);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_removechild(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct cardbus_parent_private_data *ppd;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_set_name_addr(dip, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel impl_rem_dev_props(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppd = (struct cardbus_parent_private_data *)ddi_get_parent_data(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ppd && (ppd->code == CB_PPD_CODE)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ppd->ppd.par_reg && (ppd->ppd.par_nreg > 0))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free((caddr_t)ppd->ppd.par_reg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppd->ppd.par_nreg * sizeof (struct regspec));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef sparc
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(ppd, sizeof (struct cardbus_parent_private_data));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#elif defined(__x86) || defined(__amd64)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(ppd, sizeof (struct cardbus_parent_private_data) +
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (struct intrspec));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 5,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_removechild: ddi_set_parent_data(NULL)\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_set_parent_data(dip, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic char cb_bnamestr[] = "binding_name";
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic char cb_venidstr[] = "VendorID";
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic char cb_devidstr[] = "DeviceID";
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic char cb_nnamestr[] = "nodename";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic cb_props_parse_tree_t cb_props_parse_tree[] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { cb_bnamestr, PT_STATE_STRING_VAR },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { cb_venidstr, PT_STATE_HEX_VAR },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { cb_devidstr, PT_STATE_HEX_VAR } };
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcheck_token(char *token, int *len)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int state = PT_STATE_DEC_VAR;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int sl = strlen(token), il = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char c;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (token[0] == '0' && token[2] && (token[1] == 'x' || token[1] ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 'X')) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_HEX_VAR;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token += 2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (c = *token++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (isdigit(c))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (c == PARSE_COMMA) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel il++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (token[0] == '0' && token[2] && isx(token[1])) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_HEX_VAR;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token += 2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!isxdigit(c)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *len = sl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (PT_STATE_STRING_VAR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_HEX_VAR;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *len = il;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic char *
3db86aab554edbb4244c8d1a1c90f152eee768afstevelfind_token(char **cp, int *l, char *endc)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *cpp = *cp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while ((**cp && (isalpha(**cp) || isxdigit(**cp) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (**cp == PARSE_UNDERSCORE) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (**cp == PARSE_COMMA) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (**cp == PARSE_DASH)))) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (*cp)++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (*l)++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *endc = **cp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel **cp = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (cpp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelparse_token(char *token)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cb_props_parse_tree_t *pt = cb_props_parse_tree;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int k = sizeof (cb_props_parse_tree) /
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (cb_props_parse_tree_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (k--) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp((char *)token, pt->token) == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (pt->state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pt++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (PT_STATE_UNKNOWN);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afsteveltoken_to_hex(char *token, unsigned *val, int len)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uchar_t c;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *val = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (token[0] == '0' && (token[1] == 'x' || token[1] == 'X')) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token += 2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (*token) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!isxdigit(*token)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (*token == PARSE_COMMA) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(--len))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *val = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (token[0] == '0' && (token[1] == 'x' ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token[1] == 'X')) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token += 2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel c = toupper(*token);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (c >= 'A')
3db86aab554edbb4244c8d1a1c90f152eee768afstevel c = c - 'A' + 10 + '0';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *val = ((*val * 16) + (c - '0'));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afsteveltoken_to_dec(char *token, unsigned *val, int len)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *val = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (*token) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!isdigit(*token)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (*token == PARSE_COMMA) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(--len))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *val = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *val = ((*val * 10) + (*token - '0'));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_add_prop(struct cb_deviceset_props *cdsp, int type, char *name,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel caddr_t vp, int len)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_t *propp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int pnlen = strlen(name) + 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel propp = (ddi_prop_t *)kmem_zalloc(sizeof (ddi_prop_t), KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel propp->prop_name = (char *)kmem_alloc(pnlen, KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel propp->prop_val = vp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcopy(name, propp->prop_name, pnlen);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel propp->prop_len = len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel propp->prop_flags = type;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel propp->prop_next = cdsp->prop_list;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->prop_list = propp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_add_stringprop(struct cb_deviceset_props *cdsp, char *name,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *vp, int len)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *nstr = kmem_zalloc(len + 1, KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bcopy(vp, nstr, len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_add_prop(cdsp, DDI_PROP_TYPE_STRING, name, (caddr_t)nstr,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel len + 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_prop_free(ddi_prop_t *propp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (propp->prop_len) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (propp->prop_flags) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_PROP_TYPE_STRING:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(propp->prop_val, propp->prop_len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_PROP_TYPE_INT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(propp->prop_val,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel propp->prop_len * sizeof (int));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(propp->prop_name, strlen(propp->prop_name) + 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(propp, sizeof (ddi_prop_t *));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_devprops_free(struct cb_deviceset_props *cbdp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_t *propp, *npropp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel propp = cbdp->prop_list;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (propp) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel npropp = propp->prop_next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_prop_free(propp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel propp = npropp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbdp->nodename)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(cbdp->nodename, strlen(cbdp->nodename) + 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbdp->binding_name)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(cbdp->binding_name, strlen(cbdp->binding_name) +
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(cbdp, sizeof (*cbdp));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Format of "cb-device-init-props" property:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Anything before the semi-colon is an identifying equate, anything
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * after the semi-colon is a setting equate.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * "binding_name=xXxXxX VendorID=NNNN DeviceID=NNNN; nodename=NewName
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Prop=PropVal"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_parse_devprop(cbus_t *cbp, char *cp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int state = PT_STATE_TOKEN, qm = 0, em = 0, smc = 0, l = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int length;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *token = "beginning of line";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *ptoken = NULL, *quote;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char eq = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct cb_deviceset_props *cdsp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp = (struct cb_deviceset_props *)kmem_zalloc(sizeof (*cdsp),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel length = strlen(cp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while ((*cp) && (l < length)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Check for escaped characters
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (*cp == PARSE_ESCAPE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *cpp = cp, *cppp = cp + 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel em = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!qm) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "cardbus_parse_devprop: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "escape not allowed outside "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "of quotes at [%s]\n", token);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* if (!qm) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (*cppp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *cpp++ = *cppp++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel l++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *cpp = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* PARSE_ESCAPE */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Check for quoted strings
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!em && (*cp == PARSE_QUOTE)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel qm ^= 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (qm) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel quote = cp + 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *cp = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (state == PT_STATE_CHECK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp(token, cb_nnamestr) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->nodename = kmem_alloc(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel strlen(quote) + 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) strcpy(cdsp->nodename,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel quote);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_add_stringprop(cdsp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token, quote,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel strlen(quote));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (state != PT_STATE_STRING_VAR) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_parse_devprop: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "unexpected string [%s] after "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "[%s]\n", quote, token);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp(token, cb_bnamestr) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->binding_name = kmem_alloc(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel strlen(quote) + 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) strcpy(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->binding_name, quote);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_TOKEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* if (qm) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* PARSE_QUOTE */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel em = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!qm && (*cp == PARSE_SEMICOLON)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel smc = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Check for tokens
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else if (!qm && (isalpha(*cp) || isxdigit(*cp))) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int tl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unsigned *intp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ptoken = token;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token = find_token(&cp, &l, &eq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (state) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PT_STATE_TOKEN:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (smc) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (eq == PARSE_EQUALS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_CHECK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_add_prop(cdsp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_TYPE_ANY,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (eq == PARSE_EQUALS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (state = parse_token(token)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PT_STATE_UNKNOWN:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_parse_devprop: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "unknown token [%s]\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_TOKEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch (parse_token) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_TOKEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PT_STATE_CHECK:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (check_token(token, &tl)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PT_STATE_DEC_VAR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intp = (unsigned *)kmem_alloc(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (int)*tl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (token_to_dec(token, intp, tl))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_add_prop(cdsp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_TYPE_INT, ptoken,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)intp, tl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(intp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (int)*tl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PT_STATE_HEX_VAR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intp = (unsigned *)kmem_alloc(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (int)*tl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (token_to_hex(token, intp, tl))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_add_prop(cdsp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_TYPE_INT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ptoken,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)intp, tl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(intp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (int)*tl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PT_STATE_STRING_VAR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp(ptoken, cb_nnamestr) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->nodename = kmem_alloc(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tl + 1, KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) strcpy(cdsp->nodename,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_add_stringprop(cdsp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ptoken, token, tl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_TOKEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PT_STATE_HEX_VAR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp(ptoken, cb_venidstr) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (token_to_hex(token, &val, 1))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->venid = val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (strcmp(ptoken, cb_devidstr) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (token_to_hex(token, &val, 1))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->devid = val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_TOKEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PT_STATE_DEC_VAR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp(ptoken, cb_venidstr) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (token_to_dec(token, &val, 1))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->venid = val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else if (strcmp(ptoken, cb_devidstr) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (token_to_dec(token, &val, 1))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->devid = val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_TOKEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PT_STATE_STRING_VAR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (strcmp(ptoken, cb_bnamestr) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->binding_name = kmem_alloc(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel strlen(token) + 1, KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) strcpy(cdsp->binding_name,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel token);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state = PT_STATE_TOKEN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "cardbus_parse_devprop: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "unknown state machine state = %d\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_devprops_free(cdsp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch (state) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (eq == PARSE_SEMICOLON)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel smc = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cp++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel l++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* while (*cp) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (qm) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "cb_props_parse_line: unterminated "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "string = [%s]\n", quote);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_devprops_free(cdsp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (state != PT_STATE_TOKEN) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "cardbus_parse_devprop: token [%s] "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "requires value\n", token);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_devprops_free(cdsp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cdsp->venid == 0 || cdsp->devid == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "cardbus_parse_devprop: Entry "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "requires VendorID and DeviceID\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_devprops_free(cdsp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cdsp->next = cbp->cb_dsp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp->cb_dsp = cdsp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_device_props(cbus_t *cbp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char **prop_array;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t i, n;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, cbp->cb_dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cb-device-init-props", &prop_array,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &n) != DDI_PROP_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < n; i++)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) cardbus_parse_devprop(cbp, prop_array[i]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_free(prop_array);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel off_t offset, off_t len, caddr_t *vaddrp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel register dev_info_t *pdip = (dev_info_t *)DEVI(dip)->devi_parent;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rc;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 9,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_bus_map(dip=0x%p, rdip=0x%p)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) dip, (void *) rdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pdip == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* A child has asked us to set something up */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 9,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_bus_map(%s) calling %s - 0x%p, "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "offset 0x%x, len 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(rdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_map,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (int)offset, (int)len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rc = (DEVI(pdip)->devi_ops->devo_bus_ops->bus_map)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (pdip, rdip, mp, offset, len, vaddrp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* rc = ddi_map(dip, mp, offset, len, vaddrp); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw if (rc != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(rdip, 8, "cardbus_bus_map failed, rc = %d\n", rc);
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw return (DDI_FAILURE);
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(rdip, 9, "cardbus_bus_map OK\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcirp2rp(const pci_regspec_t *pci_rp, struct regspec *rp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (PCI_REG_ADDR_G(pci_rp->pci_phys_hi) ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_REG_ADDR_G(PCI_ADDR_IO)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* I/O */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rp->regspec_bustype = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* memory */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rp->regspec_bustype = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rp->regspec_addr = pci_rp->pci_phys_low;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rp->regspec_size = pci_rp->pci_size_low;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int (*waitfp)(caddr_t), caddr_t arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t *handlep)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 10,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_allochdl(dip=0x%p, rdip=0x%p)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) dip, (void *) rdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pdip == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 11,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_allochdl calling %s - 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_allochdl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ddi_dma_allochdl(dip, rdip, attr, waitfp, arg, handlep));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dma_freehdl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t handle)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 10,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_freehdl(dip=0x%p, rdip=0x%p)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) dip, (void *) rdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pdip == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 11,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_freehdl calling %s - 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_freehdl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ddi_dma_freehdl(dip, rdip, handle));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t handle, struct ddi_dma_req *dmareq,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_cookie_t *cp, uint_t *ccountp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 10,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_bindhdl(dip=0x%p, rdip=0x%p)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) dip, (void *) rdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pdip == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 11,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_bindhdl calling %s - 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_bindhdl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_bindhdl(pdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rdip, handle, dmareq, cp, ccountp));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t handle)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 10,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_unbindhdl(dip=0x%p, rdip=0x%p)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) dip, (void *) rdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pdip == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 11,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_unbindhdl calling %s - 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_unbindhdl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_unbindhdl(pdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rdip, handle));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dma_flush(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t handle, off_t off, size_t len,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t cache_flags)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 10,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_flush(dip=0x%p, rdip=0x%p)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) dip, (void *) rdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pdip == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 11,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_flush calling %s - 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_flush);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_flush(pdip, rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel handle, off, len, cache_flags));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dma_win(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_handle_t handle, uint_t win, off_t *offp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel size_t *lenp, ddi_dma_cookie_t *cookiep, uint_t *ccountp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_win(dip=0x%p, rdip=0x%p)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) dip, (void *) rdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pdip == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_win calling %s - 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_win);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_win(pdip, rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel handle, win, offp, lenp, cookiep, ccountp));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_dma_map(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct ddi_dma_req *dmareqp, ddi_dma_handle_t *handlep)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 10,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_map(dip=0x%p, rdip=0x%p)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) dip, (void *) rdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pdip == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 11,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_dma_map calling %s - 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_map);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DEVI(pdip)->devi_ops->devo_bus_ops->bus_dma_map(pdip, rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dmareqp, handlep));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_get_eventcookie(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *eventname, ddi_eventcookie_t *cookiep)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cb_instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rc;
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);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(cb_instance >= 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6, "cardbus_get_eventcookie %s\n", eventname);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(number_of_cardbus_cards != 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->cb_ndi_event_hdl == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We can't handle up (probably called at the attachment
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * point) so pass it on up
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_get_eventcookie calling %s - 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DEVI(pdip)->devi_ops->devo_bus_ops->bus_get_eventcookie);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DEVI(pdip)->devi_ops->devo_bus_ops->
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus_get_eventcookie(pdip, rdip, eventname, cookiep));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_get_eventcookie calling ndi_event_retrieve_cookie\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rc = ndi_event_retrieve_cookie(cbp->cb_ndi_event_hdl, rdip, eventname,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cookiep, NDI_EVENT_NOPASS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_get_eventcookie rc %d cookie %p\n", rc, (void *)*cookiep);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rc);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_eventcookie_t cookie, void (*callback)(dev_info_t *dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_eventcookie_t cookie, void *arg, void *bus_impldata),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel void *arg, ddi_callback_id_t *cb_id)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cb_instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int rc;
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);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(cb_instance >= 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6, "cardbus_add_eventcall\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(number_of_cardbus_cards != 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->cb_ndi_event_hdl == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We can't handle up (probably called at the attachment
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * point) so pass it on up
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_add_eventcall calling %s - 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DEVI(pdip)->devi_ops->devo_bus_ops->bus_add_eventcall);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DEVI(pdip)->devi_ops->devo_bus_ops->
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus_add_eventcall(pdip, rdip, cookie, callback,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel arg, cb_id));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_add_eventcall calling ndi_event_add_callback\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rc = ndi_event_add_callback(cbp->cb_ndi_event_hdl, rdip, cookie,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel callback, arg, NDI_EVENT_NOPASS, cb_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 7,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_add_eventcall rc %d cookie %p\n", rc, (void *)cookie);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rc);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbus_t *cbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cb_instance;
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);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(cb_instance >= 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbp = (cbus_t *)ddi_get_soft_state(cardbus_state, cb_instance);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 6, "cardbus_remove_eventcall\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(number_of_cardbus_cards != 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbp->cb_ndi_event_hdl == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We can't handle up (probably called at the attachment
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * point) so pass it on up
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_remove_eventcall calling %s - 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_driver_name(pdip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DEVI(pdip)->devi_ops->devo_bus_ops->bus_remove_eventcall);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DEVI(pdip)->devi_ops->devo_bus_ops->
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus_remove_eventcall(pdip, cb_id));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ndi_event_remove_callback(cbp->cb_ndi_event_hdl, cb_id));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_post_event(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_eventcookie_t cookie, void *bus_impldata)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _NOTE(ARGUNUSED(rdip, cookie, bus_impldata))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_post_event()\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_remove_intr_impl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_intr_handle_impl_t *hdlp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_add_intr_impl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_intr_handle_impl_t *hdlp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_enable_intr_impl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_intr_handle_impl_t *hdlp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_disable_intr_impl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_intr_handle_impl_t *hdlp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
0d282d1376eb7ba06504448622a6d65726e4bd3erwstatic int
0d282d1376eb7ba06504448622a6d65726e4bd3erwcardbus_get_pil(dev_info_t *dip)
0d282d1376eb7ba06504448622a6d65726e4bd3erw{
0d282d1376eb7ba06504448622a6d65726e4bd3erw return ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
0d282d1376eb7ba06504448622a6d65726e4bd3erw "interrupt-priorities", 6);
0d282d1376eb7ba06504448622a6d65726e4bd3erw}
0d282d1376eb7ba06504448622a6d65726e4bd3erw
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_intr_handle_impl_t *hdlp, void *result)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ret = DDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 8, "cardbus_intr_ops() intr_op=%d\n", (int)intr_op);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (intr_op) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_GETCAP:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *(int *)result = DDI_INTR_FLAG_LEVEL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_ALLOC:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *(int *)result = hdlp->ih_scratch1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_FREE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_GETPRI:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *(int *)result = hdlp->ih_pri ?
0d282d1376eb7ba06504448622a6d65726e4bd3erw hdlp->ih_pri : cardbus_get_pil(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_SETPRI:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_ADDISR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_REMISR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hdlp->ih_type != DDI_INTR_TYPE_FIXED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "Only fixed interrupts\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_ENABLE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = cardbus_enable_intr_impl(dip, rdip, hdlp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_DISABLE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = cardbus_disable_intr_impl(dip, rdip, hdlp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_NINTRS:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_NAVAIL:
0d282d1376eb7ba06504448622a6d65726e4bd3erw#ifdef sparc
a54f81fbf66e3e4c14a94d571c0fe241e4cf2394anish *(int *)result = i_ddi_get_intx_nintrs(rdip);
0d282d1376eb7ba06504448622a6d65726e4bd3erw#else
0d282d1376eb7ba06504448622a6d65726e4bd3erw *(int *)result = 1;
0d282d1376eb7ba06504448622a6d65726e4bd3erw#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_INTROP_SUPPORTED_TYPES:
0d282d1376eb7ba06504448622a6d65726e4bd3erw *(int *)result = DDI_INTR_TYPE_FIXED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = DDI_ENOTSUP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ret);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_enable_intr_impl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_intr_handle_impl_t *hdlp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = (anp_t *)ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel set_irq_handler_t sih;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t socket = 0; /* We only support devices */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* with one socket per function */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(anp != NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 9,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_enable_intr_impl, intr=0x%p, arg1=0x%p, arg2=0x%p"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "rdip=0x%p(%s)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) hdlp->ih_cb_func,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hdlp->ih_cb_arg1, hdlp->ih_cb_arg2,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) rdip, ddi_driver_name(rdip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hdlp->ih_type != DDI_INTR_TYPE_FIXED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "Only fixed interrupts\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sih.socket = socket;
0d282d1376eb7ba06504448622a6d65726e4bd3erw sih.handler_id = (unsigned)(long)rdip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sih.handler = (f_tt *)hdlp->ih_cb_func;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sih.arg1 = hdlp->ih_cb_arg1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sih.arg2 = hdlp->ih_cb_arg2;
0d282d1376eb7ba06504448622a6d65726e4bd3erw sih.irq = cardbus_get_pil(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((*anp->an_if->pcif_set_interrupt)(dip, &sih) != SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_disable_intr_impl(dev_info_t *dip, dev_info_t *rdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_intr_handle_impl_t *hdlp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = (anp_t *)ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clear_irq_handler_t cih;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t socket = 0; /* We only support devices with 1 socket per */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* function. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(anp != NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 9,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus_disable_intr_impl, intr=0x%p, arg1=0x%p, arg2=0x%p"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "rdip=0x%p(%s%d)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) hdlp->ih_cb_func,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel hdlp->ih_cb_arg1, hdlp->ih_cb_arg2,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) rdip, ddi_driver_name(rdip), ddi_get_instance(rdip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (hdlp->ih_type != DDI_INTR_TYPE_FIXED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "Only fixed interrupts\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cih.socket = socket;
0d282d1376eb7ba06504448622a6d65726e4bd3erw cih.handler_id = (unsigned)(long)rdip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cih.handler = (f_tt *)hdlp->ih_cb_func;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((*anp->an_if->pcif_clr_interrupt)(dip, &cih) != SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int cardbus_do_pprintf = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*PRINTFLIKE3*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_err(dev_info_t *dip, int level, const char *fmt, ...)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_debug && (level <= cardbus_debug)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel va_list adx;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char buf[256];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel const char *name;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *nl = "";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if !defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ce;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char qmark = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (level <= 3)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ce = CE_WARN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ce = CE_CONT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (level == 4)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel qmark = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (dip) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel instance = ddi_get_instance(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* name = ddi_binding_name(dip); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel name = ddi_driver_name(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel instance = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel name = "";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel va_start(adx, fmt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* vcmn_err(ce, fmt, adx); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* vprintf(fmt, adx); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* prom_vprintf(fmt, adx); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) vsprintf(buf, fmt, adx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel va_end(adx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (buf[strlen(buf) - 1] != '\n')
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nl = "\n";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(CARDBUS_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_do_pprintf) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (dip) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (instance >= 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel prom_printf("%s(%d),0x%p: %s%s",
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh name, instance, (void *)dip,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh buf, nl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel prom_printf("%s,0x%p: %s%s", name,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh (void *)dip, buf, nl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel prom_printf("%s%s", buf, nl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (dip) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (instance >= 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "%s(%d),0x%p: %s%s",
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh name, instance, (void *)dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel buf, nl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "%s,0x%p: %s%s",
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh name, (void *)dip, buf, nl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "%s%s", buf, nl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(ce, qmark ? "?%s%d: %s%s" : "%s%d: %s%s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel name, instance, buf, nl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(ce, qmark ? "?%s%s" : "%s%s", buf, nl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void cardbus_expand_busrange(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_bus_range_t *bus_range;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pdip = ddi_get_parent(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getlongprop(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS, "bus-range",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&bus_range, &len) == DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_ra_request_t req;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t next_bus, blen;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t ret;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_acc_handle_t handle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (bus_range->lo != bus_range->hi)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(pdip, 1, "cardbus_expand_busrange: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%u -> %u\n", bus_range->lo, bus_range->hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_addr = bus_range->lo + 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_len = 12;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while ((req.ra_len > 0) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (ret = ndi_ra_alloc(ddi_get_parent(pdip), &req,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &next_bus, &blen, NDI_RA_TYPE_PCI_BUSNUM,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NDI_RA_PASS)) != NDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_len--;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ret != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(pdip, 1, "cardbus_expand_busrange: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "fail to allocate bus number\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto exit;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus_range->hi = bus_range->lo + req.ra_len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_prop_update_int_array(DDI_DEV_T_NONE, pdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "bus-range", (int *)bus_range, 2) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(pdip, 1, "cardbus_expand_busrange: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "fail to update bus-range property\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto exit;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pci_config_setup(pdip, &handle) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(pdip, 1, "cardbus_expand_busrange: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "fail to pci_config_setup\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto exit;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_put8(handle, PCI_BCNF_SECBUS, bus_range->lo);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_put8(handle, PCI_BCNF_SUBBUS, bus_range->hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(pdip, 1, "cardbus_expand_busrange: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "parent dip %u -> %u\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_get8(handle, PCI_BCNF_SECBUS),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_get8(handle, PCI_BCNF_SUBBUS));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_teardown(&handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_ra_map_setup(pdip, NDI_RA_TYPE_PCI_BUSNUM)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(pdip, 1, "cardbus_expand_busrange: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "fail to ndi_ra_map_setup of bus number\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto exit;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_ra_free(pdip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint64_t)bus_range->lo + 1, req.ra_len,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NDI_RA_TYPE_PCI_BUSNUM, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_len = 2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while ((req.ra_len > 0) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (ret = ndi_ra_alloc(pdip, &req,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &next_bus, &blen, NDI_RA_TYPE_PCI_BUSNUM,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0)) != NDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_len--;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_expand_busrange: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cardbus dip base %u length %d\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (int)next_bus, (int)req.ra_len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ret != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_expand_busrange: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "fail to allocate bus number of length %d "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "from parent\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (int)req.ra_len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto exit;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ndi_ra_map_setup(dip, NDI_RA_TYPE_PCI_BUSNUM)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel != NDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(dip, 1, "cardbus_expand_busrange: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "fail to ndi_ra_map_setup of bus numbers\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto exit;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ndi_ra_free(dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint64_t)next_bus, req.ra_len,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NDI_RA_TYPE_PCI_BUSNUM, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelexit:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(bus_range, len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_err(pdip, 1, "cardbus_expand_busrange: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "parent dip doesn't have busrange prop\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}