diff options
author | Jeff Skirvin <jeffrey.d.skirvin@intel.com> | 2012-03-09 01:42:08 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2012-05-17 17:33:43 -0400 |
commit | 1f05388933cb6e57ed9e51768c194ff145002f3b (patch) | |
tree | 4e4bae448746ffdb0196b8e16a4f25893eb10855 /drivers/scsi/isci | |
parent | c5457a82a404db3c447df22e6425c5c140c4bee1 (diff) |
isci: Don't wait for an RNC suspend if it's being destroyed.
Make sure that the wait for suspend can handle the RNC destruction case.
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci')
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 20 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_node_context.c | 5 | ||||
-rw-r--r-- | drivers/scsi/isci/remote_node_context.h | 7 |
3 files changed, 28 insertions, 4 deletions
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index be9f0e0be4ff..68ab4fb9032e 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c | |||
@@ -142,7 +142,12 @@ static bool isci_compare_suspendcount( | |||
142 | u32 localcount) | 142 | u32 localcount) |
143 | { | 143 | { |
144 | smp_rmb(); | 144 | smp_rmb(); |
145 | return localcount != idev->rnc.suspend_count; | 145 | |
146 | /* Check for a change in the suspend count, or the RNC | ||
147 | * being destroyed. | ||
148 | */ | ||
149 | return (localcount != idev->rnc.suspend_count) | ||
150 | || sci_remote_node_context_is_being_destroyed(&idev->rnc); | ||
146 | } | 151 | } |
147 | 152 | ||
148 | static bool isci_check_reqterm( | 153 | static bool isci_check_reqterm( |
@@ -1380,7 +1385,8 @@ enum sci_status isci_remote_device_resume_from_abort( | |||
1380 | struct isci_remote_device *idev) | 1385 | struct isci_remote_device *idev) |
1381 | { | 1386 | { |
1382 | unsigned long flags; | 1387 | unsigned long flags; |
1383 | enum sci_status status; | 1388 | enum sci_status status = SCI_SUCCESS; |
1389 | int destroyed; | ||
1384 | 1390 | ||
1385 | spin_lock_irqsave(&ihost->scic_lock, flags); | 1391 | spin_lock_irqsave(&ihost->scic_lock, flags); |
1386 | /* Preserve any current resume callbacks, for instance from other | 1392 | /* Preserve any current resume callbacks, for instance from other |
@@ -1390,11 +1396,17 @@ enum sci_status isci_remote_device_resume_from_abort( | |||
1390 | idev->abort_resume_cbparam = idev->rnc.user_cookie; | 1396 | idev->abort_resume_cbparam = idev->rnc.user_cookie; |
1391 | set_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); | 1397 | set_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); |
1392 | clear_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags); | 1398 | clear_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags); |
1393 | status = sci_remote_device_resume( | 1399 | destroyed = sci_remote_node_context_is_being_destroyed(&idev->rnc); |
1400 | if (!destroyed) | ||
1401 | status = sci_remote_device_resume( | ||
1394 | idev, isci_remote_device_resume_from_abort_complete, | 1402 | idev, isci_remote_device_resume_from_abort_complete, |
1395 | idev); | 1403 | idev); |
1396 | spin_unlock_irqrestore(&ihost->scic_lock, flags); | 1404 | spin_unlock_irqrestore(&ihost->scic_lock, flags); |
1397 | isci_remote_device_wait_for_resume_from_abort(ihost, idev); | 1405 | if (!destroyed) |
1406 | isci_remote_device_wait_for_resume_from_abort(ihost, idev); | ||
1407 | else | ||
1408 | clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags); | ||
1409 | |||
1398 | return status; | 1410 | return status; |
1399 | } | 1411 | } |
1400 | 1412 | ||
diff --git a/drivers/scsi/isci/remote_node_context.c b/drivers/scsi/isci/remote_node_context.c index a0a62e3a500d..920c2bb39333 100644 --- a/drivers/scsi/isci/remote_node_context.c +++ b/drivers/scsi/isci/remote_node_context.c | |||
@@ -270,6 +270,8 @@ static void sci_remote_node_context_invalidate_context_buffer(struct sci_remote_ | |||
270 | static void sci_remote_node_context_initial_state_enter(struct sci_base_state_machine *sm) | 270 | static void sci_remote_node_context_initial_state_enter(struct sci_base_state_machine *sm) |
271 | { | 271 | { |
272 | struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); | 272 | struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); |
273 | struct isci_remote_device *idev = rnc_to_dev(rnc); | ||
274 | struct isci_host *ihost = idev->owning_port->owning_controller; | ||
273 | 275 | ||
274 | /* Check to see if we have gotten back to the initial state because | 276 | /* Check to see if we have gotten back to the initial state because |
275 | * someone requested to destroy the remote node context object. | 277 | * someone requested to destroy the remote node context object. |
@@ -277,6 +279,9 @@ static void sci_remote_node_context_initial_state_enter(struct sci_base_state_ma | |||
277 | if (sm->previous_state_id == SCI_RNC_INVALIDATING) { | 279 | if (sm->previous_state_id == SCI_RNC_INVALIDATING) { |
278 | rnc->destination_state = RNC_DEST_UNSPECIFIED; | 280 | rnc->destination_state = RNC_DEST_UNSPECIFIED; |
279 | sci_remote_node_context_notify_user(rnc); | 281 | sci_remote_node_context_notify_user(rnc); |
282 | |||
283 | smp_wmb(); | ||
284 | wake_up(&ihost->eventq); | ||
280 | } | 285 | } |
281 | } | 286 | } |
282 | 287 | ||
diff --git a/drivers/scsi/isci/remote_node_context.h b/drivers/scsi/isci/remote_node_context.h index c61c02e095ad..0d4a24d647b4 100644 --- a/drivers/scsi/isci/remote_node_context.h +++ b/drivers/scsi/isci/remote_node_context.h | |||
@@ -226,4 +226,11 @@ enum sci_status sci_remote_node_context_start_io(struct sci_remote_node_context | |||
226 | int sci_remote_node_context_is_safe_to_abort( | 226 | int sci_remote_node_context_is_safe_to_abort( |
227 | struct sci_remote_node_context *sci_rnc); | 227 | struct sci_remote_node_context *sci_rnc); |
228 | 228 | ||
229 | static inline bool sci_remote_node_context_is_being_destroyed( | ||
230 | struct sci_remote_node_context *sci_rnc) | ||
231 | { | ||
232 | return ((sci_rnc->sm.current_state_id == SCI_RNC_INVALIDATING) | ||
233 | && (sci_rnc->destination_state == RNC_DEST_FINAL)) | ||
234 | || (sci_rnc->sm.current_state_id == SCI_RNC_INITIAL); | ||
235 | } | ||
229 | #endif /* _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ */ | 236 | #endif /* _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ */ |