aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/isci/core/scic_port.h17
-rw-r--r--drivers/scsi/isci/core/scic_sds_controller.c22
-rw-r--r--drivers/scsi/isci/core/scic_sds_port.c334
-rw-r--r--drivers/scsi/isci/core/scic_sds_port.h9
-rw-r--r--drivers/scsi/isci/host.c7
5 files changed, 298 insertions, 91 deletions
diff --git a/drivers/scsi/isci/core/scic_port.h b/drivers/scsi/isci/core/scic_port.h
index e55abb68ff9a..8222443c9fd7 100644
--- a/drivers/scsi/isci/core/scic_port.h
+++ b/drivers/scsi/isci/core/scic_port.h
@@ -147,23 +147,6 @@ enum sci_status scic_port_get_properties(
147 struct scic_sds_port *port, 147 struct scic_sds_port *port,
148 struct scic_port_properties *properties); 148 struct scic_port_properties *properties);
149 149
150
151
152/**
153 * scic_port_start() - This method will make the port ready for operation.
154 * Prior to calling the start method IO operation is not possible.
155 * @port: This parameter specifies the port to be started.
156 *
157 * Indicate if the port was successfully started. SCI_SUCCESS This value is
158 * returned if the port was successfully started. SCI_WARNING_ALREADY_IN_STATE
159 * This value is returned if the port is in the process of starting.
160 * SCI_FAILURE_INVALID_PORT This value is returned if the supplied port is not
161 * valid. SCI_FAILURE_INVALID_STATE This value is returned if a start operation
162 * can't be completed due to the state of port.
163 */
164enum sci_status scic_port_start(
165 struct scic_sds_port *port);
166
167/** 150/**
168 * scic_port_stop() - This method will make the port no longer ready for 151 * scic_port_stop() - This method will make the port no longer ready for
169 * operation. After invoking this method IO operation is not possible. 152 * operation. After invoking this method IO operation is not possible.
diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c
index d642ff7be6db..5e26df7fcb3a 100644
--- a/drivers/scsi/isci/core/scic_sds_controller.c
+++ b/drivers/scsi/isci/core/scic_sds_controller.c
@@ -796,7 +796,11 @@ enum sci_status scic_sds_controller_stop_ports(struct scic_sds_controller *scic)
796 enum sci_status status = SCI_SUCCESS; 796 enum sci_status status = SCI_SUCCESS;
797 797
798 for (index = 0; index < scic->logical_port_entries; index++) { 798 for (index = 0; index < scic->logical_port_entries; index++) {
799 port_status = scic_port_stop(&scic->port_table[index]); 799 struct scic_sds_port *sci_port = &scic->port_table[index];
800 SCI_BASE_PORT_HANDLER_T stop;
801
802 stop = sci_port->state_handlers->parent.stop_handler;
803 port_status = stop(&sci_port->parent);
800 804
801 if ((port_status != SCI_SUCCESS) && 805 if ((port_status != SCI_SUCCESS) &&
802 (port_status != SCI_FAILURE_INVALID_STATE)) { 806 (port_status != SCI_FAILURE_INVALID_STATE)) {
@@ -806,7 +810,7 @@ enum sci_status scic_sds_controller_stop_ports(struct scic_sds_controller *scic)
806 "%s: Controller stop operation failed to " 810 "%s: Controller stop operation failed to "
807 "stop port %d because of status %d.\n", 811 "stop port %d because of status %d.\n",
808 __func__, 812 __func__,
809 scic->port_table[index].logical_port_index, 813 sci_port->logical_port_index,
810 port_status); 814 port_status);
811 } 815 }
812 } 816 }
@@ -3003,7 +3007,7 @@ static enum sci_status scic_sds_controller_initialized_state_start_handler(
3003 scic_sds_controller_ram_initialization(this_controller); 3007 scic_sds_controller_ram_initialization(this_controller);
3004 } 3008 }
3005 3009
3006 if (SCI_SUCCESS == result) { 3010 if (result == SCI_SUCCESS) {
3007 /* Build the TCi free pool */ 3011 /* Build the TCi free pool */
3008 sci_pool_initialize(this_controller->tci_pool); 3012 sci_pool_initialize(this_controller->tci_pool);
3009 for (index = 0; index < this_controller->task_context_entries; index++) { 3013 for (index = 0; index < this_controller->task_context_entries; index++) {
@@ -3017,7 +3021,7 @@ static enum sci_status scic_sds_controller_initialized_state_start_handler(
3017 ); 3021 );
3018 } 3022 }
3019 3023
3020 if (SCI_SUCCESS == result) { 3024 if (result == SCI_SUCCESS) {
3021 /* 3025 /*
3022 * Before anything else lets make sure we will not be interrupted 3026 * Before anything else lets make sure we will not be interrupted
3023 * by the hardware. */ 3027 * by the hardware. */
@@ -3036,7 +3040,15 @@ static enum sci_status scic_sds_controller_initialized_state_start_handler(
3036 scic_sds_controller_initialize_unsolicited_frame_queue(this_controller); 3040 scic_sds_controller_initialize_unsolicited_frame_queue(this_controller);
3037 } 3041 }
3038 3042
3039 if (SCI_SUCCESS == result) { 3043 /* Start all of the ports on this controller */
3044 for (index = 0; index < this_controller->logical_port_entries &&
3045 result == SCI_SUCCESS; index++) {
3046 struct scic_sds_port *sci_port = &this_controller->port_table[index];
3047
3048 result = sci_port->state_handlers->parent.start_handler(&sci_port->parent);
3049 }
3050
3051 if (result == SCI_SUCCESS) {
3040 scic_sds_controller_start_next_phy(this_controller); 3052 scic_sds_controller_start_next_phy(this_controller);
3041 3053
3042 isci_event_timer_start(this_controller, 3054 isci_event_timer_start(this_controller,
diff --git a/drivers/scsi/isci/core/scic_sds_port.c b/drivers/scsi/isci/core/scic_sds_port.c
index d374c7ac0b71..2a193d30c55d 100644
--- a/drivers/scsi/isci/core/scic_sds_port.c
+++ b/drivers/scsi/isci/core/scic_sds_port.c
@@ -67,6 +67,7 @@
67#include "scic_sds_remote_node_context.h" 67#include "scic_sds_remote_node_context.h"
68#include "scic_sds_request.h" 68#include "scic_sds_request.h"
69#include "sci_environment.h" 69#include "sci_environment.h"
70#include "scic_sds_controller_registers.h"
70 71
71 72
72static void scic_sds_port_invalid_link_up( 73static void scic_sds_port_invalid_link_up(
@@ -78,6 +79,7 @@ static void scic_sds_port_timeout_handler(
78#define SCIC_SDS_PORT_MAX_TIMER_COUNT (SCI_MAX_PORTS) 79#define SCIC_SDS_PORT_MAX_TIMER_COUNT (SCI_MAX_PORTS)
79 80
80#define SCIC_SDS_PORT_HARD_RESET_TIMEOUT (1000) 81#define SCIC_SDS_PORT_HARD_RESET_TIMEOUT (1000)
82#define SCU_DUMMY_INDEX (0xFFFF)
81 83
82void sci_base_port_construct( 84void sci_base_port_construct(
83 struct sci_base_port *base_port, 85 struct sci_base_port *base_port,
@@ -474,67 +476,131 @@ void scic_sds_port_get_attached_protocols(
474} 476}
475 477
476/** 478/**
477 * This method returns the amount of memory requred for a port object. 479 * scic_sds_port_construct_dummy_rnc() - create dummy rnc for si workaround
478 * 480 *
479 * u32 481 * @sci_port: logical port on which we need to create the remote node context
480 */ 482 * @rni: remote node index for this remote node context.
481
482/**
483 * This method returns the minimum number of timers required for all port
484 * objects.
485 * 483 *
486 * u32 484 * This routine will construct a dummy remote node context data structure
485 * This structure will be posted to the hardware to work around a scheduler
486 * error in the hardware.
487 */ 487 */
488void scic_sds_port_construct_dummy_rnc(struct scic_sds_port *sci_port, u16 rni)
489{
490 union scu_remote_node_context *rnc;
488 491
489/** 492 rnc = &sci_port->owning_controller->remote_node_context_table[rni];
490 * This method returns the maximum number of timers required for all port 493
491 * objects. 494 memset(rnc, 0, sizeof(union scu_remote_node_context));
492 * 495
493 * u32 496 rnc->ssp.remote_sas_address_hi = 0;
494 */ 497 rnc->ssp.remote_sas_address_lo = 0;
498
499 rnc->ssp.remote_node_index = rni;
500 rnc->ssp.remote_node_port_width = 1;
501 rnc->ssp.logical_port_index = sci_port->physical_port_index;
502
503 rnc->ssp.nexus_loss_timer_enable = false;
504 rnc->ssp.check_bit = false;
505 rnc->ssp.is_valid = true;
506 rnc->ssp.is_remote_node_context = true;
507 rnc->ssp.function_number = 0;
508 rnc->ssp.arbitration_wait_time = 0;
509}
495 510
496/** 511/**
512 * scic_sds_port_construct_dummy_task() - create dummy task for si workaround
513 * @sci_port The logical port on which we need to create the
514 * remote node context.
515 * context.
516 * @tci The remote node index for this remote node context.
497 * 517 *
498 * @this_port: 518 * This routine will construct a dummy task context data structure. This
499 * @port_index: 519 * structure will be posted to the hardwre to work around a scheduler error
500 * 520 * in the hardware.
501 * 521 *
502 */ 522 */
503void scic_sds_port_construct( 523void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tci)
504 struct scic_sds_port *this_port, 524{
505 u8 port_index, 525 struct scu_task_context *task_context;
506 struct scic_sds_controller *owning_controller) 526
527 task_context = scic_sds_controller_get_task_context_buffer(sci_port->owning_controller, tci);
528
529 memset(task_context, 0, sizeof(struct scu_task_context));
530
531 task_context->abort = 0;
532 task_context->priority = 0;
533 task_context->initiator_request = 1;
534 task_context->connection_rate = 1;
535 task_context->protocol_engine_index = 0;
536 task_context->logical_port_index = sci_port->physical_port_index;
537 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
538 task_context->task_index = scic_sds_io_tag_get_index(tci);
539 task_context->valid = SCU_TASK_CONTEXT_VALID;
540 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
541
542 task_context->remote_node_index = sci_port->reserved_rni;
543 task_context->command_code = 0;
544
545 task_context->link_layer_control = 0;
546 task_context->do_not_dma_ssp_good_response = 1;
547 task_context->strict_ordering = 0;
548 task_context->control_frame = 0;
549 task_context->timeout_enable = 0;
550 task_context->block_guard_enable = 0;
551
552 task_context->address_modifier = 0;
553
554 task_context->task_phase = 0x01;
555}
556
557void scic_sds_port_destroy_dummy_resources(struct scic_sds_port *sci_port)
558{
559 struct scic_sds_controller *scic = sci_port->owning_controller;
560
561 if (sci_port->reserved_tci != SCU_DUMMY_INDEX)
562 scic_controller_free_io_tag(scic, sci_port->reserved_tci);
563
564 if (sci_port->reserved_rni != SCU_DUMMY_INDEX)
565 scic_sds_remote_node_table_release_remote_node_index(&scic->available_remote_nodes,
566 1, sci_port->reserved_rni);
567
568 sci_port->reserved_rni = SCU_DUMMY_INDEX;
569 sci_port->reserved_tci = SCU_DUMMY_INDEX;
570}
571
572void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 port_index,
573 struct scic_sds_controller *scic)
507{ 574{
508 u32 index; 575 u32 index;
509 576
510 sci_base_port_construct( 577 sci_base_port_construct(&sci_port->parent, scic_sds_port_state_table);
511 &this_port->parent,
512 scic_sds_port_state_table
513 );
514 578
515 sci_base_state_machine_construct( 579 sci_base_state_machine_construct(
516 scic_sds_port_get_ready_substate_machine(this_port), 580 scic_sds_port_get_ready_substate_machine(sci_port),
517 &this_port->parent.parent, 581 &sci_port->parent.parent,
518 scic_sds_port_ready_substate_table, 582 scic_sds_port_ready_substate_table,
519 SCIC_SDS_PORT_READY_SUBSTATE_WAITING 583 SCIC_SDS_PORT_READY_SUBSTATE_WAITING
520 ); 584 );
521 585
522 this_port->logical_port_index = SCIC_SDS_DUMMY_PORT; 586 sci_port->logical_port_index = SCIC_SDS_DUMMY_PORT;
523 this_port->physical_port_index = port_index; 587 sci_port->physical_port_index = port_index;
524 this_port->active_phy_mask = 0; 588 sci_port->active_phy_mask = 0;
525 589
526 this_port->owning_controller = owning_controller; 590 sci_port->owning_controller = scic;
527 591
528 this_port->started_request_count = 0; 592 sci_port->started_request_count = 0;
529 this_port->assigned_device_count = 0; 593 sci_port->assigned_device_count = 0;
530 594
531 this_port->timer_handle = NULL; 595 sci_port->reserved_rni = SCU_DUMMY_INDEX;
596 sci_port->reserved_tci = SCU_DUMMY_INDEX;
532 597
533 this_port->port_task_scheduler_registers = NULL; 598 sci_port->timer_handle = NULL;
534 599
535 for (index = 0; index < SCI_MAX_PHYS; index++) { 600 sci_port->port_task_scheduler_registers = NULL;
536 this_port->phy_table[index] = NULL; 601
537 } 602 for (index = 0; index < SCI_MAX_PHYS; index++)
603 sci_port->phy_table[index] = NULL;
538} 604}
539 605
540/** 606/**
@@ -634,19 +700,11 @@ void scic_sds_port_general_link_up_handler(
634 } 700 }
635} 701}
636 702
637
638enum sci_status scic_port_start(struct scic_sds_port *port)
639{
640 return port->state_handlers->parent.start_handler(&port->parent);
641}
642
643
644enum sci_status scic_port_stop(struct scic_sds_port *port) 703enum sci_status scic_port_stop(struct scic_sds_port *port)
645{ 704{
646 return port->state_handlers->parent.stop_handler(&port->parent); 705 return port->state_handlers->parent.stop_handler(&port->parent);
647} 706}
648 707
649
650enum sci_status scic_port_get_properties( 708enum sci_status scic_port_get_properties(
651 struct scic_sds_port *port, 709 struct scic_sds_port *port,
652 struct scic_port_properties *prop) 710 struct scic_port_properties *prop)
@@ -1542,6 +1600,58 @@ static void scic_sds_port_suspend_port_task_scheduler(
1542} 1600}
1543 1601
1544/** 1602/**
1603 * scic_sds_port_post_dummy_request() - post dummy/workaround request
1604 * @sci_port: port to post task
1605 *
1606 * Prevent the hardware scheduler from posting new requests to the front
1607 * of the scheduler queue causing a starvation problem for currently
1608 * ongoing requests.
1609 *
1610 */
1611void scic_sds_port_post_dummy_request(struct scic_sds_port *sci_port)
1612{
1613 u32 command;
1614 struct scu_task_context *task_context;
1615 struct scic_sds_controller *scic = sci_port->owning_controller;
1616 u16 tci = sci_port->reserved_tci;
1617
1618 task_context = scic_sds_controller_get_task_context_buffer(scic, tci);
1619
1620 task_context->abort = 0;
1621
1622 command = SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
1623 sci_port->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
1624 tci;
1625
1626 scic_sds_controller_post_request(scic, command);
1627}
1628
1629/**
1630 * This routine will abort the dummy request. This will alow the hardware to
1631 * power down parts of the silicon to save power.
1632 *
1633 * @sci_port: The port on which the task must be aborted.
1634 *
1635 */
1636void scic_sds_port_abort_dummy_request(struct scic_sds_port *sci_port)
1637{
1638 struct scic_sds_controller *scic = sci_port->owning_controller;
1639 u16 tci = sci_port->reserved_tci;
1640 struct scu_task_context *tc;
1641 u32 command;
1642
1643 tc = scic_sds_controller_get_task_context_buffer(scic, tci);
1644
1645 tc->abort = 1;
1646
1647 command = SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT |
1648 sci_port->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
1649 tci;
1650
1651 scic_sds_controller_post_request(scic, command);
1652}
1653
1654/**
1545 * 1655 *
1546 * @this_port: This is the struct scic_sds_port object to resume. 1656 * @this_port: This is the struct scic_sds_port object to resume.
1547 * 1657 *
@@ -1584,6 +1694,12 @@ static void scic_sds_port_ready_substate_waiting_enter(
1584 1694
1585 scic_sds_port_suspend_port_task_scheduler(this_port); 1695 scic_sds_port_suspend_port_task_scheduler(this_port);
1586 1696
1697 /* Kill the dummy task for this port if it has not yet posted
1698 * the hardware will treat this as a NOP and just return abort
1699 * complete.
1700 */
1701 scic_sds_port_abort_dummy_request(this_port);
1702
1587 this_port->not_ready_reason = SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS; 1703 this_port->not_ready_reason = SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS;
1588 1704
1589 if (this_port->active_phy_mask != 0) { 1705 if (this_port->active_phy_mask != 0) {
@@ -1629,6 +1745,11 @@ static void scic_sds_port_ready_substate_operational_enter(
1629 scic_sds_port_update_viit_entry(this_port); 1745 scic_sds_port_update_viit_entry(this_port);
1630 1746
1631 scic_sds_port_resume_port_task_scheduler(this_port); 1747 scic_sds_port_resume_port_task_scheduler(this_port);
1748
1749 /* Post the dummy task for the port so the hardware can schedule
1750 * io correctly
1751 */
1752 scic_sds_port_post_dummy_request(this_port);
1632} 1753}
1633 1754
1634/** 1755/**
@@ -2062,6 +2183,7 @@ static enum sci_status scic_sds_port_general_complete_io_handler(
2062 * **************************************************************************** */ 2183 * **************************************************************************** */
2063 2184
2064/** 2185/**
2186 * scic_sds_port_stopped_state_start_handler() - stop a port from "started"
2065 * 2187 *
2066 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port 2188 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2067 * object. 2189 * object.
@@ -2075,13 +2197,14 @@ static enum sci_status scic_sds_port_general_complete_io_handler(
2075 * start request is successful and the struct scic_sds_port object has transitioned to 2197 * start request is successful and the struct scic_sds_port object has transitioned to
2076 * the SCI_BASE_PORT_STATE_READY. 2198 * the SCI_BASE_PORT_STATE_READY.
2077 */ 2199 */
2078static enum sci_status scic_sds_port_stopped_state_start_handler( 2200static enum sci_status scic_sds_port_stopped_state_start_handler(struct sci_base_port *base_port)
2079 struct sci_base_port *port)
2080{ 2201{
2202 struct scic_sds_port *sci_port = container_of(base_port, typeof(*sci_port), parent);
2203 struct scic_sds_controller *scic = sci_port->owning_controller;
2204 enum sci_status status = SCI_SUCCESS;
2081 u32 phy_mask; 2205 u32 phy_mask;
2082 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2083 2206
2084 if (this_port->assigned_device_count > 0) { 2207 if (sci_port->assigned_device_count > 0) {
2085 /* 2208 /*
2086 * / @todo This is a start failure operation because there are still 2209 * / @todo This is a start failure operation because there are still
2087 * / devices assigned to this port. There must be no devices 2210 * / devices assigned to this port. There must be no devices
@@ -2089,22 +2212,56 @@ static enum sci_status scic_sds_port_stopped_state_start_handler(
2089 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; 2212 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
2090 } 2213 }
2091 2214
2092 phy_mask = scic_sds_port_get_phys(this_port); 2215 sci_port->timer_handle = isci_event_timer_create(scic,
2216 scic_sds_port_timeout_handler,
2217 sci_port);
2093 2218
2094 /* 2219 if (!sci_port->timer_handle)
2095 * There are one or more phys assigned to this port. Make sure 2220 return SCI_FAILURE_INSUFFICIENT_RESOURCES;
2096 * the port's phy mask is in fact legal and supported by the
2097 * silicon. */
2098 if (scic_sds_port_is_phy_mask_valid(this_port, phy_mask) == true) {
2099 sci_base_state_machine_change_state(
2100 scic_sds_port_get_base_state_machine(this_port),
2101 SCI_BASE_PORT_STATE_READY
2102 );
2103 2221
2104 return SCI_SUCCESS; 2222 if (sci_port->reserved_rni == SCU_DUMMY_INDEX) {
2223 u16 rni = scic_sds_remote_node_table_allocate_remote_node(&scic->available_remote_nodes, 1);
2224
2225 if (rni != SCU_DUMMY_INDEX)
2226 scic_sds_port_construct_dummy_rnc(sci_port, rni);
2227 else
2228 status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
2229 sci_port->reserved_rni = rni;
2230 }
2231
2232 if (sci_port->reserved_tci == SCU_DUMMY_INDEX) {
2233 /* Allocate a TCI and remove the sequence nibble */
2234 u16 tci = scic_controller_allocate_io_tag(scic);
2235
2236 if (tci != SCU_DUMMY_INDEX)
2237 scic_sds_port_construct_dummy_task(sci_port, tci);
2238 else
2239 status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
2240 sci_port->reserved_tci = tci;
2241 }
2242
2243 if (status == SCI_SUCCESS) {
2244 phy_mask = scic_sds_port_get_phys(sci_port);
2245
2246 /*
2247 * There are one or more phys assigned to this port. Make sure
2248 * the port's phy mask is in fact legal and supported by the
2249 * silicon.
2250 */
2251 if (scic_sds_port_is_phy_mask_valid(sci_port, phy_mask) == true) {
2252 sci_base_state_machine_change_state(
2253 scic_sds_port_get_base_state_machine(sci_port),
2254 SCI_BASE_PORT_STATE_READY);
2255
2256 return SCI_SUCCESS;
2257 } else
2258 status = SCI_FAILURE;
2105 } 2259 }
2106 2260
2107 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION; 2261 if (status != SCI_SUCCESS)
2262 scic_sds_port_destroy_dummy_resources(sci_port);
2263
2264 return status;
2108} 2265}
2109 2266
2110/** 2267/**
@@ -2467,6 +2624,52 @@ static void scic_sds_port_disable_port_task_scheduler(
2467 scu_port_task_scheduler_write(this_port, control, pts_control_value); 2624 scu_port_task_scheduler_write(this_port, control, pts_control_value);
2468} 2625}
2469 2626
2627void scic_sds_port_post_dummy_remote_node(struct scic_sds_port *sci_port)
2628{
2629 struct scic_sds_controller *scic = sci_port->owning_controller;
2630 u8 phys_index = sci_port->physical_port_index;
2631 union scu_remote_node_context *rnc;
2632 u16 rni = sci_port->reserved_rni;
2633 u32 command;
2634
2635 rnc = &scic->remote_node_context_table[rni];
2636 rnc->ssp.is_valid = true;
2637
2638 command = SCU_CONTEXT_COMMAND_POST_RNC_32 |
2639 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
2640
2641 scic_sds_controller_post_request(scic, command);
2642
2643 /* ensure hardware has seen the post rnc command and give it
2644 * ample time to act before sending the suspend
2645 */
2646 SMU_ISR_READ(scic); /* flush */
2647 udelay(10);
2648
2649 command = SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX |
2650 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
2651
2652 scic_sds_controller_post_request(scic, command);
2653}
2654
2655void scic_sds_port_invalidate_dummy_remote_node(struct scic_sds_port *sci_port)
2656{
2657 struct scic_sds_controller *scic = sci_port->owning_controller;
2658 u8 phys_index = sci_port->physical_port_index;
2659 union scu_remote_node_context *rnc;
2660 u16 rni = sci_port->reserved_rni;
2661 u32 command;
2662
2663 rnc = &scic->remote_node_context_table[rni];
2664
2665 rnc->ssp.is_valid = false;
2666
2667 command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE |
2668 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
2669
2670 scic_sds_controller_post_request(scic, command);
2671}
2672
2470/* 2673/*
2471 * ****************************************************************************** 2674 * ******************************************************************************
2472 * * PORT STATE METHODS 2675 * * PORT STATE METHODS
@@ -2562,6 +2765,9 @@ static void scic_sds_port_ready_state_enter(
2562 ); 2765 );
2563 } 2766 }
2564 2767
2768 /* Post and suspend the dummy remote node context for this port. */
2769 scic_sds_port_post_dummy_remote_node(this_port);
2770
2565 /* Start the ready substate machine */ 2771 /* Start the ready substate machine */
2566 sci_base_state_machine_start( 2772 sci_base_state_machine_start(
2567 scic_sds_port_get_ready_substate_machine(this_port) 2773 scic_sds_port_get_ready_substate_machine(this_port)
@@ -2583,6 +2789,8 @@ static void scic_sds_port_ready_state_exit(
2583 this_port = (struct scic_sds_port *)object; 2789 this_port = (struct scic_sds_port *)object;
2584 2790
2585 sci_base_state_machine_stop(&this_port->ready_substate_machine); 2791 sci_base_state_machine_stop(&this_port->ready_substate_machine);
2792
2793 scic_sds_port_invalidate_dummy_remote_node(this_port);
2586} 2794}
2587 2795
2588/** 2796/**
@@ -2663,6 +2871,8 @@ static void scic_sds_port_stopping_state_exit(
2663 scic_sds_port_get_controller(this_port), 2871 scic_sds_port_get_controller(this_port),
2664 this_port->timer_handle 2872 this_port->timer_handle
2665 ); 2873 );
2874
2875 scic_sds_port_destroy_dummy_resources(this_port);
2666} 2876}
2667 2877
2668/** 2878/**
diff --git a/drivers/scsi/isci/core/scic_sds_port.h b/drivers/scsi/isci/core/scic_sds_port.h
index 3eb80cb2ea47..c98caefa7cf2 100644
--- a/drivers/scsi/isci/core/scic_sds_port.h
+++ b/drivers/scsi/isci/core/scic_sds_port.h
@@ -73,6 +73,12 @@
73#define SCIC_SDS_DUMMY_PORT 0xFF 73#define SCIC_SDS_DUMMY_PORT 0xFF
74 74
75/** 75/**
76 * This constant defines the value utilized by SCI Components to indicate
77 * an invalid handle.
78 */
79#define SCI_INVALID_HANDLE 0x0
80
81/**
76 * enum SCIC_SDS_PORT_READY_SUBSTATES - 82 * enum SCIC_SDS_PORT_READY_SUBSTATES -
77 * 83 *
78 * This enumeration depicts all of the states for the core port ready substate 84 * This enumeration depicts all of the states for the core port ready substate
@@ -134,6 +140,9 @@ struct scic_sds_port {
134 */ 140 */
135 u8 active_phy_mask; 141 u8 active_phy_mask;
136 142
143 u16 reserved_rni;
144 u16 reserved_tci;
145
137 /** 146 /**
138 * This field contains the count of the io requests started on this port 147 * This field contains the count of the io requests started on this port
139 * object. It is used to control controller shutdown. 148 * object. It is used to control controller shutdown.
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 1bc91f2b4f93..40614e9ab41b 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -381,7 +381,6 @@ int isci_host_init(struct isci_host *isci_host)
381 int index = 0; 381 int index = 0;
382 enum sci_status status; 382 enum sci_status status;
383 struct scic_sds_controller *controller; 383 struct scic_sds_controller *controller;
384 struct scic_sds_port *scic_port;
385 union scic_oem_parameters scic_oem_params; 384 union scic_oem_parameters scic_oem_params;
386 union scic_user_parameters scic_user_params; 385 union scic_user_parameters scic_user_params;
387 386
@@ -517,11 +516,5 @@ int isci_host_init(struct isci_host *isci_host)
517 for (index = 0; index < SCI_MAX_PHYS; index++) 516 for (index = 0; index < SCI_MAX_PHYS; index++)
518 isci_phy_init(&isci_host->phys[index], isci_host, index); 517 isci_phy_init(&isci_host->phys[index], isci_host, index);
519 518
520 /* Start the ports */
521 for (index = 0; index < SCI_MAX_PORTS; index++) {
522 scic_controller_get_port_handle(controller, index, &scic_port);
523 scic_port_start(scic_port);
524 }
525
526 return 0; 519 return 0;
527} 520}