px_msi.c revision a195726fa33097e56cf1c25c31feddb827e140f0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* px_msi.c
*/
#include <sys/ddi_impldefs.h>
#include <sys/pci_impl.h>
#include "px_obj.h"
/*
* msi_attach()
*/
int
{
int i, ret;
/*
* Check for all MSI related properties and
* save all information.
*/
return (DDI_FAILURE);
}
}
return (ret);
}
/*
* msi_detach()
*/
void
{
}
}
if (msi_state_p->msi_p) {
}
}
/*
* msi_alloc()
*/
/* ARGSUSED */
int
{
int orig_msi_count = msi_count;
*actual_msi_count_p = 0;
/*
* For MSI, make sure that MSIs are allocated in the power of 2
* contiguous range.
*/
/* Jump to next MSI range */
/* Reset the counter */
i = next_msi_range - 1;
count = -1;
}
}
if (msi_count > 1) {
msi_count >>= 1;
"Retry MSI allocation with new msi_count 0x%x\n",
goto retry_alloc;
}
return (DDI_FAILURE);
}
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*
* msi_free()
*/
int
{
int i, j;
/*
* Look for an entry corresponds to first MSI
* used by this device.
*/
for (i = 0; i < msi_state_p->msi_cnt; i++) {
break;
}
}
if (i >= msi_state_p->msi_cnt) {
return (DDI_FAILURE);
}
/* Mark all MSIs used by this device as free */
for (j = i; j < (i + msi_count); j++) {
}
return (DDI_SUCCESS);
}
/*
* msi_get_msinum()
*/
int
{
int i;
for (i = 0; i < msi_state_p->msi_cnt; i++) {
return (DDI_SUCCESS);
}
}
if (i >= msi_state_p->msi_cnt)
"no msi for inum 0x%x\n", inum);
return (DDI_FAILURE);
}
/*
* px_msi_get_props()
*/
static int
{
int ret = DDI_SUCCESS;
int length = sizeof (int);
/* #msi */
/* msi-ranges: msi# field */
if (ret == DDI_PROP_SUCCESS) {
} else
/* msi-data-mask */
/* msi-data-width */
/*
* Assume MSI is always supported, but also check if MSIX is supported
*/
if (msi_state_p->msi_data_width) {
}
/* msi-address-ranges */
&length);
if (ret == DDI_PROP_SUCCESS) {
return (ret);
}
/*
* If msi-address-ranges property does not exist in OBP, Fire
* driver will need to allocate memory.
*
* Allocate 64KB of memory from unused PCI-E address space for the MSI
* transactions and program MSI 32-bit address register.
*
* This register is used by the Fire hardware to compare against the
* address of incoming PCI-E 32-bit addressed memory write commands.
* If the address matches bits 31:16 then PCI-E command is considered
* to be MSI transaction.
*
* pci_resource_setup() is called in context of PCI hotplug
* initialization.
*
* Setup resource maps for this bus node.
*/
"pci_resource_setup failed\n",
return (DDI_FAILURE);
}
/*
* Reserve PCI MEM 32 resources to perform 32 bit MSI transactions.
*/
request.ra_boundbase = 0;
request.ra_align_mask = 0;
"64KB mem\n");
return (DDI_FAILURE);
}
/*
* Reserve PCI MEM 64 resources to perform 64 bit MSI transactions.
*
* NOTE:
*
* Currently OBP do not export any "available" property or range in
* the MEM64 space. Hence ndi_ra_alloc() request will return failure.
* So, for time being ignore this failure.
*/
request.ra_align_mask = 0;
"64KB mem\n");
return (DDI_SUCCESS);
}
return (DDI_SUCCESS);
}