diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/ipr.c | 58 |
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 | **/ | ||
3296 | static 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 | ||
3348 | static int ipr_eh_dev_reset(struct scsi_cmnd * cmd) | 3372 | static int ipr_eh_dev_reset(struct scsi_cmnd * cmd) |