aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c141
1 files changed, 113 insertions, 28 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index f0396e79b6fa..b79fca7d461b 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -287,9 +287,12 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
287 int ques, req, ret; 287 int ques, req, ret;
288 struct qla_hw_data *ha = vha->hw; 288 struct qla_hw_data *ha = vha->hw;
289 289
290 if (!(ha->fw_attributes & BIT_6)) {
291 qla_printk(KERN_INFO, ha,
292 "Firmware is not multi-queue capable\n");
293 goto fail;
294 }
290 if (ql2xmultique_tag) { 295 if (ql2xmultique_tag) {
291 /* CPU affinity mode */
292 ha->wq = create_workqueue("qla2xxx_wq");
293 /* create a request queue for IO */ 296 /* create a request queue for IO */
294 options |= BIT_7; 297 options |= BIT_7;
295 req = qla25xx_create_req_que(ha, options, 0, 0, -1, 298 req = qla25xx_create_req_que(ha, options, 0, 0, -1,
@@ -299,6 +302,7 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
299 "Can't create request queue\n"); 302 "Can't create request queue\n");
300 goto fail; 303 goto fail;
301 } 304 }
305 ha->wq = create_workqueue("qla2xxx_wq");
302 vha->req = ha->req_q_map[req]; 306 vha->req = ha->req_q_map[req];
303 options |= BIT_1; 307 options |= BIT_1;
304 for (ques = 1; ques < ha->max_rsp_queues; ques++) { 308 for (ques = 1; ques < ha->max_rsp_queues; ques++) {
@@ -309,6 +313,8 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
309 goto fail2; 313 goto fail2;
310 } 314 }
311 } 315 }
316 ha->flags.cpu_affinity_enabled = 1;
317
312 DEBUG2(qla_printk(KERN_INFO, ha, 318 DEBUG2(qla_printk(KERN_INFO, ha,
313 "CPU affinity mode enabled, no. of response" 319 "CPU affinity mode enabled, no. of response"
314 " queues:%d, no. of request queues:%d\n", 320 " queues:%d, no. of request queues:%d\n",
@@ -317,8 +323,13 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
317 return 0; 323 return 0;
318fail2: 324fail2:
319 qla25xx_delete_queues(vha); 325 qla25xx_delete_queues(vha);
326 destroy_workqueue(ha->wq);
327 ha->wq = NULL;
320fail: 328fail:
321 ha->mqenable = 0; 329 ha->mqenable = 0;
330 kfree(ha->req_q_map);
331 kfree(ha->rsp_q_map);
332 ha->max_req_queues = ha->max_rsp_queues = 1;
322 return 1; 333 return 1;
323} 334}
324 335
@@ -462,6 +473,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
462 sp->flags = 0; 473 sp->flags = 0;
463 CMD_SP(cmd) = (void *)sp; 474 CMD_SP(cmd) = (void *)sp;
464 cmd->scsi_done = done; 475 cmd->scsi_done = done;
476 sp->ctx = NULL;
465 477
466 return sp; 478 return sp;
467} 479}
@@ -556,11 +568,8 @@ qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
556 unsigned long wait_iter = ABORT_WAIT_ITER; 568 unsigned long wait_iter = ABORT_WAIT_ITER;
557 int ret = QLA_SUCCESS; 569 int ret = QLA_SUCCESS;
558 570
559 while (CMD_SP(cmd)) { 571 while (CMD_SP(cmd) && wait_iter--) {
560 msleep(ABORT_POLLING_PERIOD); 572 msleep(ABORT_POLLING_PERIOD);
561
562 if (--wait_iter)
563 break;
564 } 573 }
565 if (CMD_SP(cmd)) 574 if (CMD_SP(cmd))
566 ret = QLA_FUNCTION_FAILED; 575 ret = QLA_FUNCTION_FAILED;
@@ -698,6 +707,8 @@ qla2x00_abort_fcport_cmds(fc_port_t *fcport)
698 continue; 707 continue;
699 if (sp->fcport != fcport) 708 if (sp->fcport != fcport)
700 continue; 709 continue;
710 if (sp->ctx)
711 continue;
701 712
702 spin_unlock_irqrestore(&ha->hardware_lock, flags); 713 spin_unlock_irqrestore(&ha->hardware_lock, flags);
703 if (ha->isp_ops->abort_command(sp)) { 714 if (ha->isp_ops->abort_command(sp)) {
@@ -783,7 +794,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
783 794
784 if (sp == NULL) 795 if (sp == NULL)
785 continue; 796 continue;
786 797 if (sp->ctx)
798 continue;
787 if (sp->cmd != cmd) 799 if (sp->cmd != cmd)
788 continue; 800 continue;
789 801
@@ -848,7 +860,8 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
848 sp = req->outstanding_cmds[cnt]; 860 sp = req->outstanding_cmds[cnt];
849 if (!sp) 861 if (!sp)
850 continue; 862 continue;
851 863 if (sp->ctx)
864 continue;
852 if (vha->vp_idx != sp->fcport->vha->vp_idx) 865 if (vha->vp_idx != sp->fcport->vha->vp_idx)
853 continue; 866 continue;
854 match = 0; 867 match = 0;
@@ -1106,8 +1119,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
1106 struct fc_port *fcport; 1119 struct fc_port *fcport;
1107 struct qla_hw_data *ha = vha->hw; 1120 struct qla_hw_data *ha = vha->hw;
1108 1121
1109 if (ha->flags.enable_lip_full_login && !vha->vp_idx && 1122 if (ha->flags.enable_lip_full_login && !IS_QLA81XX(ha)) {
1110 !IS_QLA81XX(ha)) {
1111 ret = qla2x00_full_login_lip(vha); 1123 ret = qla2x00_full_login_lip(vha);
1112 if (ret != QLA_SUCCESS) { 1124 if (ret != QLA_SUCCESS) {
1113 DEBUG2_3(printk("%s(%ld): failed: " 1125 DEBUG2_3(printk("%s(%ld): failed: "
@@ -1120,7 +1132,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
1120 qla2x00_wait_for_loop_ready(vha); 1132 qla2x00_wait_for_loop_ready(vha);
1121 } 1133 }
1122 1134
1123 if (ha->flags.enable_lip_reset && !vha->vp_idx) { 1135 if (ha->flags.enable_lip_reset) {
1124 ret = qla2x00_lip_reset(vha); 1136 ret = qla2x00_lip_reset(vha);
1125 if (ret != QLA_SUCCESS) { 1137 if (ret != QLA_SUCCESS) {
1126 DEBUG2_3(printk("%s(%ld): failed: " 1138 DEBUG2_3(printk("%s(%ld): failed: "
@@ -1154,6 +1166,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
1154 int que, cnt; 1166 int que, cnt;
1155 unsigned long flags; 1167 unsigned long flags;
1156 srb_t *sp; 1168 srb_t *sp;
1169 struct srb_ctx *ctx;
1157 struct qla_hw_data *ha = vha->hw; 1170 struct qla_hw_data *ha = vha->hw;
1158 struct req_que *req; 1171 struct req_que *req;
1159 1172
@@ -1166,8 +1179,14 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
1166 sp = req->outstanding_cmds[cnt]; 1179 sp = req->outstanding_cmds[cnt];
1167 if (sp) { 1180 if (sp) {
1168 req->outstanding_cmds[cnt] = NULL; 1181 req->outstanding_cmds[cnt] = NULL;
1169 sp->cmd->result = res; 1182 if (!sp->ctx) {
1170 qla2x00_sp_compl(ha, sp); 1183 sp->cmd->result = res;
1184 qla2x00_sp_compl(ha, sp);
1185 } else {
1186 ctx = sp->ctx;
1187 del_timer_sync(&ctx->timer);
1188 ctx->free(sp);
1189 }
1171 } 1190 }
1172 } 1191 }
1173 } 1192 }
@@ -1193,6 +1212,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
1193 scsi_qla_host_t *vha = shost_priv(sdev->host); 1212 scsi_qla_host_t *vha = shost_priv(sdev->host);
1194 struct qla_hw_data *ha = vha->hw; 1213 struct qla_hw_data *ha = vha->hw;
1195 struct fc_rport *rport = starget_to_rport(sdev->sdev_target); 1214 struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
1215 fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
1196 struct req_que *req = vha->req; 1216 struct req_que *req = vha->req;
1197 1217
1198 if (sdev->tagged_supported) 1218 if (sdev->tagged_supported)
@@ -1201,6 +1221,8 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
1201 scsi_deactivate_tcq(sdev, req->max_q_depth); 1221 scsi_deactivate_tcq(sdev, req->max_q_depth);
1202 1222
1203 rport->dev_loss_tmo = ha->port_down_retry_count; 1223 rport->dev_loss_tmo = ha->port_down_retry_count;
1224 if (sdev->type == TYPE_TAPE)
1225 fcport->flags |= FCF_TAPE_PRESENT;
1204 1226
1205 return 0; 1227 return 0;
1206} 1228}
@@ -1923,6 +1945,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1923 if (ret) 1945 if (ret)
1924 goto probe_init_failed; 1946 goto probe_init_failed;
1925 /* Alloc arrays of request and response ring ptrs */ 1947 /* Alloc arrays of request and response ring ptrs */
1948que_init:
1926 if (!qla2x00_alloc_queues(ha)) { 1949 if (!qla2x00_alloc_queues(ha)) {
1927 qla_printk(KERN_WARNING, ha, 1950 qla_printk(KERN_WARNING, ha,
1928 "[ERROR] Failed to allocate memory for queue" 1951 "[ERROR] Failed to allocate memory for queue"
@@ -1959,11 +1982,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1959 goto probe_failed; 1982 goto probe_failed;
1960 } 1983 }
1961 1984
1962 if (ha->mqenable) 1985 if (ha->mqenable) {
1963 if (qla25xx_setup_mode(base_vha)) 1986 if (qla25xx_setup_mode(base_vha)) {
1964 qla_printk(KERN_WARNING, ha, 1987 qla_printk(KERN_WARNING, ha,
1965 "Can't create queues, falling back to single" 1988 "Can't create queues, falling back to single"
1966 " queue mode\n"); 1989 " queue mode\n");
1990 goto que_init;
1991 }
1992 }
1967 1993
1968 if (ha->flags.running_gold_fw) 1994 if (ha->flags.running_gold_fw)
1969 goto skip_dpc; 1995 goto skip_dpc;
@@ -2155,17 +2181,19 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
2155 int defer) 2181 int defer)
2156{ 2182{
2157 struct fc_rport *rport; 2183 struct fc_rport *rport;
2184 scsi_qla_host_t *base_vha;
2158 2185
2159 if (!fcport->rport) 2186 if (!fcport->rport)
2160 return; 2187 return;
2161 2188
2162 rport = fcport->rport; 2189 rport = fcport->rport;
2163 if (defer) { 2190 if (defer) {
2191 base_vha = pci_get_drvdata(vha->hw->pdev);
2164 spin_lock_irq(vha->host->host_lock); 2192 spin_lock_irq(vha->host->host_lock);
2165 fcport->drport = rport; 2193 fcport->drport = rport;
2166 spin_unlock_irq(vha->host->host_lock); 2194 spin_unlock_irq(vha->host->host_lock);
2167 set_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags); 2195 set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
2168 qla2xxx_wake_dpc(vha); 2196 qla2xxx_wake_dpc(base_vha);
2169 } else 2197 } else
2170 fc_remote_port_delete(rport); 2198 fc_remote_port_delete(rport);
2171} 2199}
@@ -2237,8 +2265,9 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
2237 fc_port_t *fcport; 2265 fc_port_t *fcport;
2238 2266
2239 list_for_each_entry(fcport, &vha->vp_fcports, list) { 2267 list_for_each_entry(fcport, &vha->vp_fcports, list) {
2240 if (vha->vp_idx != fcport->vp_idx) 2268 if (vha->vp_idx != 0 && vha->vp_idx != fcport->vp_idx)
2241 continue; 2269 continue;
2270
2242 /* 2271 /*
2243 * No point in marking the device as lost, if the device is 2272 * No point in marking the device as lost, if the device is
2244 * already DEAD. 2273 * already DEAD.
@@ -2246,10 +2275,12 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
2246 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) 2275 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
2247 continue; 2276 continue;
2248 if (atomic_read(&fcport->state) == FCS_ONLINE) { 2277 if (atomic_read(&fcport->state) == FCS_ONLINE) {
2249 atomic_set(&fcport->state, FCS_DEVICE_LOST); 2278 if (defer)
2250 qla2x00_schedule_rport_del(vha, fcport, defer); 2279 qla2x00_schedule_rport_del(vha, fcport, defer);
2251 } else 2280 else if (vha->vp_idx == fcport->vp_idx)
2252 atomic_set(&fcport->state, FCS_DEVICE_LOST); 2281 qla2x00_schedule_rport_del(vha, fcport, defer);
2282 }
2283 atomic_set(&fcport->state, FCS_DEVICE_LOST);
2253 } 2284 }
2254} 2285}
2255 2286
@@ -2598,7 +2629,31 @@ qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb)
2598 return qla2x00_post_work(vha, e); 2629 return qla2x00_post_work(vha, e);
2599} 2630}
2600 2631
2601static void 2632#define qla2x00_post_async_work(name, type) \
2633int qla2x00_post_async_##name##_work( \
2634 struct scsi_qla_host *vha, \
2635 fc_port_t *fcport, uint16_t *data) \
2636{ \
2637 struct qla_work_evt *e; \
2638 \
2639 e = qla2x00_alloc_work(vha, type); \
2640 if (!e) \
2641 return QLA_FUNCTION_FAILED; \
2642 \
2643 e->u.logio.fcport = fcport; \
2644 if (data) { \
2645 e->u.logio.data[0] = data[0]; \
2646 e->u.logio.data[1] = data[1]; \
2647 } \
2648 return qla2x00_post_work(vha, e); \
2649}
2650
2651qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN);
2652qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE);
2653qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
2654qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
2655
2656void
2602qla2x00_do_work(struct scsi_qla_host *vha) 2657qla2x00_do_work(struct scsi_qla_host *vha)
2603{ 2658{
2604 struct qla_work_evt *e, *tmp; 2659 struct qla_work_evt *e, *tmp;
@@ -2620,6 +2675,21 @@ qla2x00_do_work(struct scsi_qla_host *vha)
2620 case QLA_EVT_IDC_ACK: 2675 case QLA_EVT_IDC_ACK:
2621 qla81xx_idc_ack(vha, e->u.idc_ack.mb); 2676 qla81xx_idc_ack(vha, e->u.idc_ack.mb);
2622 break; 2677 break;
2678 case QLA_EVT_ASYNC_LOGIN:
2679 qla2x00_async_login(vha, e->u.logio.fcport,
2680 e->u.logio.data);
2681 break;
2682 case QLA_EVT_ASYNC_LOGIN_DONE:
2683 qla2x00_async_login_done(vha, e->u.logio.fcport,
2684 e->u.logio.data);
2685 break;
2686 case QLA_EVT_ASYNC_LOGOUT:
2687 qla2x00_async_logout(vha, e->u.logio.fcport);
2688 break;
2689 case QLA_EVT_ASYNC_LOGOUT_DONE:
2690 qla2x00_async_logout_done(vha, e->u.logio.fcport,
2691 e->u.logio.data);
2692 break;
2623 } 2693 }
2624 if (e->flags & QLA_EVT_FLAG_FREE) 2694 if (e->flags & QLA_EVT_FLAG_FREE)
2625 kfree(e); 2695 kfree(e);
@@ -2635,6 +2705,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
2635 int status; 2705 int status;
2636 uint16_t next_loopid = 0; 2706 uint16_t next_loopid = 0;
2637 struct qla_hw_data *ha = vha->hw; 2707 struct qla_hw_data *ha = vha->hw;
2708 uint16_t data[2];
2638 2709
2639 list_for_each_entry(fcport, &vha->vp_fcports, list) { 2710 list_for_each_entry(fcport, &vha->vp_fcports, list) {
2640 /* 2711 /*
@@ -2644,6 +2715,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
2644 if (atomic_read(&fcport->state) != 2715 if (atomic_read(&fcport->state) !=
2645 FCS_ONLINE && fcport->login_retry) { 2716 FCS_ONLINE && fcport->login_retry) {
2646 2717
2718 fcport->login_retry--;
2647 if (fcport->flags & FCF_FABRIC_DEVICE) { 2719 if (fcport->flags & FCF_FABRIC_DEVICE) {
2648 if (fcport->flags & FCF_TAPE_PRESENT) 2720 if (fcport->flags & FCF_TAPE_PRESENT)
2649 ha->isp_ops->fabric_logout(vha, 2721 ha->isp_ops->fabric_logout(vha,
@@ -2652,13 +2724,22 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
2652 fcport->d_id.b.area, 2724 fcport->d_id.b.area,
2653 fcport->d_id.b.al_pa); 2725 fcport->d_id.b.al_pa);
2654 2726
2655 status = qla2x00_fabric_login(vha, fcport, 2727 if (IS_ALOGIO_CAPABLE(ha)) {
2656 &next_loopid); 2728 data[0] = 0;
2729 data[1] = QLA_LOGIO_LOGIN_RETRIED;
2730 status = qla2x00_post_async_login_work(
2731 vha, fcport, data);
2732 if (status == QLA_SUCCESS)
2733 continue;
2734 /* Attempt a retry. */
2735 status = 1;
2736 } else
2737 status = qla2x00_fabric_login(vha,
2738 fcport, &next_loopid);
2657 } else 2739 } else
2658 status = qla2x00_local_device_login(vha, 2740 status = qla2x00_local_device_login(vha,
2659 fcport); 2741 fcport);
2660 2742
2661 fcport->login_retry--;
2662 if (status == QLA_SUCCESS) { 2743 if (status == QLA_SUCCESS) {
2663 fcport->old_loop_id = fcport->loop_id; 2744 fcport->old_loop_id = fcport->loop_id;
2664 2745
@@ -2831,6 +2912,9 @@ qla2x00_do_dpc(void *data)
2831 */ 2912 */
2832 ha->dpc_active = 0; 2913 ha->dpc_active = 0;
2833 2914
2915 /* Cleanup any residual CTX SRBs. */
2916 qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
2917
2834 return 0; 2918 return 0;
2835} 2919}
2836 2920
@@ -2971,6 +3055,8 @@ qla2x00_timer(scsi_qla_host_t *vha)
2971 sp = req->outstanding_cmds[index]; 3055 sp = req->outstanding_cmds[index];
2972 if (!sp) 3056 if (!sp)
2973 continue; 3057 continue;
3058 if (sp->ctx)
3059 continue;
2974 sfcp = sp->fcport; 3060 sfcp = sp->fcport;
2975 if (!(sfcp->flags & FCF_TAPE_PRESENT)) 3061 if (!(sfcp->flags & FCF_TAPE_PRESENT))
2976 continue; 3062 continue;
@@ -2987,8 +3073,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
2987 3073
2988 /* if the loop has been down for 4 minutes, reinit adapter */ 3074 /* if the loop has been down for 4 minutes, reinit adapter */
2989 if (atomic_dec_and_test(&vha->loop_down_timer) != 0) { 3075 if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
2990 if (!(vha->device_flags & DFLG_NO_CABLE) && 3076 if (!(vha->device_flags & DFLG_NO_CABLE)) {
2991 !vha->vp_idx) {
2992 DEBUG(printk("scsi(%ld): Loop down - " 3077 DEBUG(printk("scsi(%ld): Loop down - "
2993 "aborting ISP.\n", 3078 "aborting ISP.\n",
2994 vha->host_no)); 3079 vha->host_no));