Skip to content

Commit

Permalink
[SCSI] libsas: Add an LU reset mechanism to the error handler
Browse files Browse the repository at this point in the history
After discussion with andmike and dougg, it seems that the purpose of
eh_device_reset_handler is to issue LU resets, and that
eh_bus_reset_handler would be a more appropriate place for a phy reset.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
Darrick J. Wong authored and James Bottomley committed Feb 3, 2007
1 parent 423f7cf commit a9344e6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
40 changes: 36 additions & 4 deletions drivers/scsi/libsas/sas_scsi_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,16 +421,37 @@ struct sas_phy *find_local_sas_phy(struct domain_device *dev)
return exphy->phy;
}

/* Attempt to send a target reset message to a device */
/* Attempt to send a LUN reset message to a device */
int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
{
struct domain_device *dev = cmd_to_domain_dev(cmd);
struct sas_internal *i =
to_sas_internal(dev->port->ha->core.shost->transportt);
struct scsi_lun lun;
int res;

int_to_scsilun(cmd->device->lun, &lun);

if (!i->dft->lldd_lu_reset)
return FAILED;

res = i->dft->lldd_lu_reset(dev, lun.scsi_lun);
if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
return SUCCESS;

return FAILED;
}

/* Attempt to send a phy (bus) reset */
int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd)
{
struct domain_device *dev = cmd_to_domain_dev(cmd);
struct sas_phy *phy = find_local_sas_phy(dev);
int res;

res = sas_phy_reset(phy, 1);
if (res)
SAS_DPRINTK("Device reset of %s failed 0x%x\n",
SAS_DPRINTK("Bus reset of %s failed 0x%x\n",
phy->dev.kobj.k_name,
res);
if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
Expand All @@ -443,10 +464,20 @@ int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
static int try_to_reset_cmd_device(struct Scsi_Host *shost,
struct scsi_cmnd *cmd)
{
int res;

if (!shost->hostt->eh_device_reset_handler)
return FAILED;
goto try_bus_reset;

res = shost->hostt->eh_device_reset_handler(cmd);
if (res == SUCCESS)
return res;

return shost->hostt->eh_device_reset_handler(cmd);
try_bus_reset:
if (shost->hostt->eh_bus_reset_handler)
return shost->hostt->eh_bus_reset_handler(cmd);

return FAILED;
}

static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
Expand Down Expand Up @@ -976,3 +1007,4 @@ EXPORT_SYMBOL_GPL(sas_task_abort);
EXPORT_SYMBOL_GPL(sas_phy_reset);
EXPORT_SYMBOL_GPL(sas_phy_enable);
EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler);
EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler);
1 change: 1 addition & 0 deletions include/scsi/libsas.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,5 +661,6 @@ void sas_init_dev(struct domain_device *);
void sas_task_abort(struct sas_task *);
int __sas_task_abort(struct sas_task *);
int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd);

#endif /* _SASLIB_H_ */

0 comments on commit a9344e6

Please sign in to comment.