aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2014-12-02 13:47:37 -0500
committerChristoph Hellwig <hch@lst.de>2014-12-15 07:34:28 -0500
commitf688f96d86794600686e2c11745ee3ffa3e6554e (patch)
treec6c65dcaee38a548c763602e76479b1fa74c9841 /drivers/scsi
parentf49accf1eb398102d722a89fdbb76ad17c5c5220 (diff)
ipr: add support for async scanning to speed up boot
Switch device scanning logic in the ipr driver to use the async scan API. This speeds up boot times, particularly on large systems. Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Reviewed-by: Wen Xiong<wenxiong@linux.vnet.ibm.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ipr.c88
-rw-r--r--drivers/scsi/ipr.h4
2 files changed, 44 insertions, 48 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index c91c7c5da569..beee3843e420 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -1426,16 +1426,14 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg,
1426 if (res->sdev) { 1426 if (res->sdev) {
1427 res->del_from_ml = 1; 1427 res->del_from_ml = 1;
1428 res->res_handle = IPR_INVALID_RES_HANDLE; 1428 res->res_handle = IPR_INVALID_RES_HANDLE;
1429 if (ioa_cfg->allow_ml_add_del) 1429 schedule_work(&ioa_cfg->work_q);
1430 schedule_work(&ioa_cfg->work_q);
1431 } else { 1430 } else {
1432 ipr_clear_res_target(res); 1431 ipr_clear_res_target(res);
1433 list_move_tail(&res->queue, &ioa_cfg->free_res_q); 1432 list_move_tail(&res->queue, &ioa_cfg->free_res_q);
1434 } 1433 }
1435 } else if (!res->sdev || res->del_from_ml) { 1434 } else if (!res->sdev || res->del_from_ml) {
1436 res->add_to_ml = 1; 1435 res->add_to_ml = 1;
1437 if (ioa_cfg->allow_ml_add_del) 1436 schedule_work(&ioa_cfg->work_q);
1438 schedule_work(&ioa_cfg->work_q);
1439 } 1437 }
1440 1438
1441 ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE, hostrcb); 1439 ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE, hostrcb);
@@ -3273,8 +3271,7 @@ static void ipr_worker_thread(struct work_struct *work)
3273restart: 3271restart:
3274 do { 3272 do {
3275 did_work = 0; 3273 did_work = 0;
3276 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds || 3274 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) {
3277 !ioa_cfg->allow_ml_add_del) {
3278 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3275 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3279 return; 3276 return;
3280 } 3277 }
@@ -3311,6 +3308,7 @@ restart:
3311 } 3308 }
3312 } 3309 }
3313 3310
3311 ioa_cfg->scan_done = 1;
3314 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3312 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
3315 kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE); 3313 kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE);
3316 LEAVE; 3314 LEAVE;
@@ -5207,6 +5205,28 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd)
5207 * @scsi_cmd: scsi command struct 5205 * @scsi_cmd: scsi command struct
5208 * 5206 *
5209 * Return value: 5207 * Return value:
5208 * 0 if scan in progress / 1 if scan is complete
5209 **/
5210static int ipr_scan_finished(struct Scsi_Host *shost, unsigned long elapsed_time)
5211{
5212 unsigned long lock_flags;
5213 struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
5214 int rc = 0;
5215
5216 spin_lock_irqsave(shost->host_lock, lock_flags);
5217 if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead || ioa_cfg->scan_done)
5218 rc = 1;
5219 if ((elapsed_time/HZ) > (ioa_cfg->transop_timeout * 2))
5220 rc = 1;
5221 spin_unlock_irqrestore(shost->host_lock, lock_flags);
5222 return rc;
5223}
5224
5225/**
5226 * ipr_eh_host_reset - Reset the host adapter
5227 * @scsi_cmd: scsi command struct
5228 *
5229 * Return value:
5210 * SUCCESS / FAILED 5230 * SUCCESS / FAILED
5211 **/ 5231 **/
5212static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) 5232static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd)
@@ -6275,6 +6295,7 @@ static struct scsi_host_template driver_template = {
6275 .slave_alloc = ipr_slave_alloc, 6295 .slave_alloc = ipr_slave_alloc,
6276 .slave_configure = ipr_slave_configure, 6296 .slave_configure = ipr_slave_configure,
6277 .slave_destroy = ipr_slave_destroy, 6297 .slave_destroy = ipr_slave_destroy,
6298 .scan_finished = ipr_scan_finished,
6278 .target_alloc = ipr_target_alloc, 6299 .target_alloc = ipr_target_alloc,
6279 .target_destroy = ipr_target_destroy, 6300 .target_destroy = ipr_target_destroy,
6280 .change_queue_depth = ipr_change_queue_depth, 6301 .change_queue_depth = ipr_change_queue_depth,
@@ -6816,7 +6837,7 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd)
6816 ioa_cfg->doorbell |= IPR_RUNTIME_RESET; 6837 ioa_cfg->doorbell |= IPR_RUNTIME_RESET;
6817 6838
6818 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { 6839 list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
6819 if (ioa_cfg->allow_ml_add_del && (res->add_to_ml || res->del_from_ml)) { 6840 if (res->add_to_ml || res->del_from_ml) {
6820 ipr_trace; 6841 ipr_trace;
6821 break; 6842 break;
6822 } 6843 }
@@ -6845,6 +6866,7 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd)
6845 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) 6866 if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds)
6846 scsi_block_requests(ioa_cfg->host); 6867 scsi_block_requests(ioa_cfg->host);
6847 6868
6869 schedule_work(&ioa_cfg->work_q);
6848 LEAVE; 6870 LEAVE;
6849 return IPR_RC_JOB_RETURN; 6871 return IPR_RC_JOB_RETURN;
6850} 6872}
@@ -7585,6 +7607,19 @@ static int ipr_ioafp_page0_inquiry(struct ipr_cmnd *ipr_cmd)
7585 type[4] = '\0'; 7607 type[4] = '\0';
7586 ioa_cfg->type = simple_strtoul((char *)type, NULL, 16); 7608 ioa_cfg->type = simple_strtoul((char *)type, NULL, 16);
7587 7609
7610 if (ipr_invalid_adapter(ioa_cfg)) {
7611 dev_err(&ioa_cfg->pdev->dev,
7612 "Adapter not supported in this hardware configuration.\n");
7613
7614 if (!ipr_testmode) {
7615 ioa_cfg->reset_retries += IPR_NUM_RESET_RELOAD_RETRIES;
7616 ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
7617 list_add_tail(&ipr_cmd->queue,
7618 &ioa_cfg->hrrq->hrrq_free_q);
7619 return IPR_RC_JOB_RETURN;
7620 }
7621 }
7622
7588 ipr_cmd->job_step = ipr_ioafp_page3_inquiry; 7623 ipr_cmd->job_step = ipr_ioafp_page3_inquiry;
7589 7624
7590 ipr_ioafp_inquiry(ipr_cmd, 1, 0, 7625 ipr_ioafp_inquiry(ipr_cmd, 1, 0,
@@ -8772,20 +8807,6 @@ static int ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg)
8772 _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, 8807 _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa,
8773 IPR_SHUTDOWN_NONE); 8808 IPR_SHUTDOWN_NONE);
8774 spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); 8809 spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
8775 wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
8776 spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
8777
8778 if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) {
8779 rc = -EIO;
8780 } else if (ipr_invalid_adapter(ioa_cfg)) {
8781 if (!ipr_testmode)
8782 rc = -EIO;
8783
8784 dev_err(&ioa_cfg->pdev->dev,
8785 "Adapter not supported in this hardware configuration.\n");
8786 }
8787
8788 spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
8789 8810
8790 LEAVE; 8811 LEAVE;
8791 return rc; 8812 return rc;
@@ -9239,7 +9260,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
9239 * ioa_cfg->max_devs_supported))); 9260 * ioa_cfg->max_devs_supported)));
9240 } 9261 }
9241 9262
9242 host->max_channel = IPR_MAX_BUS_TO_SCAN; 9263 host->max_channel = IPR_VSET_BUS;
9243 host->unique_id = host->host_no; 9264 host->unique_id = host->host_no;
9244 host->max_cmd_len = IPR_MAX_CDB_LEN; 9265 host->max_cmd_len = IPR_MAX_CDB_LEN;
9245 host->can_queue = ioa_cfg->max_cmds; 9266 host->can_queue = ioa_cfg->max_cmds;
@@ -9739,25 +9760,6 @@ out_scsi_host_put:
9739} 9760}
9740 9761
9741/** 9762/**
9742 * ipr_scan_vsets - Scans for VSET devices
9743 * @ioa_cfg: ioa config struct
9744 *
9745 * Description: Since the VSET resources do not follow SAM in that we can have
9746 * sparse LUNs with no LUN 0, we have to scan for these ourselves.
9747 *
9748 * Return value:
9749 * none
9750 **/
9751static void ipr_scan_vsets(struct ipr_ioa_cfg *ioa_cfg)
9752{
9753 int target, lun;
9754
9755 for (target = 0; target < IPR_MAX_NUM_TARGETS_PER_BUS; target++)
9756 for (lun = 0; lun < IPR_MAX_NUM_VSET_LUNS_PER_TARGET; lun++)
9757 scsi_add_device(ioa_cfg->host, IPR_VSET_BUS, target, lun);
9758}
9759
9760/**
9761 * ipr_initiate_ioa_bringdown - Bring down an adapter 9763 * ipr_initiate_ioa_bringdown - Bring down an adapter
9762 * @ioa_cfg: ioa config struct 9764 * @ioa_cfg: ioa config struct
9763 * @shutdown_type: shutdown type 9765 * @shutdown_type: shutdown type
@@ -9912,10 +9914,6 @@ static int ipr_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
9912 } 9914 }
9913 9915
9914 scsi_scan_host(ioa_cfg->host); 9916 scsi_scan_host(ioa_cfg->host);
9915 ipr_scan_vsets(ioa_cfg);
9916 scsi_add_device(ioa_cfg->host, IPR_IOA_BUS, IPR_IOA_TARGET, IPR_IOA_LUN);
9917 ioa_cfg->allow_ml_add_del = 1;
9918 ioa_cfg->host->max_channel = IPR_VSET_BUS;
9919 ioa_cfg->iopoll_weight = ioa_cfg->chip_cfg->iopoll_weight; 9917 ioa_cfg->iopoll_weight = ioa_cfg->chip_cfg->iopoll_weight;
9920 9918
9921 if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) { 9919 if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) {
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 9ebdebd944e7..b4f3eec51bc9 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -157,13 +157,11 @@
157 157
158#define IPR_MAX_NUM_TARGETS_PER_BUS 256 158#define IPR_MAX_NUM_TARGETS_PER_BUS 256
159#define IPR_MAX_NUM_LUNS_PER_TARGET 256 159#define IPR_MAX_NUM_LUNS_PER_TARGET 256
160#define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8
161#define IPR_VSET_BUS 0xff 160#define IPR_VSET_BUS 0xff
162#define IPR_IOA_BUS 0xff 161#define IPR_IOA_BUS 0xff
163#define IPR_IOA_TARGET 0xff 162#define IPR_IOA_TARGET 0xff
164#define IPR_IOA_LUN 0xff 163#define IPR_IOA_LUN 0xff
165#define IPR_MAX_NUM_BUSES 16 164#define IPR_MAX_NUM_BUSES 16
166#define IPR_MAX_BUS_TO_SCAN IPR_MAX_NUM_BUSES
167 165
168#define IPR_NUM_RESET_RELOAD_RETRIES 3 166#define IPR_NUM_RESET_RELOAD_RETRIES 3
169 167
@@ -1453,7 +1451,7 @@ struct ipr_ioa_cfg {
1453 u8 in_ioa_bringdown:1; 1451 u8 in_ioa_bringdown:1;
1454 u8 ioa_unit_checked:1; 1452 u8 ioa_unit_checked:1;
1455 u8 dump_taken:1; 1453 u8 dump_taken:1;
1456 u8 allow_ml_add_del:1; 1454 u8 scan_done:1;
1457 u8 needs_hard_reset:1; 1455 u8 needs_hard_reset:1;
1458 u8 dual_raid:1; 1456 u8 dual_raid:1;
1459 u8 needs_warm_reset:1; 1457 u8 needs_warm_reset:1;