|
| 1 | +From c84869dbb3e68651cf15b20df5d2703603066615 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Brian King < [email protected]> |
| 3 | +Date: Fri, 21 Mar 2014 15:11:41 +1100 |
| 4 | +Subject: [PATCH 4/5] ipr: Add support for async scanning to speed up boot |
| 5 | + |
| 6 | +Signed-off-by: Jeremy Kerr < [email protected]> |
| 7 | +--- |
| 8 | + drivers/scsi/ipr.c | 88 ++++++++++++++++++++++++++---------------------------- |
| 9 | + drivers/scsi/ipr.h | 4 +-- |
| 10 | + 2 files changed, 44 insertions(+), 48 deletions(-) |
| 11 | + |
| 12 | +diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c |
| 13 | +index 79e5099..4ad4a7e 100644 |
| 14 | +--- a/drivers/scsi/ipr.c |
| 15 | ++++ b/drivers/scsi/ipr.c |
| 16 | +@@ -1426,16 +1426,14 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, |
| 17 | + if (res->sdev) { |
| 18 | + res->del_from_ml = 1; |
| 19 | + res->res_handle = IPR_INVALID_RES_HANDLE; |
| 20 | +- if (ioa_cfg->allow_ml_add_del) |
| 21 | +- schedule_work(&ioa_cfg->work_q); |
| 22 | ++ schedule_work(&ioa_cfg->work_q); |
| 23 | + } else { |
| 24 | + ipr_clear_res_target(res); |
| 25 | + list_move_tail(&res->queue, &ioa_cfg->free_res_q); |
| 26 | + } |
| 27 | + } else if (!res->sdev || res->del_from_ml) { |
| 28 | + res->add_to_ml = 1; |
| 29 | +- if (ioa_cfg->allow_ml_add_del) |
| 30 | +- schedule_work(&ioa_cfg->work_q); |
| 31 | ++ schedule_work(&ioa_cfg->work_q); |
| 32 | + } |
| 33 | + |
| 34 | + ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE, hostrcb); |
| 35 | +@@ -3263,8 +3261,7 @@ static void ipr_worker_thread(struct work_struct *work) |
| 36 | + restart: |
| 37 | + do { |
| 38 | + did_work = 0; |
| 39 | +- if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds || |
| 40 | +- !ioa_cfg->allow_ml_add_del) { |
| 41 | ++ if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) { |
| 42 | + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
| 43 | + return; |
| 44 | + } |
| 45 | +@@ -3301,6 +3298,7 @@ restart: |
| 46 | + } |
| 47 | + } |
| 48 | + |
| 49 | ++ ioa_cfg->scan_done = 1; |
| 50 | + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
| 51 | + kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE); |
| 52 | + LEAVE; |
| 53 | +@@ -5240,6 +5238,28 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd) |
| 54 | + * @scsi_cmd: scsi command struct |
| 55 | + * |
| 56 | + * Return value: |
| 57 | ++ * 0 if scan in progress / 1 if scan is complete |
| 58 | ++ **/ |
| 59 | ++static int ipr_scan_finished(struct Scsi_Host *shost, unsigned long elapsed_time) |
| 60 | ++{ |
| 61 | ++ unsigned long lock_flags; |
| 62 | ++ struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; |
| 63 | ++ int rc = 0; |
| 64 | ++ |
| 65 | ++ spin_lock_irqsave(shost->host_lock, lock_flags); |
| 66 | ++ if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead || ioa_cfg->scan_done) |
| 67 | ++ rc = 1; |
| 68 | ++ if ((elapsed_time/HZ) > (ioa_cfg->transop_timeout * 2)) |
| 69 | ++ rc = 1; |
| 70 | ++ spin_unlock_irqrestore(shost->host_lock, lock_flags); |
| 71 | ++ return rc; |
| 72 | ++} |
| 73 | ++ |
| 74 | ++/** |
| 75 | ++ * ipr_eh_host_reset - Reset the host adapter |
| 76 | ++ * @scsi_cmd: scsi command struct |
| 77 | ++ * |
| 78 | ++ * Return value: |
| 79 | + * SUCCESS / FAILED |
| 80 | + **/ |
| 81 | + static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) |
| 82 | +@@ -6335,6 +6355,7 @@ static struct scsi_host_template driver_template = { |
| 83 | + .slave_alloc = ipr_slave_alloc, |
| 84 | + .slave_configure = ipr_slave_configure, |
| 85 | + .slave_destroy = ipr_slave_destroy, |
| 86 | ++ .scan_finished = ipr_scan_finished, |
| 87 | + .target_alloc = ipr_target_alloc, |
| 88 | + .target_destroy = ipr_target_destroy, |
| 89 | + .change_queue_depth = ipr_change_queue_depth, |
| 90 | +@@ -6875,7 +6896,7 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd) |
| 91 | + ioa_cfg->doorbell |= IPR_RUNTIME_RESET; |
| 92 | + |
| 93 | + list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { |
| 94 | +- if (ioa_cfg->allow_ml_add_del && (res->add_to_ml || res->del_from_ml)) { |
| 95 | ++ if (res->add_to_ml || res->del_from_ml) { |
| 96 | + ipr_trace; |
| 97 | + break; |
| 98 | + } |
| 99 | +@@ -6904,6 +6925,7 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd) |
| 100 | + if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) |
| 101 | + scsi_block_requests(ioa_cfg->host); |
| 102 | + |
| 103 | ++ schedule_work(&ioa_cfg->work_q); |
| 104 | + LEAVE; |
| 105 | + return IPR_RC_JOB_RETURN; |
| 106 | + } |
| 107 | +@@ -7644,6 +7666,19 @@ static int ipr_ioafp_page0_inquiry(struct ipr_cmnd *ipr_cmd) |
| 108 | + type[4] = '\0'; |
| 109 | + ioa_cfg->type = simple_strtoul((char *)type, NULL, 16); |
| 110 | + |
| 111 | ++ if (ipr_invalid_adapter(ioa_cfg)) { |
| 112 | ++ dev_err(&ioa_cfg->pdev->dev, |
| 113 | ++ "Adapter not supported in this hardware configuration.\n"); |
| 114 | ++ |
| 115 | ++ if (!ipr_testmode) { |
| 116 | ++ ioa_cfg->reset_retries += IPR_NUM_RESET_RELOAD_RETRIES; |
| 117 | ++ ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); |
| 118 | ++ list_add_tail(&ipr_cmd->queue, |
| 119 | ++ &ioa_cfg->hrrq->hrrq_free_q); |
| 120 | ++ return IPR_RC_JOB_RETURN; |
| 121 | ++ } |
| 122 | ++ } |
| 123 | ++ |
| 124 | + ipr_cmd->job_step = ipr_ioafp_page3_inquiry; |
| 125 | + |
| 126 | + ipr_ioafp_inquiry(ipr_cmd, 1, 0, |
| 127 | +@@ -8831,20 +8866,6 @@ static int ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg) |
| 128 | + _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, |
| 129 | + IPR_SHUTDOWN_NONE); |
| 130 | + spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); |
| 131 | +- wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); |
| 132 | +- spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); |
| 133 | +- |
| 134 | +- if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) { |
| 135 | +- rc = -EIO; |
| 136 | +- } else if (ipr_invalid_adapter(ioa_cfg)) { |
| 137 | +- if (!ipr_testmode) |
| 138 | +- rc = -EIO; |
| 139 | +- |
| 140 | +- dev_err(&ioa_cfg->pdev->dev, |
| 141 | +- "Adapter not supported in this hardware configuration.\n"); |
| 142 | +- } |
| 143 | +- |
| 144 | +- spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); |
| 145 | + |
| 146 | + LEAVE; |
| 147 | + return rc; |
| 148 | +@@ -9296,7 +9317,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, |
| 149 | + * ioa_cfg->max_devs_supported))); |
| 150 | + } |
| 151 | + |
| 152 | +- host->max_channel = IPR_MAX_BUS_TO_SCAN; |
| 153 | ++ host->max_channel = IPR_VSET_BUS; |
| 154 | + host->unique_id = host->host_no; |
| 155 | + host->max_cmd_len = IPR_MAX_CDB_LEN; |
| 156 | + host->can_queue = ioa_cfg->max_cmds; |
| 157 | +@@ -9806,25 +9827,6 @@ out_scsi_host_put: |
| 158 | + } |
| 159 | + |
| 160 | + /** |
| 161 | +- * ipr_scan_vsets - Scans for VSET devices |
| 162 | +- * @ioa_cfg: ioa config struct |
| 163 | +- * |
| 164 | +- * Description: Since the VSET resources do not follow SAM in that we can have |
| 165 | +- * sparse LUNs with no LUN 0, we have to scan for these ourselves. |
| 166 | +- * |
| 167 | +- * Return value: |
| 168 | +- * none |
| 169 | +- **/ |
| 170 | +-static void ipr_scan_vsets(struct ipr_ioa_cfg *ioa_cfg) |
| 171 | +-{ |
| 172 | +- int target, lun; |
| 173 | +- |
| 174 | +- for (target = 0; target < IPR_MAX_NUM_TARGETS_PER_BUS; target++) |
| 175 | +- for (lun = 0; lun < IPR_MAX_NUM_VSET_LUNS_PER_TARGET; lun++) |
| 176 | +- scsi_add_device(ioa_cfg->host, IPR_VSET_BUS, target, lun); |
| 177 | +-} |
| 178 | +- |
| 179 | +-/** |
| 180 | + * ipr_initiate_ioa_bringdown - Bring down an adapter |
| 181 | + * @ioa_cfg: ioa config struct |
| 182 | + * @shutdown_type: shutdown type |
| 183 | +@@ -9979,10 +9981,6 @@ static int ipr_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) |
| 184 | + } |
| 185 | + |
| 186 | + scsi_scan_host(ioa_cfg->host); |
| 187 | +- ipr_scan_vsets(ioa_cfg); |
| 188 | +- scsi_add_device(ioa_cfg->host, IPR_IOA_BUS, IPR_IOA_TARGET, IPR_IOA_LUN); |
| 189 | +- ioa_cfg->allow_ml_add_del = 1; |
| 190 | +- ioa_cfg->host->max_channel = IPR_VSET_BUS; |
| 191 | + ioa_cfg->iopoll_weight = ioa_cfg->chip_cfg->iopoll_weight; |
| 192 | + |
| 193 | + if (blk_iopoll_enabled && ioa_cfg->iopoll_weight && |
| 194 | +diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h |
| 195 | +index 0dc4275..79017fa 100644 |
| 196 | +--- a/drivers/scsi/ipr.h |
| 197 | ++++ b/drivers/scsi/ipr.h |
| 198 | +@@ -156,13 +156,11 @@ |
| 199 | + |
| 200 | + #define IPR_MAX_NUM_TARGETS_PER_BUS 256 |
| 201 | + #define IPR_MAX_NUM_LUNS_PER_TARGET 256 |
| 202 | +-#define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8 |
| 203 | + #define IPR_VSET_BUS 0xff |
| 204 | + #define IPR_IOA_BUS 0xff |
| 205 | + #define IPR_IOA_TARGET 0xff |
| 206 | + #define IPR_IOA_LUN 0xff |
| 207 | + #define IPR_MAX_NUM_BUSES 16 |
| 208 | +-#define IPR_MAX_BUS_TO_SCAN IPR_MAX_NUM_BUSES |
| 209 | + |
| 210 | + #define IPR_NUM_RESET_RELOAD_RETRIES 3 |
| 211 | + |
| 212 | +@@ -1452,7 +1450,7 @@ struct ipr_ioa_cfg { |
| 213 | + u8 in_ioa_bringdown:1; |
| 214 | + u8 ioa_unit_checked:1; |
| 215 | + u8 dump_taken:1; |
| 216 | +- u8 allow_ml_add_del:1; |
| 217 | ++ u8 scan_done:1; |
| 218 | + u8 needs_hard_reset:1; |
| 219 | + u8 dual_raid:1; |
| 220 | + u8 needs_warm_reset:1; |
| 221 | +-- |
| 222 | +1.8.3.2 |
| 223 | + |
0 commit comments