aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/ipr.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 695799699131..8b80e59c8c52 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3281,6 +3281,44 @@ static int ipr_eh_host_reset(struct scsi_cmnd * cmd)
3281} 3281}
3282 3282
3283/** 3283/**
3284 * ipr_device_reset - Reset the device
3285 * @ioa_cfg: ioa config struct
3286 * @res: resource entry struct
3287 *
3288 * This function issues a device reset to the affected device.
3289 * If the device is a SCSI device, a LUN reset will be sent
3290 * to the device first. If that does not work, a target reset
3291 * will be sent.
3292 *
3293 * Return value:
3294 * 0 on success / non-zero on failure
3295 **/
3296static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
3297 struct ipr_resource_entry *res)
3298{
3299 struct ipr_cmnd *ipr_cmd;
3300 struct ipr_ioarcb *ioarcb;
3301 struct ipr_cmd_pkt *cmd_pkt;
3302 u32 ioasc;
3303
3304 ENTER;
3305 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
3306 ioarcb = &ipr_cmd->ioarcb;
3307 cmd_pkt = &ioarcb->cmd_pkt;
3308
3309 ioarcb->res_handle = res->cfgte.res_handle;
3310 cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
3311 cmd_pkt->cdb[0] = IPR_RESET_DEVICE;
3312
3313 ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
3314 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
3315 list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
3316
3317 LEAVE;
3318 return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0);
3319}
3320
3321/**
3284 * ipr_eh_dev_reset - Reset the device 3322 * ipr_eh_dev_reset - Reset the device
3285 * @scsi_cmd: scsi command struct 3323 * @scsi_cmd: scsi command struct
3286 * 3324 *
@@ -3296,8 +3334,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
3296 struct ipr_cmnd *ipr_cmd; 3334 struct ipr_cmnd *ipr_cmd;
3297 struct ipr_ioa_cfg *ioa_cfg; 3335 struct ipr_ioa_cfg *ioa_cfg;
3298 struct ipr_resource_entry *res; 3336 struct ipr_resource_entry *res;
3299 struct ipr_cmd_pkt *cmd_pkt; 3337 int rc;
3300 u32 ioasc;
3301 3338
3302 ENTER; 3339 ENTER;
3303 ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; 3340 ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
@@ -3324,25 +3361,12 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
3324 } 3361 }
3325 3362
3326 res->resetting_device = 1; 3363 res->resetting_device = 1;
3327
3328 ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
3329
3330 ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle;
3331 cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
3332 cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
3333 cmd_pkt->cdb[0] = IPR_RESET_DEVICE;
3334
3335 scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n"); 3364 scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n");
3336 ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); 3365 rc = ipr_device_reset(ioa_cfg, res);
3337
3338 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
3339
3340 res->resetting_device = 0; 3366 res->resetting_device = 0;
3341 3367
3342 list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
3343
3344 LEAVE; 3368 LEAVE;
3345 return (IPR_IOASC_SENSE_KEY(ioasc) ? FAILED : SUCCESS); 3369 return (rc ? FAILED : SUCCESS);
3346} 3370}
3347 3371
3348static int ipr_eh_dev_reset(struct scsi_cmnd * cmd) 3372static int ipr_eh_dev_reset(struct scsi_cmnd * cmd)