Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 293010
b: refs/heads/master
c: 9277699
h: refs/heads/master
v: v3
  • Loading branch information
Dan Williams authored and James Bottomley committed Feb 29, 2012
1 parent e1d9692 commit 33f6886
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 22 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: fca4ecbdc440337b3c257b38c2f4cc8d0ca0286c
refs/heads/master: 9277699121b81891e303ada0a53fa1d04b7ffe72
31 changes: 20 additions & 11 deletions trunk/drivers/scsi/isci/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,9 @@ static void port_state_machine_change(struct isci_port *iport,
static void isci_port_hard_reset_complete(struct isci_port *isci_port,
enum sci_status completion_status)
{
dev_dbg(&isci_port->isci_host->pdev->dev,
struct isci_host *ihost = isci_port->owning_controller;

dev_dbg(&ihost->pdev->dev,
"%s: isci_port = %p, completion_status=%x\n",
__func__, isci_port, completion_status);

Expand All @@ -316,23 +318,24 @@ static void isci_port_hard_reset_complete(struct isci_port *isci_port,

/* The reset failed. The port state is now SCI_PORT_FAILED. */
if (isci_port->active_phy_mask == 0) {
int phy_idx = isci_port->last_active_phy;
struct isci_phy *iphy = &ihost->phys[phy_idx];

/* Generate the link down now to the host, since it
* was intercepted by the hard reset state machine when
* it really happened.
*/
isci_port_link_down(isci_port->isci_host,
&isci_port->isci_host->phys[
isci_port->last_active_phy],
isci_port);
isci_port_link_down(ihost, iphy, isci_port);
}
/* Advance the port state so that link state changes will be
* noticed.
*/
* noticed.
*/
port_state_machine_change(isci_port, SCI_PORT_SUB_WAITING);

}
complete_all(&isci_port->hard_reset_complete);
clear_bit(IPORT_RESET_PENDING, &isci_port->state);
wake_up(&ihost->eventq);

}

/* This method will return a true value if the specified phy can be assigned to
Expand Down Expand Up @@ -1610,6 +1613,11 @@ void sci_port_broadcast_change_received(struct isci_port *iport, struct isci_phy
isci_port_bc_change_received(ihost, iport, iphy);
}

static void wait_port_reset(struct isci_host *ihost, struct isci_port *iport)
{
wait_event(ihost->eventq, !test_bit(IPORT_RESET_PENDING, &iport->state));
}

int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
struct isci_phy *iphy)
{
Expand All @@ -1620,17 +1628,16 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n",
__func__, iport);

init_completion(&iport->hard_reset_complete);

spin_lock_irqsave(&ihost->scic_lock, flags);
set_bit(IPORT_RESET_PENDING, &iport->state);

#define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT
status = sci_port_hard_reset(iport, ISCI_PORT_RESET_TIMEOUT);

spin_unlock_irqrestore(&ihost->scic_lock, flags);

if (status == SCI_SUCCESS) {
wait_for_completion(&iport->hard_reset_complete);
wait_port_reset(ihost, iport);

dev_dbg(&ihost->pdev->dev,
"%s: iport = %p; hard reset completion\n",
Expand All @@ -1644,6 +1651,8 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
__func__, iport, iport->hard_reset_status);
}
} else {
clear_bit(IPORT_RESET_PENDING, &iport->state);
wake_up(&ihost->eventq);
ret = TMF_RESP_FUNC_FAILED;

dev_err(&ihost->pdev->dev,
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/scsi/isci/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ struct isci_port {
struct isci_host *isci_host;
struct list_head remote_dev_list;
struct list_head domain_dev_list;
struct completion hard_reset_complete;
#define IPORT_RESET_PENDING 0
unsigned long state;
enum sci_status hard_reset_status;
struct sci_base_state_machine sm;
bool ready_exit;
Expand Down
24 changes: 15 additions & 9 deletions trunk/drivers/scsi/isci/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -1330,29 +1330,35 @@ isci_task_request_complete(struct isci_host *ihost,
}

static int isci_reset_device(struct isci_host *ihost,
struct domain_device *dev,
struct isci_remote_device *idev)
{
struct sas_phy *phy = sas_get_local_phy(idev->domain_dev);
enum sci_status status;
unsigned long flags;
int rc;
unsigned long flags;
enum sci_status status;
struct sas_phy *phy = sas_get_local_phy(dev);
struct isci_port *iport = dev->port->lldd_port;

dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev);

spin_lock_irqsave(&ihost->scic_lock, flags);
status = sci_remote_device_reset(idev);
if (status != SCI_SUCCESS) {
spin_unlock_irqrestore(&ihost->scic_lock, flags);
spin_unlock_irqrestore(&ihost->scic_lock, flags);

if (status != SCI_SUCCESS) {
dev_dbg(&ihost->pdev->dev,
"%s: sci_remote_device_reset(%p) returned %d!\n",
__func__, idev, status);
rc = TMF_RESP_FUNC_FAILED;
goto out;
}
spin_unlock_irqrestore(&ihost->scic_lock, flags);

rc = sas_phy_reset(phy, true);
if (scsi_is_sas_phy_local(phy)) {
struct isci_phy *iphy = &ihost->phys[phy->number];

rc = isci_port_perform_hard_reset(ihost, iport, iphy);
} else
rc = sas_phy_reset(phy, !dev_is_sata(dev));

/* Terminate in-progress I/O now. */
isci_remote_device_nuke_requests(ihost, idev);
Expand Down Expand Up @@ -1390,7 +1396,7 @@ int isci_task_I_T_nexus_reset(struct domain_device *dev)
goto out;
}

ret = isci_reset_device(ihost, idev);
ret = isci_reset_device(ihost, dev, idev);
out:
isci_put_device(idev);
return ret;
Expand All @@ -1413,7 +1419,7 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd)
goto out;
}

ret = isci_reset_device(ihost, idev);
ret = isci_reset_device(ihost, dev, idev);
out:
isci_put_device(idev);
return ret;
Expand Down

0 comments on commit 33f6886

Please sign in to comment.