aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-05-10 02:28:46 -0700
committerDan Williams <dan.j.williams@intel.com>2011-07-03 04:04:47 -0700
commite2f8db509fdd354bb7a68c86515e9d2d8909ccc9 (patch)
treee27f2d33290b0c6f7ca20e408ce7f8ff9309dc43 /drivers/scsi
parentd35bc1bd18ab9e986cfb67c5a281a70cfd717f05 (diff)
isci: uplevel port infrastructure
* Move port configuration agent implementation * Merge core/scic_sds_port.[ch] into port.[ch] Reported-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/isci/Makefile4
-rw-r--r--drivers/scsi/isci/core/scic_config_parameters.h249
-rw-r--r--drivers/scsi/isci/core/scic_port.h97
-rw-r--r--drivers/scsi/isci/core/scic_sds_port.c2423
-rw-r--r--drivers/scsi/isci/core/scic_sds_port.h435
-rw-r--r--drivers/scsi/isci/core/scic_sds_port_configuration_agent.h107
-rw-r--r--drivers/scsi/isci/host.c1
-rw-r--r--drivers/scsi/isci/host.h29
-rw-r--r--drivers/scsi/isci/phy.c3
-rw-r--r--drivers/scsi/isci/phy.h1
-rw-r--r--drivers/scsi/isci/port.c2451
-rw-r--r--drivers/scsi/isci/port.h425
-rw-r--r--drivers/scsi/isci/port_config.c (renamed from drivers/scsi/isci/core/scic_sds_port_configuration_agent.c)1
-rw-r--r--drivers/scsi/isci/probe_roms.h124
-rw-r--r--drivers/scsi/isci/remote_device.c2
-rw-r--r--drivers/scsi/isci/remote_node_context.c1
-rw-r--r--drivers/scsi/isci/request.c1
17 files changed, 2929 insertions, 3425 deletions
diff --git a/drivers/scsi/isci/Makefile b/drivers/scsi/isci/Makefile
index 2830a97a822..48218ca908f 100644
--- a/drivers/scsi/isci/Makefile
+++ b/drivers/scsi/isci/Makefile
@@ -1,4 +1,3 @@
-EXTRA_CFLAGS += -Idrivers/scsi/isci/core/ -Idrivers/scsi/isci/
obj-$(CONFIG_SCSI_ISCI) += isci.o
isci-objs := init.o phy.o request.o sata.o \
remote_device.o port.o timers.o \
@@ -10,5 +9,4 @@ isci-objs := init.o phy.o request.o sata.o \
stp_request.o \
ssp_request.o \
smp_request.o \
- core/scic_sds_port.o \
- core/scic_sds_port_configuration_agent.o \
+ port_config.o \
diff --git a/drivers/scsi/isci/core/scic_config_parameters.h b/drivers/scsi/isci/core/scic_config_parameters.h
deleted file mode 100644
index 15e7744dbdc..00000000000
--- a/drivers/scsi/isci/core/scic_config_parameters.h
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _SCIC_SDS_USER_PARAMETERS_H_
-#define _SCIC_SDS_USER_PARAMETERS_H_
-
-#include "probe_roms.h"
-
-struct scic_sds_controller;
-
-/**
- *
- *
- * SCIC_SDS_PARM_PHY_SPEED These constants define the speeds utilized for a
- * phy/port.
- */
-#define SCIC_SDS_PARM_NO_SPEED 0
-
-/**
- *
- *
- * This value of 1 indicates generation 1 (i.e. 1.5 Gb/s).
- */
-#define SCIC_SDS_PARM_GEN1_SPEED 1
-
-/**
- *
- *
- * This value of 2 indicates generation 2 (i.e. 3.0 Gb/s).
- */
-#define SCIC_SDS_PARM_GEN2_SPEED 2
-
-/**
- *
- *
- * This value of 3 indicates generation 3 (i.e. 6.0 Gb/s).
- */
-#define SCIC_SDS_PARM_GEN3_SPEED 3
-
-/**
- *
- *
- * For range checks, the max speed generation
- */
-#define SCIC_SDS_PARM_MAX_SPEED SCIC_SDS_PARM_GEN3_SPEED
-
-/**
- * struct scic_sds_user_parameters - This structure delineates the various user
- * parameters that can be changed by the core user.
- *
- *
- */
-struct scic_sds_user_parameters {
- struct sci_phy_user_params {
- /**
- * This field specifies the NOTIFY (ENABLE SPIN UP) primitive
- * insertion frequency for this phy index.
- */
- u32 notify_enable_spin_up_insertion_frequency;
-
- /**
- * This method specifies the number of transmitted DWORDs within which
- * to transmit a single ALIGN primitive. This value applies regardless
- * of what type of device is attached or connection state. A value of
- * 0 indicates that no ALIGN primitives will be inserted.
- */
- u16 align_insertion_frequency;
-
- /**
- * This method specifies the number of transmitted DWORDs within which
- * to transmit 2 ALIGN primitives. This applies for SAS connections
- * only. A minimum value of 3 is required for this field.
- */
- u16 in_connection_align_insertion_frequency;
-
- /**
- * This field indicates the maximum speed generation to be utilized
- * by phys in the supplied port.
- * - A value of 1 indicates generation 1 (i.e. 1.5 Gb/s).
- * - A value of 2 indicates generation 2 (i.e. 3.0 Gb/s).
- * - A value of 3 indicates generation 3 (i.e. 6.0 Gb/s).
- */
- u8 max_speed_generation;
-
- } phys[SCI_MAX_PHYS];
-
- /**
- * This field specifies the maximum number of direct attached devices
- * that can have power supplied to them simultaneously.
- */
- u8 max_number_concurrent_device_spin_up;
-
- /**
- * This field specifies the number of seconds to allow a phy to consume
- * power before yielding to another phy.
- *
- */
- u8 phy_spin_up_delay_interval;
-
- /**
- * These timer values specifies how long a link will remain open with no
- * activity in increments of a microsecond, it can be in increments of
- * 100 microseconds if the upper most bit is set.
- *
- */
- u16 stp_inactivity_timeout;
- u16 ssp_inactivity_timeout;
-
- /**
- * These timer values specifies how long a link will remain open in increments
- * of 100 microseconds.
- *
- */
- u16 stp_max_occupancy_timeout;
- u16 ssp_max_occupancy_timeout;
-
- /**
- * This timer value specifies how long a link will remain open with no
- * outbound traffic in increments of a microsecond.
- *
- */
- u8 no_outbound_task_timeout;
-
-};
-
-/**
- * This structure/union specifies the various different user parameter sets
- * available. Each type is specific to a hardware controller version.
- *
- * union scic_user_parameters
- */
-union scic_user_parameters {
- /**
- * This field specifies the user parameters specific to the
- * Storage Controller Unit (SCU) Driver Standard (SDS) version
- * 1.
- */
- struct scic_sds_user_parameters sds1;
-
-};
-
-
-/**
- *
- *
- * SCIC_SDS_OEM_PHY_MASK These constants define the valid values for phy_mask
- */
-
-/**
- *
- *
- * This is the min value assignable to a port's phy mask
- */
-#define SCIC_SDS_PARM_PHY_MASK_MIN 0x0
-
-/**
- *
- *
- * This is the max value assignable to a port's phy mask
- */
-#define SCIC_SDS_PARM_PHY_MASK_MAX 0xF
-
-#define MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT 4
-
-/**
- * This structure/union specifies the various different OEM parameter sets
- * available. Each type is specific to a hardware controller version.
- *
- * union scic_oem_parameters
- */
-union scic_oem_parameters {
- /**
- * This field specifies the OEM parameters specific to the
- * Storage Controller Unit (SCU) Driver Standard (SDS) version
- * 1.
- */
- struct scic_sds_oem_params sds1;
-};
-
-int scic_oem_parameters_validate(struct scic_sds_oem_params *oem);
-
-/**
- * scic_oem_parameters_get() - This method allows the user to retreive the OEM
- * parameters utilized by the controller.
- * @controller: This parameter specifies the controller on which to set the
- * user parameters.
- * @oem_parameters: This parameter specifies the OEM parameters object in which
- * to write the core's OEM parameters.
- *
- */
-void scic_oem_parameters_get(
- struct scic_sds_controller *controller,
- union scic_oem_parameters *oem_parameters);
-
-
-#endif /* _SCIC_SDS_USER_PARAMETERS_H_ */
-
diff --git a/drivers/scsi/isci/core/scic_port.h b/drivers/scsi/isci/core/scic_port.h
deleted file mode 100644
index 431dbd2093f..00000000000
--- a/drivers/scsi/isci/core/scic_port.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _SCIC_PORT_H_
-#define _SCIC_PORT_H_
-
-#include "isci.h"
-#include "sas.h"
-#include "phy.h"
-
-struct scic_sds_port;
-
-enum scic_port_not_ready_reason_code {
- SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS,
- SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED,
- SCIC_PORT_NOT_READY_INVALID_PORT_CONFIGURATION,
- SCIC_PORT_NOT_READY_RECONFIGURING,
-
- SCIC_PORT_NOT_READY_REASON_CODE_MAX
-};
-
-struct scic_port_end_point_properties {
- struct sci_sas_address sas_address;
- struct scic_phy_proto protocols;
-};
-
-struct scic_port_properties {
- u32 index;
- struct scic_port_end_point_properties local;
- struct scic_port_end_point_properties remote;
- u32 phy_mask;
-};
-
-enum sci_status scic_port_get_properties(
- struct scic_sds_port *port,
- struct scic_port_properties *properties);
-
-enum sci_status scic_port_hard_reset(
- struct scic_sds_port *port,
- u32 reset_timeout);
-
-void scic_port_enable_broadcast_change_notification(
- struct scic_sds_port *port);
-
-#endif /* _SCIC_PORT_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_port.c b/drivers/scsi/isci/core/scic_sds_port.c
deleted file mode 100644
index 11b516a9a13..00000000000
--- a/drivers/scsi/isci/core/scic_sds_port.c
+++ /dev/null
@@ -1,2423 +0,0 @@
-/*
- * 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.
- */
-
-#include "host.h"
-#include "scic_port.h"
-#include "scic_sds_port.h"
-#include "remote_device.h"
-#include "remote_node_context.h"
-#include "registers.h"
-#include "timers.h"
-#include "scu_task_context.h"
-
-#define SCIC_SDS_PORT_MIN_TIMER_COUNT (SCI_MAX_PORTS)
-#define SCIC_SDS_PORT_MAX_TIMER_COUNT (SCI_MAX_PORTS)
-
-#define SCIC_SDS_PORT_HARD_RESET_TIMEOUT (1000)
-#define SCU_DUMMY_INDEX (0xFFFF)
-
-
-/**
- *
- * @sci_port: This is the port object to which the phy is being assigned.
- * @phy_index: This is the phy index that is being assigned to the port.
- *
- * This method will return a true value if the specified phy can be assigned to
- * this port The following is a list of phys for each port that are allowed: -
- * Port 0 - 3 2 1 0 - Port 1 - 1 - Port 2 - 3 2 - Port 3 - 3 This method
- * doesn't preclude all configurations. It merely ensures that a phy is part
- * of the allowable set of phy identifiers for that port. For example, one
- * could assign phy 3 to port 0 and no other phys. Please refer to
- * scic_sds_port_is_phy_mask_valid() for information regarding whether the
- * phy_mask for a port can be supported. bool true if this is a valid phy
- * assignment for the port false if this is not a valid phy assignment for the
- * port
- */
-bool scic_sds_port_is_valid_phy_assignment(
- struct scic_sds_port *sci_port,
- u32 phy_index)
-{
- /* Initialize to invalid value. */
- u32 existing_phy_index = SCI_MAX_PHYS;
- u32 index;
-
- if ((sci_port->physical_port_index == 1) && (phy_index != 1)) {
- return false;
- }
-
- if (sci_port->physical_port_index == 3 && phy_index != 3) {
- return false;
- }
-
- if (
- (sci_port->physical_port_index == 2)
- && ((phy_index == 0) || (phy_index == 1))
- ) {
- return false;
- }
-
- for (index = 0; index < SCI_MAX_PHYS; index++) {
- if ((sci_port->phy_table[index] != NULL)
- && (index != phy_index)) {
- existing_phy_index = index;
- }
- }
-
- /*
- * Ensure that all of the phys in the port are capable of
- * operating at the same maximum link rate. */
- if (
- (existing_phy_index < SCI_MAX_PHYS)
- && (sci_port->owning_controller->user_parameters.sds1.phys[
- phy_index].max_speed_generation !=
- sci_port->owning_controller->user_parameters.sds1.phys[
- existing_phy_index].max_speed_generation)
- )
- return false;
-
- return true;
-}
-
-/**
- * This method requests a list (mask) of the phys contained in the supplied SAS
- * port.
- * @sci_port: a handle corresponding to the SAS port for which to return the
- * phy mask.
- *
- * Return a bit mask indicating which phys are a part of this port. Each bit
- * corresponds to a phy identifier (e.g. bit 0 = phy id 0).
- */
-static u32 scic_sds_port_get_phys(struct scic_sds_port *sci_port)
-{
- u32 index;
- u32 mask;
-
- mask = 0;
-
- for (index = 0; index < SCI_MAX_PHYS; index++) {
- if (sci_port->phy_table[index] != NULL) {
- mask |= (1 << index);
- }
- }
-
- return mask;
-}
-
-/**
- *
- * @sci_port: This is the port object for which to determine if the phy mask
- * can be supported.
- *
- * This method will return a true value if the port's phy mask can be supported
- * by the SCU. The following is a list of valid PHY mask configurations for
- * each port: - Port 0 - [[3 2] 1] 0 - Port 1 - [1] - Port 2 - [[3] 2]
- * - Port 3 - [3] This method returns a boolean indication specifying if the
- * phy mask can be supported. true if this is a valid phy assignment for the
- * port false if this is not a valid phy assignment for the port
- */
-static bool scic_sds_port_is_phy_mask_valid(
- struct scic_sds_port *sci_port,
- u32 phy_mask)
-{
- if (sci_port->physical_port_index == 0) {
- if (((phy_mask & 0x0F) == 0x0F)
- || ((phy_mask & 0x03) == 0x03)
- || ((phy_mask & 0x01) == 0x01)
- || (phy_mask == 0))
- return true;
- } else if (sci_port->physical_port_index == 1) {
- if (((phy_mask & 0x02) == 0x02)
- || (phy_mask == 0))
- return true;
- } else if (sci_port->physical_port_index == 2) {
- if (((phy_mask & 0x0C) == 0x0C)
- || ((phy_mask & 0x04) == 0x04)
- || (phy_mask == 0))
- return true;
- } else if (sci_port->physical_port_index == 3) {
- if (((phy_mask & 0x08) == 0x08)
- || (phy_mask == 0))
- return true;
- }
-
- return false;
-}
-
-/**
- *
- * @sci_port: This parameter specifies the port from which to return a
- * connected phy.
- *
- * This method retrieves a currently active (i.e. connected) phy contained in
- * the port. Currently, the lowest order phy that is connected is returned.
- * This method returns a pointer to a SCIS_SDS_PHY object. NULL This value is
- * returned if there are no currently active (i.e. connected to a remote end
- * point) phys contained in the port. All other values specify a struct scic_sds_phy
- * object that is active in the port.
- */
-static struct scic_sds_phy *scic_sds_port_get_a_connected_phy(
- struct scic_sds_port *sci_port
- ) {
- u32 index;
- struct scic_sds_phy *phy;
-
- for (index = 0; index < SCI_MAX_PHYS; index++) {
- /*
- * Ensure that the phy is both part of the port and currently
- * connected to the remote end-point. */
- phy = sci_port->phy_table[index];
- if (
- (phy != NULL)
- && scic_sds_port_active_phy(sci_port, phy)
- ) {
- return phy;
- }
- }
-
- return NULL;
-}
-
-/**
- * scic_sds_port_set_phy() -
- * @out]: port The port object to which the phy assignement is being made.
- * @out]: phy The phy which is being assigned to the port.
- *
- * This method attempts to make the assignment of the phy to the port. If
- * successful the phy is assigned to the ports phy table. bool true if the phy
- * assignment can be made. false if the phy assignement can not be made. This
- * is a functional test that only fails if the phy is currently assigned to a
- * different port.
- */
-static enum sci_status scic_sds_port_set_phy(
- struct scic_sds_port *port,
- struct scic_sds_phy *phy)
-{
- /*
- * Check to see if we can add this phy to a port
- * that means that the phy is not part of a port and that the port does
- * not already have a phy assinged to the phy index. */
- if (
- (port->phy_table[phy->phy_index] == NULL)
- && (scic_sds_phy_get_port(phy) == NULL)
- && scic_sds_port_is_valid_phy_assignment(port, phy->phy_index)
- ) {
- /*
- * Phy is being added in the stopped state so we are in MPC mode
- * make logical port index = physical port index */
- port->logical_port_index = port->physical_port_index;
- port->phy_table[phy->phy_index] = phy;
- scic_sds_phy_set_port(phy, port);
-
- return SCI_SUCCESS;
- }
-
- return SCI_FAILURE;
-}
-
-/**
- * scic_sds_port_clear_phy() -
- * @out]: port The port from which the phy is being cleared.
- * @out]: phy The phy being cleared from the port.
- *
- * This method will clear the phy assigned to this port. This method fails if
- * this phy is not currently assinged to this port. bool true if the phy is
- * removed from the port. false if this phy is not assined to this port.
- */
-static enum sci_status scic_sds_port_clear_phy(
- struct scic_sds_port *port,
- struct scic_sds_phy *phy)
-{
- /* Make sure that this phy is part of this port */
- if (port->phy_table[phy->phy_index] == phy &&
- scic_sds_phy_get_port(phy) == port) {
- struct scic_sds_controller *scic = port->owning_controller;
- struct isci_host *ihost = scic_to_ihost(scic);
-
- /* Yep it is assigned to this port so remove it */
- scic_sds_phy_set_port(phy, &ihost->ports[SCI_MAX_PORTS].sci);
- port->phy_table[phy->phy_index] = NULL;
- return SCI_SUCCESS;
- }
-
- return SCI_FAILURE;
-}
-
-/**
- * scic_sds_port_add_phy() -
- * @sci_port: This parameter specifies the port in which the phy will be added.
- * @sci_phy: This parameter is the phy which is to be added to the port.
- *
- * This method will add a PHY to the selected port. This method returns an
- * enum sci_status. SCI_SUCCESS the phy has been added to the port. Any other status
- * is failre to add the phy to the port.
- */
-enum sci_status scic_sds_port_add_phy(
- struct scic_sds_port *sci_port,
- struct scic_sds_phy *sci_phy)
-{
- return sci_port->state_handlers->add_phy_handler(
- sci_port, sci_phy);
-}
-
-
-/**
- * scic_sds_port_remove_phy() -
- * @sci_port: This parameter specifies the port in which the phy will be added.
- * @sci_phy: This parameter is the phy which is to be added to the port.
- *
- * This method will remove the PHY from the selected PORT. This method returns
- * an enum sci_status. SCI_SUCCESS the phy has been removed from the port. Any other
- * status is failre to add the phy to the port.
- */
-enum sci_status scic_sds_port_remove_phy(
- struct scic_sds_port *sci_port,
- struct scic_sds_phy *sci_phy)
-{
- return sci_port->state_handlers->remove_phy_handler(
- sci_port, sci_phy);
-}
-
-/**
- * This method requests the SAS address for the supplied SAS port from the SCI
- * implementation.
- * @sci_port: a handle corresponding to the SAS port for which to return the
- * SAS address.
- * @sas_address: This parameter specifies a pointer to a SAS address structure
- * into which the core will copy the SAS address for the port.
- *
- */
-void scic_sds_port_get_sas_address(
- struct scic_sds_port *sci_port,
- struct sci_sas_address *sas_address)
-{
- u32 index;
-
- sas_address->high = 0;
- sas_address->low = 0;
-
- for (index = 0; index < SCI_MAX_PHYS; index++) {
- if (sci_port->phy_table[index] != NULL) {
- scic_sds_phy_get_sas_address(sci_port->phy_table[index], sas_address);
- }
- }
-}
-
-/*
- * This function will indicate which protocols are supported by this port.
- * @sci_port: a handle corresponding to the SAS port for which to return the
- * supported protocols.
- * @protocols: This parameter specifies a pointer to a data structure
- * which the core will copy the protocol values for the port from the
- * transmit_identification register.
- */
-static void
-scic_sds_port_get_protocols(struct scic_sds_port *sci_port,
- struct scic_phy_proto *protocols)
-{
- u8 index;
-
- protocols->all = 0;
-
- for (index = 0; index < SCI_MAX_PHYS; index++) {
- if (sci_port->phy_table[index] != NULL) {
- scic_sds_phy_get_protocols(sci_port->phy_table[index],
- protocols);
- }
- }
-}
-
-/*
- * This function requests the SAS address for the device directly attached to
- * this SAS port.
- * @sci_port: a handle corresponding to the SAS port for which to return the
- * SAS address.
- * @sas_address: This parameter specifies a pointer to a SAS address structure
- * into which the core will copy the SAS address for the device directly
- * attached to the port.
- *
- */
-void scic_sds_port_get_attached_sas_address(
- struct scic_sds_port *sci_port,
- struct sci_sas_address *sas_address)
-{
- struct scic_sds_phy *sci_phy;
-
- /*
- * Ensure that the phy is both part of the port and currently
- * connected to the remote end-point.
- */
- sci_phy = scic_sds_port_get_a_connected_phy(sci_port);
- if (sci_phy) {
- if (sci_phy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA) {
- scic_sds_phy_get_attached_sas_address(sci_phy,
- sas_address);
- } else {
- scic_sds_phy_get_sas_address(sci_phy, sas_address);
- sas_address->low += sci_phy->phy_index;
- }
- } else {
- sas_address->high = 0;
- sas_address->low = 0;
- }
-}
-
-/**
- * scic_sds_port_construct_dummy_rnc() - create dummy rnc for si workaround
- *
- * @sci_port: logical port on which we need to create the remote node context
- * @rni: remote node index for this remote node context.
- *
- * This routine will construct a dummy remote node context data structure
- * This structure will be posted to the hardware to work around a scheduler
- * error in the hardware.
- */
-static void scic_sds_port_construct_dummy_rnc(struct scic_sds_port *sci_port, u16 rni)
-{
- union scu_remote_node_context *rnc;
-
- rnc = &sci_port->owning_controller->remote_node_context_table[rni];
-
- memset(rnc, 0, sizeof(union scu_remote_node_context));
-
- rnc->ssp.remote_sas_address_hi = 0;
- rnc->ssp.remote_sas_address_lo = 0;
-
- rnc->ssp.remote_node_index = rni;
- rnc->ssp.remote_node_port_width = 1;
- rnc->ssp.logical_port_index = sci_port->physical_port_index;
-
- rnc->ssp.nexus_loss_timer_enable = false;
- rnc->ssp.check_bit = false;
- rnc->ssp.is_valid = true;
- rnc->ssp.is_remote_node_context = true;
- rnc->ssp.function_number = 0;
- rnc->ssp.arbitration_wait_time = 0;
-}
-
-/**
- * scic_sds_port_construct_dummy_task() - create dummy task for si workaround
- * @sci_port The logical port on which we need to create the
- * remote node context.
- * context.
- * @tci The remote node index for this remote node context.
- *
- * This routine will construct a dummy task context data structure. This
- * structure will be posted to the hardwre to work around a scheduler error
- * in the hardware.
- *
- */
-static void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tci)
-{
- struct scu_task_context *task_context;
-
- task_context = scic_sds_controller_get_task_context_buffer(sci_port->owning_controller, tci);
-
- memset(task_context, 0, sizeof(struct scu_task_context));
-
- task_context->abort = 0;
- task_context->priority = 0;
- task_context->initiator_request = 1;
- task_context->connection_rate = 1;
- task_context->protocol_engine_index = 0;
- task_context->logical_port_index = sci_port->physical_port_index;
- task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
- task_context->task_index = scic_sds_io_tag_get_index(tci);
- task_context->valid = SCU_TASK_CONTEXT_VALID;
- task_context->context_type = SCU_TASK_CONTEXT_TYPE;
-
- task_context->remote_node_index = sci_port->reserved_rni;
- task_context->command_code = 0;
-
- task_context->link_layer_control = 0;
- task_context->do_not_dma_ssp_good_response = 1;
- task_context->strict_ordering = 0;
- task_context->control_frame = 0;
- task_context->timeout_enable = 0;
- task_context->block_guard_enable = 0;
-
- task_context->address_modifier = 0;
-
- task_context->task_phase = 0x01;
-}
-
-static void scic_sds_port_destroy_dummy_resources(struct scic_sds_port *sci_port)
-{
- struct scic_sds_controller *scic = sci_port->owning_controller;
-
- if (sci_port->reserved_tci != SCU_DUMMY_INDEX)
- scic_controller_free_io_tag(scic, sci_port->reserved_tci);
-
- if (sci_port->reserved_rni != SCU_DUMMY_INDEX)
- scic_sds_remote_node_table_release_remote_node_index(&scic->available_remote_nodes,
- 1, sci_port->reserved_rni);
-
- sci_port->reserved_rni = SCU_DUMMY_INDEX;
- sci_port->reserved_tci = SCU_DUMMY_INDEX;
-}
-
-/**
- * This method performs initialization of the supplied port. Initialization
- * includes: - state machine initialization - member variable initialization
- * - configuring the phy_mask
- * @sci_port:
- * @transport_layer_registers:
- * @port_task_scheduler_registers:
- * @port_configuration_regsiter:
- *
- * enum sci_status SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION This value is returned
- * if the phy being added to the port
- */
-enum sci_status scic_sds_port_initialize(
- struct scic_sds_port *sci_port,
- void __iomem *port_task_scheduler_registers,
- void __iomem *port_configuration_regsiter,
- void __iomem *viit_registers)
-{
- sci_port->port_task_scheduler_registers = port_task_scheduler_registers;
- sci_port->port_pe_configuration_register = port_configuration_regsiter;
- sci_port->viit_registers = viit_registers;
-
- return SCI_SUCCESS;
-}
-
-/**
- * scic_port_get_properties() - This method simply returns the properties
- * regarding the port, such as: physi