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
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Use is subject to license terms.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * PCIC device/interrupt handler
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The "pcic" driver handles the Intel 82365SL, Cirrus Logic
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and Toshiba (and possibly other clones) PCMCIA adapter chip
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * sets. It implements a subset of Socket Services as defined
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * in the Solaris PCMCIA design documents
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * currently defined "properties"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * clock-frequency bus clock frequency
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * smi system management interrupt override
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * need-mult-irq need status IRQ for each pair of sockets
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * disable-audio don't route audio signal to speaker
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/types.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/inttypes.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/param.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/systm.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/user.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/buf.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/file.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/uio.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/conf.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/stat.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/autoconf.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/vtoc.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/dkio.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/ddi.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/sunddi.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/sunndi.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/var.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/callb.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/open.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/ddidmareq.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/dma_engine.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/kstat.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/kmem.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/modctl.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pci.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pci_impl.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pctypes.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pcmcia.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/sservice.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/note.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pcic_reg.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pcic_var.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China#if defined(__i386) || defined(__amd64)
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China#include <sys/pci_cfgspace.h>
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China#endif
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(__sparc)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include <sys/pci/pci_nexus.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
0d282d1376eb7ba06504448622a6d65726e4bd3erw#include <sys/hotplug/hpcsvc.h>
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#include "cardbus/cardbus.h"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define SOFTC_SIZE (sizeof (anp_t))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_attach(dev_info_t *, ddi_attach_cmd_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_detach(dev_info_t *, ddi_detach_cmd_t);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fangstatic int32_t pcic_quiesce(dev_info_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint_t pcic_intr(caddr_t, caddr_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_do_io_intr(pcicdev_t *, uint32_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_probe(dev_info_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_open(dev_t *, int, int, cred_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_close(dev_t, int, int, cred_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afsteveltypedef struct pcm_regs pcm_regs_t;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_init_assigned(dev_info_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_apply_avail_ranges(dev_info_t *, pcm_regs_t *,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_regspec_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pci_resource_setup_avail(dev_info_t *, pci_regspec_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * On x86 platforms the ddi_iobp_alloc(9F) and ddi_mem_alloc(9F) calls
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * are xlated into DMA ctlops. To make this nexus work on x86, we
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * need to have the default ddi_dma_mctl ctlops in the bus_ops
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * structure, just to pass the request to the parent. The correct
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * ctlops should be ddi_no_dma_mctl because so far we don't do DMA.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstruct bus_ops pcmciabus_ops = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel BUSO_REV,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcmcia_bus_map,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel i_ddi_map_fault,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_no_dma_map,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_no_dma_allochdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_no_dma_freehdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_no_dma_bindhdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_no_dma_unbindhdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_no_dma_flush,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_no_dma_win,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_dma_mctl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcmcia_ctlops,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcmcia_prop_op,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_get_eventcookie)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_add_eventcall)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*bus_remove_eventcall)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL, /* (*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 pcmcia_intr_ops /* (*bus_intr_op)(); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct cb_ops pcic_cbops = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_open,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_close,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_ioctl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nodev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nochpoll,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_prop_op,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS
3db86aab554edbb4244c8d1a1c90f152eee768afstevel D_NEW | D_MP | D_HOTPLUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel D_NEW | D_MP
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct dev_ops pcic_devops = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DEVO_REV,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getinfo,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nulldev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_probe,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_attach,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_detach,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nulldev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &pcic_cbops,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &pcmciabus_ops,
193974072f41a843678abf5f61979c748687e66bSherry Moore NULL,
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang pcic_quiesce, /* devo_quiesce */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid *pcic_soft_state_p = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_maxinst = -1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_do_insertion = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_do_removal = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstruct irqmap {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int irq;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int count;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel} pcic_irq_map[16];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_debug = 0x0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_err(dev_info_t *dip, int level, const char *fmt, ...);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern void cardbus_dump_pci_config(dev_info_t *dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern void cardbus_dump_socket(dev_info_t *dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern int cardbus_validate_iline(dev_info_t *dip, ddi_acc_handle_t handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_dump_debqueue(char *msg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void xxdmp_all_regs(pcicdev_t *, int, uint32_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define pcic_mutex_enter(a) \
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { \
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(NULL, 10, "Set lock at %d\n", __LINE__); \
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(a); \
3db86aab554edbb4244c8d1a1c90f152eee768afstevel };
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define pcic_mutex_exit(a) \
3db86aab554edbb4244c8d1a1c90f152eee768afstevel { \
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(NULL, 10, "Clear lock at %d\n", __LINE__); \
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(a); \
3db86aab554edbb4244c8d1a1c90f152eee768afstevel };
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define pcic_mutex_enter(a) mutex_enter(a)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define pcic_mutex_exit(a) mutex_exit(a)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define PCIC_VCC_3VLEVEL 1
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define PCIC_VCC_5VLEVEL 2
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define PCIC_VCC_12LEVEL 3
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* bit patterns to select voltage levels */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_vpp_levels[13] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0, 0, 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 1, /* 3.3V */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 1, /* 5V */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0, 0, 0, 0, 0, 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 2 /* 12V */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afsteveluint8_t pcic_cbv_levels[13] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0, 0, 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 3, /* 3.3V */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 2, /* 5V */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0, 0, 0, 0, 0, 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 1 /* 12V */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstruct power_entry pcic_power[4] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0, VCC|VPP1|VPP2
3db86aab554edbb4244c8d1a1c90f152eee768afstevel },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 33, /* 3.3Volt */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel VCC|VPP1|VPP2
3db86aab554edbb4244c8d1a1c90f152eee768afstevel },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 5*10, /* 5Volt */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel VCC|VPP1|VPP2 /* currently only know about this */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel },
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 12*10, /* 12Volt */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel VPP1|VPP2
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Base used to allocate ranges of PCI memory on x86 systems
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Each instance gets a chunk above the base that is used to map
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * in the memory and I/O windows for that device.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Pages below the base are also allocated for the EXCA registers,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * one per instance.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#define PCIC_PCI_MEMCHUNK 0x1000000
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_wait_insert_time = 5000000; /* In micro-seconds */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_debounce_time = 200000; /* In micro-seconds */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstruct debounce {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *pcs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clock_t expire;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct debounce *next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct debounce *pcic_deb_queue = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic kmutex_t pcic_deb_mtx;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic kcondvar_t pcic_deb_cv;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic kthread_t *pcic_deb_threadid;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic inthandler_t *pcic_handlers;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_setup_adapter(pcicdev_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_change(pcicdev_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_ll_reset(pcicdev_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_mswait(pcicdev_t *, int, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic boolean_t pcic_check_ready(pcicdev_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_set_cdtimers(pcicdev_t *, int, uint32_t, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_ready_wait(pcicdev_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern int pcmcia_get_intr(dev_info_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelextern int pcmcia_return_intr(dev_info_t *, int);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwextern void pcmcia_cb_suspended(int);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwextern void pcmcia_cb_resumed(int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_callback(dev_info_t *, int (*)(), int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_inquire_adapter(dev_info_t *, inquire_adapter_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_get_adapter(dev_info_t *, get_adapter_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_get_page(dev_info_t *, get_page_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_get_socket(dev_info_t *, get_socket_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_get_status(dev_info_t *, get_ss_status_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_get_window(dev_info_t *, get_window_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_inquire_socket(dev_info_t *, inquire_socket_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_inquire_window(dev_info_t *, inquire_window_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_reset_socket(dev_info_t *, int, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_set_page(dev_info_t *, set_page_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_set_window(dev_info_t *, set_window_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_set_socket(dev_info_t *, set_socket_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_set_interrupt(dev_info_t *, set_irq_handler_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_clear_interrupt(dev_info_t *, clear_irq_handler_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_pm_detection(void *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_iomem_pci_ctl(ddi_acc_handle_t, uchar_t *, unsigned);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int clext_reg_read(pcicdev_t *, int, uchar_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void clext_reg_write(pcicdev_t *, int, uchar_t, uchar_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_calc_speed(pcicdev_t *, uint32_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_card_state(pcicdev_t *, pcic_socket_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_find_pci_type(pcicdev_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_82092_smiirq_ctl(pcicdev_t *, int, int, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_handle_cd_change(pcicdev_t *, pcic_socket_t *, uint8_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint_t pcic_cd_softint(caddr_t, caddr_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint8_t pcic_getb(pcicdev_t *, int, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_putb(pcicdev_t *, int, int, int8_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_set_vcc_level(pcicdev_t *, set_socket_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint_t pcic_softintr(caddr_t, caddr_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_debounce(pcic_socket_t *);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwstatic void pcic_do_resume(pcicdev_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void *pcic_add_debqueue(pcic_socket_t *, int);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_rm_debqueue(void *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_deb_thread();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic boolean_t pcic_load_cardbus(pcicdev_t *pcic, const pcic_socket_t *sockp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_unload_cardbus(pcicdev_t *pcic, const pcic_socket_t *sockp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint32_t pcic_getcb(pcicdev_t *pcic, int reg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_putcb(pcicdev_t *pcic, int reg, uint32_t value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_cb_enable_intr(dev_info_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_cb_disable_intr(dev_info_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_enable_io_intr(pcicdev_t *pcic, int socket, int irq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void pcic_disable_io_intr(pcicdev_t *pcic, int socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic cb_nexus_cb_t pcic_cbnexus_ops = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_cb_enable_intr,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_cb_disable_intr
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_exca_powerctl(pcicdev_t *pcic, int socket, int powerlevel);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_cbus_powerctl(pcicdev_t *pcic, int socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(__sparc)
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_fault(enum pci_fault_ops op, void *arg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcmcia interface operations structure
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this is the private interface that is exported to the nexus
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcmcia_if_t pcic_if_ops = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIF_MAGIC,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIF_VERSION,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_callback,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_get_adapter,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_get_page,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_get_socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_get_status,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_get_window,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_inquire_adapter,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_inquire_socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_inquire_window,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_reset_socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_set_page,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_set_window,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_set_socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_set_interrupt,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_clear_interrupt,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * chip type identification routines
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this list of functions is searched until one of them succeeds
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * or all fail. i82365SL is assumed if failed.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_ci_cirrus(pcicdev_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_ci_vadem(pcicdev_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_ci_ricoh(pcicdev_t *);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint (*pcic_ci_funcs[])(pcicdev_t *) = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_ci_cirrus,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_ci_vadem,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_ci_ricoh,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct modldrv modldrv = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &mod_driverops, /* Type of module. This one is a driver */
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh "PCIC PCMCIA adapter driver", /* Name of the module. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &pcic_devops, /* driver ops */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct modlinkage modlinkage = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel MODREV_1, (void *)&modldrv, NULL
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel_init()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int stat;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Allocate soft state */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((stat = ddi_soft_state_init(&pcic_soft_state_p,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel SOFTC_SIZE, 2)) != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (stat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((stat = mod_install(&modlinkage)) != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_soft_state_fini(&pcic_soft_state_p);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (stat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel_fini()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int stat = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((stat = mod_remove(&modlinkage)) != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (stat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_deb_threadid) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_deb_threadid = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (!pcic_deb_threadid)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cv_wait(&pcic_deb_cv, &pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_deb_threadid = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cv_destroy(&pcic_deb_cv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_soft_state_fini(&pcic_soft_state_p);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (stat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel_info(struct modinfo *modinfop)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (mod_info(&modlinkage, modinfop));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_getinfo()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * provide instance/device information about driver
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int error = DDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel minor_t minor;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (cmd) {
193974072f41a843678abf5f61979c748687e66bSherry Moore case DDI_INFO_DEVT2DEVINFO:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel minor = getminor((dev_t)arg);
459fbba0bc115fe006d3634487b686fa707e1fbfgd minor &= 0x7f;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(anp = ddi_get_soft_state(pcic_soft_state_p, minor)))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *result = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *result = anp->an_dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case DDI_INFO_DEVT2INSTANCE:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel minor = getminor((dev_t)arg);
459fbba0bc115fe006d3634487b686fa707e1fbfgd minor &= 0x7f;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *result = (void *)((long)minor);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel error = DDI_FAILURE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (error);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_probe(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_device_acc_attr_t attr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_acc_handle_t handle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uchar_t *index, *data;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_dev_is_sid(dip) == DDI_SUCCESS)
193974072f41a843678abf5f61979c748687e66bSherry Moore return (DDI_PROBE_DONTCARE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * find a PCIC device (any vendor)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * while there can be up to 4 such devices in
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * a system, we currently only look for 1
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * per probe. There will be up to 2 chips per
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * instance since they share I/O space
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_regs_map_setup(dip, PCIC_ISA_CONTROL_REG_NUM,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&index,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_ISA_CONTROL_REG_OFFSET,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_ISA_CONTROL_REG_LENGTH,
193974072f41a843678abf5f61979c748687e66bSherry Moore &attr, &handle) != DDI_SUCCESS)
193974072f41a843678abf5f61979c748687e66bSherry Moore return (DDI_PROBE_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel data = index + 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_probe: entered\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tindex=%p\n", (void *)index);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(handle, index, PCIC_CHIP_REVISION);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(handle, data, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ddi_get8(handle, data);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tchip revision register = %x\n", value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((value & PCIC_REV_MASK) >= PCIC_REV_LEVEL_LOW &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (value & 0x30) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we probably have a PCIC chip in the system
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * do a little more checking. If we find one,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * reset everything in case of softboot
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(handle, index, PCIC_MAPPING_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(handle, data, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ddi_get8(handle, data);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tzero test = %x\n", value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* should read back as zero */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we do have one and it is off the bus
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_probe: success\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_PROBE_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_probe: failed\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_PROBE_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * These are just defaults they can also be changed via a property in the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * conf file.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pci_config_reg_num = PCIC_PCI_CONFIG_REG_NUM;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pci_control_reg_num = PCIC_PCI_CONTROL_REG_NUM;
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwstatic int pcic_do_pcmcia_sr = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_use_cbpwrctl = PCF_CBPWRCTL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * enable insertion/removal interrupt for 32bit cards
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelcardbus_enable_cd_intr(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_acc_handle_t iohandle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel caddr_t ioaddr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_device_acc_attr_t attr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_regs_map_setup(dip, 1,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&ioaddr,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore 4096,
193974072f41a843678abf5f61979c748687e66bSherry Moore &attr, &iohandle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* CSC Interrupt: Card detect interrupt on */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put32(iohandle, (uint32_t *)(ioaddr+CB_STATUS_MASK),
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get32(iohandle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(ioaddr+CB_STATUS_MASK)) | CB_SE_CCDMASK);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put32(iohandle, (uint32_t *)(ioaddr+CB_STATUS_EVENT),
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get32(iohandle, (uint32_t *)(ioaddr+CB_STATUS_EVENT)));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&iohandle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang/*
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * quiesce(9E) entry point.
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang *
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * This function is called when the system is single-threaded at high
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * PIL with preemption disabled. Therefore, this function must not be
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * blocked.
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang *
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang * DDI_FAILURE indicates an error condition and should almost never happen.
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang */
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fangstatic int32_t
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fangpcic_quiesce(dev_info_t *dip)
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang{
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang anp_t *anp = ddi_get_driver_private(dip);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang pcicdev_t *pcic = anp->an_private;
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang int i;
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang for (i = 0; i < pcic->pc_numsockets; i++) {
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang pcic_putb(pcic, i, PCIC_MANAGEMENT_INT, 0);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang pcic_putb(pcic, i, PCIC_CARD_DETECT, 0);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang pcic_putb(pcic, i, PCIC_MAPPING_ENABLE, 0);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang /* disable interrupts and put card into RESET */
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang pcic_putb(pcic, i, PCIC_INTERRUPT, 0);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang /* poweroff socket */
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang pcic_putb(pcic, i, PCIC_POWER_CONTROL, 0);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang pcic_putcb(pcic, CB_CONTROL, 0);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang }
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang return (DDI_SUCCESS);
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang}
5644143a6cf1e70bc2e78d5140970830aae0e8cdQuaker Fang
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_attach()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * attach the PCIC (Intel 82365SL/CirrusLogic/Toshiba) driver
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to the system. This is a child of "sysbus" since that is where
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the hardware lives, but it provides services to the "pcmcia"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * nexus driver. It gives a pointer back via its private data
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * structure which contains both the dip and socket services entry
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * points
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *pcic_nexus;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int irqlevel, value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int pci_cfrn, pci_ctrn;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i, j, smi, actual;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *typename;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char bus_type[16] = "(unknown)";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int len = sizeof (bus_type);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_device_acc_attr_t attr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t pri;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_attach: entered\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_ATTACH:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_RESUME:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * for now, this is a simulated resume.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * a real one may need different things.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic != NULL && pcic->pc_flags & PCF_SUSPENDED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* should probe for new sockets showing up */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_setup_adapter(pcic);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags &= ~PCF_SUSPENDED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcmcia_begin_resume(dip);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw pcic_do_resume(pcic);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw#ifdef CARDBUS
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw cardbus_restore_children(ddi_get_child(dip));
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * for complete implementation need END_RESUME (later)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Allocate soft state associated with this instance.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_soft_state_zalloc(pcic_soft_state_p,
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip)) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic%d: Unable to alloc state\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_nexus = ddi_get_soft_state(pcic_soft_state_p,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic = kmem_zalloc(sizeof (pcicdev_t), KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->dip = dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_nexus->an_dip = dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_nexus->an_if = &pcic_if_ops;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_nexus->an_private = pcic;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_numpower = sizeof (pcic_power)/sizeof (pcic_power[0]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_power = pcic_power;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_ctrn = ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_CANSLEEP,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pci-control-reg-number", pci_control_reg_num);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_cfrn = ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_CANSLEEP,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pci-config-reg-number", pci_config_reg_num);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_set_driver_private(dip, pcic_nexus);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic->pc_irq is really the IPL level we want to run at
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * set the default values here and override from intr spec
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_irq = ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_CANSLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore "interrupt-priorities", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_irq == -1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int actual;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t pri;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_intr_handle_t hdl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* see if intrspec tells us different */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_intr_alloc(dip, &hdl, DDI_INTR_TYPE_FIXED,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel 0, 1, &actual, DDI_INTR_ALLOC_NORMAL) == DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_intr_get_pri(hdl, &pri) == DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_irq = pri;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_irq = LOCK_LEVEL + 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_free(hdl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_nexus->an_ipl = pcic->pc_irq;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Check our parent bus type. We do different things based on which
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * bus we're on.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_op(DDI_DEV_T_ANY, ddi_get_parent(dip),
193974072f41a843678abf5f61979c748687e66bSherry Moore PROP_LEN_AND_VAL_BUF, DDI_PROP_CANSLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore "device_type", (caddr_t)&bus_type[0], &len) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_prop_op(DDI_DEV_T_ANY, ddi_get_parent(dip),
193974072f41a843678abf5f61979c748687e66bSherry Moore PROP_LEN_AND_VAL_BUF, DDI_PROP_CANSLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore "bus-type", (caddr_t)&bus_type[0], &len) !=
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic%d: can't find parent bus type\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
b8a60a54bb33ac7b5184fd07e6a63ae6d365fd69rw ddi_soft_state_free(pcic_soft_state_p,
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* ddi_prop_op("device_type") */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
8134ee03588a08f05c327533a618d35625381520rw if (strcmp(bus_type, DEVI_PCI_NEXNAME) == 0 ||
193974072f41a843678abf5f61979c748687e66bSherry Moore strcmp(bus_type, DEVI_PCIEX_NEXNAME) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags = PCF_PCIBUS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
b8a60a54bb33ac7b5184fd07e6a63ae6d365fd69rw cmn_err(CE_WARN, "!pcic%d: non-pci mode (%s) not supported, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "set BIOS to yenta mode if applicable\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip), bus_type);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
b8a60a54bb33ac7b5184fd07e6a63ae6d365fd69rw ddi_soft_state_free(pcic_soft_state_p,
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((pcic->bus_speed = ddi_getprop(DDI_DEV_T_ANY, ddi_get_parent(dip),
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_PROP_CANSLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore "clock-frequency", 0)) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_PCIBUS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->bus_speed = PCIC_PCI_DEF_SYSCLK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->bus_speed = PCIC_ISA_DEF_SYSCLK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * OBP can declare the speed in Hz...
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->bus_speed > 1000000)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->bus_speed /= 1000000;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* ddi_prop_op("clock-frequency") */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_io_type = PCIC_IO_TYPE_82365SL; /* default mode */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic%d: parent bus type = [%s], speed = %d MHz\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip),
193974072f41a843678abf5f61979c748687e66bSherry Moore bus_type, pcic->bus_speed);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The reg properties on a PCI node are different than those
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * on a non-PCI node. Handle that difference here.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If it turns out to be a CardBus chip, we have even more
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * differences.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_PCIBUS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int class_code;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(__i386) || defined(__amd64)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_base = 0x1000000;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_bound = (uint32_t)~0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_iobase = 0x1000;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_iobound = 0xefff;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#elif defined(__sparc)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_base = 0x0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_bound = (uint32_t)~0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_iobase = 0x00000;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_iobound = 0xffff;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* usually need to get at config space so map first */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_regs_map_setup(dip, pci_cfrn,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&pcic->cfgaddr,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_PCI_CONFIG_REG_OFFSET,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_PCI_CONFIG_REG_LENGTH,
193974072f41a843678abf5f61979c748687e66bSherry Moore &attr,
193974072f41a843678abf5f61979c748687e66bSherry Moore &pcic->cfg_handle) !=
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic%d: unable to map config space"
193974072f41a843678abf5f61979c748687e66bSherry Moore "regs\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* ddi_regs_map_setup */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel class_code = ddi_getprop(DDI_DEV_T_ANY, dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_PROP_CANSLEEP|DDI_PROP_DONTPASS,
193974072f41a843678abf5f61979c748687e66bSherry Moore "class-code", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_attach class_code=%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel class_code);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (class_code) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_PCI_CARDBUS:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_CARDBUS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_io_type = PCIC_IO_TYPE_YENTA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get access to the adapter registers on the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * PCI bus. A 4K memory page
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(dip, 8, "Is Cardbus device\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int nr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel long rs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_dev_nregs(dip, &nr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(dip, 9, "\tdev, cfgaddr 0x%p,"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cfghndl 0x%p nregs %d",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *)pcic->cfgaddr,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *)pcic->cfg_handle, nr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_dev_regsize(dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_PCI_CONTROL_REG_NUM, &rs);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(dip, 9, "\tsize of reg %d is 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_PCI_CONTROL_REG_NUM, (int)rs);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_regs_map_setup(dip, pci_ctrn,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&pcic->ioaddr,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_PCI_CONTROL_REG_OFFSET,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CB_CONTROL_REG_LENGTH,
193974072f41a843678abf5f61979c748687e66bSherry Moore &attr, &pcic->handle) !=
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic%d: unable to map PCI regs\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->cfg_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* ddi_regs_map_setup */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Find out the chip type - If we're on a PCI bus,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the adapter has that information in the PCI
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * config space.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Note that we call pcic_find_pci_type here since
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * it needs a valid mapped pcic->handle to
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * access some of the adapter registers in
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * some cases.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_find_pci_type(pcic) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->cfg_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "pcic: %s: unsupported "
193974072f41a843678abf5f61979c748687e66bSherry Moore "bridge\n", ddi_get_name_addr(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_PCI_PCMCIA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Get access to the adapter IO registers on the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * PCI bus config space.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We need a default mapping to the adapter's IO
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * control register space. For most adapters
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * that are of class PCIC_PCI_PCMCIA (or of
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * a default class) the control registers
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * will be using the 82365-type control/data
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * format.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_regs_map_setup(dip, pci_ctrn,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&pcic->ioaddr,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_PCI_CONTROL_REG_OFFSET,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_PCI_CONTROL_REG_LENGTH,
193974072f41a843678abf5f61979c748687e66bSherry Moore &attr,
193974072f41a843678abf5f61979c748687e66bSherry Moore &pcic->handle) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic%d: unable to map PCI regs\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->cfg_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* ddi_regs_map_setup */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Find out the chip type - If we're on a PCI bus,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the adapter has that information in the PCI
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * config space.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Note that we call pcic_find_pci_type here since
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * it needs a valid mapped pcic->handle to
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * access some of the adapter registers in
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * some cases.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_find_pci_type(pcic) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->cfg_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "pcic: %s: unsupported "
193974072f41a843678abf5f61979c748687e66bSherry Moore "bridge\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_name_addr(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Some PCI-PCMCIA(R2) adapters are Yenta-compliant
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * for extended registers even though they are
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * not CardBus adapters. For those adapters,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * re-map pcic->handle to be large enough to
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * encompass the Yenta registers.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1031:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_regs_map_setup(dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_PCI_CONTROL_REG_NUM,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&pcic->ioaddr,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_PCI_CONTROL_REG_OFFSET,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CB_CONTROL_REG_LENGTH,
193974072f41a843678abf5f61979c748687e66bSherry Moore &attr,
193974072f41a843678abf5f61979c748687e66bSherry Moore &pcic->handle) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic%d: unable to map "
193974072f41a843678abf5f61979c748687e66bSherry Moore "PCI regs\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->cfg_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* ddi_regs_map_setup */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch (pcic->pc_type) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch (class_code) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We're not on a PCI bus, so assume an ISA bus type
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * register property. Get access to the adapter IO
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * registers on a non-PCI bus.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->mem_reg_num = PCIC_ISA_MEM_REG_NUM;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->io_reg_num = PCIC_ISA_IO_REG_NUM;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_regs_map_setup(dip, PCIC_ISA_CONTROL_REG_NUM,
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&pcic->ioaddr,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_ISA_CONTROL_REG_OFFSET,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_ISA_CONTROL_REG_LENGTH,
193974072f41a843678abf5f61979c748687e66bSherry Moore &attr,
193974072f41a843678abf5f61979c748687e66bSherry Moore &pcic->handle) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic%d: unable to map ISA registers\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* ddi_regs_map_setup */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* ISA bus is limited to 24-bits, but not first 640K */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_base = 0xd0000;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_bound = (uint32_t)~0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_iobase = 0x1000;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_iobound = 0xefff;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* !PCF_PCIBUS */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_attach pc_flags=%x pc_type=%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags, pcic->pc_type);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Setup various adapter registers for the PCI case. For the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * non-PCI case, find out the chip type.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_PCIBUS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int iline;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(__sparc)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel iline = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel iline = cardbus_validate_iline(dip, pcic->cfg_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* set flags and socket counts based on chip type */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t cfg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_82092_PCICON);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* we can only support 4 Socket version */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cfg & PCIC_82092_4_SOCKETS) {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_numsockets = 4;
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_type = PCIC_INTEL_i82092;
193974072f41a843678abf5f61979c748687e66bSherry Moore if (iline != 0xFF)
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_intr_mode =
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_INTR_MODE_PCI_1;
193974072f41a843678abf5f61979c748687e66bSherry Moore else
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_intr_mode = PCIC_INTR_MODE_ISA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
193974072f41a843678abf5f61979c748687e66bSherry Moore cmn_err(CE_CONT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic%d: Intel 82092 adapter "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "in unsupported configuration: 0x%x",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_instance(pcic->dip), cfg);
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_numsockets = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* PCIC_82092_4_SOCKETS */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6730:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6729:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_intr_mode = PCIC_INTR_MODE_PCI_1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_getprop(DDI_DEV_T_ANY, dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_PROP_CANSLEEP,
193974072f41a843678abf5f61979c748687e66bSherry Moore "interrupts", 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* if not interrupt pin then must use ISA style IRQs */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cfg == 0 || iline == 0xFF)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_intr_mode = PCIC_INTR_MODE_ISA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we have the option to use PCI interrupts.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this might not be optimal but in some cases
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is the only thing possible (sparc case).
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we now deterine what is possible.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_intr_mode = PCIC_INTR_MODE_PCI_1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_numsockets = 2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_IO_REMAP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1031:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* this chip doesn't do CardBus but looks like one */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags &= ~PCF_CARDBUS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* FALLTHROUGH */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_IO_REMAP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* FALLTHROUGH */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* indicate feature even if not supported */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_DMA | PCF_ZV;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Not sure if these apply to all these chips */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= (PCF_VPPX|PCF_33VCAP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= pcic_use_cbpwrctl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_numsockets = 1; /* one per function */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (iline != 0xFF) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t cfg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_intr_mode = PCIC_INTR_MODE_PCI_1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (pcic->cfgaddr + PCIC_BRIDGE_CTL_REG));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg &= (~PCIC_FUN_INT_MOD_ISA);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle, (pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_BRIDGE_CTL_REG), cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_intr_mode = PCIC_INTR_MODE_ISA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_io_type = PCIC_IOTYPE_YENTA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We're not on a PCI bus so do some more
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * checking for adapter type here.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * For the non-PCI bus case:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * It could be any one of a number of different chips
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If we can't determine anything else, it is assumed
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to be an Intel 82365SL. The Cirrus Logic PD6710
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * has an extension register that provides unique
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * identification. Toshiba chip isn't detailed as yet.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Init the CL id mode */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, 0, PCIC_CHIP_INFO, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, 0, PCIC_CHIP_INFO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* default to Intel i82365SL and then refine */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_I82365SL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_I82365SL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (value = 0; pcic_ci_funcs[value] != NULL; value++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* go until one succeeds or none left */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_ci_funcs[value](pcic))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* any chip specific flags get set here */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6722:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_DMA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < PCIC_MAX_SOCKETS; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * look for total number of sockets.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * basically check each possible socket for
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * presence like in probe
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* turn all windows off */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MAPPING_ENABLE, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, i, PCIC_MAPPING_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if a zero is read back, then this socket
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * might be present. It would be except for
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * some systems that map the secondary PCIC
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * chip space back to the first.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* definitely not so skip */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* note: this is for Compaq support */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* further tests */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, i, PCIC_CHIP_REVISION) &
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_REV_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(value >= PCIC_REV_LEVEL_LOW &&
193974072f41a843678abf5f61979c748687e66bSherry Moore value <= PCIC_REV_LEVEL_HI))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_SYSMEM_0_STARTLOW, 0xaa);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_SYSMEM_1_STARTLOW, 0x55);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, i, PCIC_SYSMEM_0_STARTLOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j = pcic_getb(pcic, i, PCIC_SYSMEM_1_STARTLOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value != 0xaa || j != 0x55)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * at this point we know if we have hardware
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * of some type and not just the bus holding
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * a pattern for us. We still have to determine
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the case where more than 2 sockets are
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * really the same due to peculiar mappings of
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * hardware.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j = pcic->pc_numsockets++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[j].pcs_flags = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[j].pcs_io = pcic->ioaddr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[j].pcs_socket = i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* put PC Card into RESET, just in case */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, i, PCIC_INTERRUPT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_INTERRUPT,
193974072f41a843678abf5f61979c748687e66bSherry Moore value & ~PCIC_RESET);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "num sockets = %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_numsockets);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_numsockets == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * need to think this through again in light of
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Compaq not following the model that all the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * chip vendors recommend. IBM 755 seems to be
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * afflicted as well. Basically, if the vendor
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * wired things wrong, socket 0 responds for socket 2
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * accesses, etc.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_numsockets > 2) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int count = pcic->pc_numsockets / 4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < count; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* put pattern into socket 0 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_SYSMEM_0_STARTLOW, 0x11);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* put pattern into socket 2 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i + 2,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_SYSMEM_0_STARTLOW, 0x33);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* read back socket 0 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, i,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_SYSMEM_0_STARTLOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* read back chip 1 socket 0 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j = pcic_getb(pcic, i + 2,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_SYSMEM_0_STARTLOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (j == value) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_numsockets -= 2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel smi = 0xff; /* no more override */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getprop(DDI_DEV_T_NONE, dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_PROP_DONTPASS, "need-mult-irq",
193974072f41a843678abf5f61979c748687e66bSherry Moore 0xffff) != 0xffff)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_MULT_IRQ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* !PCF_PCIBUS */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * some platforms/busses need to have resources setup
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this is temporary until a real resource allocator is
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * implemented.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_init_assigned(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel typename = pcic->pc_chipname;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int nregs, nintrs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_dev_nregs(dip, &nregs) != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nregs = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_dev_nintrs(dip, &nintrs) != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nintrs = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic%d: %d register sets, %d interrupts\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(dip), nregs, nintrs);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nintrs = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (nregs--) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel off_t size;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_dev_regsize(dip, nintrs, &size) ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tregnum %d size %ld (0x%lx)"
193974072f41a843678abf5f61979c748687e66bSherry Moore "bytes",
193974072f41a843678abf5f61979c748687e66bSherry Moore nintrs, size, size);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (nintrs ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (pcic->pc_io_type == PCIC_IO_TYPE_82365SL ?
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_ISA_CONTROL_REG_NUM :
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_PCI_CONTROL_REG_NUM))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore " mapped at: 0x%p\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic->ioaddr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tddi_dev_regsize(rnumber"
193974072f41a843678abf5f61979c748687e66bSherry Moore "= %d) returns DDI_FAILURE\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore nintrs);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nintrs++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* while */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* if (pcic_debug) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cv_init(&pcic->pm_cv, NULL, CV_DRIVER, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!ddi_getprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
193974072f41a843678abf5f61979c748687e66bSherry Moore "disable-audio", 0))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_AUDIO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_CANSLEEP,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "disable-cardbus", 0))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags &= ~PCF_CARDBUS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_prop_update_string(DDI_DEV_T_NONE, dip, PCICPROP_CTL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel typename);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Init all socket SMI levels to 0 (no SMI)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < PCIC_MAX_SOCKETS; i++) {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_sockets[i].pcs_smi = 0;
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_sockets[i].pcs_debounce_id = 0;
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_sockets[i].pcs_pcic = pcic;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_lastreg = -1; /* just to make sure we are in sync */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Setup the IRQ handler(s)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_intr_mode) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int xx;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_ISA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * On a non-PCI bus, we just use whatever SMI IRQ level was
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * specified above, and the IO IRQ levels are allocated
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * dynamically.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (xx = 15, smi = 0; xx >= 0; xx--) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (PCIC_IRQ(xx) &
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_AVAIL_IRQS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel smi = pcmcia_get_intr(dip, xx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (smi >= 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE, "\tselected IRQ %d as SMI\n", smi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* init to same so share is easy */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < pcic->pc_numsockets; i++)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_smi = smi;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* any special handling of IRQ levels */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_MULT_IRQ) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 2; i < pcic->pc_numsockets; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((i & 1) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int xx;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (xx = 15, smi = 0; xx >= 0; xx--) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (PCIC_IRQ(xx) &
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_AVAIL_IRQS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel smi =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcmcia_get_intr(dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore xx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (smi >= 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (smi >= 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_smi = smi;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_intr_htblp = kmem_alloc(pcic->pc_numsockets *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (ddi_intr_handle_t), KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0, irqlevel = -1; i < pcic->pc_numsockets; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct intrspec *ispecp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct ddi_parent_private_data *pdp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (irqlevel == pcic->pc_sockets[i].pcs_smi)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irqlevel = pcic->pc_sockets[i].pcs_smi;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * now convert the allocated IRQ into an intrspec
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and ask our parent to add it. Don't use
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the ddi_add_intr since we don't have a
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * default intrspec in all cases.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * note: this sort of violates DDI but we don't
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * get hardware intrspecs for many of the devices.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * at the same time, we know how to allocate them
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * so we do the right thing.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_intr_alloc(dip, &pcic->pc_intr_htblp[i],
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_INTR_TYPE_FIXED, 0, 1, &actual,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_INTR_ALLOC_NORMAL) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s: ddi_intr_alloc failed",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_name(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto isa_exit1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * See earlier note:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Since some devices don't have 'intrspec'
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we make one up in rootnex.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * However, it is not properly initialized as
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the data it needs is present in this driver
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and there is no interface to pass that up.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Specially 'irqlevel' is very important and
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * it is part of pcic struct.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Set 'intrspec' up here; otherwise adding the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * interrupt will fail.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pdp = ddi_get_parent_data(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ispecp = (struct intrspec *)&pdp->par_intr[0];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ispecp->intrspec_vec = irqlevel;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ispecp->intrspec_pri = pcic->pc_irq;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Stay compatible w/ PCMCIA */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_pri = (ddi_iblock_cookie_t)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uintptr_t)pcic->pc_irq;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_dcookie.idev_priority =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uintptr_t)pcic->pc_pri;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_dcookie.idev_vector = (ushort_t)irqlevel;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_set_pri(pcic->pc_intr_htblp[i],
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_irq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (i == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_init(&pcic->intr_lock, NULL, MUTEX_DRIVER,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_INTR_PRI(pcic->pc_irq));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_init(&pcic->pc_lock, NULL, MUTEX_DRIVER,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_intr_add_handler(pcic->pc_intr_htblp[i],
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_intr, (caddr_t)pcic, NULL)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%s: ddi_intr_add_handler failed",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_name(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto isa_exit2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_intr_enable(pcic->pc_intr_htblp[i])) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s: ddi_intr_enable failed",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_name(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (j = i; j < 0; j--)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_remove_handler(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_intr_htblp[j]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto isa_exit2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_PCI_1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_PCI:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If we're on a PCI bus, we route all interrupts, both SMI
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and IO interrupts, through a single interrupt line.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Assign the SMI IRQ level to the IO IRQ level here.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_pci_intr_hdlp = kmem_alloc(sizeof (ddi_intr_handle_t),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_intr_alloc(dip, pcic->pc_pci_intr_hdlp,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_INTR_TYPE_FIXED, 0, 1, &actual,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_INTR_ALLOC_NORMAL) != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto pci_exit1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_intr_get_pri(pcic->pc_pci_intr_hdlp[0],
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &pri) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_free(pcic->pc_pci_intr_hdlp[0]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto pci_exit1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_pri = (void *)(uintptr_t)pri;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_init(&pcic->intr_lock, NULL, MUTEX_DRIVER, pcic->pc_pri);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_init(&pcic->pc_lock, NULL, MUTEX_DRIVER, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_intr_add_handler(pcic->pc_pci_intr_hdlp[0],
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_intr, (caddr_t)pcic, NULL))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto pci_exit2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_intr_enable(pcic->pc_pci_intr_hdlp[0])) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_remove_handler(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_pci_intr_hdlp[0]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto pci_exit2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Stay compatible w/ PCMCIA */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_dcookie.idev_priority = (ushort_t)pri;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* init to same (PCI) so share is easy */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < pcic->pc_numsockets; i++)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_smi = 0xF; /* any valid */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Setup the adapter hardware to some reasonable defaults.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* mark the driver state as attached */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_ATTACHED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_setup_adapter(pcic);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (j = 0; j < pcic->pc_numsockets; j++)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_intr_add_softint(dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &pcic->pc_sockets[j].pcs_cd_softint_hdl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_SOFTINT_PRI_VAL, pcic_cd_softint,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&pcic->pc_sockets[j]) != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto pci_exit2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "type = %s sockets = %d\n", typename,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_numsockets);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_nexus->an_iblock = &pcic->pc_pri;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_nexus->an_idev = &pcic->pc_dcookie;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) cardbus_enable_cd_intr(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dump_pci_config(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dump_socket(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Give the Cardbus misc module a chance to do it's per-adapter
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * instance setup. Note that there is no corresponding detach()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * call.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_CARDBUS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_attach(dip, &pcic_cbnexus_ops) != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_attach: cardbus_attach failed\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto pci_exit2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Give the PCMCIA misc module a chance to do it's per-adapter
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * instance setup.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((i = pcmcia_attach(dip, pcic_nexus)) != DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto pci_exit2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_maxinst == -1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* This assumes that all instances run at the same IPL. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_init(&pcic_deb_mtx, NULL, MUTEX_DRIVER, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cv_init(&pcic_deb_cv, NULL, CV_DRIVER, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_deb_threadid = thread_create((caddr_t)NULL, 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_deb_thread, (caddr_t)NULL, 0, &p0, TS_RUN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel v.v_maxsyspri - 2);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_maxinst = max(pcic_maxinst, ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Setup a debounce timeout to do an initial card detect
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and enable interrupts.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (j = 0; j < pcic->pc_numsockets; j++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[j].pcs_debounce_id =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_add_debqueue(&pcic->pc_sockets[j],
193974072f41a843678abf5f61979c748687e66bSherry Moore drv_usectohz(pcic_debounce_time));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelisa_exit2:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (j = i; j < 0; j--)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_free(pcic->pc_intr_htblp[j]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelisa_exit1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcmcia_return_intr(dip, pcic->pc_sockets[i].pcs_smi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_PCIBUS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->cfg_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic->pc_intr_htblp, pcic->pc_numsockets *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sizeof (ddi_intr_handle_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpci_exit2:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_free(pcic->pc_pci_intr_hdlp[0]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpci_exit1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_PCIBUS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&pcic->cfg_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic->pc_pci_intr_hdlp, sizeof (ddi_intr_handle_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_detach()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * request to detach from the system
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (cmd) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_DETACH:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* don't detach if the nexus still talks to us */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_callback != NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* kill off the pm simulation */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_pmtimer)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) untimeout(pcic->pc_pmtimer);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* turn everything off for all sockets and chips */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < pcic->pc_numsockets; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_sockets[i].pcs_debounce_id)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_rm_debqueue(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_debounce_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_debounce_id = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MANAGEMENT_INT, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_CARD_DETECT, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MAPPING_ENABLE, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* disable interrupts and put card into RESET */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_INTERRUPT, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_disable(pcic->pc_pci_intr_hdlp[0]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_remove_handler(pcic->pc_pci_intr_hdlp[0]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_free(pcic->pc_pci_intr_hdlp[0]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic->pc_pci_intr_hdlp, sizeof (ddi_intr_handle_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_destroy(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cv_destroy(&pcic->pm_cv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_PCIBUS)
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_regs_map_free(&pcic->cfg_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->handle)
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_regs_map_free(&pcic->handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic, sizeof (pcicdev_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_soft_state_free(pcic_soft_state_p, ddi_get_instance(dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_SUSPEND:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case DDI_PM_SUSPEND:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we got a suspend event (either real or imagined)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * so notify the nexus proper that all existing cards
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * should go away.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (pcic->pc_flags & PCF_CARDBUS) {
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw for (i = 0; i < pcic->pc_numsockets; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((pcic->pc_sockets[i].pcs_flags &
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (PCS_CARD_PRESENT|PCS_CARD_ISCARDBUS)) ==
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw (PCS_CARD_PRESENT|PCS_CARD_ISCARDBUS)) {
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw pcmcia_cb_suspended(
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_sockets[i].pcs_socket);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw }
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw }
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw cardbus_save_children(ddi_get_child(dip));
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* turn everything off for all sockets and chips */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < pcic->pc_numsockets; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_sockets[i].pcs_debounce_id)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_rm_debqueue(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_debounce_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_debounce_id = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MANAGEMENT_INT, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_CARD_DETECT, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MAPPING_ENABLE, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* disable interrupts and put card into RESET */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_INTERRUPT, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_POWER_CONTROL, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_CBPWRCTL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putcb(pcic, CB_CONTROL, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_sockets[i].pcs_flags & PCS_CARD_PRESENT) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_flags = PCS_STARTING;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Because we are half way through a save
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * all this does is schedule a removal event
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to cs for when the system comes back.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This doesn't actually matter.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!pcic_do_pcmcia_sr && pcic_do_removal &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_callback) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PC_CALLBACK(pcic->dip, pcic->pc_cb_arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCE_CARD_REMOVAL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_SUSPENDED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * when true power management exists, save the adapter
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * state here to enable a recovery. For the emulation
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * condition, the state is gone
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EINVAL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint32_t pcic_tisysctl_onbits = ((1<<27) | (1<<15) | (1<<14));
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint32_t pcic_tisysctl_offbits = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint32_t pcic_default_latency = 0x40;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_setup_adapter(pcicdev_t *pcic)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value, flags;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China#if defined(__i386) || defined(__amd64)
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China pci_regspec_t *reg;
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China uchar_t bus, dev, func;
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China uint_t classcode;
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China int length;
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China#endif
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_PCIBUS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * all PCI-to-PCMCIA bus bridges need memory and I/O enabled
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel flags = (PCIC_ENABLE_IO | PCIC_ENABLE_MEM);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_iomem_pci_ctl(pcic->cfg_handle, pcic->cfgaddr, flags);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* enable each socket */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < pcic->pc_numsockets; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_flags = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* find out the socket capabilities (I/O vs memory) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, i,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CHIP_REVISION) & PCIC_REV_ID_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value == PCIC_REV_ID_IO || value == PCIC_REV_ID_BOTH)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[i].pcs_flags |= PCS_SOCKET_IO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* disable all windows just in case */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MAPPING_ENABLE, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t cfg32;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint16_t cfg16;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t cfg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* enable extended registers for Vadem */
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_VADEM_VG469:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_VADEM:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* enable card status change interrupt for socket */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_I82365SL:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_CL_PD6710:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, 0, PCIC_MISC_CTL_2, PCIC_LED_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * On the CL_6730, we need to set up the interrupt
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * signalling mode (PCI mode) and set the SMI and
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * IRQ interrupt lines to PCI/level-mode.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_CL_PD6730:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_intr_mode) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_PCI_1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clext_reg_write(pcic, i, PCIC_CLEXT_MISC_CTL_3,
193974072f41a843678abf5f61979c748687e66bSherry Moore ((clext_reg_read(pcic, i,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CLEXT_MISC_CTL_3) &
193974072f41a843678abf5f61979c748687e66bSherry Moore ~PCIC_CLEXT_INT_PCI) |
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CLEXT_INT_PCI));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clext_reg_write(pcic, i, PCIC_CLEXT_EXT_CTL_1,
193974072f41a843678abf5f61979c748687e66bSherry Moore (PCIC_CLEXT_IRQ_LVL_MODE |
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CLEXT_SMI_LVL_MODE));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = PCIC_CL_LP_DYN_MODE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MISC_CTL_2, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_ISA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * On the CL_6729, we set the SMI and IRQ interrupt
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * lines to PCI/level-mode. as well as program the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * correct clock speed divider bit.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_CL_PD6729:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_intr_mode) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_PCI_1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clext_reg_write(pcic, i, PCIC_CLEXT_EXT_CTL_1,
193974072f41a843678abf5f61979c748687e66bSherry Moore (PCIC_CLEXT_IRQ_LVL_MODE |
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CLEXT_SMI_LVL_MODE));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_ISA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->bus_speed > PCIC_PCI_25MHZ && i == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_CL_TIMER_CLK_DIV;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MISC_CTL_2, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = PCIC_82092_EN_TIMING;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->bus_speed < PCIC_SYSCLK_33MHZ)
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg |= PCIC_82092_PCICLK_25MHZ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle, pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_82092_PCICON, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1130:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1131:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1250:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1031:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_DEVCTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg &= ~PCIC_DEVCTL_INTR_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_intr_mode) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_ISA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_DEVCTL_INTR_ISA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_setup_adapter: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "write reg 0x%x=%x \n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_DEVCTL_REG, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_DEVCTL_REG,
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_CRDCTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg &= ~(PCIC_CRDCTL_PCIINTR|PCIC_CRDCTL_PCICSC|
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CRDCTL_PCIFUNC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_intr_mode) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_PCI_1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_CRDCTL_PCIINTR |
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CRDCTL_PCICSC |
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CRDCTL_PCIFUNC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_USE_SMI;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_setup_adapter: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " write reg 0x%x=%x \n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_CRDCTL_REG, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_CRDCTL_REG,
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1221:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1225:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->cfgaddr + PCIC_DEVCTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= (PCIC_DEVCTL_INTR_DFLT | PCIC_DEVCTL_3VCAPABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_setup_adapter: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " write reg 0x%x=%x \n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_DEVCTL_REG, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->cfgaddr + PCIC_DEVCTL_REG, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->cfgaddr + PCIC_DIAG_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_type == PCIC_TI_PCI1225) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= (PCIC_DIAG_CSC | PCIC_DIAG_ASYNC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_DIAG_ASYNC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_USE_SMI;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_setup_adapter: "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " write reg 0x%x=%x \n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_DIAG_REG, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->cfgaddr + PCIC_DIAG_REG, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1520:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1510:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_intr_mode == PCIC_INTR_MODE_ISA) {
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China /* functional intr routed by ExCA register */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_FUN_INT_MOD_ISA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG,
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China /* IRQ serialized interrupts */
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_DEVCTL_REG);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China cfg &= ~PCIC_DEVCTL_INTR_MASK;
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China cfg |= PCIC_DEVCTL_INTR_ISA;
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_DEVCTL_REG,
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China break;
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China }
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China /* CSC interrupt routed to PCI */
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China cfg = ddi_get8(pcic->cfg_handle,
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China pcic->cfgaddr + PCIC_DIAG_REG);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China cfg |= (PCIC_DIAG_CSC | PCIC_DIAG_ASYNC);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China ddi_put8(pcic->cfg_handle,
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China pcic->cfgaddr + PCIC_DIAG_REG, cfg);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China#if defined(__i386) || defined(__amd64)
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China /*
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China * Some TI chips have 2 cardbus slots(function0 and
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China * function1), and others may have just 1 cardbus slot.
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China * The interrupt routing register is shared between the
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China * 2 functions and can only be accessed through
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China * function0. Here we check the presence of the second
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China * cardbus slot and do the right thing.
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China */
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China if (ddi_getlongprop(DDI_DEV_T_ANY, pcic->dip,
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China DDI_PROP_DONTPASS, "reg", (caddr_t)&reg,
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China &length) != DDI_PROP_SUCCESS) {
193974072f41a843678abf5f61979c748687e66bSherry Moore cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_setup_adapter(), failed to"
193974072f41a843678abf5f61979c748687e66bSherry Moore " read reg property\n");
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China break;
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China }
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China bus = PCI_REG_BUS_G(reg->pci_phys_hi);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China dev = PCI_REG_DEV_G(reg->pci_phys_hi);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China func = PCI_REG_FUNC_G(reg->pci_phys_hi);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China kmem_free((caddr_t)reg, length);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China if (func != 0) {
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China break;
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China }
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China classcode = (*pci_getl_func)(bus, dev, 1,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCI_CONF_REVID);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China classcode >>= 8;
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China if (classcode != 0x060700 &&
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China classcode != 0x060500) {
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China /* Parallel PCI interrupts only */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_DEVCTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg &= ~PCIC_DEVCTL_INTR_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_DEVCTL_REG,
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* tie INTA and INTB together */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (pcic->cfgaddr + PCIC_SYSCTL_REG + 3));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_SYSCTL_INTRTIE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle, (pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_SYSCTL_REG + 3), cfg);
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China#endif
e12b469ade633bb8f834d51aab6173e6f6f8c6d9rui wang - Sun Microsystems - Beijing China
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->cfgaddr + PCIC_DIAG_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= (PCIC_DIAG_CSC | PCIC_DIAG_ASYNC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->cfgaddr + PCIC_DIAG_REG, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TOSHIBA_TOPIC100:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TOSHIBA_TOPIC95:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TOSHIBA_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle, pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_TOSHIBA_SLOT_CTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= (PCIC_TOSHIBA_SCR_SLOTON |
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_TOSHIBA_SCR_SLOTEN);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg &= (~PCIC_TOSHIBA_SCR_PRT_MASK);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_TOSHIBA_SCR_PRT_3E2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle, pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_TOSHIBA_SLOT_CTL_REG, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle, pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_TOSHIBA_INTR_CTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_intr_mode) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_ISA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg &= ~PCIC_TOSHIBA_ICR_SRC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_TOSHIBA_INTR_CTL_REG, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_FUN_INT_MOD_ISA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG,
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_PCI_1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_TOSHIBA_ICR_SRC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg &= (~PCIC_TOSHIBA_ICR_PIN_MASK);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_TOSHIBA_ICR_PIN_INTA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_TOSHIBA_INTR_CTL_REG, cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_O2MICRO_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg32 = ddi_get32(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_O2MICRO_MISC_CTL));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_intr_mode) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_ISA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg32 |= (PCIC_O2MICRO_ISA_LEGACY |
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_O2MICRO_INT_MOD_PCI);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put32(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_O2MICRO_MISC_CTL),
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg32);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_FUN_INT_MOD_ISA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG,
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_PCI_1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg32 &= ~PCIC_O2MICRO_ISA_LEGACY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg32 |= PCIC_O2MICRO_INT_MOD_PCI;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put32(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t *)(pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_O2MICRO_MISC_CTL),
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg32);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_RICOH_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_intr_mode == PCIC_INTR_MODE_ISA) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg16 = ddi_get16(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint16_t *)(pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_RICOH_MISC_CTL_2));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg16 |= (PCIC_RICOH_CSC_INT_MOD |
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_RICOH_FUN_INT_MOD);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put16(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint16_t *)(pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_RICOH_MISC_CTL_2),
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg16);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg16 = ddi_get16(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint16_t *)(pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_RICOH_MISC_CTL));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg16 |= PCIC_RICOH_SIRQ_EN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put16(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint16_t *)(pcic->cfgaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_RICOH_MISC_CTL),
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg16);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cfg |= PCIC_FUN_INT_MOD_ISA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG,
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw /*
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw * The default value in the EEPROM (loaded on reset) for
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw * MFUNC0/MFUNC1 may be incorrect. Here we make sure that
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw * MFUNC0 is connected to INTA, and MFUNC1 is connected to
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw * INTB. This applies to all TI CardBus controllers.
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw */
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw if ((pcic->pc_type >> 16) == PCIC_TI_VENDORID &&
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_intr_mode == PCIC_INTR_MODE_PCI_1) {
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw value = ddi_get32(pcic->cfg_handle,
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw (uint32_t *)(pcic->cfgaddr + PCIC_MFROUTE_REG));
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw value &= ~0xff;
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw ddi_put32(pcic->cfg_handle, (uint32_t *)(pcic->cfgaddr +
8134ee03588a08f05c327533a618d35625381520rw PCIC_MFROUTE_REG), value|PCIC_TI_MFUNC_SEL);
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw }
bb3a048dd74d073e10c2a5d4aa060b4405ba7dfdrw
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* setup general card status change interrupt */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1225:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1221:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1031:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1520:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MANAGEMENT_INT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_CHANGE_DEFAULT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_intr_mode ==
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_INTR_MODE_PCI_1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MANAGEMENT_INT,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CHANGE_DEFAULT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MANAGEMENT_INT,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CHANGE_DEFAULT |
193974072f41a843678abf5f61979c748687e66bSherry Moore (pcic->pc_sockets[i].pcs_smi << 4));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_INTRENAB;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* take card out of RESET */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_INTERRUPT, PCIC_RESET);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* turn power off and let CS do this */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_POWER_CONTROL, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* final chip specific initialization */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_VADEM:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_VG_CONTROL,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_VC_DELAYENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_DEBOUNCE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* FALLTHROUGH */
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_I82365SL:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_GLOBAL_CONTROL,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_GC_CSC_WRITE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* clear any pending interrupts */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, i, PCIC_CARD_STATUS_CHANGE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_CARD_STATUS_CHANGE, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* The 82092 uses PCI config space to enable interrupts */
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_82092_smiirq_ctl(pcic, i, PCIC_82092_CTL_SMI,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_82092_INT_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_CL_PD6729:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->bus_speed >= PCIC_PCI_DEF_SYSCLK && i == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, i, PCIC_MISC_CTL_2);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_MISC_CTL_2,
193974072f41a843678abf5f61979c748687e66bSherry Moore value | PCIC_CL_TIMER_CLK_DIV);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "socket %d value=%x, flags = %x (%s)\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore i, value, pcic->pc_sockets[i].pcs_flags,
193974072f41a843678abf5f61979c748687e66bSherry Moore (pcic->pc_sockets[i].pcs_flags &
193974072f41a843678abf5f61979c748687e66bSherry Moore PCS_CARD_PRESENT) ?
193974072f41a843678abf5f61979c748687e66bSherry Moore "card present" : "no card");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_intr(caddr_t, caddr_t)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * interrupt handler for the PCIC style adapter
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * handles all basic interrupts and also checks
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * for status changes and notifies the nexus if
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * necessary
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * On PCI bus adapters, also handles all card
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * IO interrupts.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afsteveluint32_t
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_intr(caddr_t arg1, caddr_t arg2)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = (pcicdev_t *)arg1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value = 0, i, ret = DDI_INTR_UNCLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t io_ints;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 0xf,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_intr: enter pc_flags=0x%x PCF_ATTACHED=0x%x"
193974072f41a843678abf5f61979c748687e66bSherry Moore " pc_numsockets=%d \n",
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_flags, PCF_ATTACHED, pcic->pc_numsockets);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(pcic->pc_flags & PCF_ATTACHED))
193974072f41a843678abf5f61979c748687e66bSherry Moore return (DDI_INTR_UNCLAIMED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_SUSPENDED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ret);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * need to change to only ACK and touch the slot that
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * actually caused the interrupt. Currently everything
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is acked
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we need to look at all known sockets to determine
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * what might have happened, so step through the list
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * of them
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Set the bitmask for IO interrupts to initially include all sockets
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io_ints = (1 << pcic->pc_numsockets) - 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < pcic->pc_numsockets; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int card_type;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *sockp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value_cb = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp = &pcic->pc_sockets[i];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* get the socket's I/O addresses */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_flags & PCS_WAITING) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io_ints &= ~(1 << i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_flags & PCS_CARD_IO)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel card_type = IF_IO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel card_type = IF_MEMORY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_io_type == PCIC_IO_TYPE_YENTA)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value_cb = pcic_getcb(pcic, CB_STATUS_EVENT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_change(pcic, i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((value != 0) || (value_cb != 0)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int x = pcic->pc_cb_arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 0x9,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "card_type = %d, value_cb = 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel card_type,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value_cb ? value_cb :
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_getcb(pcic, CB_STATUS_EVENT));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tchange on socket %d (%x)\n", i,
193974072f41a843678abf5f61979c748687e66bSherry Moore value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* find out what happened */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = pcic_getb(pcic, i, PCIC_INTERFACE_STATUS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* acknowledge the interrupt */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value_cb)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putcb(pcic, CB_STATUS_EVENT, value_cb);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, i, PCIC_CARD_STATUS_CHANGE,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_callback == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* if not callback handler, nothing to do */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Card Detect */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value & PCIC_CD_DETECT ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value_cb & CB_PS_CCDMASK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t irq;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tcd_detect: status=%x,"
193974072f41a843678abf5f61979c748687e66bSherry Moore " flags=%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore status, sockp->pcs_flags);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef lint
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status == 0)
193974072f41a843678abf5f61979c748687e66bSherry Moore status++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Turn off all interrupts for this socket here.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq = pcic_getb(pcic, sockp->pcs_socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_MANAGEMENT_INT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq &= ~PCIC_CHANGE_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, sockp->pcs_socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_MANAGEMENT_INT, irq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putcb(pcic, CB_STATUS_MASK, 0x0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
0d282d1376eb7ba06504448622a6d65726e4bd3erw /*
0d282d1376eb7ba06504448622a6d65726e4bd3erw * Put the socket in debouncing state so that
0d282d1376eb7ba06504448622a6d65726e4bd3erw * the leaf driver won't receive interrupts.
0d282d1376eb7ba06504448622a6d65726e4bd3erw * Crucial for handling surprise-removal.
0d282d1376eb7ba06504448622a6d65726e4bd3erw */
0d282d1376eb7ba06504448622a6d65726e4bd3erw sockp->pcs_flags |= PCS_DEBOUNCING;
0d282d1376eb7ba06504448622a6d65726e4bd3erw
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!sockp->pcs_cd_softint_flg) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_cd_softint_flg = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_trigger_softint(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_cd_softint_hdl, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io_ints &= ~(1 << i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* PCIC_CD_DETECT */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Ready/Change Detect */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_state ^= SBM_RDYBSY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (card_type == IF_MEMORY && value & PCIC_RD_DETECT) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_flags |= PCS_READY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PC_CALLBACK(pcic->dip, x, PCE_CARD_READY, i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Battery Warn Detect */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (card_type == IF_MEMORY &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value & PCIC_BW_DETECT &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel !(sockp->pcs_state & SBM_BVD2)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_state |= SBM_BVD2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PC_CALLBACK(pcic->dip, x,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCE_CARD_BATTERY_WARN, i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Battery Dead Detect */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value & PCIC_BD_DETECT) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * need to work out event if RI not enabled
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and card_type == IF_IO
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (card_type == IF_MEMORY &&
193974072f41a843678abf5f61979c748687e66bSherry Moore !(sockp->pcs_state & SBM_BVD1)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_state |= SBM_BVD1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PC_CALLBACK(pcic->dip, x,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCE_CARD_BATTERY_DEAD,
193974072f41a843678abf5f61979c748687e66bSherry Moore i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * information in pin replacement
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * register if one is available
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PC_CALLBACK(pcic->dip, x,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCE_CARD_STATUS_CHANGE,
193974072f41a843678abf5f61979c748687e66bSherry Moore i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* IF_MEMORY */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* PCIC_BD_DETECT */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* if pcic_change */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * for any controllers that we can detect whether a socket
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * had an interrupt for the PC Card, we should sort that out
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * here.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* for pc_numsockets */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If we're on a PCI bus, we may need to cycle through each IO
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * interrupt handler that is registered since they all
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * share the same interrupt line.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 0xf,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_intr: pc_intr_mode=%d pc_type=%x io_ints=0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_intr_mode, pcic->pc_type, io_ints);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
0d282d1376eb7ba06504448622a6d65726e4bd3erw if (io_ints) {
0d282d1376eb7ba06504448622a6d65726e4bd3erw if (pcic_do_io_intr(pcic, io_ints) == DDI_INTR_CLAIMED)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 0xf,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_intr: ret=%d value=%d DDI_INTR_CLAIMED=%d\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret, value, DDI_INTR_CLAIMED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ret);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_change()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * check to see if this socket had a change in state
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * by checking the status change register
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_change(pcicdev_t *pcic, int socket)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (pcic_getb(pcic, socket, PCIC_CARD_STATUS_CHANGE));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_do_io_intr - calls client interrupt handlers
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_do_io_intr(pcicdev_t *pcic, uint32_t sockets)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel inthandler_t *tmp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ret = DDI_INTR_UNCLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 0xf,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_do_io_intr: pcic=%p sockets=%d irq_top=%p\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic, (int)sockets, (void *)pcic->irq_top);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->irq_top != NULL) {
193974072f41a843678abf5f61979c748687e66bSherry Moore tmp = pcic->irq_current;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore do {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cur = pcic->irq_current->socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *sockp =
193974072f41a843678abf5f61979c748687e66bSherry Moore &pcic->pc_sockets[cur];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 0xf,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\t pcs_flags=0x%x PCS_CARD_PRESENT=0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_flags, PCS_CARD_PRESENT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 0xf,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\t sockets=%d cur=%d intr=%p arg1=%p "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "arg2=%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockets, cur, (void *)pcic->irq_current->intr,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current->arg1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current->arg2);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
0d282d1376eb7ba06504448622a6d65726e4bd3erw if ((sockp->pcs_flags & PCS_CARD_PRESENT) &&
0d282d1376eb7ba06504448622a6d65726e4bd3erw !(sockp->pcs_flags & PCS_DEBOUNCING) &&
0d282d1376eb7ba06504448622a6d65726e4bd3erw (sockets & (1 << cur))) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((*pcic->irq_current->intr)(pcic->irq_current->arg1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current->arg2) == DDI_INTR_CLAIMED)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 0xf,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\t ret=%d DDI_INTR_CLAIMED=%d\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret, DDI_INTR_CLAIMED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((pcic->irq_current = pcic->irq_current->next) == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current = pcic->irq_top;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore } while (pcic->irq_current != tmp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore if ((pcic->irq_current = pcic->irq_current->next) == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current = pcic->irq_top;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = DDI_INTR_UNCLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 0xf,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_do_io_intr: exit ret=%d DDI_INTR_CLAIMED=%d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ret, DDI_INTR_CLAIMED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ret);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_inquire_adapter()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices InquireAdapter function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * get characteristics of the physical adapter
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_inquire_adapter(dev_info_t *dip, inquire_adapter_t *config)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel config->NumSockets = pcic->pc_numsockets;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel config->NumWindows = pcic->pc_numsockets * PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel config->NumEDCs = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel config->AdpCaps = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel config->ActiveHigh = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel config->ActiveLow = PCIC_AVAIL_IRQS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel config->NumPower = pcic->pc_numpower;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel config->power_entry = pcic->pc_power; /* until we resolve this */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_inquire_adapter:\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tNumSockets=%d\n", config->NumSockets);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tNumWindows=%d\n", config->NumWindows);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel config->ResourceFlags = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_intr_mode) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_PCI_1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel config->ResourceFlags |= RES_OWN_IRQ | RES_IRQ_NEXUS |
193974072f41a843678abf5f61979c748687e66bSherry Moore RES_IRQ_SHAREABLE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_callback()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The PCMCIA nexus calls us via this function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * in order to set the callback function we are
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to call the nexus with
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_callback(dev_info_t *dip, int (*handler)(), int arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (handler != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_callback = handler;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_cb_arg = arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_CALLBACK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_callback = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_cb_arg = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags &= ~PCF_CALLBACK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we're now registered with the nexus
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * it is acceptable to do callbacks at this point.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * don't call back from here though since it could block
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (PC_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_calc_speed (pcicdev_t *pcic, uint32_t speed)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * calculate the speed bits from the specified memory speed
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * there may be more to do here
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_calc_speed(pcicdev_t *pcic, uint32_t speed)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t wspeed = 1; /* assume 1 wait state when unknown */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t bspeed = PCIC_ISA_DEF_SYSCLK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_I82365SL:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_VADEM:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_VADEM_VG469:
193974072f41a843678abf5f61979c748687e66bSherry Moore default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Intel chip wants it in waitstates */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed = mhztons(PCIC_ISA_DEF_SYSCLK) * 3;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (speed <= wspeed)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else if (speed <= (wspeed += mhztons(bspeed)))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else if (speed <= (wspeed += mhztons(bspeed)))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed = 2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed = 3;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed <<= 6; /* put in right bit positions */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed = SYSMEM_82092_80NS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (speed > 80)
193974072f41a843678abf5f61979c748687e66bSherry Moore wspeed = SYSMEM_82092_100NS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (speed > 100)
193974072f41a843678abf5f61979c748687e66bSherry Moore wspeed = SYSMEM_82092_150NS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (speed > 150)
193974072f41a843678abf5f61979c748687e66bSherry Moore wspeed = SYSMEM_82092_200NS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (speed > 200)
193974072f41a843678abf5f61979c748687e66bSherry Moore wspeed = SYSMEM_82092_250NS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (speed > 250)
193974072f41a843678abf5f61979c748687e66bSherry Moore wspeed = SYSMEM_82092_600NS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed <<= 5; /* put in right bit positions */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (wspeed);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * These values are taken from the PC Card Standard Electrical Specification.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Generally the larger value is taken if 2 are possible.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct pcic_card_times {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint16_t cycle; /* Speed as found in the atribute space of he card. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint16_t setup; /* Corresponding address setup time. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint16_t width; /* Corresponding width, OE or WE. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint16_t hold; /* Corresponding data or address hold time. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel} pcic_card_times[] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Note: The rounded up times for 250, 200 & 150 have been increased
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * due to problems with the 3-Com ethernet cards (pcelx) on UBIIi.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * See BugID 00663.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Rounded up times Original times from
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * that add up to the the PCMCIA Spec.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * cycle time.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {600, 180, 370, 140}, /* 100, 300, 70 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {400, 120, 300, 90}, /* Made this one up */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {250, 100, 190, 70}, /* 30, 150, 30 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {200, 80, 170, 70}, /* 20, 120, 30 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {150, 50, 110, 40}, /* 20, 80, 20 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {100, 40, 80, 40}, /* 10, 60, 15 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {0, 10, 60, 15} /* 10, 60, 15 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_set_cdtimers
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This is specific to several Cirrus Logic chips
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_set_cdtimers(pcicdev_t *pcic, int socket, uint32_t speed, int tset)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int cmd, set, rec, offset, clk_pulse;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct pcic_card_times *ctp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((tset == IOMEM_CLTIMER_SET_1) || (tset == SYSMEM_CLTIMER_SET_1))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel offset = 3;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel offset = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clk_pulse = mhztons(pcic->bus_speed);
193974072f41a843678abf5f61979c748687e66bSherry Moore for (ctp = pcic_card_times; speed < ctp->cycle; ctp++)
193974072f41a843678abf5f61979c748687e66bSherry Moore ;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Add (clk_pulse/2) and an extra 1 to account for rounding errors.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel set = ((ctp->setup + 10 + 1 + (clk_pulse/2))/clk_pulse) - 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (set < 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel set = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmd = ((ctp->width + 10 + 1 + (clk_pulse/2))/clk_pulse) - 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cmd < 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmd = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rec = ((ctp->hold + 10 + 1 + (clk_pulse/2))/clk_pulse) - 2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (rec < 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rec = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8, "pcic_set_cdtimers(%d, Timer Set %d)\n"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "ct=%d, cp=%d, cmd=0x%x, setup=0x%x, rec=0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (unsigned)speed, offset == 3 ? 1 : 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ctp->cycle, clk_pulse, cmd, set, rec);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_TIME_COMMAND_0 + offset, cmd);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_TIME_SETUP_0 + offset, set);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_TIME_RECOVER_0 + offset, rec);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_set_window
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * essentially the same as the Socket Services specification
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We use socket and not adapter since they are identifiable
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * but the rest is the same
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * dip pcic driver's device information
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * window parameters for the request
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_set_window(dev_info_t *dip, set_window_t *window)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int select;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int socket, pages, which, ret;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *sockp = &pcic->pc_sockets[window->socket];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ra_return_t res;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_ra_request_t req;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t base = window->base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_set_window: entered\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\twindow=%d, socket=%d, WindowSize=%d, speed=%d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore window->window, window->socket, window->WindowSize,
193974072f41a843678abf5f61979c748687e66bSherry Moore window->speed);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tbase=%x, state=%x\n", (unsigned)window->base,
193974072f41a843678abf5f61979c748687e66bSherry Moore (unsigned)window->state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * do some basic sanity checking on what we support
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we don't do paged mode
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window->state & WS_PAGED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "pcic_set_window: BAD_ATTRIBUTE\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_ATTRIBUTE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we don't care about previous mappings.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Card Services will deal with that so don't
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * even check
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket = window->socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(window->state & WS_IO)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int win, tmp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcs_memwin_t *memp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\twindow type is memory\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* this is memory window mapping */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel win = window->window % PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tmp = window->window / PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* only windows 2-6 can do memory mapping */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (tmp != window->socket || win < PCIC_IOWINDOWS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tattempt to map to non-mem window\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_WINDOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window->WindowSize == 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->WindowSize = MEM_MIN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else if ((window->WindowSize & (PCIC_PAGE-1)) != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "pcic_set_window: BAD_SIZE\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_SIZE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock); /* protect the registers */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp = &sockp->pcs_windows[win].mem;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_speed = window->speed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel win -= PCIC_IOWINDOWS; /* put in right range */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window->WindowSize != memp->pcw_len)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which = memp->pcw_len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window->state & WS_ENABLED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t wspeed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tbase=%x, win=%d\n", (unsigned)base,
193974072f41a843678abf5f61979c748687e66bSherry Moore win);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (which)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tneed to remap window\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (which && (memp->pcw_status & PCW_MAPPED)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&memp->pcw_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel res.ra_addr_lo = memp->pcw_base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel res.ra_len = memp->pcw_len;
8134ee03588a08f05c327533a618d35625381520rw (void) pcmcia_free_mem(memp->res_dip, &res);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_status &= ~(PCW_MAPPED|PCW_ENABLED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_hostmem = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_base = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_len = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which = window->WindowSize >> PAGE_SHIFT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(memp->pcw_status & PCW_MAPPED)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ret = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_base = base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bzero(&req, sizeof (req));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_len = which << PAGE_SHIFT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_addr = (uint64_t)memp->pcw_base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_boundbase = pcic->pc_base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_boundlen = pcic->pc_bound;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_flags = (memp->pcw_base ?
193974072f41a843678abf5f61979c748687e66bSherry Moore NDI_RA_ALLOC_SPECIFIED : 0) |
193974072f41a843678abf5f61979c748687e66bSherry Moore NDI_RA_ALLOC_BOUNDED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_align_mask =
193974072f41a843678abf5f61979c748687e66bSherry Moore (PAGESIZE - 1) | (PCIC_PAGE - 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\tlen 0x%"PRIx64
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "addr 0x%"PRIx64"bbase 0x%"PRIx64
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " blen 0x%"PRIx64" flags 0x%x"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " algn 0x%"PRIx64"\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_len, req.ra_addr,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_boundbase,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_boundlen, req.ra_flags,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_align_mask);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
8134ee03588a08f05c327533a618d35625381520rw ret = pcmcia_alloc_mem(dip, &req, &res,
193974072f41a843678abf5f61979c748687e66bSherry Moore &memp->res_dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ret == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\tpcmcia_alloc_mem() failed\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_SIZE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_base = res.ra_addr_lo;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel base = memp->pcw_base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tsetwindow: new base=%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (unsigned)memp->pcw_base);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_len = window->WindowSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which = pcmcia_map_reg(pcic->dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore window->child,
193974072f41a843678abf5f61979c748687e66bSherry Moore &res,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t)(window->state &
193974072f41a843678abf5f61979c748687e66bSherry Moore 0xffff) |
193974072f41a843678abf5f61979c748687e66bSherry Moore (window->socket << 16),
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&memp->pcw_hostmem,
193974072f41a843678abf5f61979c748687e66bSherry Moore &memp->pcw_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore &window->attr, NULL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (which != DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "\tpcmcia_map_reg() "
193974072f41a843678abf5f61979c748687e66bSherry Moore "failed\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore res.ra_addr_lo = memp->pcw_base;
193974072f41a843678abf5f61979c748687e66bSherry Moore res.ra_len = memp->pcw_len;
193974072f41a843678abf5f61979c748687e66bSherry Moore (void) pcmcia_free_mem(memp->res_dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore &res);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore return (BAD_WINDOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_status |= PCW_MAPPED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tmap=%x, hostmem=%p\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore which,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)memp->pcw_hostmem);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel base = memp->pcw_base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* report the handle back to caller */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->handle = memp->pcw_handle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\twindow mapped to %x@%x len=%d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (unsigned)window->base,
193974072f41a843678abf5f61979c748687e66bSherry Moore (unsigned)memp->pcw_base,
193974072f41a843678abf5f61979c748687e66bSherry Moore memp->pcw_len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* find the register set offset */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select = win * PCIC_MEM_1_OFFSET;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tselect=%x\n", select);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * at this point, the register window indicator has
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * been converted to be an offset from the first
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * set of registers that are used for programming
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the window mapping and the offset used to select
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the correct set of registers to access the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * specified socket. This allows basing everything
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * off the _0 window
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* map the physical page base address */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which = (window->state & WS_16BIT) ? SYSMEM_DATA_16 : 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which |= (window->speed <= MEM_SPEED_MIN) ?
193974072f41a843678abf5f61979c748687e66bSherry Moore SYSMEM_ZERO_WAIT : 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* need to select register set */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select = PCIC_MEM_1_OFFSET * win;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_SYSMEM_0_STARTLOW + select,
193974072f41a843678abf5f61979c748687e66bSherry Moore SYSMEM_LOW(base));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_SYSMEM_0_STARTHI + select,
193974072f41a843678abf5f61979c748687e66bSherry Moore SYSMEM_HIGH(base) | which);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Some adapters can decode window addresses greater
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * than 16-bits worth, so handle them here.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_82092_CPAGE,
193974072f41a843678abf5f61979c748687e66bSherry Moore SYSMEM_EXT(base));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6729:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6730:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clext_reg_write(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CLEXT_MMAP0_UA + win,
193974072f41a843678abf5f61979c748687e66bSherry Moore SYSMEM_EXT(base));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1130:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Note that the TI chip has one upper byte
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * per socket so all windows get bound to a
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 16MB segment. This must be detected and
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * handled appropriately. We can detect that
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * it is done by seeing if the pc_base has
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * changed and changing when the register
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is first set. This will force the bounds
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to be correct.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_bound == 0xffffffff) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_TI_WINDOW_PAGE_PCI,
193974072f41a843678abf5f61979c748687e66bSherry Moore SYSMEM_EXT(base));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_base = SYSMEM_EXT(base) << 24;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_bound = 0x1000000;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1031:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1131:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1250:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1225:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1221:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_SMC_34C90:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6832:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_RICOH_RL5C466:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_ENE_1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1510:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1520:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_O2_OZ6912:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_ENE_1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TOSHIBA_TOPIC100:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TOSHIBA_TOPIC95:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TOSHIBA_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_RICOH_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_O2MICRO_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_YENTA_MEM_PAGE + win,
193974072f41a843678abf5f61979c748687e66bSherry Moore SYSMEM_EXT(base));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_NOTE, "pcic_set_window: unknown "
193974072f41a843678abf5f61979c748687e66bSherry Moore "cardbus vendor:0x%X\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_type);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_YENTA_MEM_PAGE + win,
193974072f41a843678abf5f61979c748687e66bSherry Moore SYSMEM_EXT(base));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * specify the length of the mapped range
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we convert to pages (rounding up) so that
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the hardware gets the right thing
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pages = (window->WindowSize+PCIC_PAGE-1)/PCIC_PAGE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Setup this window's timing.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6729:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6730:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6710:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6722:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed = SYSMEM_CLTIMER_SET_0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_set_cdtimers(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore window->speed,
193974072f41a843678abf5f61979c748687e66bSherry Moore wspeed);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed = pcic_calc_speed(pcic, window->speed);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\twindow %d speed bits = %x for "
193974072f41a843678abf5f61979c748687e66bSherry Moore "%dns\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore win, (unsigned)wspeed, window->speed);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_SYSMEM_0_STOPLOW + select,
193974072f41a843678abf5f61979c748687e66bSherry Moore SYSMEM_LOW(base +
193974072f41a843678abf5f61979c748687e66bSherry Moore (pages * PCIC_PAGE)-1));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel wspeed |= SYSMEM_HIGH(base + (pages * PCIC_PAGE)-1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_SYSMEM_0_STOPHI + select,
193974072f41a843678abf5f61979c748687e66bSherry Moore wspeed);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * now map the card's memory pages - we start with page
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 0
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we also default to AM -- set page might change it
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel base = memp->pcw_base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CARDMEM_0_LOW + select,
193974072f41a843678abf5f61979c748687e66bSherry Moore CARDMEM_LOW(0 - (uint32_t)base));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CARDMEM_0_HI + select,
193974072f41a843678abf5f61979c748687e66bSherry Moore CARDMEM_HIGH(0 - (uint32_t)base) |
193974072f41a843678abf5f61979c748687e66bSherry Moore CARDMEM_REG_ACTIVE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * enable the window even though redundant
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and SetPage may do it again.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select = pcic_getb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_MAPPING_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select |= SYSMEM_WINDOW(win);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_MAPPING_ENABLE, select);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_offset = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_status |= PCW_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * not only do we unmap the memory, the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * window has been turned off.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (which && memp->pcw_status & PCW_MAPPED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&memp->pcw_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel res.ra_addr_lo = memp->pcw_base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel res.ra_len = memp->pcw_len;
8134ee03588a08f05c327533a618d35625381520rw (void) pcmcia_free_mem(memp->res_dip, &res);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_hostmem = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_status &= ~PCW_MAPPED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* disable current mapping */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select = pcic_getb(pcic, socket, PCIC_MAPPING_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select &= ~SYSMEM_WINDOW(win);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_MAPPING_ENABLE, select);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_status &= ~PCW_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_len = window->WindowSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->handle = memp->pcw_handle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel xxdmp_all_regs(pcic, window->socket, -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This is a request for an IO window
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int win, tmp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcs_iowin_t *winp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* I/O windows */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\twindow type is I/O\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* only windows 0 and 1 can do I/O */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel win = window->window % PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel tmp = window->window / PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (win >= PCIC_IOWINDOWS || tmp != window->socket) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\twindow is out of range (%d)\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore window->window);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_WINDOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock); /* protect the registers */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp = &sockp->pcs_windows[win].io;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_speed = window->speed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window->WindowSize != 1 && window->WindowSize & 1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* we don't want an odd-size window */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->WindowSize++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_len = window->WindowSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window->state & WS_ENABLED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (winp->pcw_status & PCW_MAPPED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&winp->pcw_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel res.ra_addr_lo = winp->pcw_base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel res.ra_len = winp->pcw_len;
8134ee03588a08f05c327533a618d35625381520rw (void) pcmcia_free_io(winp->res_dip, &res);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_status &= ~(PCW_MAPPED|PCW_ENABLED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if the I/O address wasn't allocated, allocate
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * it now. If it was allocated, it better
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * be free to use.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The winp->pcw_offset value is set and used
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * later on if the particular adapter
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * that we're running on has the ability
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to translate IO accesses to the card
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * (such as some adapters in the Cirrus
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Logic family).
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_offset = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Setup the request parameters for the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * requested base and length. If
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we're on an adapter that has
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * IO window offset registers, then
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we don't need a specific base
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * address, just a length, and then
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * we'll cause the correct IO address
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to be generated on the socket by
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * setting up the IO window offset
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * registers.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * For adapters that support this capability, we
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * always use the IO window offset registers,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * even if the passed base/length would be in
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * range.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel base = window->base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bzero(&req, sizeof (req));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_len = window->WindowSize;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_addr = (uint64_t)
193974072f41a843678abf5f61979c748687e66bSherry Moore ((pcic->pc_flags & PCF_IO_REMAP) ? 0 : base);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_flags = (req.ra_addr) ?
193974072f41a843678abf5f61979c748687e66bSherry Moore NDI_RA_ALLOC_SPECIFIED : 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_flags |= NDI_RA_ALIGN_SIZE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* need to rethink this */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_boundbase = pcic->pc_iobase;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_boundlen = pcic->pc_iobound;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel req.ra_flags |= NDI_RA_ALLOC_BOUNDED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_err(dip, 8,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tlen 0x%"PRIx64" addr 0x%"PRIx64
193974072f41a843678abf5f61979c748687e66bSherry Moore "bbase 0x%"PRIx64
193974072f41a843678abf5f61979c748687e66bSherry Moore "blen 0x%"PRIx64" flags 0x%x algn 0x%"
193974072f41a843678abf5f61979c748687e66bSherry Moore PRIx64"\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore req.ra_len, (uint64_t)req.ra_addr,
193974072f41a843678abf5f61979c748687e66bSherry Moore req.ra_boundbase,
193974072f41a843678abf5f61979c748687e66bSherry Moore req.ra_boundlen, req.ra_flags,
193974072f41a843678abf5f61979c748687e66bSherry Moore req.ra_align_mask);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Try to allocate the space. If we fail this,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * return the appropriate error depending
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * on whether the caller specified a
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * specific base address or not.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
8134ee03588a08f05c327533a618d35625381520rw if (pcmcia_alloc_io(dip, &req, &res,
193974072f41a843678abf5f61979c748687e66bSherry Moore &winp->res_dip) == DDI_FAILURE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_status &= ~PCW_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "Failed to alloc I/O:\n"
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tlen 0x%" PRIx64 " addr 0x%" PRIx64
193974072f41a843678abf5f61979c748687e66bSherry Moore "bbase 0x%" PRIx64
193974072f41a843678abf5f61979c748687e66bSherry Moore "blen 0x%" PRIx64 "flags 0x%x"
193974072f41a843678abf5f61979c748687e66bSherry Moore "algn 0x%" PRIx64 "\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore req.ra_len, req.ra_addr,
193974072f41a843678abf5f61979c748687e66bSherry Moore req.ra_boundbase,
193974072f41a843678abf5f61979c748687e66bSherry Moore req.ra_boundlen, req.ra_flags,
193974072f41a843678abf5f61979c748687e66bSherry Moore req.ra_align_mask);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (base?BAD_BASE:BAD_SIZE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* pcmcia_alloc_io */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Don't change the original base. Either we use
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the offset registers below (PCF_IO_REMAP is set)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * or it was allocated correctly anyway.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_base = res.ra_addr_lo;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_err(dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\tsetwindow: new base=%x orig base 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (unsigned)winp->pcw_base, base);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((which = pcmcia_map_reg(pcic->dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore window->child,
193974072f41a843678abf5f61979c748687e66bSherry Moore &res,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t)(window->state &
193974072f41a843678abf5f61979c748687e66bSherry Moore 0xffff) |
193974072f41a843678abf5f61979c748687e66bSherry Moore (window->socket << 16),
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t *)&winp->pcw_hostmem,
193974072f41a843678abf5f61979c748687e66bSherry Moore &winp->pcw_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore &window->attr,
193974072f41a843678abf5f61979c748687e66bSherry Moore base)) != DDI_SUCCESS) {
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore cmn_err(CE_WARN, "pcmcia_map_reg()"
193974072f41a843678abf5f61979c748687e66bSherry Moore "failed\n");
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore res.ra_addr_lo = winp->pcw_base;
193974072f41a843678abf5f61979c748687e66bSherry Moore res.ra_len = winp->pcw_len;
193974072f41a843678abf5f61979c748687e66bSherry Moore (void) pcmcia_free_io(winp->res_dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore &res);
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore mutex_exit(&pcic->pc_lock);
193974072f41a843678abf5f61979c748687e66bSherry Moore return (BAD_WINDOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->handle = winp->pcw_handle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_status |= PCW_MAPPED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* find the register set offset */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select = win * PCIC_IO_OFFSET;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tenable: window=%d, select=%x, "
193974072f41a843678abf5f61979c748687e66bSherry Moore "base=%x, handle=%p\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore win, select,
193974072f41a843678abf5f61979c748687e66bSherry Moore (unsigned)window->base,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)window->handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * at this point, the register window indicator has
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * been converted to be an offset from the first
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * set of registers that are used for programming
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the window mapping and the offset used to select
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the correct set of registers to access the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * specified socket. This allows basing everything
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * off the _0 window
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* map the I/O base in */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_IO_ADDR_0_STARTLOW + select,
193974072f41a843678abf5f61979c748687e66bSherry Moore LOW_BYTE((uint32_t)winp->pcw_base));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_IO_ADDR_0_STARTHI + select,
193974072f41a843678abf5f61979c748687e66bSherry Moore HIGH_BYTE((uint32_t)winp->pcw_base));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_IO_ADDR_0_STOPLOW + select,
193974072f41a843678abf5f61979c748687e66bSherry Moore LOW_BYTE((uint32_t)winp->pcw_base +
193974072f41a843678abf5f61979c748687e66bSherry Moore window->WindowSize - 1));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_IO_ADDR_0_STOPHI + select,
193974072f41a843678abf5f61979c748687e66bSherry Moore HIGH_BYTE((uint32_t)winp->pcw_base +
193974072f41a843678abf5f61979c748687e66bSherry Moore window->WindowSize - 1));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We've got the requested IO space, now see if we
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * need to adjust the IO window offset registers
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * so that the correct IO address is generated
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * at the socket. If this window doesn't have
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this capability, then we're all done setting
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * up the IO resources.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_IO_REMAP) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Note that only 16 bits are used to program
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the registers but leave 32 bits on pcw_offset
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * so that we can generate the original base
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * in get_window()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_offset = (base - winp->pcw_base);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_IO_OFFSET_LOW +
193974072f41a843678abf5f61979c748687e66bSherry Moore (win * PCIC_IO_OFFSET_OFFSET),
193974072f41a843678abf5f61979c748687e66bSherry Moore winp->pcw_offset & 0x0ff);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_IO_OFFSET_HI +
193974072f41a843678abf5f61979c748687e66bSherry Moore (win * PCIC_IO_OFFSET_OFFSET),
193974072f41a843678abf5f61979c748687e66bSherry Moore (winp->pcw_offset >> 8) & 0x0ff);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* PCF_IO_REMAP */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* now get the other details (size, etc) right */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Set the data size control bits here. Most of the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * adapters will ignore IOMEM_16BIT when
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * IOMEM_IOCS16 is set, except for the Intel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * 82092, which only pays attention to the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * IOMEM_16BIT bit. Sigh... Intel can't even
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * make a proper clone of their own chip.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The 82092 also apparently can't set the timing
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * of I/O windows.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which = (window->state & WS_16BIT) ?
193974072f41a843678abf5f61979c748687e66bSherry Moore (IOMEM_16BIT | IOMEM_IOCS16) : 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6729:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6730:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6710:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6722:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6832:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Select Timer Set 1 - this will take
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * effect when the PCIC_IO_CONTROL
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * register is written to later on;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the call to pcic_set_cdtimers
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * just sets up the timer itself.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which |= IOMEM_CLTIMER_SET_1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_set_cdtimers(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore window->speed,
193974072f41a843678abf5f61979c748687e66bSherry Moore IOMEM_CLTIMER_SET_1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which |= IOMEM_IOCS16;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1031:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window->state & WS_16BIT)
193974072f41a843678abf5f61979c748687e66bSherry Moore which |= IOMEM_WAIT16;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1130:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window->state & WS_16BIT)
193974072f41a843678abf5f61979c748687e66bSherry Moore which |= IOMEM_WAIT16;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window->speed >
193974072f41a843678abf5f61979c748687e66bSherry Moore mhztons(pcic->bus_speed) * 3)
193974072f41a843678abf5f61979c748687e66bSherry Moore which |= IOMEM_WAIT16;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef notdef
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window->speed <
193974072f41a843678abf5f61979c748687e66bSherry Moore mhztons(pcic->bus_speed) * 6)
193974072f41a843678abf5f61979c748687e66bSherry Moore which |= IOMEM_ZERO_WAIT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch (pc_type) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Setup the data width and timing
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select = pcic_getb(pcic, socket, PCIC_IO_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select &= ~(PCIC_IO_WIN_MASK << (win * 4));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select |= IOMEM_SETWIN(win, which);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_IO_CONTROL, select);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Enable the IO window
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select = pcic_getb(pcic, socket, PCIC_MAPPING_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_MAPPING_ENABLE,
193974072f41a843678abf5f61979c748687e66bSherry Moore select | IOMEM_WINDOW(win));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_status |= PCW_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\twhich = %x, select = %x (%x)\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore which, select,
193974072f41a843678abf5f61979c748687e66bSherry Moore IOMEM_SETWIN(win, which));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel xxdmp_all_regs(pcic, window->socket * 0x40, 24);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * not only do we unmap the IO space, the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * window has been turned off.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (winp->pcw_status & PCW_MAPPED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_regs_map_free(&winp->pcw_handle);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel res.ra_addr_lo = winp->pcw_base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel res.ra_len = winp->pcw_len;
8134ee03588a08f05c327533a618d35625381520rw (void) pcmcia_free_io(winp->res_dip, &res);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_status &= ~PCW_MAPPED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* disable current mapping */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select = pcic_getb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_MAPPING_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_MAPPING_ENABLE,
193974072f41a843678abf5f61979c748687e66bSherry Moore select &= ~IOMEM_WINDOW(win));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_status &= ~PCW_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_base = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_len = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp->pcw_offset = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->base = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* now make sure we don't accidentally re-enable */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* find the register set offset */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select = win * PCIC_IO_OFFSET;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_IO_ADDR_0_STARTLOW + select, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_IO_ADDR_0_STARTHI + select, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_IO_ADDR_0_STOPLOW + select, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_IO_ADDR_0_STOPHI + select, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_card_state()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * compute the instantaneous Card State information
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_card_state(pcicdev_t *pcic, pcic_socket_t *sockp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value, result;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int orig_value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock); /* protect the registers */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, sockp->pcs_socket, PCIC_INTERFACE_STATUS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel orig_value = value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug >= 8)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_card_state(%p) if status = %b for %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)sockp,
193974072f41a843678abf5f61979c748687e66bSherry Moore value,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\020\1BVD1\2BVD2\3CD1\4CD2\5WP\6RDY\7PWR\10~GPI",
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Lie to socket services if we are not ready.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This is when we are starting up or during debounce timeouts
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * or if the card is a cardbus card.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(sockp->pcs_flags & (PCS_STARTING|PCS_CARD_ISCARDBUS)) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel !sockp->pcs_debounce_id &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (value & PCIC_ISTAT_CD_MASK) == PCIC_CD_PRESENT_OK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel result = SBM_CD;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value & PCIC_WRITE_PROTECT || !(value & PCIC_POWER_ON))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel result |= SBM_WP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value & PCIC_POWER_ON) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value & PCIC_READY)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel result |= SBM_RDYBSY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = (~value) & (PCIC_BVD1 | PCIC_BVD2);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value & PCIC_BVD1)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel result |= SBM_BVD1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value & PCIC_BVD2)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel result |= SBM_BVD2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel result = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_card_state(%p) if status = %b for %d (rval=0x%x)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) sockp, orig_value,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\020\1BVD1\2BVD2\3CD1\4CD2\5WP\6RDY\7PWR\10~GPI",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_socket, result);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (result);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_set_page()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices SetPage function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * set the page of PC Card memory that should be in the mapped
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * window
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_set_page(dev_info_t *dip, set_page_t *page)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int select;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int which, socket, window;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t base;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcs_memwin_t *memp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* get real socket/window numbers */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window = page->window % PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket = page->window / PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_set_page: window=%d, socket=%d, page=%d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore window, socket, page->page);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* only windows 2-6 work on memory */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window < PCIC_IOWINDOWS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_WINDOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* only one page supported (but any size) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (page->page != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_PAGE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock); /* protect the registers */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp = &pcic->pc_sockets[socket].pcs_windows[window].mem;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window -= PCIC_IOWINDOWS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tpcw_base=%x, pcw_hostmem=%p, pcw_len=%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t)memp->pcw_base,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)memp->pcw_hostmem, memp->pcw_len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* window must be enabled */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(memp->pcw_status & PCW_ENABLED))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_ATTRIBUTE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* find the register set offset */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel select = window * PCIC_MEM_1_OFFSET;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tselect=%x\n", select);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * now map the card's memory pages - we start with page 0
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which = 0; /* assume simple case */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (page->state & PS_ATTRIBUTE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which |= CARDMEM_REG_ACTIVE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_status |= PCW_ATTRIBUTE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_status &= ~PCW_ATTRIBUTE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if caller says Write Protect, enforce it.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (page->state & PS_WP) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which |= CARDMEM_WRITE_PROTECT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_status |= PCW_WP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_status &= ~PCW_WP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tmemory type = %s\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (which & CARDMEM_REG_ACTIVE) ? "attribute" : "common");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (which & CARDMEM_WRITE_PROTECT)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\twrite protect\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tpage offset=%x pcw_base=%x (%x)\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (unsigned)page->offset,
193974072f41a843678abf5f61979c748687e66bSherry Moore (unsigned)memp->pcw_base,
193974072f41a843678abf5f61979c748687e66bSherry Moore (int)page->offset - (int)memp->pcw_base & 0xffffff);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* address computation based on 64MB range and not larger */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel base = (uint32_t)memp->pcw_base & 0x3ffffff;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_CARDMEM_0_LOW + select,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CARDMEM_LOW((int)page->offset - (int)base));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket, PCIC_CARDMEM_0_LOW + select);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_CARDMEM_0_HI + select,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CARDMEM_HIGH((int)page->offset - base) | which);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket, PCIC_CARDMEM_0_HI + select);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * while not really necessary, this just makes sure
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * nothing turned the window off behind our backs
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which = pcic_getb(pcic, socket, PCIC_MAPPING_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel which |= SYSMEM_WINDOW(window);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_MAPPING_ENABLE, which);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket, PCIC_MAPPING_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel memp->pcw_offset = (off_t)page->offset;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tbase=%p, *base=%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)memp->pcw_hostmem,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t)*memp->pcw_hostmem);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel xxdmp_all_regs(pcic, socket, -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tbase=%p, *base=%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)memp->pcw_hostmem,
193974072f41a843678abf5f61979c748687e66bSherry Moore (uint32_t)*memp->pcw_hostmem);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (which & PCW_ATTRIBUTE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket, 2);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_set_vcc_level()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * set voltage based on adapter information
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this routine implements a limited solution for support of 3.3v cards.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the general solution, which would fully support the pcmcia spec
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * as far as allowing client drivers to request which voltage levels
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to be set, requires more framework support and driver changes - ess
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_set_vcc_level(pcicdev_t *pcic, set_socket_t *socket)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t socket_present_state;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_set_vcc_level(pcic=%p, VccLevel=%d)\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic, socket->VccLevel);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * check VccLevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if this is zero, power is being turned off
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if it is non-zero, power is being turned on.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (socket->VccLevel == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * range checking for sanity's sake
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (socket->VccLevel >= pcic->pc_numpower) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VCC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_io_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Yenta-compliant adapters have vcc info in the extended registers
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Other adapters can be added as needed, but the 'default' case
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * has been left as it was previously so as not to break existing
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * adapters.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_IO_TYPE_YENTA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Here we ignore the VccLevel passed in and read the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * card type from the adapter socket present state register
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket_present_state =
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get32(pcic->handle, (uint32_t *)(pcic->ioaddr +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_PRESENT_STATE_REG));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "socket present state = 0x%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore socket_present_state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (socket_present_state & PCIC_VCC_MASK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_VCC_3VCARD:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* fall through */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_VCC_3VCARD|PCIC_VCC_5VCARD:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->VccLevel = PCIC_VCC_3VLEVEL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (POWER_3VCARD_ENABLE|POWER_OUTPUT_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_VCC_5VCARD:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->VccLevel = PCIC_VCC_5VLEVEL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (POWER_CARD_ENABLE|POWER_OUTPUT_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if no card is present, this can be the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * case of a client making a SetSocket call
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * after card removal. In this case we return
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the current power level
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return ((unsigned)ddi_get8(pcic->handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->ioaddr + CB_R2_OFFSET +
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_POWER_CONTROL));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (socket->VccLevel) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_VCC_3VLEVEL:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VCC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_VCC_5VLEVEL:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* enable Vcc */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (POWER_CARD_ENABLE|POWER_OUTPUT_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VCC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_set_socket()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Socket Services SetSocket call
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * sets basic socket configuration
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_set_socket(dev_info_t *dip, set_socket_t *socket)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *sockp = &pcic->pc_sockets[socket->socket];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int irq, interrupt, mirq;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int powerlevel = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ind, value, orig_pwrctl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_set_socket(dip=%p, socket=%d)"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " Vcc=%d Vpp1=%d Vpp2=%d\n", (void *)dip,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->socket, socket->VccLevel, socket->Vpp1Level,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->Vpp2Level);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * check VccLevel, etc. before setting mutex
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if this is zero, power is being turned off
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if it is non-zero, power is being turned on.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the default case is to assume Vcc only.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* this appears to be very implementation specific */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (socket->Vpp1Level != socket->Vpp2Level)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VPP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (socket->VccLevel == 0 || !(sockp->pcs_flags & PCS_CARD_PRESENT)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_vcc = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_vpp1 = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_vpp2 = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(dip, 9, "\tVcc=%d Vpp1Level=%d, Vpp2Level=%d\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->VccLevel, socket->Vpp1Level, socket->Vpp2Level);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* valid Vcc power level? */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (socket->VccLevel >= pcic->pc_numpower)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VCC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic_power[socket->VccLevel].PowerLevel) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case 33: /* 3.3V */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case 60: /* for bad CIS in Option GPRS card */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(pcic->pc_flags & PCF_33VCAP)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%s%d: Bad Request for 3.3V "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "(Controller incapable)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_name(pcic->dip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_instance(pcic->dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VCC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* FALLTHROUGH */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case 50: /* 5V */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((pcic->pc_io_type == PCIC_IO_TYPE_YENTA) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getcb(pcic, CB_PRESENT_STATE) &
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CB_PS_33VCARD) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This is actually a 3.3V card.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Solaris Card Services
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * doesn't understand 3.3V
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * so we cheat and change
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the setting to the one appropriate to 3.3V.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Note that this is the entry number
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * in the pcic_power[] array.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_vcc = PCIC_VCC_3VLEVEL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_vcc = socket->VccLevel;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VCC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* enable Vcc */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel = POWER_CARD_ENABLE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tVcc=%d powerlevel=%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->VccLevel, powerlevel);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ind = 0; /* default index to 0 power */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((int)socket->Vpp1Level >= 0 &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->Vpp1Level < pcic->pc_numpower) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(pcic_power[socket->Vpp1Level].ValidSignals
3db86aab554edbb4244c8d1a1c90f152eee768afstevel & VPP1)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VPP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ind = pcic_power[socket->Vpp1Level].PowerLevel/10;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel |= pcic_vpp_levels[ind];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_vpp1 = socket->Vpp1Level;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((int)socket->Vpp2Level >= 0 &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->Vpp2Level < pcic->pc_numpower) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(pcic_power[socket->Vpp2Level].ValidSignals
3db86aab554edbb4244c8d1a1c90f152eee768afstevel & VPP2)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VPP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ind = pcic_power[socket->Vpp2Level].PowerLevel/10;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel |= (pcic_vpp_levels[ind] << 2);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_vpp2 = socket->Vpp2Level;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_VPPX) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this adapter doesn't allow separate Vpp1/Vpp2
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * if one is turned on, both are turned on and only
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the Vpp1 bits should be set
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_vpp2 != sockp->pcs_vpp1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* must be the same if one not zero */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_vpp1 != 0 &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_vpp2 != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%s%d: Bad Power Request "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "(Vpp1/2 not the same)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_name(pcic->dip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_instance(pcic->dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VPP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel &= ~(3<<2);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tpowerlevel=%x, ind=%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel, ind);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock); /* protect the registers */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* turn socket->IREQRouting off while programming */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel interrupt = pcic_getb(pcic, socket->socket, PCIC_INTERRUPT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel interrupt &= ~PCIC_INTR_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_USE_SMI)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel interrupt |= PCIC_INTR_ENABLE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket, PCIC_INTERRUPT, interrupt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_82092_smiirq_ctl(pcic, socket->socket, PCIC_82092_CTL_IRQ,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_82092_INT_DISABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* the SCIntMask specifies events to detect */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mirq = pcic_getb(pcic, socket->socket, PCIC_MANAGEMENT_INT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tSCIntMask=%x, interrupt=%x, mirq=%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore socket->SCIntMask, interrupt, mirq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mirq &= ~(PCIC_BD_DETECT|PCIC_BW_DETECT|PCIC_RD_DETECT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket, PCIC_MANAGEMENT_INT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mirq & ~PCIC_CHANGE_MASK);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* save the mask we want to use */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_intmask = socket->SCIntMask;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Until there is a card present it's not worth enabling
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * any interrupts except "Card detect". This is done
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * elsewhere in the driver so don't change things if
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * there is no card!
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_flags & PCS_CARD_PRESENT) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* now update the hardware to reflect events desired */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_intmask & SBM_BVD1 || socket->IFType == IF_IO)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mirq |= PCIC_BD_DETECT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_intmask & SBM_BVD2)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mirq |= PCIC_BW_DETECT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_intmask & SBM_RDYBSY)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mirq |= PCIC_RD_DETECT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_intmask & SBM_CD)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mirq |= PCIC_CD_DETECT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_flags & PCS_READY) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * card just came ready.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * make sure enough time elapses
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * before touching it.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_flags &= ~PCS_READY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket->socket, 10);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tstatus change set to %x\n", mirq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_I82365SL:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_VADEM:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_VADEM_VG469:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The Intel version has different options. This is a
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * special case of GPI which might be used for eject
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq = pcic_getb(pcic, socket->socket, PCIC_CARD_DETECT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_intmask & (SBM_EJECT|SBM_INSERT) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags & PCF_GPI_EJECT) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq |= PCIC_GPI_ENABLE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq &= ~PCIC_GPI_ENABLE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket, PCIC_CARD_DETECT, irq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_CL_PD6710:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_CL_PD6722:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (socket->IFType == IF_IO) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket, PCIC_MISC_CTL_2, 0x0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, socket->socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_MISC_CTL_1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_AUDIO)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value |= PCIC_MC_SPEAKER_ENB;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket, PCIC_MISC_CTL_1,
193974072f41a843678abf5f61979c748687e66bSherry Moore value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, socket->socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_MISC_CTL_1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value &= ~PCIC_MC_SPEAKER_ENB;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket, PCIC_MISC_CTL_1,
193974072f41a843678abf5f61979c748687e66bSherry Moore value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_CL_PD6729:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_CL_PD6730:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_CL_PD6832:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, socket->socket, PCIC_MISC_CTL_1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((socket->IFType == IF_IO) && (pcic->pc_flags & PCF_AUDIO)) {
193974072f41a843678abf5f61979c748687e66bSherry Moore value |= PCIC_MC_SPEAKER_ENB;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
193974072f41a843678abf5f61979c748687e66bSherry Moore value &= ~PCIC_MC_SPEAKER_ENB;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_power[sockp->pcs_vcc].PowerLevel == 33)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value |= PCIC_MC_3VCC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value &= ~PCIC_MC_3VCC;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket, PCIC_MISC_CTL_1, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_O2_OZ6912:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getcb(pcic, CB_MISCCTRL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((socket->IFType == IF_IO) && (pcic->pc_flags & PCF_AUDIO))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value |= (1<<25);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value &= ~(1<<25);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putcb(pcic, CB_MISCCTRL, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_power[sockp->pcs_vcc].PowerLevel == 33)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel |= 0x08;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1250:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1221:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1225:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1410:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_ENE_1410:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1510:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1520:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_TI_PCI1420:
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_ENE_1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = ddi_get8(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->cfgaddr + PCIC_CRDCTL_REG);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((socket->IFType == IF_IO) && (pcic->pc_flags & PCF_AUDIO)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value |= PCIC_CRDCTL_SPKR_ENBL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value &= ~PCIC_CRDCTL_SPKR_ENBL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->cfgaddr + PCIC_CRDCTL_REG, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_power[sockp->pcs_vcc].PowerLevel == 33)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel |= 0x08;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * ctlind processing -- we can ignore this
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * there aren't any outputs on the chip for this and
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the GUI will display what it thinks is correct
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If outputs are enabled and the power is going off
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * turn off outputs first.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* power setup -- if necessary */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel orig_pwrctl = pcic_getb(pcic, socket->socket, PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((orig_pwrctl & POWER_OUTPUT_ENABLE) && sockp->pcs_vcc == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel orig_pwrctl &= ~POWER_OUTPUT_ENABLE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_POWER_CONTROL, orig_pwrctl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket->socket, PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_CBPWRCTL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_cbus_powerctl(pcic, socket->socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_exca_powerctl(pcic, socket->socket, powerlevel);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value != SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If outputs were disabled and the power is going on
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * turn on outputs afterwards.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(orig_pwrctl & POWER_OUTPUT_ENABLE) && sockp->pcs_vcc != 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel orig_pwrctl = pcic_getb(pcic, socket->socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel orig_pwrctl |= POWER_OUTPUT_ENABLE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_POWER_CONTROL, orig_pwrctl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket->socket, PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Once we have done the power stuff can re-enable management
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * interrupts.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket, PCIC_MANAGEMENT_INT, mirq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(dip, 8, "\tmanagement int set to %x pwrctl to 0x%x "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cbctl 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mirq, pcic_getb(pcic, socket->socket, PCIC_POWER_CONTROL),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getcb(pcic, CB_CONTROL));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* irq processing */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (socket->IFType == IF_IO) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* IRQ only for I/O */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq = socket->IREQRouting & PCIC_INTR_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, socket->socket, PCIC_INTERRUPT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value &= ~PCIC_INTR_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* to enable I/O operation */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value |= PCIC_IO_CARD | PCIC_RESET;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_flags |= PCS_CARD_IO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (irq != sockp->pcs_irq) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_irq != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "SetSocket: IRQ mismatch %x != %x!\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore irq, sockp->pcs_irq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_irq = irq;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq = sockp->pcs_irq;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket, PCIC_INTERRUPT, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (socket->IREQRouting & IRQ_ENABLE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_enable_io_intr(pcic, socket->socket, irq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_flags |= PCS_IRQ_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_disable_io_intr(pcic, socket->socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_flags &= ~PCS_IRQ_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tsocket type is I/O and irq %x is %s\n", irq,
193974072f41a843678abf5f61979c748687e66bSherry Moore (socket->IREQRouting & IRQ_ENABLE) ?
193974072f41a843678abf5f61979c748687e66bSherry Moore "enabled" : "not enabled");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel xxdmp_all_regs(pcic, socket->socket, 20);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* make sure I/O mode is off */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_irq = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, socket->socket, PCIC_INTERRUPT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value &= ~PCIC_IO_CARD;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket->socket, PCIC_INTERRUPT, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_disable_io_intr(pcic, socket->socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_flags &= ~(PCS_CARD_IO|PCS_IRQ_ENABLED);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_state &= ~socket->State;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_inquire_socket()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices InquireSocket function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * returns basic characteristics of the socket
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_inquire_socket(dev_info_t *dip, inquire_socket_t *socket)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->SCIntCaps = PCIC_DEFAULT_INT_CAPS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->SCRptCaps = PCIC_DEFAULT_RPT_CAPS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->CtlIndCaps = PCIC_DEFAULT_CTL_CAPS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic->pc_sockets[socket->socket].pcs_flags;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->SocketCaps = (value & PCS_SOCKET_IO) ? IF_IO : IF_MEMORY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->ActiveHigh = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* these are the usable IRQs */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->ActiveLow = 0xfff0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_inquire_window()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices InquireWindow function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * returns detailed characteristics of the window
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this is where windows get tied to sockets
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_inquire_window(dev_info_t *dip, inquire_window_t *window)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int type, socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel type = window->window % PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket = window->window / PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug >= 8)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_inquire_window: window = %d/%d socket=%d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore window->window, type, socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (type < PCIC_IOWINDOWS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->WndCaps = WC_IO|WC_WAIT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel type = IF_IO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->WndCaps = WC_COMMON|WC_ATTRIBUTE|WC_WAIT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel type = IF_MEMORY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* initialize the socket map - one socket per window */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PR_ZERO(window->Sockets);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PR_SET(window->Sockets, socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (type == IF_IO) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel iowin_char_t *io;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io = &window->iowin_char;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io->IOWndCaps = WC_BASE|WC_SIZE|WC_WENABLE|WC_8BIT|
193974072f41a843678abf5f61979c748687e66bSherry Moore WC_16BIT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io->FirstByte = (baseaddr_t)IOMEM_FIRST;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io->LastByte = (baseaddr_t)IOMEM_LAST;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io->MinSize = IOMEM_MIN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io->MaxSize = IOMEM_MAX;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io->ReqGran = IOMEM_GRAN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io->AddrLines = IOMEM_DECODE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io->EISASlot = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem_win_char_t *mem;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem = &window->mem_win_char;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->MemWndCaps = WC_BASE|WC_SIZE|WC_WENABLE|WC_8BIT|
193974072f41a843678abf5f61979c748687e66bSherry Moore WC_16BIT|WC_WP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->FirstByte = (baseaddr_t)MEM_FIRST;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->LastByte = (baseaddr_t)MEM_LAST;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->MinSize = MEM_MIN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->MaxSize = MEM_MAX;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->ReqGran = PCIC_PAGE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->ReqBase = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->ReqOffset = PCIC_PAGE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->Slowest = MEM_SPEED_MAX;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->Fastest = MEM_SPEED_MIN;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_get_adapter()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices GetAdapter function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this is nearly a no-op.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_get_adapter(dev_info_t *dip, get_adapter_t *adapt)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_flags & PCF_INTRENAB)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel adapt->SCRouting = IRQ_ENABLE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel adapt->state = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_get_page()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices GetPage function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * returns info about the window
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_get_page(dev_info_t *dip, get_page_t *page)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int socket, window;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcs_memwin_t *winp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket = page->window / PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window = page->window % PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* I/O windows are the first two */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (window < PCIC_IOWINDOWS || socket >= pcic->pc_numsockets) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_WINDOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp = &pcic->pc_sockets[socket].pcs_windows[window].mem;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (page->page != 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_PAGE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel page->state = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (winp->pcw_status & PCW_ENABLED)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel page->state |= PS_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (winp->pcw_status & PCW_ATTRIBUTE)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel page->state |= PS_ATTRIBUTE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (winp->pcw_status & PCW_WP)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel page->state |= PS_WP;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel page->offset = (off_t)winp->pcw_offset;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_get_socket()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices GetSocket
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * returns information about the current socket setting
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_get_socket(dev_info_t *dip, get_socket_t *socket)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int socknum, irq_enabled;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *sockp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socknum = socket->socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp = &pcic->pc_sockets[socknum];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->SCIntMask = sockp->pcs_intmask;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_state = pcic_card_state(pcic, sockp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->state = sockp->pcs_state;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (socket->state & SBM_CD) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->VccLevel = sockp->pcs_vcc;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->Vpp1Level = sockp->pcs_vpp1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->Vpp2Level = sockp->pcs_vpp2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq_enabled = (sockp->pcs_flags & PCS_IRQ_ENABLED) ?
3db86aab554edbb4244c8d1a1c90f152eee768afstevel IRQ_ENABLE : 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->IRQRouting = sockp->pcs_irq | irq_enabled;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->IFType = (sockp->pcs_flags & PCS_CARD_IO) ?
3db86aab554edbb4244c8d1a1c90f152eee768afstevel IF_IO : IF_MEMORY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->VccLevel = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->Vpp1Level = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->Vpp2Level = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->IRQRouting = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->IFType = IF_MEMORY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket->CtlInd = 0; /* no indicators */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_get_status()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices GetStatus
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * returns status information about the PC Card in
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the selected socket
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_get_status(dev_info_t *dip, get_ss_status_t *status)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int socknum, irq_enabled;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *sockp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socknum = status->socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp = &pcic->pc_sockets[socknum];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status->CardState = pcic_card_state(pcic, sockp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status->SocketState = sockp->pcs_state;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status->CtlInd = 0; /* no indicators */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_flags & PCS_CARD_PRESENT)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status->SocketState |= SBM_CD;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (status->CardState & SBM_CD) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq_enabled = (sockp->pcs_flags & PCS_CARD_ENABLED) ?
3db86aab554edbb4244c8d1a1c90f152eee768afstevel IRQ_ENABLE : 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status->IRQRouting = sockp->pcs_irq | irq_enabled;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status->IFType = (sockp->pcs_flags & PCS_CARD_IO) ?
3db86aab554edbb4244c8d1a1c90f152eee768afstevel IF_IO : IF_MEMORY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status->IRQRouting = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status->IFType = IF_MEMORY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug >= 8)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_get_status: socket=%d, CardState=%x,"
193974072f41a843678abf5f61979c748687e66bSherry Moore "SocketState=%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore socknum, status->CardState, status->SocketState);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t present_state;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1520:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_ENE_1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TOSHIBA_TOPIC100:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TOSHIBA_TOPIC95:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TOSHIBA_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_O2MICRO_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_RICOH_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel present_state = pcic_getcb(pcic, CB_PRESENT_STATE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (present_state & PCIC_CB_CARD)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status->IFType = IF_CARDBUS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug >= 8)
193974072f41a843678abf5f61979c748687e66bSherry Moore cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_get_status: present_state=0x%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore present_state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_get_window()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices GetWindow function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * returns state information about the specified window
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*ARGSUSED*/
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_get_window(dev_info_t *dip, get_window_t *window)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int socket, win;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *sockp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcs_memwin_t *winp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket = window->window / PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel win = window->window % PCIC_NUMWINSOCK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_get_window(socket=%d, window=%d)\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore socket, win);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (socket > pcic->pc_numsockets)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_WINDOW);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp = &pcic->pc_sockets[socket];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel winp = &sockp->pcs_windows[win].mem;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->socket = socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->size = winp->pcw_len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->speed = winp->pcw_speed;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->handle = (ddi_acc_handle_t)winp->pcw_handle;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->base = (uint32_t)winp->pcw_base + winp->pcw_offset;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (win >= PCIC_IOWINDOWS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->state = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->state = WS_IO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (winp->pcw_status & PCW_ENABLED)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->state |= WS_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (winp->pcw_status & PCS_CARD_16BIT)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel window->state |= WS_16BIT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tsize=%d, speed=%d, base=%p, state=%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore window->size, (unsigned)window->speed,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)window->handle, window->state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_ll_reset
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * low level reset
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * separated out so it can be called when already locked
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * There are two variables that control the RESET timing:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_prereset_time - time in mS before asserting RESET
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_reset_time - time in mS to assert RESET
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_prereset_time = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_reset_time = 10;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_postreset_time = 20;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_vpp_is_vcc_during_reset = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_ll_reset(pcicdev_t *pcic, int socket)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int windowbits, iobits;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t pwr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* save windows that were on */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel windowbits = pcic_getb(pcic, socket, PCIC_MAPPING_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_reset_time == 0)
193974072f41a843678abf5f61979c748687e66bSherry Moore return (windowbits);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* turn all windows off */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_MAPPING_ENABLE, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 6,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_ll_reset(socket %d) powerlevel=%x cbctl 0x%x cbps 0x%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore socket, pcic_getb(pcic, socket, PCIC_POWER_CONTROL),
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_getcb(pcic, CB_CONTROL),
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_getcb(pcic, CB_PRESENT_STATE));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_vpp_is_vcc_during_reset) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Set VPP to VCC for the duration of the reset - for aironet
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * card.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
193974072f41a843678abf5f61979c748687e66bSherry Moore if (pcic->pc_flags & PCF_CBPWRCTL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pwr = pcic_getcb(pcic, CB_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putcb(pcic, CB_CONTROL, (pwr&~CB_C_VPPMASK)|CB_C_VPPVCC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getcb(pcic, CB_CONTROL);
193974072f41a843678abf5f61979c748687e66bSherry Moore } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pwr = pcic_getb(pcic, socket, PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_POWER_CONTROL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pwr | 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket, PCIC_POWER_CONTROL);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_prereset_time > 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8, "pcic_ll_reset pre_wait %d mS\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_prereset_time);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket, pcic_prereset_time);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* turn interrupts off and start a reset */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_ll_reset turn interrupts off and start a reset\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel iobits = pcic_getb(pcic, socket, PCIC_INTERRUPT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel iobits &= ~(PCIC_INTR_MASK | PCIC_RESET);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_INTERRUPT, iobits);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket, PCIC_INTERRUPT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
193974072f41a843678abf5f61979c748687e66bSherry Moore case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_82092_smiirq_ctl(pcic, socket, PCIC_82092_CTL_IRQ,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_82092_INT_DISABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[socket].pcs_state = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_reset_time > 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8, "pcic_ll_reset reset_wait %d mS\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_reset_time);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket, pcic_reset_time);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8, "pcic_ll_reset take it out of reset now\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* take it out of RESET now */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_INTERRUPT, PCIC_RESET | iobits);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket, PCIC_INTERRUPT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * can't access the card for 20ms, but we really don't
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * want to sit around that long. The pcic is still usable.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * memory accesses must wait for RDY to come up.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_postreset_time > 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8, "pcic_ll_reset post_wait %d mS\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_postreset_time);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket, pcic_postreset_time);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_vpp_is_vcc_during_reset > 1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Return VPP power to whatever it was before.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
193974072f41a843678abf5f61979c748687e66bSherry Moore if (pcic->pc_flags & PCF_CBPWRCTL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putcb(pcic, CB_CONTROL, pwr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getcb(pcic, CB_CONTROL);
193974072f41a843678abf5f61979c748687e66bSherry Moore } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_POWER_CONTROL, pwr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket, PCIC_POWER_CONTROL);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 7, "pcic_ll_reset returning 0x%x\n", windowbits);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (windowbits);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_reset_socket()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices ResetSocket function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * puts the PC Card in the socket into the RESET state
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and then takes it out after the the cycle time
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The socket is back to initial state when done
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_reset_socket(dev_info_t *dip, int socket, int mode)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i, mint;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *sockp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug >= 8)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_reset_socket(%p, %d, %d/%s)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *)dip, socket, mode,
193974072f41a843678abf5f61979c748687e66bSherry Moore mode == RESET_MODE_FULL ? "full" : "partial");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock); /* protect the registers */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Turn off management interupts. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mint = pcic_getb(pcic, socket, PCIC_MANAGEMENT_INT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_MANAGEMENT_INT, mint & ~PCIC_CHANGE_MASK);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp = &pcic->pc_sockets[socket];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_ll_reset(pcic, socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (mode == RESET_MODE_FULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* disable and unmap all mapped windows */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < PCIC_NUMWINSOCK; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (i < PCIC_IOWINDOWS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_windows[i].io.pcw_status &
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCW_MAPPED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcs_iowin_t *io;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io = &sockp->pcs_windows[i].io;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel io->pcw_status &= ~PCW_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_windows[i].mem.pcw_status &
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCW_MAPPED) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcs_memwin_t *mem;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem = &sockp->pcs_windows[i].mem;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mem->pcw_status &= ~PCW_ENABLED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* turn windows back on */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_MAPPING_ENABLE, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* wait the rest of the time here */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket, 10);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_MANAGEMENT_INT, mint);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_set_interrupt()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices SetInterrupt function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_set_interrupt(dev_info_t *dip, set_irq_handler_t *handler)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value = DDI_SUCCESS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel inthandler_t *intr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_set_interrupt: entered pc_intr_mode=0x%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_intr_mode);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\t irq_top=%p handler=%p handler_id=%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic->irq_top, (void *)handler->handler,
193974072f41a843678abf5f61979c748687e66bSherry Moore handler->handler_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If we're on a PCI bus, we route all IO IRQs through a single
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * PCI interrupt (typically INT A#) so we don't have to do
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * much other than add the caller to general interrupt handler
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and set some state.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr = kmem_zalloc(sizeof (inthandler_t), KM_NOSLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (intr == NULL)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (NO_RESOURCE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_intr_mode) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_PCI_1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We only allow above-lock-level IO IRQ handlers
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * in the PCI bus case.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->irq_top == NULL) {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->irq_top = intr;
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->irq_current = pcic->irq_top;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
193974072f41a843678abf5f61979c748687e66bSherry Moore while (pcic->irq_current->next != NULL)
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->irq_current = pcic->irq_current->next;
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->irq_current->next = intr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current = pcic->irq_current->next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current->intr =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (ddi_intr_handler_t *)handler->handler;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current->handler_id = handler->handler_id;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current->arg1 = handler->arg1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current->arg2 = handler->arg2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current->socket = handler->socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel handler->iblk_cookie = &pcic->pc_pri;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel handler->idev_cookie = &pcic->pc_dcookie;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr->intr = (ddi_intr_handler_t *)handler->handler;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr->handler_id = handler->handler_id;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr->arg1 = handler->arg1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr->arg2 = handler->arg2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr->socket = handler->socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr->irq = handler->irq;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * need to revisit this to see if interrupts can be
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * shared someday. Note that IRQ is set in the common
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * code.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->pc_handlers == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_handlers = intr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr->next = intr->prev = intr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel insque(intr, pcic->pc_handlers);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * need to fill in cookies in event of multiple high priority
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * interrupt handlers on same IRQ
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_set_interrupt: exit irq_top=%p value=%d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic->irq_top, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value == DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_IRQ);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_clear_interrupt()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * SocketServices ClearInterrupt function
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Interrupts for PCIC are complicated by the fact that we must
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * follow several different models for interrupts.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * ISA: there is an interrupt per adapter and per socket and
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * they can't be shared.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * PCI: some adapters have one PCI interrupt available while others
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * have up to 4. Solaris may or may not allow us to use more
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * than 1 so we essentially share them all at this point.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Hybrid: PCI bridge but interrupts wired to host interrupt controller.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This is like ISA but we have to fudge and create an intrspec
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * that PCI's parent understands and bypass the PCI nexus.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * multifunction: this requires sharing the interrupts on a per-socket
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * basis.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_clear_interrupt(dev_info_t *dip, clear_irq_handler_t *handler)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel inthandler_t *intr, *prev, *current;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * If we're on a PCI bus, we route all IO IRQs through a single
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * PCI interrupt (typically INT A#) so we don't have to do
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * much other than remove the caller from the general
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * interrupt handler callout list.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_clear_interrupt: entered pc_intr_mode=0x%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_intr_mode);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\t irq_top=%p handler=%p handler_id=%x\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic->irq_top, (void *)handler->handler,
193974072f41a843678abf5f61979c748687e66bSherry Moore handler->handler_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_intr_mode) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTR_MODE_PCI_1:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->irq_top == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_IRQ);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current = pcic->irq_top;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while ((pcic->irq_current != NULL) &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (pcic->irq_current->handler_id !=
193974072f41a843678abf5f61979c748687e66bSherry Moore handler->handler_id)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr = pcic->irq_current;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current = pcic->irq_current->next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic->irq_current == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_IRQ);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (intr != NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr->next = pcic->irq_current->next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_top = pcic->irq_current->next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel current = pcic->irq_current;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->irq_current = pcic->irq_top;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->intr_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(current, sizeof (inthandler_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr = pcic_handlers;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel prev = (inthandler_t *)&pcic_handlers;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (intr != NULL) {
193974072f41a843678abf5f61979c748687e66bSherry Moore if (intr->handler_id == handler->handler_id) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel i = intr->irq & PCIC_INTR_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (--pcic_irq_map[i].count == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* multi-handler form */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_disable(pcic->pc_intr_htblp[i]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_remove_handler(
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_intr_htblp[i]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_intr_free(pcic->pc_intr_htblp[i]);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcmcia_return_intr(pcic->dip, i);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "removing interrupt %d at %s "
193974072f41a843678abf5f61979c748687e66bSherry Moore "priority\n", i, "high");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "ddi_remove_intr(%p, %x, %p)\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore 0,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)intr->iblk_cookie);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel prev->next = intr->next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(intr, sizeof (inthandler_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr = prev->next;
193974072f41a843678abf5f61979c748687e66bSherry Moore } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel prev = intr;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intr = intr->next;
193974072f41a843678abf5f61979c748687e66bSherry Moore } /* if (handler_id) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* while */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_clear_interrupt: exit irq_top=%p\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic->irq_top);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstruct intel_regs {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *name;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int off;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *fmt;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel} iregs[] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"ident ", 0},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"if-status ", 1, "\020\1BVD1\2BVD2\3CD1\4CD2\5WP\6RDY\7PWR\10~GPI"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"power ", 2, "\020\1Vpp1c0\2Vpp1c1\3Vpp2c0\4Vpp2c1\5PE\6AUTO"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\7DRD\10OE"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"cardstatus", 4, "\020\1BD\2BW\3RC\4CD\5GPI\6R1\7R2\010R3"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"enable ", 6, "\020\1MW0\2MW1\3MW2\4MW3\5MW4\6MEM16\7IO0\10IO1"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"cd-gcr ", 0x16, "\020\1MDI16\2CRE\3GPIE\4GPIT\5CDR\6S/W"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"GCR ", 0x1e, "\020\1PD\2LEVEL\3WCSC\4PLS14"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"int-gcr ", 3, "\020\5INTR\6IO\7~RST\10RI"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"management", 5, "\020\1BDE\2BWE\3RE\4CDE"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"volt-sense", 0x1f, "\020\1A_VS1\2A_VS2\3B_VS1\4B_VS2"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"volt-sel ", 0x2f, "\020\5EXTCONF\6BUSSELECT\7MIXEDV\10ISAV"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"VG ext A ", 0x3c, "\20\3IVS\4CABLE\5CSTEP\6TEST\7RIO"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"io-ctrl ", 7, "\020\1DS0\2IOCS0\3ZWS0\4WS0\5DS1\6IOS1\7ZWS1\10WS1"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"io0-slow ", 8},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"io0-shi ", 9},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"io0-elow ", 0xa},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"io0-ehi ", 0xb},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"io1-slow ", 0xc},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"io1-shi ", 0xd},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"io1-elow ", 0xe},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"io1-ehi ", 0xf},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem0-slow ", 0x10},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem0-shi ", 0x11, "\020\7ZW\10DS"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem0-elow ", 0x12},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem0-ehi ", 0x13, "\020\7WS0\10WS1"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"card0-low ", 0x14},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"card0-hi ", 0x15, "\020\7AM\10WP"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem1-slow ", 0x18},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem1-shi ", 0x19, "\020\7ZW\10DS"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem1-elow ", 0x1a},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem1-ehi ", 0x1b, "\020\7WS0\10WS1"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"card1-low ", 0x1c},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"card1-hi ", 0x1d, "\020\7AM\10WP"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem2-slow ", 0x20},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem2-shi ", 0x21, "\020\7ZW\10DS"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem2-elow ", 0x22},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem2-ehi ", 0x23, "\020\7WS0\10WS1"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"card2-low ", 0x24},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"card2-hi ", 0x25, "\020\7AM\10WP"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem3-slow ", 0x28},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem3-shi ", 0x29, "\020\7ZW\10DS"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem3-elow ", 0x2a},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem3-ehi ", 0x2b, "\020\7WS0\10WS1"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"card3-low ", 0x2c},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"card3-hi ", 0x2d, "\020\7AM\10WP"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem4-slow ", 0x30},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem4-shi ", 0x31, "\020\7ZW\10DS"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem4-elow ", 0x32},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem4-ehi ", 0x33, "\020\7WS0\10WS1"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"card4-low ", 0x34},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"card4-hi ", 0x35, "\020\7AM\10WP"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mpage0 ", 0x40},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mpage1 ", 0x41},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mpage2 ", 0x42},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mpage3 ", 0x43},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mpage4 ", 0x44},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {NULL},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct intel_regs cregs[] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"misc-ctl1 ", 0x16, "\20\2VCC3\3PMI\4PSI\5SPKR\10INPACK"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"fifo ", 0x17, "\20\6DIOP\7DMEMP\10EMPTY"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"misc-ctl2 ", 0x1e, "\20\1XCLK\2LOW\3SUSP\4CORE5V\5TCD\10RIOUT"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"chip-info ", 0x1f, "\20\6DUAL"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"IO-offlow0", 0x36},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"IO-offhi0 ", 0x37},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"IO-offlow1", 0x38},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"IO-offhi1 ", 0x39},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel NULL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic struct intel_regs cxregs[] = {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"ext-ctl-1 ", 0x03,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\20\1VCCLCK\2AUTOCLR\3LED\4INVIRQC\5INVIRQM\6PUC"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"misc-ctl3 ", 0x25, "\20\5HWSUSP"},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem0-up ", 0x05},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem1-up ", 0x06},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem2-up ", 0x07},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem3-up ", 0x08},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {"mem4-up ", 0x09},
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {NULL}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel};
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelvoid
3db86aab554edbb4244c8d1a1c90f152eee768afstevelxxdmp_cl_regs(pcicdev_t *pcic, int socket, uint32_t len)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i, value, j;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char buff[256];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *fmt;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "--------- Cirrus Logic Registers --------\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (buff[0] = '\0', i = 0; cregs[i].name != NULL && len-- != 0; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int sval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cregs[i].off == PCIC_MISC_CTL_2)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sval = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sval = socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, sval, cregs[i].off);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (i & 1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cregs[i].fmt)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "%s\t%s\t%b\n";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "%s\t%s\t%x\n";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, fmt, buff,
193974072f41a843678abf5f61979c748687e66bSherry Moore cregs[i].name, value, cregs[i].fmt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel buff[0] = '\0';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cregs[i].fmt)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "\t%s\t%b";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "\t%s\t%x";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(buff, fmt,
193974072f41a843678abf5f61979c748687e66bSherry Moore cregs[i].name, value, cregs[i].fmt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (j = strlen(buff); j < 40; j++)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel buff[j] = ' ';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel buff[40] = '\0';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "%s\n", buff);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel i = pcic_getb(pcic, socket, PCIC_TIME_SETUP_0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j = pcic_getb(pcic, socket, PCIC_TIME_SETUP_1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tsetup-tim0\t%x\tsetup-tim1\t%x\n", i, j);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel i = pcic_getb(pcic, socket, PCIC_TIME_COMMAND_0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j = pcic_getb(pcic, socket, PCIC_TIME_COMMAND_1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\tcmd-tim0 \t%x\tcmd-tim1 \t%x\n", i, j);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel i = pcic_getb(pcic, socket, PCIC_TIME_RECOVER_0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel j = pcic_getb(pcic, socket, PCIC_TIME_RECOVER_1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "\trcvr-tim0 \t%x\trcvr-tim1 \t%x\n", i, j);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "--------- Extended Registers --------\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (buff[0] = '\0', i = 0; cxregs[i].name != NULL && len-- != 0; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = clext_reg_read(pcic, socket, cxregs[i].off);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (i & 1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cxregs[i].fmt)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "%s\t%s\t%b\n";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "%s\t%s\t%x\n";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, fmt, buff,
193974072f41a843678abf5f61979c748687e66bSherry Moore cxregs[i].name, value, cxregs[i].fmt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel buff[0] = '\0';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cxregs[i].fmt)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "\t%s\t%b";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "\t%s\t%x";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(buff, fmt,
193974072f41a843678abf5f61979c748687e66bSherry Moore cxregs[i].name, value, cxregs[i].fmt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (j = strlen(buff); j < 40; j++)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel buff[j] = ' ';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel buff[40] = '\0';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelxxdmp_all_regs(pcicdev_t *pcic, int socket, uint32_t len)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i, value, j;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char buff[256];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char *fmt;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug < 2)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "----------- PCIC Registers for socket %d---------\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "\tname value name value\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (buff[0] = '\0', i = 0; iregs[i].name != NULL && len-- != 0; i++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, socket, iregs[i].off);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (i & 1) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (iregs[i].fmt)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "%s\t%s\t%b\n";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "%s\t%s\t%x\n";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, fmt, buff,
193974072f41a843678abf5f61979c748687e66bSherry Moore iregs[i].name, value, iregs[i].fmt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel buff[0] = '\0';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (iregs[i].fmt)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "\t%s\t%b";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel fmt = "\t%s\t%x";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(buff, fmt,
193974072f41a843678abf5f61979c748687e66bSherry Moore iregs[i].name, value, iregs[i].fmt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (j = strlen(buff); j < 40; j++)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel buff[j] = ' ';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel buff[40] = '\0';
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6710:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6722:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6729:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6832:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) xxdmp_cl_regs(pcic, socket, 0xFFFF);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "%s\n", buff);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_mswait(ms)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * sleep ms milliseconds
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * call drv_usecwait once for each ms
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_mswait(pcicdev_t *pcic, int socket, int ms)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ms) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[socket].pcs_flags |= PCS_WAITING;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel delay(drv_usectohz(ms*1000));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mutex_enter(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_sockets[socket].pcs_flags &= ~PCS_WAITING;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_check_ready(pcic, index, off)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Wait for card to come ready
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We only wait if the card is NOT in RESET
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and power is on.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic boolean_t
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_check_ready(pcicdev_t *pcic, int socket)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ifstate, intstate;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel intstate = pcic_getb(pcic, socket, PCIC_INTERRUPT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ifstate = pcic_getb(pcic, socket, PCIC_INTERFACE_STATUS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((intstate & PCIC_RESET) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ((ifstate & (PCIC_READY|PCIC_POWER_ON|PCIC_ISTAT_CD_MASK)) ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (PCIC_READY|PCIC_POWER_ON|PCIC_CD_PRESENT_OK)))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (B_TRUE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(NULL, 5, "pcic_check_read: Card not ready, intstate = 0x%x, "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "ifstate = 0x%x\n", intstate, ifstate);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_debug += 4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel xxdmp_all_regs(pcic, socket, -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_debug -= 4;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (B_FALSE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Cirrus Logic extended register read/write routines
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelclext_reg_read(pcicdev_t *pcic, int sn, uchar_t ext_reg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_io_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_IO_TYPE_YENTA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = ddi_get8(pcic->handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->ioaddr + CB_CLEXT_OFFSET + ext_reg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, sn, PCIC_CL_EXINDEX, ext_reg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = pcic_getb(pcic, sn, PCIC_CL_EXINDEX + 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (val);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelclext_reg_write(pcicdev_t *pcic, int sn, uchar_t ext_reg, uchar_t value)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_io_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_IO_TYPE_YENTA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->ioaddr + CB_CLEXT_OFFSET + ext_reg, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, sn, PCIC_CL_EXINDEX, ext_reg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, sn, PCIC_CL_EXINDEX + 1, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Misc PCI functions
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_iomem_pci_ctl(ddi_acc_handle_t handle, uchar_t *cfgaddr, unsigned flags)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unsigned cmd;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (flags & (PCIC_ENABLE_IO | PCIC_ENABLE_MEM)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmd = ddi_get16(handle, (ushort_t *)(cfgaddr + 4));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((cmd & (PCI_COMM_IO|PCI_COMM_MAE)) ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (PCI_COMM_IO|PCI_COMM_MAE))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (flags & PCIC_ENABLE_IO)
193974072f41a843678abf5f61979c748687e66bSherry Moore cmd |= PCI_COMM_IO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (flags & PCIC_ENABLE_MEM)
193974072f41a843678abf5f61979c748687e66bSherry Moore cmd |= PCI_COMM_MAE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put16(handle, (ushort_t *)(cfgaddr + 4), cmd);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* if (PCIC_ENABLE_IO | PCIC_ENABLE_MEM) */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_find_pci_type - Find and return PCI-PCMCIA adapter type
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_find_pci_type(pcicdev_t *pcic)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t vend, device;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel vend = ddi_getprop(DDI_DEV_T_ANY, pcic->dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_PROP_CANSLEEP|DDI_PROP_DONTPASS,
193974072f41a843678abf5f61979c748687e66bSherry Moore "vendor-id", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel device = ddi_getprop(DDI_DEV_T_ANY, pcic->dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_PROP_CANSLEEP|DDI_PROP_DONTPASS,
193974072f41a843678abf5f61979c748687e66bSherry Moore "device-id", -1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel device = PCI_ID(vend, device);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = device;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = "PCI:unknown";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (device) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_i82092;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6729:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PD6729;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Some 6730's incorrectly identify themselves
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * as a 6729, so we need to do some more tests
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * here to see if the device that's claiming
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * to be a 6729 is really a 6730.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((clext_reg_read(pcic, 0, PCIC_CLEXT_MISC_CTL_3) &
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_CLEXT_MISC_CTL_3_REV_MASK) ==
193974072f41a843678abf5f61979c748687e66bSherry Moore 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PD6730;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_CL_PD6730;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6730:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PD6730;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6832:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PD6832;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_SMC_34C90:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_34C90;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TOSHIBA_TOPIC95:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_TOPIC95;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TOSHIBA_TOPIC100:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_TOPIC100;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1031:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1031;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1130:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1130;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1131:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1131;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1250:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1250;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1225:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1225;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1410;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1510:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1510;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1520:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1520;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1221:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1221;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1050:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1050;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_ENE_1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_1410;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_O2_OZ6912:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_OZ6912;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_RICOH_RL5C466:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_RL5C466;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PCI1420;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_ENE_1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_1420;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (PCI_ID(vend, (uint32_t)0)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TOSHIBA_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_TOSHIBA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_TOSHIBA_VENDOR;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_TI;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_TI_VENDOR;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_O2MICRO_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_O2MICRO;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_O2MICRO_VENDOR;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_RICOH_VENDOR:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_RICOH;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_RICOH_VENDOR;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(pcic->pc_flags & PCF_CARDBUS))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_YENTA;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_82092_smiirq_ctl(pcicdev_t *pcic, int socket, int intr, int state)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uchar_t ppirr = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_82092_PPIRR);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uchar_t val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (intr == PCIC_82092_CTL_SMI) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = PCIC_82092_SMI_CTL(socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_82092_INT_DISABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppirr &= ~val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = PCIC_82092_SMI_CTL(socket, state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppirr |= val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = PCIC_82092_IRQ_CTL(socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_82092_INT_DISABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppirr &= ~val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel val = PCIC_82092_IRQ_CTL(socket, state);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ppirr |= val;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->cfg_handle, pcic->cfgaddr + PCIC_82092_PPIRR,
193974072f41a843678abf5f61979c748687e66bSherry Moore ppirr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint_t
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_cd_softint(caddr_t arg1, caddr_t arg2)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *sockp = (pcic_socket_t *)arg1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint_t rc = DDI_INTR_UNCLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel _NOTE(ARGUNUSED(arg2))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&sockp->pcs_pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_cd_softint_flg) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t status;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_cd_softint_flg = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel rc = DDI_INTR_CLAIMED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = pcic_getb(sockp->pcs_pcic, sockp->pcs_socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_INTERFACE_STATUS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_handle_cd_change(sockp->pcs_pcic, sockp, status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&sockp->pcs_pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (rc);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_debounce_cnt = PCIC_REM_DEBOUNCE_CNT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_debounce_intr_time = PCIC_REM_DEBOUNCE_TIME;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelint pcic_debounce_cnt_ok = PCIC_DEBOUNCE_OK_CNT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint32_t pcic_cbps_on = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint32_t pcic_cbps_off = CB_PS_NOTACARD | CB_PS_CCDMASK |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CB_PS_XVCARD | CB_PS_YVCARD;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint32_t pcic_cbps_on = CB_PS_16BITCARD;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint32_t pcic_cbps_off = CB_PS_NOTACARD | CB_PS_CCDMASK |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CB_PS_CBCARD |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CB_PS_XVCARD | CB_PS_YVCARD;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_handle_cd_change(pcicdev_t *pcic, pcic_socket_t *sockp, uint8_t status)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel boolean_t do_debounce = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int debounce_time = drv_usectohz(pcic_debounce_time);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t irq;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel timeout_id_t debounce;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Always reset debounce but may need to check original state later.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel debounce = sockp->pcs_debounce_id;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_debounce_id = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Check to see whether a card is present or not. There are
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * only two states that we are concerned with - the state
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * where both CD pins are asserted, which means that the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * card is fully seated, and the state where neither CD
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pin is asserted, which means that the card is not
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * present.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The CD signals are generally very noisy and cause a lot of
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * contact bounce as the card is being inserted and
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * removed, so we need to do some software debouncing.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_err(pcic->dip, 6,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic%d handle_cd_change: socket %d card status 0x%x"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel " deb 0x%p\n", ddi_get_instance(pcic->dip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_socket, status, debounce);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (status & PCIC_ISTAT_CD_MASK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CD_PRESENT_OK:
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_flags &= ~(PCS_CARD_REMOVED|PCS_CARD_CBREM);
193974072f41a843678abf5f61979c748687e66bSherry Moore if (!(sockp->pcs_flags & PCS_CARD_PRESENT)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t cbps;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8, "New card (0x%x)\n", sockp->pcs_flags);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbps = pcic_getcb(pcic, CB_PRESENT_STATE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8, "CBus PS (0x%x)\n", cbps);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Check the CB bits are sane.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((cbps & pcic_cbps_on) != pcic_cbps_on ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbps & pcic_cbps_off) {
193974072f41a843678abf5f61979c748687e66bSherry Moore cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%s%d: Odd Cardbus Present State 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_name(pcic->dip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_instance(pcic->dip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbps);
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_putcb(pcic, CB_EVENT_FORCE, CB_EF_CVTEST);
193974072f41a843678abf5f61979c748687e66bSherry Moore debounce = 0;
193974072f41a843678abf5f61979c748687e66bSherry Moore debounce_time = drv_usectohz(1000000);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (debounce) {
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_flags |= PCS_CARD_PRESENT;
193974072f41a843678abf5f61979c748687e66bSherry Moore if (pcic_do_insertion) {
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore cbps = pcic_getcb(pcic, CB_PRESENT_STATE);
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore if (cbps & CB_PS_16BITCARD) {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_err(pcic->dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore 8, "16 bit card inserted\n");
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_flags |= PCS_CARD_IS16BIT;
193974072f41a843678abf5f61979c748687e66bSherry Moore /* calls pcm_adapter_callback() */
193974072f41a843678abf5f61979c748687e66bSherry Moore if (pcic->pc_callback) {
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore (void) ddi_prop_update_string(
193974072f41a843678abf5f61979c748687e66bSherry Moore DDI_DEV_T_NONE,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->dip, PCM_DEVICETYPE,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pccard");
193974072f41a843678abf5f61979c748687e66bSherry Moore PC_CALLBACK(pcic->dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_cb_arg,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCE_CARD_INSERT,
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_socket);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore } else if (cbps & CB_PS_CBCARD) {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_err(pcic->dip,
193974072f41a843678abf5f61979c748687e66bSherry Moore 8, "32 bit card inserted\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore if (pcic->pc_flags & PCF_CARDBUS) {
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_flags |=
193974072f41a843678abf5f61979c748687e66bSherry Moore PCS_CARD_ISCARDBUS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS
193974072f41a843678abf5f61979c748687e66bSherry Moore if (!pcic_load_cardbus(pcic,
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp)) {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_unload_cardbus(
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic, sockp);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
193974072f41a843678abf5f61979c748687e66bSherry Moore cmn_err(CE_NOTE,
193974072f41a843678abf5f61979c748687e66bSherry Moore "32 bit Cardbus not"
193974072f41a843678abf5f61979c748687e66bSherry Moore " supported in"
193974072f41a843678abf5f61979c748687e66bSherry Moore " this device driver\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
193974072f41a843678abf5f61979c748687e66bSherry Moore } else {
193974072f41a843678abf5f61979c748687e66bSherry Moore /*
193974072f41a843678abf5f61979c748687e66bSherry Moore * Ignore the card
193974072f41a843678abf5f61979c748687e66bSherry Moore */
193974072f41a843678abf5f61979c748687e66bSherry Moore cmn_err(CE_NOTE,
193974072f41a843678abf5f61979c748687e66bSherry Moore "32 bit Cardbus not"
193974072f41a843678abf5f61979c748687e66bSherry Moore " supported on this"
193974072f41a843678abf5f61979c748687e66bSherry Moore " device\n");
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore } else {
193974072f41a843678abf5f61979c748687e66bSherry Moore cmn_err(CE_NOTE,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Unsupported PCMCIA card"
193974072f41a843678abf5f61979c748687e66bSherry Moore " inserted\n");
193974072f41a843678abf5f61979c748687e66bSherry Moore }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
193974072f41a843678abf5f61979c748687e66bSherry Moore do_debounce = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
193974072f41a843678abf5f61979c748687e66bSherry Moore } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * It is possible to come through here if the system
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * starts up with cards already inserted. Do nothing
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * and don't worry about it.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 5,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic%d: Odd card insertion indication on socket %d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(pcic->dip),
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
193974072f41a843678abf5f61979c748687e66bSherry Moore if (!(sockp->pcs_flags & PCS_CARD_PRESENT)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Someone has started to insert a card so delay a while.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel do_debounce = B_TRUE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Otherwise this is basically the same as not present
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * so fall through.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* FALLTHRU */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case 0:
193974072f41a843678abf5f61979c748687e66bSherry Moore if (sockp->pcs_flags & PCS_CARD_PRESENT) {
193974072f41a843678abf5f61979c748687e66bSherry Moore if (pcic->pc_flags & PCF_CBPWRCTL) {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_putcb(pcic, CB_CONTROL, 0);
193974072f41a843678abf5f61979c748687e66bSherry Moore } else {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_putb(pcic, sockp->pcs_socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_POWER_CONTROL, 0);
193974072f41a843678abf5f61979c748687e66bSherry Moore (void) pcic_getb(pcic, sockp->pcs_socket,
193974072f41a843678abf5f61979c748687e66bSherry Moore PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8, "Card removed\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_flags &= ~PCS_CARD_PRESENT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_flags & PCS_CARD_IS16BIT) {
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_flags &= ~PCS_CARD_IS16BIT;
193974072f41a843678abf5f61979c748687e66bSherry Moore if (pcic_do_removal && pcic->pc_callback) {
193974072f41a843678abf5f61979c748687e66bSherry Moore PC_CALLBACK(pcic->dip, pcic->pc_cb_arg,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCE_CARD_REMOVAL, sockp->pcs_socket);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (sockp->pcs_flags & PCS_CARD_ISCARDBUS) {
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_flags &= ~PCS_CARD_ISCARDBUS;
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_flags |= PCS_CARD_CBREM;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel sockp->pcs_flags |= PCS_CARD_REMOVED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel do_debounce = B_TRUE;
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore if (debounce && (sockp->pcs_flags & PCS_CARD_REMOVED)) {
193974072f41a843678abf5f61979c748687e66bSherry Moore if (sockp->pcs_flags & PCS_CARD_CBREM) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Ensure that we do the unloading in the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * debounce handler, that way we're not doing
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * nasty things in an interrupt handler. e.g.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * a USB device will wait for data which will
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * obviously never come because we've
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * unplugged the device, but the wait will
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * wait forever because no interrupts can
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * come in...
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_unload_cardbus(pcic, sockp);
193974072f41a843678abf5f61979c748687e66bSherry Moore /* pcic_dump_all(pcic); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_flags &= ~PCS_CARD_CBREM;
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_flags &= ~PCS_CARD_REMOVED;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
193974072f41a843678abf5f61979c748687e66bSherry Moore break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } /* switch */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (do_debounce) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Delay doing
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * anything for a while so that things can settle
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * down a little. Interrupts are already disabled.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Reset the state and we'll reevaluate the
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * whole kit 'n kaboodle when the timeout fires
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8, "Queueing up debounce timeout for "
193974072f41a843678abf5f61979c748687e66bSherry Moore "socket %d.%d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_get_instance(pcic->dip),
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_socket);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
193974072f41a843678abf5f61979c748687e66bSherry Moore sockp->pcs_debounce_id =
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_add_debqueue(sockp, debounce_time);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * We bug out here without re-enabling interrupts. They will
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * be re-enabled when the debounce timeout swings through
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * here.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
193974072f41a843678abf5f61979c748687e66bSherry Moore return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Turn on Card detect interrupts. Other interrupts will be
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * enabled during set_socket calls.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Note that set_socket only changes interrupt settings when there
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is a card present.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq = pcic_getb(pcic, sockp->pcs_socket, PCIC_MANAGEMENT_INT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel irq |= PCIC_CD_DETECT;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, sockp->pcs_socket, PCIC_MANAGEMENT_INT, irq);
0e995c33333aa22fefbb5edf7712b69135dcc2d3rw pcic_putcb(pcic, CB_STATUS_MASK, CB_SE_CCDMASK);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
0d282d1376eb7ba06504448622a6d65726e4bd3erw /* Out from debouncing state */
0d282d1376eb7ba06504448622a6d65726e4bd3erw sockp->pcs_flags &= ~PCS_DEBOUNCING;
0d282d1376eb7ba06504448622a6d65726e4bd3erw
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 7, "Leaving pcic_handle_cd_change\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * pcic_getb()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * get an I/O byte based on the yardware decode method
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint8_t
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_getb(pcicdev_t *pcic, int socket, int reg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int work;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug == 0x7fff) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_getb0: pcic=%p socket=%d reg=%d\n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic, socket, reg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "pcic_getb1: type=%d handle=%p ioaddr=%p \n",
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_io_type, (void *)pcic->handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic->ioaddr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_io_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_IO_TYPE_YENTA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ddi_get8(pcic->handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->ioaddr + CB_R2_OFFSET + reg));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel work = (socket * PCIC_SOCKET_1) | reg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->handle, pcic->ioaddr, work);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ddi_get8(pcic->handle, pcic->ioaddr + 1));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_putb(pcicdev_t *pcic, int socket, int reg, int8_t value)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int work;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug == 0x7fff) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_putb0: pcic=%p socket=%d reg=%d value=%x \n",
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic, socket, reg, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
193974072f41a843678abf5f61979c748687e66bSherry Moore "pcic_putb1: type=%d handle=%p ioaddr=%p \n",
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->pc_io_type, (void *)pcic->handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore (void *)pcic->ioaddr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_io_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_IO_TYPE_YENTA:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->handle, pcic->ioaddr + CB_R2_OFFSET + reg,
193974072f41a843678abf5f61979c748687e66bSherry Moore value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel work = (socket * PCIC_SOCKET_1) | reg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->handle, pcic->ioaddr, work);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->handle, pcic->ioaddr + 1, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * chip identification functions
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * chip identification: Cirrus Logic PD6710/6720/6722
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_ci_cirrus(pcicdev_t *pcic)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value1, value2;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Init the CL id mode */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value1 = pcic_getb(pcic, 0, PCIC_CHIP_INFO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, 0, PCIC_CHIP_INFO, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value1 = pcic_getb(pcic, 0, PCIC_CHIP_INFO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value2 = pcic_getb(pcic, 0, PCIC_CHIP_INFO);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((value1 & PCIC_CI_ID) == PCIC_CI_ID &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (value2 & PCIC_CI_ID) == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* chip is a Cirrus Logic and not Intel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_CL_PD6710;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value1 & PCIC_CI_SLOTS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PD6720;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PD6710;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* now fine tune things just in case a 6722 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value1 = clext_reg_read(pcic, 0, PCIC_CLEXT_DMASK_0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value1 == 0) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clext_reg_write(pcic, 0, PCIC_CLEXT_SCRATCH, 0x55);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value1 = clext_reg_read(pcic, 0, PCIC_CLEXT_SCRATCH);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (value1 == 0x55) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_PD6722;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_CL_PD6722;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clext_reg_write(pcic, 0, PCIC_CLEXT_SCRATCH, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * chip identification: Vadem (VG365/465/468/469)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_vadem_enable(pcicdev_t *pcic)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->handle, pcic->ioaddr, PCIC_VADEM_P1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->handle, pcic->ioaddr, PCIC_VADEM_P2);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put8(pcic->handle, pcic->ioaddr, pcic->pc_lastreg);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_ci_vadem(pcicdev_t *pcic)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_vadem_enable(pcic);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, 0, PCIC_CHIP_REVISION);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, 0, PCIC_CHIP_REVISION, 0xFF);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_getb(pcic, 0, PCIC_CHIP_REVISION) ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (value | PCIC_VADEM_D3) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (pcic_getb(pcic, 0, PCIC_CHIP_REVISION) & PCIC_REV_MASK) ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_VADEM_469) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int vadem, new;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_vadem_enable(pcic);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel vadem = pcic_getb(pcic, 0, PCIC_VG_DMA) &
193974072f41a843678abf5f61979c748687e66bSherry Moore ~(PCIC_V_UNLOCK | PCIC_V_VADEMREV);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel new = vadem | (PCIC_V_VADEMREV|PCIC_V_UNLOCK);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, 0, PCIC_VG_DMA, new);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, 0, PCIC_CHIP_REVISION);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* want to lock but leave mouse or other on */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, 0, PCIC_VG_DMA, vadem);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (value & PCIC_REV_MASK) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_VADEM_365:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_VG_365;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_VADEM;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_VADEM_465:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_VG_465;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_VADEM;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_flags |= PCF_1SOCKET;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_VADEM_468:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_VG_468;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_VADEM;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_VADEM_469:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_VG_469;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_VADEM_VG469;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * chip identification: Ricoh
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_ci_ricoh(pcicdev_t *pcic)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, 0, PCIC_RF_CHIP_IDENT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (value) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_RF_296:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_RICOH;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_RF5C296;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_RF_396:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_type = PCIC_RICOH;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic->pc_chipname = PCIC_TYPE_RF5C396;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * set up available address spaces in busra
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_init_assigned(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcm_regs_t *pcic_avail_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_regspec_t *pci_avail_p, *regs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int len, entries, rlen;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *pdip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "available", (caddr_t)&pcic_avail_p, &len) == DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * found "available" property at the cardbus/pcmcia node
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * need to translate address space entries from pcmcia
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * format to pci format
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel entries = len / sizeof (pcm_regs_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_avail_p = kmem_alloc(sizeof (pci_regspec_t) * entries,
193974072f41a843678abf5f61979c748687e66bSherry Moore KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_apply_avail_ranges(dip, pcic_avail_p, pci_avail_p,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel entries) == DDI_SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pci_resource_setup_avail(dip, pci_avail_p,
193974072f41a843678abf5f61979c748687e66bSherry Moore entries);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic_avail_p, len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pci_avail_p, entries * sizeof (pci_regspec_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * "legacy" platforms will have "available" property in pci node
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (pdip = ddi_get_parent(dip); pdip; pdip = ddi_get_parent(pdip)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getlongprop(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "available", (caddr_t)&pci_avail_p, &len) ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* (void) pci_resource_setup(pdip); */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pci_avail_p, len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pdip == NULL) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char bus_type[16] = "(unknown)";
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *par;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "?pcic_init_assigned: no available property for pcmcia\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This code is taken from pci_resource_setup() but does
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * not attempt to use the "available" property to populate
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the ndi maps that are created.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The fact that we will actually
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * free some resource below (that was allocated by OBP)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * should be enough to be going on with.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (par = dip; par != NULL; par = ddi_get_parent(par)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel len = sizeof (bus_type);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((ddi_prop_op(DDI_DEV_T_ANY, par,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PROP_LEN_AND_VAL_BUF,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "device_type",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&bus_type, &len) == DDI_SUCCESS) &&
8134ee03588a08f05c327533a618d35625381520rw (strcmp(bus_type, DEVI_PCI_NEXNAME) == 0 ||
193974072f41a843678abf5f61979c748687e66bSherry Moore strcmp(bus_type, DEVI_PCIEX_NEXNAME) == 0))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (par != NULL &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (ndi_ra_map_setup(par, NDI_RA_TYPE_MEM) != NDI_SUCCESS ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ndi_ra_map_setup(par, NDI_RA_TYPE_IO) != NDI_SUCCESS))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel par = NULL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_bus_range_t *bus_range;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int k;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getlongprop(DDI_DEV_T_ANY, pdip, 0, "bus-range",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&bus_range, &k) == DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (bus_range->lo != bus_range->hi)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pdip, 9, "allowable bus range is "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%u->%u\n", bus_range->lo, bus_range->hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pdip, 0,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "!No spare PCI bus numbers, range is "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "%u->%u, cardbus isn't usable\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bus_range->lo, bus_range->hi);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(bus_range, k);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pdip, 0, "!No bus-range property seems to "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "have been set up\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Have a valid parent with the "available" property
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pci_resource_setup(pdip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((strcmp(ddi_get_name(dip), "pcma") == 0) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "assigned-addresses",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (caddr_t)&regs, &rlen) == DDI_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ra_return_t ra;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * On the UltraBook IIi the ranges are assigned under
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * openboot. If we don't free them here the first I/O
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * space that can be used is up above 0x10000 which
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * doesn't work for this driver due to restrictions
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * on the PCI I/O addresses the controllers can cope with.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * They are never going to be used by anything else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * so free them up to the general pool. AG.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(dip, 1, "Free assigned addresses\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((PCI_REG_ADDR_G(regs[0].pci_phys_hi) ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_REG_ADDR_G(PCI_ADDR_MEM32)) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel regs[0].pci_size_low == 0x1000000) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ra.ra_addr_lo = regs[0].pci_phys_low;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ra.ra_len = regs[0].pci_size_low;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcmcia_free_mem(dip, &ra);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((PCI_REG_ADDR_G(regs[1].pci_phys_hi) ==
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_REG_ADDR_G(PCI_ADDR_IO)) &&
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (regs[1].pci_size_low == 0x8000 ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel regs[1].pci_size_low == 0x4000)) /* UB-IIi || UB-I */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ra.ra_addr_lo = regs[1].pci_phys_low;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ra.ra_len = regs[1].pci_size_low;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcmcia_free_io(dip, &ra);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free((caddr_t)regs, rlen);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * translate "available" from pcmcia format to pci format
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_apply_avail_ranges(dev_info_t *dip, pcm_regs_t *pcic_p,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_regspec_t *pci_p, int entries)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int i, range_len, range_entries;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_ranges_t *pcic_range_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "ranges",
193974072f41a843678abf5f61979c748687e66bSherry Moore (caddr_t)&pcic_range_p, &range_len) != DDI_PROP_SUCCESS) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "?pcic_apply_avail_ranges: "
193974072f41a843678abf5f61979c748687e66bSherry Moore "no ranges property for pcmcia\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_FAILURE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel range_entries = range_len / sizeof (pcic_ranges_t);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* for each "available" entry to be translated */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (i = 0; i < entries; i++, pcic_p++, pci_p++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int j;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_ranges_t *range_p = pcic_range_p;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_p->pci_phys_hi = -1u; /* default invalid value */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* for each "ranges" entry to be searched */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (j = 0; j < range_entries; j++, range_p++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t range_end = range_p->pcic_range_caddrlo +
193974072f41a843678abf5f61979c748687e66bSherry Moore range_p->pcic_range_size;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint64_t avail_end = pcic_p->phys_lo + pcic_p->phys_len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if ((range_p->pcic_range_caddrhi != pcic_p->phys_hi) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (range_p->pcic_range_caddrlo > pcic_p->phys_lo) ||
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (range_end < avail_end))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel continue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_p->pci_phys_hi = range_p->pcic_range_paddrhi;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_p->pci_phys_mid = range_p->pcic_range_paddrmid;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_p->pci_phys_low = range_p->pcic_range_paddrlo
3db86aab554edbb4244c8d1a1c90f152eee768afstevel + (pcic_p->phys_lo - range_p->pcic_range_caddrlo);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_p->pci_size_hi = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_p->pci_size_low = pcic_p->phys_len;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(pcic_range_p, range_len);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_open(dev_t *dev, int flag, int otyp, cred_t *cred)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_is_cb_minor(*dev))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (cardbus_open(dev, flag, otyp, cred));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EINVAL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_close(dev_t dev, int flag, int otyp, cred_t *cred)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_is_cb_minor(dev))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (cardbus_close(dev, flag, otyp, cred));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EINVAL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int *rval)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef CARDBUS
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cardbus_is_cb_minor(dev))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (cardbus_ioctl(dev, cmd, arg, mode, cred, rval));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (EINVAL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic boolean_t
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_load_cardbus(pcicdev_t *pcic, const pcic_socket_t *sockp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t present_state;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *dip = pcic->dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel set_socket_t s;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel get_socket_t g;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel boolean_t retval;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel unsigned vccLevel;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(dip, 8, "entering pcic_load_cardbus\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bzero(&s, sizeof (set_socket_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.socket = sockp->pcs_socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.SCIntMask = SBM_CD|SBM_RDYBSY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.IFType = IF_CARDBUS;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.State = (unsigned)~0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel present_state = pcic_getcb(pcic, CB_PRESENT_STATE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (present_state & PCIC_VCC_3VCARD)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.VccLevel = PCIC_VCC_3VLEVEL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else if (present_state & PCIC_VCC_5VCARD)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.VccLevel = PCIC_VCC_5VLEVEL;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_load_cardbus: unsupported card voltage\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto failure;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel vccLevel = s.VccLevel;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.Vpp1Level = s.Vpp2Level = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_set_socket(dip, &s) != SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto failure;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_reset_socket(dip, sockp->pcs_socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel RESET_MODE_CARD_ONLY) != SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto failure;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bzero(&g, sizeof (get_socket_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel g.socket = sockp->pcs_socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_get_socket(dip, &g) != SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto failure;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bzero(&s, sizeof (set_socket_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.socket = sockp->pcs_socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.SCIntMask = SBM_CD;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.IREQRouting = g.IRQRouting;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.IFType = g.IFType;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.CtlInd = g.CtlInd;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.State = (unsigned)~0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.VccLevel = vccLevel;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.Vpp1Level = s.Vpp2Level = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw retval = pcic_set_socket(dip, &s);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw pcmcia_cb_resumed(s.socket);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (retval != SUCCESS)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto failure;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel retval = cardbus_load_cardbus(dip, sockp->pcs_socket, pcic->pc_base);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel goto exit;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelfailure:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel retval = B_FALSE;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelexit:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mutex_enter(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(dip, 8, "exit pcic_load_cardbus (%s)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel retval ? "success" : "failure");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (retval);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_unload_cardbus(pcicdev_t *pcic, const pcic_socket_t *sockp)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dev_info_t *dip = pcic->dip;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel set_socket_t s;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_unload_cardbus(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel bzero(&s, sizeof (set_socket_t));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.socket = sockp->pcs_socket;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.SCIntMask = SBM_CD|SBM_RDYBSY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.IREQRouting = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.IFType = IF_MEMORY;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.CtlInd = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.State = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel s.VccLevel = s.Vpp1Level = s.Vpp2Level = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_set_socket(dip, &s);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mutex_enter(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic uint32_t
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_getcb(pcicdev_t *pcic, int reg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(pcic->pc_io_type == PCIC_IO_TYPE_YENTA);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (ddi_get32(pcic->handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint32_t *)(pcic->ioaddr + CB_CB_OFFSET + reg)));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_putcb(pcicdev_t *pcic, int reg, uint32_t value)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ASSERT(pcic->pc_io_type == PCIC_IO_TYPE_YENTA);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put32(pcic->handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint32_t *)(pcic->ioaddr + CB_CB_OFFSET + reg), value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_enable_io_intr(pcicdev_t *pcic, int socket, int irq)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint16_t brdgctl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, socket, PCIC_INTERRUPT) & ~PCIC_INTR_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_INTERRUPT, value | irq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_82092_smiirq_ctl(pcic, socket, PCIC_82092_CTL_IRQ,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_82092_INT_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_O2_OZ6912:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, 0, PCIC_CENTDMA);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value |= 0x8;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, 0, PCIC_CENTDMA, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6832:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1250:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1221:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1225:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_ENE_1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1510:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1520:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_ENE_1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* route card functional interrupts to PCI interrupts */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel brdgctl = ddi_get16(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint16_t *)(pcic->cfgaddr + PCI_CBUS_BRIDGE_CTRL));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(NULL, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_enable_io_intr brdgctl(0x%x) was: 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_CBUS_BRIDGE_CTRL, brdgctl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel brdgctl &= ~PCIC_BRDGCTL_INTR_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put16(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint16_t *)(pcic->cfgaddr + PCI_CBUS_BRIDGE_CTRL),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel brdgctl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Flush the write */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_get16(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint16_t *)(pcic->cfgaddr + PCI_CBUS_BRIDGE_CTRL));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_disable_io_intr(pcicdev_t *pcic, int socket)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t value;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint16_t brdgctl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, socket, PCIC_INTERRUPT) & ~PCIC_INTR_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_INTERRUPT, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (pcic->pc_type) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_INTEL_i82092:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_82092_smiirq_ctl(pcic, socket, PCIC_82092_CTL_IRQ,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_82092_INT_DISABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_O2_OZ6912:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, 0, PCIC_CENTDMA);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value &= ~0x8;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, 0, PCIC_CENTDMA, value);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Flush the write */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, 0, PCIC_CENTDMA);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_CL_PD6832:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1250:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1221:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1225:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_ENE_1410:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1510:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1520:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_TI_PCI1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case PCIC_ENE_1420:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * This maps I/O interrupts to ExCA which
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * have been turned off by the write to
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * PCIC_INTERRUPT above. It would appear to
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * be the only way to actually turn I/O Ints off
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * while retaining CS Ints.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel brdgctl = ddi_get16(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint16_t *)(pcic->cfgaddr + PCI_CBUS_BRIDGE_CTRL));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(NULL, 1,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_disable_io_intr brdgctl(0x%x) was: 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_CBUS_BRIDGE_CTRL, brdgctl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel brdgctl |= PCIC_BRDGCTL_INTR_MASK;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_put16(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint16_t *)(pcic->cfgaddr + PCI_CBUS_BRIDGE_CTRL),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel brdgctl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Flush the write */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) ddi_get16(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (uint16_t *)(pcic->cfgaddr + PCI_CBUS_BRIDGE_CTRL));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_cb_enable_intr(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_enable_io_intr(pcic, 0, pcic->pc_sockets[0].pcs_irq);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_cb_disable_intr(dev_info_t *dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel anp_t *anp = ddi_get_driver_private(dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = anp->an_private;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_disable_io_intr(pcic, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevellog_pci_cfg_err(ushort_t e, int bridge_secondary)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int nerr = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (e & PCI_STAT_PERROR) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nerr++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "detected parity error.\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (e & PCI_STAT_S_SYSERR) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nerr++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (bridge_secondary)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "received system error.\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "signalled system error.\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (e & PCI_STAT_R_MAST_AB) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nerr++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "received master abort.\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (e & PCI_STAT_R_TARG_AB)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "received target abort.\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (e & PCI_STAT_S_TARG_AB)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "signalled target abort\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (e & PCI_STAT_S_PERROR) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nerr++;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "signalled parity error\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (nerr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(__sparc)
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_fault(enum pci_fault_ops op, void *arg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcicdev_t *pcic = (pcicdev_t *)arg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ushort_t pci_cfg_stat =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_get16(pcic->cfg_handle, PCI_CONF_STAT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ushort_t pci_cfg_sec_stat =
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_get16(pcic->cfg_handle, 0x16);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char nm[24];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int nerr = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cardbus_dump_pci_config(pcic->dip);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel switch (op) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FAULT_LOG:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) sprintf(nm, "%s-%d", ddi_driver_name(pcic->dip),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ddi_get_instance(pcic->dip));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s: PCIC fault log start:\n", nm);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s: primary err (%x):\n", nm, pci_cfg_stat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nerr += log_pci_cfg_err(pci_cfg_stat, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "%s: sec err (%x):\n", nm, pci_cfg_sec_stat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel nerr += log_pci_cfg_err(pci_cfg_sec_stat, 1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "%s: PCI fault log end.\n", nm);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (nerr);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FAULT_POKEFINI:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FAULT_RESET:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_put16(pcic->cfg_handle,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCI_CONF_STAT, pci_cfg_stat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pci_config_put16(pcic->cfg_handle, 0x16, pci_cfg_sec_stat);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel case FAULT_POKEFLT:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(pci_cfg_stat & PCI_STAT_S_SYSERR))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(pci_cfg_sec_stat & PCI_STAT_R_MAST_AB))
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (1);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel default:
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (DDI_SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rwpcic_do_resume(pcicdev_t *pcic)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw int i, interrupt;
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw uint8_t cfg;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw pcic_err(NULL, 6, "pcic_do_resume(): entered\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw pcic_mutex_enter(&pcic->pc_lock); /* protect the registers */
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw for (i = 0; i < pcic->pc_numsockets; i++) {
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw /* Enable interrupts on PCI if needs be */
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw interrupt = pcic_getb(pcic, i, PCIC_INTERRUPT);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (pcic->pc_flags & PCF_USE_SMI)
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw interrupt |= PCIC_INTR_ENABLE;
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw pcic_putb(pcic, i, PCIC_INTERRUPT,
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw PCIC_RESET | interrupt);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw pcic->pc_sockets[i].pcs_debounce_id =
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw pcic_add_debqueue(&pcic->pc_sockets[i],
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw drv_usectohz(pcic_debounce_time));
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw }
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw pcic_mutex_exit(&pcic->pc_lock); /* protect the registers */
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (pcic_do_pcmcia_sr)
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw (void) pcmcia_wait_insert(pcic->dip);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw /*
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw * The CardBus controller may be in RESET state after the
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw * system is resumed from sleeping. The RESET bit is in
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw * the Bridge Control register. This is true for all(TI,
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw * Toshiba ToPIC95/97, RICOH, and O2Micro) CardBus
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw * controllers. Need to clear the RESET bit explicitly.
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw */
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (cfg & (1<<6)) {
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw cfg &= ~(1<<6);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw ddi_put8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG,
193974072f41a843678abf5f61979c748687e66bSherry Moore cfg);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw cfg = ddi_get8(pcic->cfg_handle,
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic->cfgaddr + PCIC_BRIDGE_CTL_REG);
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw if (cfg & (1<<6)) {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_err(pcic->dip, 1,
193974072f41a843678abf5f61979c748687e66bSherry Moore "Failed to take pcic out of reset");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
11c2b4c0e543fe2e1e5910cde1f4422cc3218160rw
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_debounce(pcic_socket_t *pcs)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint8_t status, stschng;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mutex_enter(&pcs->pcs_pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcs->pcs_flags &= ~PCS_STARTING;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel stschng = pcic_getb(pcs->pcs_pcic, pcs->pcs_socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_CARD_STATUS_CHANGE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status = pcic_getb(pcs->pcs_pcic, pcs->pcs_socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_INTERFACE_STATUS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcs->pcs_pcic->dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_debounce(0x%p, dip=0x%p) socket %d st 0x%x "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "chg 0x%x flg 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *)pcs, (void *) pcs->pcs_pcic->dip, pcs->pcs_socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel status, stschng, pcs->pcs_flags);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcs->pcs_pcic, pcs->pcs_socket, PCIC_CARD_STATUS_CHANGE,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_CD_DETECT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_handle_cd_change(pcs->pcs_pcic, pcs, status);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mutex_exit(&pcs->pcs_pcic->pc_lock);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_deb_thread()
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel callb_cpr_t cprinfo;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct debounce *debp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clock_t lastt;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CALLB_CPR_INIT(&cprinfo, &pcic_deb_mtx,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel callb_generic_cpr, "pcic debounce thread");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (pcic_deb_threadid) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (pcic_deb_queue) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_dump_debqueue("Thread");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel debp = pcic_deb_queue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) drv_getparm(LBOLT, &lastt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (lastt >= debp->expire) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_deb_queue = debp->next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_debounce(debp->pcs);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(debp, sizeof (*debp));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) cv_timedwait(&pcic_deb_cv,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel &pcic_deb_mtx, debp->expire);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CALLB_CPR_SAFE_BEGIN(&cprinfo);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cv_wait(&pcic_deb_cv, &pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CALLB_CPR_SAFE_END(&cprinfo, &pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_deb_threadid = (kthread_t *)1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cv_signal(&pcic_deb_cv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CALLB_CPR_EXIT(&cprinfo); /* Also exits the mutex */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel thread_exit();
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void *
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_add_debqueue(pcic_socket_t *pcs, int clocks)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clock_t lbolt;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct debounce *dbp, **dbpp = &pcic_deb_queue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) drv_getparm(LBOLT, &lbolt);
8134ee03588a08f05c327533a618d35625381520rw dbp = kmem_alloc(sizeof (struct debounce), KM_SLEEP);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dbp->expire = lbolt + clocks;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dbp->pcs = pcs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (*dbpp) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (dbp->expire > (*dbpp)->expire)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dbpp = &((*dbpp)->next);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dbp->next = *dbpp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *dbpp = dbp;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_dump_debqueue("Add");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cv_signal(&pcic_deb_cv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (dbp);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_rm_debqueue(void *id)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct debounce *dbp, **dbpp = &pcic_deb_queue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dbp = (struct debounce *)id;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_enter(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (*dbpp) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (*dbpp == dbp) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel *dbpp = dbp->next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel kmem_free(dbp, sizeof (*dbp));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#ifdef PCIC_DEBUG
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_dump_debqueue("Remove");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cv_signal(&pcic_deb_cv);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel dbpp = &((*dbpp)->next);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(NULL, 6, "pcic: Failed to find debounce id 0x%p\n", id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel mutex_exit(&pcic_deb_mtx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_powerdelay = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_exca_powerctl(pcicdev_t *pcic, int socket, int powerlevel)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ind, value, orig_pwrctl;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* power setup -- if necessary */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel orig_pwrctl = pcic_getb(pcic, socket, PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 6,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_exca_powerctl(socket %d) powerlevel=%x orig 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket, powerlevel, orig_pwrctl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* Preserve the PCIC_OUTPUT_ENABLE (control lines output enable) bit. */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel = (powerlevel & ~POWER_OUTPUT_ENABLE) |
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (orig_pwrctl & POWER_OUTPUT_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (powerlevel != orig_pwrctl) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (powerlevel & ~POWER_OUTPUT_ENABLE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ifs;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * set power to socket
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * note that the powerlevel was calculated earlier
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_POWER_CONTROL, powerlevel);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket, PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * this second write to the power control register
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is needed to resolve a problem on
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * the IBM ThinkPad 750
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * where the first write doesn't latch.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * The second write appears to always work and
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * doesn't hurt the operation of other chips
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * so we can just use it -- this is good since we can't
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * determine what chip the 750 actually uses
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * (I suspect an early Ricoh).
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_POWER_CONTROL, powerlevel);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value = pcic_getb(pcic, socket, PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket, pcic_powerdelay);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\tpowerlevel reg = %x (ifs %x)\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel value, pcic_getb(pcic, socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_INTERFACE_STATUS));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "CBus regs: PS 0x%x, Control 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getcb(pcic, CB_PRESENT_STATE),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getcb(pcic, CB_CONTROL));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * since power was touched, make sure it says it
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * is on. This lets it become stable.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel for (ind = 0; ind < 20; ind++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ifs = pcic_getb(pcic, socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_INTERFACE_STATUS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ifs & PCIC_POWER_ON)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_POWER_CONTROL, 0);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket, 40);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (ind == 10) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putcb(pcic, CB_EVENT_FORCE,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel CB_EF_CVTEST);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket, 100);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_POWER_CONTROL,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel powerlevel & ~POWER_OUTPUT_ENABLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_powerdelay);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_POWER_CONTROL, powerlevel);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_powerdelay);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (!(ifs & PCIC_POWER_ON)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic socket %d: Power didn't get turned"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "on!\nif status 0x%x pwrc 0x%x(x%x) "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "misc1 0x%x igc 0x%x ind %d\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket, ifs,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getb(pcic, socket, PCIC_POWER_CONTROL),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel orig_pwrctl,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getb(pcic, socket, PCIC_MISC_CTL_1),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getb(pcic, socket, PCIC_INTERRUPT),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ind);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (BAD_VCC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 8,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "\tind = %d, if status %x pwrc 0x%x "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "misc1 0x%x igc 0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ind, ifs,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getb(pcic, socket, PCIC_POWER_CONTROL),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getb(pcic, socket, PCIC_MISC_CTL_1),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getb(pcic, socket, PCIC_INTERRUPT));
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* explicitly turned off the power */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putb(pcic, socket, PCIC_POWER_CONTROL, powerlevel);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) pcic_getb(pcic, socket, PCIC_POWER_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_cbdoreset_during_poweron = 1;
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_cbus_powerctl(pcicdev_t *pcic, int socket)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel uint32_t cbctl = 0, orig_cbctl, cbstev, cbps;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int ind, iobits;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_socket_t *sockp = &pcic->pc_sockets[socket];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_putcb(pcic, CB_STATUS_EVENT, CB_SE_POWER_CYCLE);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ind = pcic_power[sockp->pcs_vpp1].PowerLevel/10;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbctl |= pcic_cbv_levels[ind];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel ind = pcic_power[sockp->pcs_vcc].PowerLevel/10;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbctl |= (pcic_cbv_levels[ind]<<4);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel orig_cbctl = pcic_getcb(pcic, CB_CONTROL);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(pcic->dip, 6,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic_cbus_powerctl(socket %d) vcc %d vpp1 %d "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cbctl 0x%x->0x%x\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel socket, sockp->pcs_vcc, sockp->pcs_vpp1, orig_cbctl, cbctl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbctl != orig_cbctl) {
193974072f41a843678abf5f61979c748687e66bSherry Moore if (pcic_cbdoreset_during_poweron &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (orig_cbctl & (CB_C_VCCMASK|CB_C_VPPMASK)) == 0) {
193974072f41a843678abf5f61979c748687e66bSherry Moore iobits = pcic_getb(pcic, socket, PCIC_INTERRUPT);
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_putb(pcic, socket, PCIC_INTERRUPT,
193974072f41a843678abf5f61979c748687e66bSherry Moore iobits & ~PCIC_RESET);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_putcb(pcic, CB_CONTROL, cbctl);
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore if ((cbctl & CB_C_VCCMASK) == (orig_cbctl & CB_C_VCCMASK)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket, pcic_powerdelay);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore for (ind = 0; ind < 20; ind++) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbstev = pcic_getcb(pcic, CB_STATUS_EVENT);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (cbstev & CB_SE_POWER_CYCLE) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /*
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * delay 400 ms: though the standard defines that the Vcc
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * set-up time is 20 ms, some PC-Card bridge requires longer
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * duration.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * Note: We should check the status AFTER the delay to give time
3db86aab554edbb4244c8d1a1c90f152eee768afstevel * for things to stabilize.
3db86aab554edbb4244c8d1a1c90f152eee768afstevel */
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_mswait(pcic, socket, 400);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
193974072f41a843678abf5f61979c748687e66bSherry Moore cbps = pcic_getcb(pcic, CB_PRESENT_STATE);
193974072f41a843678abf5f61979c748687e66bSherry Moore if (cbctl && !(cbps & CB_PS_POWER_CYCLE)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel /* break; */
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "cbus_powerctl: power off??\n");
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore if (cbctl & CB_PS_BADVCC) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_WARN, "cbus_powerctl: bad power request\n");
3db86aab554edbb4244c8d1a1c90f152eee768afstevel break;
193974072f41a843678abf5f61979c748687e66bSherry Moore }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_err(pcic->dip, 8,
193974072f41a843678abf5f61979c748687e66bSherry Moore "cbstev = 0x%x cbps = 0x%x cbctl 0x%x(0x%x)",
193974072f41a843678abf5f61979c748687e66bSherry Moore cbstev, pcic_getcb(pcic, CB_PRESENT_STATE),
193974072f41a843678abf5f61979c748687e66bSherry Moore cbctl, orig_cbctl);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
193974072f41a843678abf5f61979c748687e66bSherry Moore if (pcic_cbdoreset_during_poweron &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (orig_cbctl & (CB_C_VCCMASK|CB_C_VPPMASK)) == 0) {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_putb(pcic, socket, PCIC_INTERRUPT, iobits);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_mswait(pcic, socket, 40);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore if (pcic_cbdoreset_during_poweron &&
193974072f41a843678abf5f61979c748687e66bSherry Moore (orig_cbctl & (CB_C_VCCMASK|CB_C_VPPMASK)) == 0) {
193974072f41a843678abf5f61979c748687e66bSherry Moore pcic_putb(pcic, socket, PCIC_INTERRUPT, iobits);
193974072f41a843678abf5f61979c748687e66bSherry Moore }
193974072f41a843678abf5f61979c748687e66bSherry Moore cmn_err(CE_WARN,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic socket %d: Power didn't get turned on/off!\n"
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "cbstev = 0x%x cbps = 0x%x cbctl 0x%x(0x%x) "
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "vcc %d vpp1 %d", socket, cbstev,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_getcb(pcic, CB_PRESENT_STATE),
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cbctl, orig_cbctl, sockp->pcs_vcc, sockp->pcs_vpp1);
193974072f41a843678abf5f61979c748687e66bSherry Moore return (BAD_VCC);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel return (SUCCESS);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic int pcic_do_pprintf = 0;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_dump_debqueue(char *msg)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel struct debounce *debp = pcic_deb_queue;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel clock_t lbolt;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void) drv_getparm(LBOLT, &lbolt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(NULL, 6, debp ? "pcic debounce list (%s) lbolt 0x%x:\n" :
3db86aab554edbb4244c8d1a1c90f152eee768afstevel "pcic debounce_list (%s) EMPTY lbolt 0x%x\n", msg, lbolt);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel while (debp) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel pcic_err(NULL, 6, "%p: exp 0x%x next 0x%p id 0x%p\n",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel (void *) debp, (int)debp->expire, (void *) debp->next,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel debp->pcs->pcs_debounce_id);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel debp = debp->next;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel/* PRINTFLIKE3 */
3db86aab554edbb4244c8d1a1c90f152eee768afstevelstatic void
3db86aab554edbb4244c8d1a1c90f152eee768afstevelpcic_err(dev_info_t *dip, int level, const char *fmt, ...)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel{
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_debug && (level <= pcic_debug)) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel va_list adx;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel int instance;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel char buf[256];
3db86aab554edbb4244c8d1a1c90f152eee768afstevel const char *name;
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if !defined(PCIC_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 (void) vsprintf(buf, fmt, adx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel va_end(adx);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#if defined(PCIC_DEBUG)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (pcic_do_pprintf) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (dip) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (instance >= 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel prom_printf("%s(%d),0x%p: %s", name,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh instance, (void *)dip, buf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel prom_printf("%s,0x%p: %s",
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh name, (void *)dip, buf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel prom_printf(buf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (dip) {
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (instance >= 0)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "%s(%d),0x%p: %s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel name, instance, (void *) dip, buf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, "%s,0x%p: %s",
3db86aab554edbb4244c8d1a1c90f152eee768afstevel name, (void *) dip, buf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel } else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(CE_CONT, buf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel if (dip)
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(ce, qmark ? "?%s%d: %s" : "%s%d: %s", name,
3db86aab554edbb4244c8d1a1c90f152eee768afstevel instance, buf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel else
3db86aab554edbb4244c8d1a1c90f152eee768afstevel cmn_err(ce, qmark ? "?%s" : buf, buf);
3db86aab554edbb4244c8d1a1c90f152eee768afstevel#endif
3db86aab554edbb4244c8d1a1c90f152eee768afstevel }
3db86aab554edbb4244c8d1a1c90f152eee768afstevel}