diff options
author | Kevin Barnett <kevin.barnett@microsemi.com> | 2016-08-31 15:54:35 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-09-02 06:21:37 -0400 |
commit | 14bb215d09de98a8e95fa2bb1b8f35b79672c5df (patch) | |
tree | 9f5472d353919d2b743db337b068b058695ef74c | |
parent | e58081a714275d1490e470bdaf1b5dc23043cf2a (diff) |
scsi: smartpqi: enhance reset logic
Eliminated timeout from LUN reset logic.
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/smartpqi/smartpqi.h | 2 | ||||
-rw-r--r-- | drivers/scsi/smartpqi/smartpqi_init.c | 101 |
2 files changed, 35 insertions, 68 deletions
diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index dbcdb03feabf..053be6be2077 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h | |||
@@ -370,7 +370,6 @@ struct pqi_task_management_request { | |||
370 | }; | 370 | }; |
371 | 371 | ||
372 | #define SOP_TASK_MANAGEMENT_LUN_RESET 0x8 | 372 | #define SOP_TASK_MANAGEMENT_LUN_RESET 0x8 |
373 | #define PQI_ABORT_TIMEOUT_MSECS (20 * 1000) | ||
374 | 373 | ||
375 | struct pqi_task_management_response { | 374 | struct pqi_task_management_response { |
376 | struct pqi_iu_header header; | 375 | struct pqi_iu_header header; |
@@ -762,7 +761,6 @@ struct pqi_scsi_dev { | |||
762 | 761 | ||
763 | struct pqi_sas_port *sas_port; | 762 | struct pqi_sas_port *sas_port; |
764 | struct scsi_device *sdev; | 763 | struct scsi_device *sdev; |
765 | bool reset_in_progress; | ||
766 | 764 | ||
767 | struct list_head scsi_device_list_entry; | 765 | struct list_head scsi_device_list_entry; |
768 | struct list_head new_device_list_entry; | 766 | struct list_head new_device_list_entry; |
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 198a7c2ab960..dbc8b40cd8ca 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c | |||
@@ -4537,13 +4537,6 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, | |||
4537 | bool raid_bypassed; | 4537 | bool raid_bypassed; |
4538 | 4538 | ||
4539 | device = scmd->device->hostdata; | 4539 | device = scmd->device->hostdata; |
4540 | |||
4541 | if (device->reset_in_progress) { | ||
4542 | set_host_byte(scmd, DID_RESET); | ||
4543 | pqi_scsi_done(scmd); | ||
4544 | return 0; | ||
4545 | } | ||
4546 | |||
4547 | ctrl_info = shost_to_hba(shost); | 4540 | ctrl_info = shost_to_hba(shost); |
4548 | 4541 | ||
4549 | if (pqi_ctrl_offline(ctrl_info)) { | 4542 | if (pqi_ctrl_offline(ctrl_info)) { |
@@ -4585,61 +4578,47 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, | |||
4585 | return rc; | 4578 | return rc; |
4586 | } | 4579 | } |
4587 | 4580 | ||
4588 | static inline void pqi_complete_queued_requests_queue_group( | 4581 | static void pqi_lun_reset_complete(struct pqi_io_request *io_request, |
4589 | struct pqi_queue_group *queue_group, | 4582 | void *context) |
4590 | struct pqi_scsi_dev *device_in_reset) | ||
4591 | { | 4583 | { |
4592 | unsigned int path; | 4584 | struct completion *waiting = context; |
4593 | unsigned long flags; | ||
4594 | struct pqi_io_request *io_request; | ||
4595 | struct pqi_io_request *next; | ||
4596 | struct scsi_cmnd *scmd; | ||
4597 | struct pqi_scsi_dev *device; | ||
4598 | 4585 | ||
4599 | for (path = 0; path < 2; path++) { | 4586 | complete(waiting); |
4600 | spin_lock_irqsave(&queue_group->submit_lock[path], flags); | 4587 | } |
4601 | 4588 | ||
4602 | list_for_each_entry_safe(io_request, next, | 4589 | #define PQI_LUN_RESET_TIMEOUT_SECS 10 |
4603 | &queue_group->request_list[path], | 4590 | |
4604 | request_list_entry) { | 4591 | static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info, |
4605 | scmd = io_request->scmd; | 4592 | struct pqi_scsi_dev *device, struct completion *wait) |
4606 | if (!scmd) | 4593 | { |
4607 | continue; | 4594 | int rc; |
4608 | device = scmd->device->hostdata; | 4595 | unsigned int wait_secs = 0; |
4609 | if (device == device_in_reset) { | 4596 | |
4610 | set_host_byte(scmd, DID_RESET); | 4597 | while (1) { |
4611 | pqi_scsi_done(scmd); | 4598 | if (wait_for_completion_io_timeout(wait, |
4612 | list_del(&io_request-> | 4599 | PQI_LUN_RESET_TIMEOUT_SECS * HZ)) { |
4613 | request_list_entry); | 4600 | rc = 0; |
4614 | } | 4601 | break; |
4615 | } | 4602 | } |
4616 | 4603 | ||
4617 | spin_unlock_irqrestore(&queue_group->submit_lock[path], flags); | 4604 | pqi_check_ctrl_health(ctrl_info); |
4618 | } | 4605 | if (pqi_ctrl_offline(ctrl_info)) { |
4619 | } | 4606 | rc = -ETIMEDOUT; |
4607 | break; | ||
4608 | } | ||
4620 | 4609 | ||
4621 | static void pqi_complete_queued_requests(struct pqi_ctrl_info *ctrl_info, | 4610 | wait_secs += PQI_LUN_RESET_TIMEOUT_SECS; |
4622 | struct pqi_scsi_dev *device_in_reset) | ||
4623 | { | ||
4624 | unsigned int i; | ||
4625 | struct pqi_queue_group *queue_group; | ||
4626 | 4611 | ||
4627 | for (i = 0; i < ctrl_info->num_queue_groups; i++) { | 4612 | dev_err(&ctrl_info->pci_dev->dev, |
4628 | queue_group = &ctrl_info->queue_groups[i]; | 4613 | "resetting scsi %d:%d:%d:%d - waiting %u seconds\n", |
4629 | pqi_complete_queued_requests_queue_group(queue_group, | 4614 | ctrl_info->scsi_host->host_no, device->bus, |
4630 | device_in_reset); | 4615 | device->target, device->lun, wait_secs); |
4631 | } | 4616 | } |
4632 | } | ||
4633 | 4617 | ||
4634 | static void pqi_reset_lun_complete(struct pqi_io_request *io_request, | 4618 | return rc; |
4635 | void *context) | ||
4636 | { | ||
4637 | struct completion *waiting = context; | ||
4638 | |||
4639 | complete(waiting); | ||
4640 | } | 4619 | } |
4641 | 4620 | ||
4642 | static int pqi_reset_lun(struct pqi_ctrl_info *ctrl_info, | 4621 | static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, |
4643 | struct pqi_scsi_dev *device) | 4622 | struct pqi_scsi_dev *device) |
4644 | { | 4623 | { |
4645 | int rc; | 4624 | int rc; |
@@ -4650,7 +4629,7 @@ static int pqi_reset_lun(struct pqi_ctrl_info *ctrl_info, | |||
4650 | down(&ctrl_info->lun_reset_sem); | 4629 | down(&ctrl_info->lun_reset_sem); |
4651 | 4630 | ||
4652 | io_request = pqi_alloc_io_request(ctrl_info); | 4631 | io_request = pqi_alloc_io_request(ctrl_info); |
4653 | io_request->io_complete_callback = pqi_reset_lun_complete; | 4632 | io_request->io_complete_callback = pqi_lun_reset_complete; |
4654 | io_request->context = &wait; | 4633 | io_request->context = &wait; |
4655 | 4634 | ||
4656 | request = io_request->iu; | 4635 | request = io_request->iu; |
@@ -4668,12 +4647,9 @@ static int pqi_reset_lun(struct pqi_ctrl_info *ctrl_info, | |||
4668 | &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, | 4647 | &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, |
4669 | io_request); | 4648 | io_request); |
4670 | 4649 | ||
4671 | if (!wait_for_completion_io_timeout(&wait, | 4650 | rc = pqi_wait_for_lun_reset_completion(ctrl_info, device, &wait); |
4672 | msecs_to_jiffies(PQI_ABORT_TIMEOUT_MSECS))) { | 4651 | if (rc == 0) |
4673 | rc = -ETIMEDOUT; | ||
4674 | } else { | ||
4675 | rc = io_request->status; | 4652 | rc = io_request->status; |
4676 | } | ||
4677 | 4653 | ||
4678 | pqi_free_io_request(io_request); | 4654 | pqi_free_io_request(io_request); |
4679 | up(&ctrl_info->lun_reset_sem); | 4655 | up(&ctrl_info->lun_reset_sem); |
@@ -4692,15 +4668,9 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, | |||
4692 | if (pqi_ctrl_offline(ctrl_info)) | 4668 | if (pqi_ctrl_offline(ctrl_info)) |
4693 | return FAILED; | 4669 | return FAILED; |
4694 | 4670 | ||
4695 | device->reset_in_progress = true; | 4671 | rc = pqi_lun_reset(ctrl_info, device); |
4696 | pqi_complete_queued_requests(ctrl_info, device); | ||
4697 | rc = pqi_reset_lun(ctrl_info, device); | ||
4698 | device->reset_in_progress = false; | ||
4699 | |||
4700 | if (rc) | ||
4701 | return FAILED; | ||
4702 | 4672 | ||
4703 | return SUCCESS; | 4673 | return rc == 0 ? SUCCESS : FAILED; |
4704 | } | 4674 | } |
4705 | 4675 | ||
4706 | static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) | 4676 | static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) |
@@ -4710,7 +4680,6 @@ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) | |||
4710 | struct pqi_scsi_dev *device; | 4680 | struct pqi_scsi_dev *device; |
4711 | 4681 | ||
4712 | ctrl_info = shost_to_hba(scmd->device->host); | 4682 | ctrl_info = shost_to_hba(scmd->device->host); |
4713 | |||
4714 | device = scmd->device->hostdata; | 4683 | device = scmd->device->hostdata; |
4715 | 4684 | ||
4716 | dev_err(&ctrl_info->pci_dev->dev, | 4685 | dev_err(&ctrl_info->pci_dev->dev, |