Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 302543
b: refs/heads/master
c: eb608c3
h: refs/heads/master
i:
  302541: 1584c4d
  302539: 80f69af
  302535: 726e32c
  302527: b4fe742
v: v3
  • Loading branch information
Dan Williams committed May 17, 2012
1 parent b5eb7f7 commit ae20cf8
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 53 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: abec912d71c44bbd642ce12ad98aab76f5a53163
refs/heads/master: eb608c3cb3f0a6b99252ea6a69fc0d2bbecf1f4f
99 changes: 54 additions & 45 deletions trunk/drivers/scsi/isci/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,7 @@ void isci_host_scan_start(struct Scsi_Host *shost)
spin_unlock_irq(&ihost->scic_lock);
}

static void isci_host_stop_complete(struct isci_host *ihost, enum sci_status completion_status)
static void isci_host_stop_complete(struct isci_host *ihost)
{
sci_controller_disable_interrupts(ihost);
clear_bit(IHOST_STOP_PENDING, &ihost->flags);
Expand Down Expand Up @@ -1232,7 +1232,7 @@ static enum sci_status sci_controller_reset(struct isci_host *ihost)
switch (ihost->sm.current_state_id) {
case SCIC_RESET:
case SCIC_READY:
case SCIC_STOPPED:
case SCIC_STOPPING:
case SCIC_FAILED:
/*
* The reset operation is not a graceful cleanup, just
Expand All @@ -1247,6 +1247,44 @@ static enum sci_status sci_controller_reset(struct isci_host *ihost)
}
}

static enum sci_status sci_controller_stop_phys(struct isci_host *ihost)
{
u32 index;
enum sci_status status;
enum sci_status phy_status;

status = SCI_SUCCESS;

for (index = 0; index < SCI_MAX_PHYS; index++) {
phy_status = sci_phy_stop(&ihost->phys[index]);

if (phy_status != SCI_SUCCESS &&
phy_status != SCI_FAILURE_INVALID_STATE) {
status = SCI_FAILURE;

dev_warn(&ihost->pdev->dev,
"%s: Controller stop operation failed to stop "
"phy %d because of status %d.\n",
__func__,
ihost->phys[index].phy_index, phy_status);
}
}

return status;
}


/**
* isci_host_deinit - shutdown frame reception and dma
* @ihost: host to take down
*
* This is called in either the driver shutdown or the suspend path. In
* the shutdown case libsas went through port teardown and normal device
* removal (i.e. physical links stayed up to service scsi_device removal
* commands). In the suspend case we disable the hardware without
* notifying libsas of the link down events since we want libsas to
* remember the domain across the suspend/resume cycle
*/
void isci_host_deinit(struct isci_host *ihost)
{
int i;
Expand All @@ -1255,16 +1293,6 @@ void isci_host_deinit(struct isci_host *ihost)
for (i = 0; i < isci_gpio_count(ihost); i++)
writel(SGPIO_HW_CONTROL, &ihost->scu_registers->peg0.sgpio.output_data_select[i]);

for (i = 0; i < SCI_MAX_PORTS; i++) {
struct isci_port *iport = &ihost->ports[i];
struct isci_remote_device *idev, *d;

list_for_each_entry_safe(idev, d, &iport->remote_dev_list, node) {
if (test_bit(IDEV_ALLOCATED, &idev->flags))
isci_remote_device_stop(ihost, idev);
}
}

set_bit(IHOST_STOP_PENDING, &ihost->flags);

spin_lock_irq(&ihost->scic_lock);
Expand All @@ -1273,6 +1301,13 @@ void isci_host_deinit(struct isci_host *ihost)

wait_for_stop(ihost);

/* phy stop is after controller stop to allow port and device to
* go idle before shutting down the phys, but the expectation is
* that i/o has been shut off well before we reach this
* function.
*/
sci_controller_stop_phys(ihost);

/* disable sgpio: where the above wait should give time for the
* enclosure to sample the gpios going inactive
*/
Expand Down Expand Up @@ -1476,32 +1511,6 @@ static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm)
sci_controller_set_interrupt_coalescence(ihost, 0, 0);
}

static enum sci_status sci_controller_stop_phys(struct isci_host *ihost)
{
u32 index;
enum sci_status status;
enum sci_status phy_status;

status = SCI_SUCCESS;

for (index = 0; index < SCI_MAX_PHYS; index++) {
phy_status = sci_phy_stop(&ihost->phys[index]);

if (phy_status != SCI_SUCCESS &&
phy_status != SCI_FAILURE_INVALID_STATE) {
status = SCI_FAILURE;

dev_warn(&ihost->pdev->dev,
"%s: Controller stop operation failed to stop "
"phy %d because of status %d.\n",
__func__,
ihost->phys[index].phy_index, phy_status);
}
}

return status;
}

static enum sci_status sci_controller_stop_ports(struct isci_host *ihost)
{
u32 index;
Expand Down Expand Up @@ -1561,10 +1570,11 @@ static void sci_controller_stopping_state_enter(struct sci_base_state_machine *s
{
struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);

/* Stop all of the components for this controller */
sci_controller_stop_phys(ihost);
sci_controller_stop_ports(ihost);
sci_controller_stop_devices(ihost);
sci_controller_stop_ports(ihost);

if (!sci_controller_has_remote_devices_stopping(ihost))
isci_host_stop_complete(ihost);
}

static void sci_controller_stopping_state_exit(struct sci_base_state_machine *sm)
Expand Down Expand Up @@ -1621,7 +1631,6 @@ static const struct sci_base_state sci_controller_state_table[] = {
.enter_state = sci_controller_stopping_state_enter,
.exit_state = sci_controller_stopping_state_exit,
},
[SCIC_STOPPED] = {},
[SCIC_FAILED] = {}
};

Expand All @@ -1641,7 +1650,7 @@ static void controller_timeout(unsigned long data)
sci_controller_transition_to_ready(ihost, SCI_FAILURE_TIMEOUT);
else if (sm->current_state_id == SCIC_STOPPING) {
sci_change_state(sm, SCIC_FAILED);
isci_host_stop_complete(ihost, SCI_FAILURE_TIMEOUT);
isci_host_stop_complete(ihost);
} else /* / @todo Now what do we want to do in this case? */
dev_err(&ihost->pdev->dev,
"%s: Controller timer fired when controller was not "
Expand Down Expand Up @@ -2452,7 +2461,7 @@ void sci_controller_link_down(struct isci_host *ihost, struct isci_port *iport,
}
}

static bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost)
bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost)
{
u32 index;

Expand All @@ -2478,7 +2487,7 @@ void sci_controller_remote_device_stopped(struct isci_host *ihost,
}

if (!sci_controller_has_remote_devices_stopping(ihost))
sci_change_state(&ihost->sm, SCIC_STOPPED);
isci_host_stop_complete(ihost);
}

void sci_controller_post_request(struct isci_host *ihost, u32 request)
Expand Down
8 changes: 1 addition & 7 deletions trunk/drivers/scsi/isci/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,6 @@ enum sci_controller_states {
*/
SCIC_STOPPING,

/**
* This state indicates that the controller has successfully been stopped.
* In this state no new IO operations are permitted.
* This state is entered from the STOPPING state.
*/
SCIC_STOPPED,

/**
* This state indicates that the controller could not successfully be
* initialized. In this state no new IO operations are permitted.
Expand Down Expand Up @@ -479,6 +472,7 @@ int isci_host_init(struct isci_host *);
void isci_host_completion_routine(unsigned long data);
void isci_host_deinit(struct isci_host *);
void sci_controller_disable_interrupts(struct isci_host *ihost);
bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost);

enum sci_status sci_controller_start_io(
struct isci_host *ihost,
Expand Down

0 comments on commit ae20cf8

Please sign in to comment.