aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/host.c
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.c
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.c')
-rw-r--r--drivers/scsi/isci/host.c21
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
379int isci_host_init(struct isci_host *isci_host) 379int 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}