eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * CDDL HEADER START
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * The contents of this file are subject to the terms of the
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * Common Development and Distribution License (the "License").
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * You may not use this file except in compliance with the License.
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * See the License for the specific language governing permissions
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * and limitations under the License.
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * When distributing Covered Code, include this CDDL HEADER in each
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * If applicable, add the following below this CDDL HEADER, with the
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * fields enclosed by brackets "[]" replaced with your own identifying
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * information: Portions Copyright [yyyy] [name of copyright owner]
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * CDDL HEADER END
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * Copyright (c) 2009, Intel Corporation.
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * All rights reserved.
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel/* Configurable through /etc/system. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * PCI device ID for supported hardware.
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * For memory controller devices in Intel 5000/7300 series chipset, PCI vendor
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * id and PCI device id is read only, PCI subvendor id and PCI subsystem id is
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * write-once. So we could only rely on PCI vendor id and PCI device id here.
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * For all PCI functions (0,1,2,3) in device 0x10 on bus 0, they will have the
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * same PCI (vendor_id, device_id, subvendor_id, subsystem_id, class_id).
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * We only need to access PCI device (0, 0x10, 1), all other PCI functions will
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel * be filtered out by unit address.
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel { 0x8086, 0x25f0, 0xffff, 0xffff, "10,1" }, /* Intel 5000P/V/X/Z */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel { 0x8086, 0x360c, 0xffff, 0xffff, "10,1" } /* Intel 7300 NB */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishelfipe_open(dev_t *devp, int flag, int otyp, cred_t *credp)
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel cmn_err(CE_NOTE, "!fipe: invalid otyp %d in open.", otyp);
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishelfipe_close(dev_t dev, int flag, int otyp, cred_t *credp)
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishelfipe_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel /* First check permission. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel cmn_err(CE_NOTE, "!fipe: unknown ioctl command %d.", cmd);
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishelfipe_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel/* Validate whether it's supported hardware. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel /* Get device unit address, it's "devid,funcid" in hexadecimal. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel "unit-address", &unitaddr) != DDI_PROP_SUCCESS) {
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel cmn_err(CE_CONT, "?fipe: failed to get deivce unit address.");
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel return (-1);
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel if (pci_config_setup(dip, &handle) != DDI_SUCCESS) {
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel cmn_err(CE_CONT, "?fipe: failed to setup pcicfg handler.");
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel return (-1);
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel venid = pci_config_get16(handle, PCI_CONF_VENID);
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel devid = pci_config_get16(handle, PCI_CONF_DEVID);
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel subvenid = pci_config_get16(handle, PCI_CONF_SUBVENID);
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel subsysid = pci_config_get16(handle, PCI_CONF_SUBSYSID);
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel /* Validate device. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel i < sizeof (fipe_mc_pciids) / sizeof (fipe_mc_pciids[0]);
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel if ((ip->venid == 0xffffu || ip->venid == venid) &&
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel (ip->devid == 0xffffu || ip->devid == devid) &&
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel (ip->subvenid == 0xffffu || ip->subvenid == subvenid) &&
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel (ip->subsysid == 0xffffu || ip->subsysid == subsysid) &&
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishelfipe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel /* Check whether it has been disabled by user. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel "fipe: driver has been disabled by user.");
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel /* Filter out unwanted PCI functions. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel /* There should be only one MC device in system. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel "!fipe: more than one hardware instances found.");
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel /* Initialize and start power management subsystem. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel } else if (fipe_start() != 0) {
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel /* Ignore error from creating minor node. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel if (ddi_create_minor_node(dip, "fipe", S_IFCHR, 0,
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel "?fipe: failed to create device minor node.\n");
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel cmn_err(CE_NOTE, "!fipe: failed to attach or resume device.");
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishelfipe_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel if (fipe_allow_detach == 0 || dip != fipe_drv_dip) {
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel } else if (fipe_fini() != 0) {
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel cmn_err(CE_NOTE, "!fipe: failed to detach or suspend device.");
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel /* Quiesce hardware by stopping power management subsystem. */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel cmn_err(CE_NOTE, "!fipe: failed to quiesce device.");
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel 0, /* not a STREAMS driver */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel D_NEW | D_MP, /* safe for multi-thread/multi-processor */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel 0, /* devo_refcnt */
eca2601cae391051acb146d28fba04237fe1eb85Randy Fishel "Intel 5000/7300 memory controller driver",