diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-03-03 20:59:32 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 06:55:29 -0400 |
commit | d9c37390c4f02153188a64a7a89fa6798dc3ffc2 (patch) | |
tree | 508f28b5b88348b2d989f479442cbd6813bd2b42 /drivers/scsi/isci/host.c | |
parent | 6ad31fec306d532031b2f778f8656385df1b9d8f (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.c')
-rw-r--r-- | drivers/scsi/isci/host.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index 8d255666a657..ae5d46022073 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
@@ -378,8 +378,7 @@ static void __iomem *smu_base(struct isci_host *isci_host) | |||
378 | 378 | ||
379 | int isci_host_init(struct isci_host *isci_host) | 379 | int isci_host_init(struct isci_host *isci_host) |
380 | { | 380 | { |
381 | int err = 0; | 381 | int err = 0, i; |
382 | int index = 0; | ||
383 | enum sci_status status; | 382 | enum sci_status status; |
384 | struct scic_sds_controller *controller; | 383 | struct scic_sds_controller *controller; |
385 | union scic_oem_parameters scic_oem_params; | 384 | union scic_oem_parameters scic_oem_params; |
@@ -509,13 +508,19 @@ int isci_host_init(struct isci_host *isci_host) | |||
509 | if (!isci_host->dma_pool) | 508 | if (!isci_host->dma_pool) |
510 | return -ENOMEM; | 509 | return -ENOMEM; |
511 | 510 | ||
512 | for (index = 0; index < SCI_MAX_PORTS; index++) | 511 | for (i = 0; i < SCI_MAX_PORTS; i++) |
513 | isci_port_init(&isci_host->isci_ports[index], | 512 | isci_port_init(&isci_host->isci_ports[i], isci_host, i); |
514 | isci_host, | ||
515 | index); | ||
516 | 513 | ||
517 | for (index = 0; index < SCI_MAX_PHYS; index++) | 514 | for (i = 0; i < SCI_MAX_PHYS; i++) |
518 | isci_phy_init(&isci_host->phys[index], isci_host, index); | 515 | isci_phy_init(&isci_host->phys[i], isci_host, i); |
516 | |||
517 | for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) { | ||
518 | struct isci_remote_device *idev = idev_by_id(isci_host, i); | ||
519 | |||
520 | INIT_LIST_HEAD(&idev->reqs_in_process); | ||
521 | INIT_LIST_HEAD(&idev->node); | ||
522 | spin_lock_init(&idev->state_lock); | ||
523 | } | ||
519 | 524 | ||
520 | return 0; | 525 | return 0; |
521 | } | 526 | } |