diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-06-13 20:39:44 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:51 -0400 |
commit | 209fae14fabfd48525e5630bebbbd4ca15090c60 (patch) | |
tree | b251b9b394b3493cc15242ea31002abcb4e9bb59 /drivers/scsi/isci/request.h | |
parent | 360b03ed178a4fe3971b0a098d8feeb53333481b (diff) |
isci: atomic device lookup and reference counting
We have unsafe references to remote devices that are notified to
disappear at lldd_dev_gone. In order to clean this up we need a single
canonical source for device lookups and stable references once a lookup
succeeds. Towards that end guarantee that domain_device.lldd_dev is
NULL as soon as we start the process of stopping a device. Any code
path that wants to safely lookup a remote device must do so through
task->dev->lldd_dev (isci_lookup_device()).
For in-flight references outside of scic_lock we need reference counting
to ensure that the device is not recycled before we are done with it.
Simplify device back references to just scic_sds_request.target_device
which is now the only permissible internal reference that is maintained
relative to the reference count.
There were two occasions where we wanted new i/o's to be treated as
SAS_TASK_UNDELIVERED but where the domain_dev->lldd_dev link is still
intact. Introduce a 'gone' flag to prevent i/o while waiting for libsas
to take action on the port down event.
One 'core' leftover is that we currently call
scic_remote_device_destruct() from isci_remote_device_deconstruct()
which is called when the 'core' says the device is stopped. It would be
more natural for the final put to trigger
isci_remote_device_deconstruct() but this implementation is deferred as
it requires other changes.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/request.h')
-rw-r--r-- | drivers/scsi/isci/request.h | 7 |
1 files changed, 2 insertions, 5 deletions
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h index 8de2542f081f..9bb7c36257f3 100644 --- a/drivers/scsi/isci/request.h +++ b/drivers/scsi/isci/request.h | |||
@@ -285,7 +285,6 @@ struct isci_request { | |||
285 | struct isci_tmf *tmf_task_ptr; /* When ttype==tmf_task */ | 285 | struct isci_tmf *tmf_task_ptr; /* When ttype==tmf_task */ |
286 | } ttype_ptr; | 286 | } ttype_ptr; |
287 | struct isci_host *isci_host; | 287 | struct isci_host *isci_host; |
288 | struct isci_remote_device *isci_device; | ||
289 | /* For use in the requests_to_{complete|abort} lists: */ | 288 | /* For use in the requests_to_{complete|abort} lists: */ |
290 | struct list_head completed_node; | 289 | struct list_head completed_node; |
291 | /* For use in the reqs_in_process list: */ | 290 | /* For use in the reqs_in_process list: */ |
@@ -681,12 +680,10 @@ static inline void isci_request_free(struct isci_host *isci_host, | |||
681 | 680 | ||
682 | struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost, | 681 | struct isci_request *isci_request_alloc_tmf(struct isci_host *ihost, |
683 | struct isci_tmf *isci_tmf, | 682 | struct isci_tmf *isci_tmf, |
684 | struct isci_remote_device *idev, | ||
685 | gfp_t gfp_flags); | 683 | gfp_t gfp_flags); |
686 | 684 | ||
687 | int isci_request_execute(struct isci_host *isci_host, | 685 | int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev, |
688 | struct sas_task *task, | 686 | struct sas_task *task, gfp_t gfp_flags); |
689 | gfp_t gfp_flags); | ||
690 | 687 | ||
691 | /** | 688 | /** |
692 | * isci_request_unmap_sgl() - This function unmaps the DMA address of a given | 689 | * isci_request_unmap_sgl() - This function unmaps the DMA address of a given |