aboutsummaryrefslogtreecommitdiffstats
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
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>
-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