/* * This file is provided under a dual BSD/GPLv2 license. When using or * redistributing this file, you may do so under either license. * * GPL LICENSE SUMMARY * * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * The full GNU General Public License is included in this distribution * in the file called LICENSE.GPL. * * BSD LICENSE * * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
MODULE_PARM_DESC(cable_selection_override, "This field indicates length of the SAS/SATA cable between " "host and device. If any bits > 15 are set (default) " "indicates \"use platform defaults\"");
/* GPIO support */
.lldd_write_gpio = isci_gpio_write,
};
/****************************************************************************** * P R O T E C T E D M E T H O D S
******************************************************************************/
/** * isci_register_sas_ha() - This method initializes various lldd * specific members of the sas_ha struct and calls the libsas * sas_register_ha() function. * @isci_host: This parameter specifies the lldd specific wrapper for the * libsas sas_ha struct. * * This method returns an error code indicating success or failure. The user * should check for possible memory allocation error return otherwise, a zero * indicates success.
*/ staticint isci_register_sas_ha(struct isci_host *isci_host)
{ int i; struct sas_ha_struct *sas_ha = &(isci_host->sas_ha); struct asd_sas_phy **sas_phys; struct asd_sas_port **sas_ports;
staticint num_controllers(struct pci_dev *pdev)
{ /* bar size alone can tell us if we are running with a dual controller * part, no need to trust revision ids that might be under broken firmware * control
*/
resource_size_t scu_bar_size = pci_resource_len(pdev, SCI_SCU_BAR*2);
resource_size_t smu_bar_size = pci_resource_len(pdev, SCI_SMU_BAR*2);
staticvoid isci_user_parameters_get(struct sci_user_parameters *u)
{ int i;
for (i = 0; i < SCI_MAX_PHYS; i++) { struct sci_phy_user_params *u_phy = &u->phys[i];
u_phy->max_speed_generation = phy_gen;
/* we are not exporting these for now */
u_phy->align_insertion_frequency = 0x7f;
u_phy->in_connection_align_insertion_frequency = 0xff;
u_phy->notify_enable_spin_up_insertion_frequency = 0x33;
}
/* * Validate the user parameters. If they are not legal, then * return a failure.
*/ for (index = 0; index < SCI_MAX_PHYS; index++) { struct sci_phy_user_params *u;
u = &sci_parms->phys[index];
if (!((u->max_speed_generation <= SCIC_SDS_PARM_MAX_SPEED) &&
(u->max_speed_generation > SCIC_SDS_PARM_NO_SPEED))) return SCI_FAILURE_INVALID_PARAMETER_VALUE;
staticvoid sci_oem_defaults(struct isci_host *ihost)
{ /* these defaults are overridden by the platform / firmware */ struct sci_user_parameters *user = &ihost->user_parameters; struct sci_oem_params *oem = &ihost->oem_parameters; int i;
/* Default to APC mode. */
oem->controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE;
/* Default to APC mode. */
oem->controller.max_concurr_spin_up = 1;
/* Default to no SSC operation. */
oem->controller.do_enable_ssc = false;
/* Default to short cables on all phys. */
oem->controller.cable_selection_mask = 0;
/* Initialize all of the port parameter information to narrow ports. */ for (i = 0; i < SCI_MAX_PORTS; i++)
oem->ports[i].phy_mask = 0;
/* Initialize all of the phy parameter information. */ for (i = 0; i < SCI_MAX_PHYS; i++) { /* Default to 3G (i.e. Gen 2). */
user->phys[i].max_speed_generation = SCIC_SDS_PARM_GEN2_SPEED;
/* the frequencies cannot be 0 */
user->phys[i].align_insertion_frequency = 0x7f;
user->phys[i].in_connection_align_insertion_frequency = 0xff;
user->phys[i].notify_enable_spin_up_insertion_frequency = 0x33;
/* Previous Vitesse based expanders had a arbitration issue that * is worked around by having the upper 32-bits of SAS address * with a value greater then the Vitesse company identifier. * Hence, usage of 0x5FCFFFFF.
*/
oem->phys[i].sas_address.low = 0x1 + ihost->id;
oem->phys[i].sas_address.high = 0x5FCFFFFF;
}
if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
orom = isci_get_efi_var(pdev);
if (!orom)
orom = isci_request_oprom(pdev);
for (i = 0; orom && i < num_controllers(pdev); i++) { if (sci_oem_parameters_validate(&orom->ctrl[i],
orom->hdr.version)) {
dev_warn(&pdev->dev, "[%d]: invalid oem parameters detected, falling back to firmware\n", i);
orom = NULL; break;
}
}
if (!orom) {
source = "(firmware)";
orom = isci_request_firmware(pdev, fw); if (!orom) { /* TODO convert this to WARN_TAINT_ONCE once the * orom/efi parameter support is widely available
*/
dev_warn(&pdev->dev, "Loading user firmware failed, using default " "values\n");
dev_warn(&pdev->dev, "Default OEM configuration being used: 4 " "narrow ports, and default SAS Addresses\n");
}
}
if (orom)
dev_info(&pdev->dev, "OEM SAS parameters (version: %u.%u) loaded %s\n",
(orom->hdr.version & 0xf0) >> 4,
(orom->hdr.version & 0xf), source);
pci_info->orom = orom;
err = isci_pci_init(pdev); if (err) return err;
for (i = 0; i < num_controllers(pdev); i++) { struct isci_host *h = isci_host_alloc(pdev, i);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.