aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/host.h
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-03-03 20:59:32 -0500
committerDan Williams <dan.j.williams@intel.com>2011-07-03 06:55:29 -0400
commitd9c37390c4f02153188a64a7a89fa6798dc3ffc2 (patch)
tree508f28b5b88348b2d989f479442cbd6813bd2b42 /drivers/scsi/isci/host.h
parent6ad31fec306d532031b2f778f8656385df1b9d8f (diff)
isci: preallocate remote devices
Until we synchronize against device removal this limits the damage of use after free bugs to the driver's own objects. Unless we implement reference counting we need to ensure at least a subset of a remote device is valid at all times. We follow the lead of other libsas drivers that also preallocate devices. This also enforces maximum remote device accounting at the lldd layer, but the core may still run out of RNC's before we hit this limit. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/host.h')
-rw-r--r--drivers/scsi/isci/host.h17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 6a6304c06976..3c69f1ffb1c3 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -61,6 +61,7 @@
61/*#include "task.h"*/ 61/*#include "task.h"*/
62#include "timers.h" 62#include "timers.h"
63#include "remote_device.h" 63#include "remote_device.h"
64#include "scic_remote_device.h"
64 65
65#define DRV_NAME "isci" 66#define DRV_NAME "isci"
66#define SCI_PCI_BAR_COUNT 2 67#define SCI_PCI_BAR_COUNT 2
@@ -117,8 +118,18 @@ struct isci_host {
117 struct list_head requests_to_complete; 118 struct list_head requests_to_complete;
118 struct list_head requests_to_abort; 119 struct list_head requests_to_abort;
119 spinlock_t scic_lock; 120 spinlock_t scic_lock;
121
122 /* careful only access this via idev_by_id */
123 struct isci_remote_device devices[0];
120}; 124};
121 125
126static inline struct isci_remote_device *idev_by_id(struct isci_host *ihost, int i)
127{
128 void *p = ihost->devices;
129
130 return p + i * (sizeof(struct isci_remote_device) +
131 scic_remote_device_get_object_size());
132}
122 133
123/** 134/**
124 * struct isci_pci_info - This class represents the pci function containing the 135 * struct isci_pci_info - This class represents the pci function containing the
@@ -219,11 +230,7 @@ static inline void wait_for_device_start(struct isci_host *ihost, struct isci_re
219 230
220static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_remote_device *idev) 231static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_remote_device *idev)
221{ 232{
222 /* todo switch to: 233 wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags));
223 * wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags));
224 * once devices are statically allocated
225 */
226 wait_for_completion(idev->cmp);
227} 234}
228 235
229/** 236/**