aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2009-08-20 14:06:05 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-05 10:41:57 -0400
commitac280b670e6d6666667aba02324e2fc50bd96ae7 (patch)
tree4d0d9187b26513ef9f820ab140f29a4f49f678b8
parentcf53b069f52ae3f83dec1acd339e3c3a2e979478 (diff)
[SCSI] qla2xxx: Add asynchronous-login support.
ISPs which support this feature include 23xx and above. Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h32
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h20
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c215
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c202
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c250
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c72
7 files changed, 784 insertions, 9 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 9eb7be684f0..efdfb1eb26b 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -207,6 +207,28 @@ typedef struct srb {
207#define SRB_DMA_VALID BIT_0 /* Command sent to ISP */ 207#define SRB_DMA_VALID BIT_0 /* Command sent to ISP */
208 208
209/* 209/*
210 * SRB extensions.
211 */
212struct srb_ctx {
213#define SRB_LOGIN_CMD 1
214#define SRB_LOGOUT_CMD 2
215 uint16_t type;
216 struct timer_list timer;
217
218 void (*free)(srb_t *sp);
219 void (*timeout)(srb_t *sp);
220};
221
222struct srb_logio {
223 struct srb_ctx ctx;
224
225#define SRB_LOGIN_RETRIED BIT_0
226#define SRB_LOGIN_COND_PLOGI BIT_1
227#define SRB_LOGIN_SKIP_PRLI BIT_2
228 uint16_t flags;
229};
230
231/*
210 * ISP I/O Register Set structure definitions. 232 * ISP I/O Register Set structure definitions.
211 */ 233 */
212struct device_reg_2xxx { 234struct device_reg_2xxx {
@@ -2096,6 +2118,10 @@ struct qla_msix_entry {
2096enum qla_work_type { 2118enum qla_work_type {
2097 QLA_EVT_AEN, 2119 QLA_EVT_AEN,
2098 QLA_EVT_IDC_ACK, 2120 QLA_EVT_IDC_ACK,
2121 QLA_EVT_ASYNC_LOGIN,
2122 QLA_EVT_ASYNC_LOGIN_DONE,
2123 QLA_EVT_ASYNC_LOGOUT,
2124 QLA_EVT_ASYNC_LOGOUT_DONE,
2099}; 2125};
2100 2126
2101 2127
@@ -2114,6 +2140,11 @@ struct qla_work_evt {
2114#define QLA_IDC_ACK_REGS 7 2140#define QLA_IDC_ACK_REGS 7
2115 uint16_t mb[QLA_IDC_ACK_REGS]; 2141 uint16_t mb[QLA_IDC_ACK_REGS];
2116 } idc_ack; 2142 } idc_ack;
2143 struct {
2144 struct fc_port *fcport;
2145#define QLA_LOGIO_LOGIN_RETRIED BIT_0
2146 u16 data[2];
2147 } logio;
2117 } u; 2148 } u;
2118}; 2149};
2119 2150
@@ -2354,6 +2385,7 @@ struct qla_hw_data {
2354 (ha)->flags.msix_enabled) 2385 (ha)->flags.msix_enabled)
2355#define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha)) 2386#define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha))
2356#define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha)) 2387#define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha))
2388#define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha))
2357 2389
2358#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) 2390#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA)
2359#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) 2391#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2)
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 65b12d82867..f3d1d1afa95 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -52,6 +52,14 @@ extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
52 52
53extern void qla84xx_put_chip(struct scsi_qla_host *); 53extern void qla84xx_put_chip(struct scsi_qla_host *);
54 54
55extern int qla2x00_async_login(struct scsi_qla_host *, fc_port_t *,
56 uint16_t *);
57extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *);
58extern int qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *,
59 uint16_t *);
60extern int qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
61 uint16_t *);
62
55/* 63/*
56 * Global Data in qla_os.c source file. 64 * Global Data in qla_os.c source file.
57 */ 65 */
@@ -76,6 +84,15 @@ extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
76extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum 84extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
77 fc_host_event_code, u32); 85 fc_host_event_code, u32);
78extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *); 86extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *);
87extern int qla2x00_post_async_login_work(struct scsi_qla_host *, fc_port_t *,
88 uint16_t *);
89extern int qla2x00_post_async_login_done_work(struct scsi_qla_host *,
90 fc_port_t *, uint16_t *);
91extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *,
92 uint16_t *);
93extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
94 fc_port_t *, uint16_t *);
95
79extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *); 96extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
80 97
81extern void qla2x00_abort_fcport_cmds(fc_port_t *); 98extern void qla2x00_abort_fcport_cmds(fc_port_t *);
@@ -83,6 +100,8 @@ extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
83 struct qla_hw_data *); 100 struct qla_hw_data *);
84extern void qla2x00_free_host(struct scsi_qla_host *); 101extern void qla2x00_free_host(struct scsi_qla_host *);
85extern void qla2x00_relogin(struct scsi_qla_host *); 102extern void qla2x00_relogin(struct scsi_qla_host *);
103extern void qla2x00_do_work(struct scsi_qla_host *);
104
86/* 105/*
87 * Global Functions in qla_mid.c source file. 106 * Global Functions in qla_mid.c source file.
88 */ 107 */
@@ -135,6 +154,7 @@ int qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
135 uint16_t, uint16_t, uint8_t); 154 uint16_t, uint16_t, uint8_t);
136int __qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *, 155int __qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
137 uint16_t, uint16_t, uint8_t); 156 uint16_t, uint16_t, uint8_t);
157extern int qla2x00_start_sp(srb_t *);
138 158
139/* 159/*
140 * Global Function Prototypes in qla_mbx.c source file. 160 * Global Function Prototypes in qla_mbx.c source file.
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 0cbe39e9250..37c99a27874 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -40,6 +40,210 @@ static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
40static int qla84xx_init_chip(scsi_qla_host_t *); 40static int qla84xx_init_chip(scsi_qla_host_t *);
41static int qla25xx_init_queues(struct qla_hw_data *); 41static int qla25xx_init_queues(struct qla_hw_data *);
42 42
43/* SRB Extensions ---------------------------------------------------------- */
44
45static void
46qla2x00_ctx_sp_timeout(unsigned long __data)
47{
48 srb_t *sp = (srb_t *)__data;
49 struct srb_ctx *ctx;
50 fc_port_t *fcport = sp->fcport;
51 struct qla_hw_data *ha = fcport->vha->hw;
52 struct req_que *req;
53 unsigned long flags;
54
55 spin_lock_irqsave(&ha->hardware_lock, flags);
56 req = ha->req_q_map[0];
57 req->outstanding_cmds[sp->handle] = NULL;
58 ctx = sp->ctx;
59 ctx->timeout(sp);
60 spin_unlock_irqrestore(&ha->hardware_lock, flags);
61
62 ctx->free(sp);
63}
64
65static void
66qla2x00_ctx_sp_free(srb_t *sp)
67{
68 struct srb_ctx *ctx = sp->ctx;
69
70 kfree(ctx);
71 mempool_free(sp, sp->fcport->vha->hw->srb_mempool);
72}
73
74inline srb_t *
75qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size,
76 unsigned long tmo)
77{
78 srb_t *sp;
79 struct qla_hw_data *ha = vha->hw;
80 struct srb_ctx *ctx;
81
82 sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL);
83 if (!sp)
84 goto done;
85 ctx = kzalloc(size, GFP_KERNEL);
86 if (!ctx) {
87 mempool_free(sp, ha->srb_mempool);
88 goto done;
89 }
90
91 memset(sp, 0, sizeof(*sp));
92 sp->fcport = fcport;
93 sp->ctx = ctx;
94 ctx->free = qla2x00_ctx_sp_free;
95
96 init_timer(&ctx->timer);
97 if (!tmo)
98 goto done;
99 ctx->timer.expires = jiffies + tmo * HZ;
100 ctx->timer.data = (unsigned long)sp;
101 ctx->timer.function = qla2x00_ctx_sp_timeout;
102 add_timer(&ctx->timer);
103done:
104 return sp;
105}
106
107/* Asynchronous Login/Logout Routines -------------------------------------- */
108
109#define ELS_TMO_2_RATOV(ha) ((ha)->r_a_tov / 10 * 2)
110
111static void
112qla2x00_async_logio_timeout(srb_t *sp)
113{
114 fc_port_t *fcport = sp->fcport;
115 struct srb_logio *lio = sp->ctx;
116
117 DEBUG2(printk(KERN_WARNING
118 "scsi(%ld:%x): Async-%s timeout.\n",
119 fcport->vha->host_no, sp->handle,
120 lio->ctx.type == SRB_LOGIN_CMD ? "login": "logout"));
121
122 if (lio->ctx.type == SRB_LOGIN_CMD)
123 qla2x00_post_async_logout_work(fcport->vha, fcport, NULL);
124}
125
126int
127qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
128 uint16_t *data)
129{
130 struct qla_hw_data *ha = vha->hw;
131 srb_t *sp;
132 struct srb_logio *lio;
133 int rval;
134
135 rval = QLA_FUNCTION_FAILED;
136 sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio),
137 ELS_TMO_2_RATOV(ha) + 2);
138 if (!sp)
139 goto done;
140
141 lio = sp->ctx;
142 lio->ctx.type = SRB_LOGIN_CMD;
143 lio->ctx.timeout = qla2x00_async_logio_timeout;
144 lio->flags |= SRB_LOGIN_COND_PLOGI;
145 if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
146 lio->flags |= SRB_LOGIN_RETRIED;
147 rval = qla2x00_start_sp(sp);
148 if (rval != QLA_SUCCESS)
149 goto done_free_sp;
150
151 DEBUG2(printk(KERN_DEBUG
152 "scsi(%ld:%x): Async-login - loop-id=%x portid=%02x%02x%02x "
153 "retries=%d.\n", fcport->vha->host_no, sp->handle, fcport->loop_id,
154 fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa,
155 fcport->login_retry));
156 return rval;
157
158done_free_sp:
159 del_timer_sync(&lio->ctx.timer);
160 lio->ctx.free(sp);
161done:
162 return rval;
163}
164
165int
166qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
167{
168 struct qla_hw_data *ha = vha->hw;
169 srb_t *sp;
170 struct srb_logio *lio;
171 int rval;
172
173 rval = QLA_FUNCTION_FAILED;
174 sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio),
175 ELS_TMO_2_RATOV(ha) + 2);
176 if (!sp)
177 goto done;
178
179 lio = sp->ctx;
180 lio->ctx.type = SRB_LOGOUT_CMD;
181 lio->ctx.timeout = qla2x00_async_logio_timeout;
182 rval = qla2x00_start_sp(sp);
183 if (rval != QLA_SUCCESS)
184 goto done_free_sp;
185
186 DEBUG2(printk(KERN_DEBUG
187 "scsi(%ld:%x): Async-logout - loop-id=%x portid=%02x%02x%02x.\n",
188 fcport->vha->host_no, sp->handle, fcport->loop_id,
189 fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa));
190 return rval;
191
192done_free_sp:
193 del_timer_sync(&lio->ctx.timer);
194 lio->ctx.free(sp);
195done:
196 return rval;
197}
198
199int
200qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
201 uint16_t *data)
202{
203 int rval;
204 uint8_t opts = 0;
205
206 switch (data[0]) {
207 case MBS_COMMAND_COMPLETE:
208 if (fcport->flags & FCF_TAPE_PRESENT)
209 opts |= BIT_1;
210 rval = qla2x00_get_port_database(vha, fcport, opts);
211 if (rval != QLA_SUCCESS)
212 qla2x00_mark_device_lost(vha, fcport, 1, 0);
213 else
214 qla2x00_update_fcport(vha, fcport);
215 break;
216 case MBS_COMMAND_ERROR:
217 if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
218 set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
219 else
220 qla2x00_mark_device_lost(vha, fcport, 1, 0);
221 break;
222 case MBS_PORT_ID_USED:
223 fcport->loop_id = data[1];
224 qla2x00_post_async_login_work(vha, fcport, NULL);
225 break;
226 case MBS_LOOP_ID_USED:
227 fcport->loop_id++;
228 rval = qla2x00_find_new_loop_id(vha, fcport);
229 if (rval != QLA_SUCCESS) {
230 qla2x00_mark_device_lost(vha, fcport, 1, 0);
231 break;
232 }
233 qla2x00_post_async_login_work(vha, fcport, NULL);
234 break;
235 }
236 return QLA_SUCCESS;
237}
238
239int
240qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
241 uint16_t *data)
242{
243 qla2x00_mark_device_lost(vha, fcport, 1, 0);
244 return QLA_SUCCESS;
245}
246
43/****************************************************************************/ 247/****************************************************************************/
44/* QLogic ISP2x00 Hardware Support Functions. */ 248/* QLogic ISP2x00 Hardware Support Functions. */
45/****************************************************************************/ 249/****************************************************************************/
@@ -1977,7 +2181,7 @@ qla2x00_rport_del(void *data)
1977 struct fc_rport *rport; 2181 struct fc_rport *rport;
1978 2182
1979 spin_lock_irq(fcport->vha->host->host_lock); 2183 spin_lock_irq(fcport->vha->host->host_lock);
1980 rport = fcport->drport; 2184 rport = fcport->drport ? fcport->drport: fcport->rport;
1981 fcport->drport = NULL; 2185 fcport->drport = NULL;
1982 spin_unlock_irq(fcport->vha->host->host_lock); 2186 spin_unlock_irq(fcport->vha->host->host_lock);
1983 if (rport) 2187 if (rport)
@@ -2344,8 +2548,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
2344 struct fc_rport *rport; 2548 struct fc_rport *rport;
2345 struct qla_hw_data *ha = vha->hw; 2549 struct qla_hw_data *ha = vha->hw;
2346 2550
2347 if (fcport->drport) 2551 qla2x00_rport_del(fcport);
2348 qla2x00_rport_del(fcport);
2349 2552
2350 rport_ids.node_name = wwn_to_u64(fcport->node_name); 2553 rport_ids.node_name = wwn_to_u64(fcport->node_name);
2351 rport_ids.port_name = wwn_to_u64(fcport->port_name); 2554 rport_ids.port_name = wwn_to_u64(fcport->port_name);
@@ -3038,6 +3241,12 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport,
3038 rval = QLA_SUCCESS; 3241 rval = QLA_SUCCESS;
3039 retry = 0; 3242 retry = 0;
3040 3243
3244 if (IS_ALOGIO_CAPABLE(ha)) {
3245 rval = qla2x00_post_async_login_work(vha, fcport, NULL);
3246 if (!rval)
3247 return rval;
3248 }
3249
3041 rval = qla2x00_fabric_login(vha, fcport, next_loopid); 3250 rval = qla2x00_fabric_login(vha, fcport, next_loopid);
3042 if (rval == QLA_SUCCESS) { 3251 if (rval == QLA_SUCCESS) {
3043 /* Send an ADISC to tape devices.*/ 3252 /* Send an ADISC to tape devices.*/
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index d37554ecd31..c5ccac0bef7 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -860,3 +860,205 @@ static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp)
860 else 860 else
861 *rsp = ha->rsp_q_map[0]; 861 *rsp = ha->rsp_q_map[0];
862} 862}
863
864/* Generic Control-SRB manipulation functions. */
865
866static void *
867qla2x00_alloc_iocbs(srb_t *sp)
868{
869 scsi_qla_host_t *vha = sp->fcport->vha;
870 struct qla_hw_data *ha = vha->hw;
871 struct req_que *req = ha->req_q_map[0];
872 device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
873 uint32_t index, handle;
874 request_t *pkt;
875 uint16_t cnt, req_cnt;
876
877 pkt = NULL;
878 req_cnt = 1;
879
880 /* Check for room in outstanding command list. */
881 handle = req->current_outstanding_cmd;
882 for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
883 handle++;
884 if (handle == MAX_OUTSTANDING_COMMANDS)
885 handle = 1;
886 if (!req->outstanding_cmds[handle])
887 break;
888 }
889 if (index == MAX_OUTSTANDING_COMMANDS)
890 goto queuing_error;
891
892 /* Check for room on request queue. */
893 if (req->cnt < req_cnt) {
894 if (ha->mqenable)
895 cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
896 else if (IS_FWI2_CAPABLE(ha))
897 cnt = RD_REG_DWORD(&reg->isp24.req_q_out);
898 else
899 cnt = qla2x00_debounce_register(
900 ISP_REQ_Q_OUT(ha, &reg->isp));
901
902 if (req->ring_index < cnt)
903 req->cnt = cnt - req->ring_index;
904 else
905 req->cnt = req->length -
906 (req->ring_index - cnt);
907 }
908 if (req->cnt < req_cnt)
909 goto queuing_error;
910
911 /* Prep packet */
912 req->current_outstanding_cmd = handle;
913 req->outstanding_cmds[handle] = sp;
914 req->cnt -= req_cnt;
915
916 pkt = req->ring_ptr;
917 memset(pkt, 0, REQUEST_ENTRY_SIZE);
918 pkt->entry_count = req_cnt;
919 pkt->handle = handle;
920 sp->handle = handle;
921
922queuing_error:
923 return pkt;
924}
925
926static void
927qla2x00_start_iocbs(srb_t *sp)
928{
929 struct qla_hw_data *ha = sp->fcport->vha->hw;
930 struct req_que *req = ha->req_q_map[0];
931 device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
932 struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;
933
934 /* Adjust ring index. */
935 req->ring_index++;
936 if (req->ring_index == req->length) {
937 req->ring_index = 0;
938 req->ring_ptr = req->ring;
939 } else
940 req->ring_ptr++;
941
942 /* Set chip new ring index. */
943 if (ha->mqenable) {
944 WRT_REG_DWORD(&reg->isp25mq.req_q_in, req->ring_index);
945 RD_REG_DWORD(&ioreg->hccr);
946 } else if (IS_FWI2_CAPABLE(ha)) {
947 WRT_REG_DWORD(&reg->isp24.req_q_in, req->ring_index);
948 RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
949 } else {
950 WRT_REG_WORD(ISP_REQ_Q_IN(ha, &reg->isp), req->ring_index);
951 RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, &reg->isp));
952 }
953}
954
955static void
956qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
957{
958 struct srb_logio *lio = sp->ctx;
959
960 logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
961 logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
962 if (lio->flags & SRB_LOGIN_COND_PLOGI)
963 logio->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
964 if (lio->flags & SRB_LOGIN_SKIP_PRLI)
965 logio->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
966 logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
967 logio->port_id[0] = sp->fcport->d_id.b.al_pa;
968 logio->port_id[1] = sp->fcport->d_id.b.area;
969 logio->port_id[2] = sp->fcport->d_id.b.domain;
970 logio->vp_index = sp->fcport->vp_idx;
971}
972
973static void
974qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx)
975{
976 struct qla_hw_data *ha = sp->fcport->vha->hw;
977 struct srb_logio *lio = sp->ctx;
978 uint16_t opts;
979
980 mbx->entry_type = MBX_IOCB_TYPE;;
981 SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id);
982 mbx->mb0 = cpu_to_le16(MBC_LOGIN_FABRIC_PORT);
983 opts = lio->flags & SRB_LOGIN_COND_PLOGI ? BIT_0: 0;
984 opts |= lio->flags & SRB_LOGIN_SKIP_PRLI ? BIT_1: 0;
985 if (HAS_EXTENDED_IDS(ha)) {
986 mbx->mb1 = cpu_to_le16(sp->fcport->loop_id);
987 mbx->mb10 = cpu_to_le16(opts);
988 } else {
989 mbx->mb1 = cpu_to_le16((sp->fcport->loop_id << 8) | opts);
990 }
991 mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain);
992 mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 |
993 sp->fcport->d_id.b.al_pa);
994 mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx);
995}
996
997static void
998qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
999{
1000 logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1001 logio->control_flags =
1002 cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
1003 logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
1004 logio->port_id[0] = sp->fcport->d_id.b.al_pa;
1005 logio->port_id[1] = sp->fcport->d_id.b.area;
1006 logio->port_id[2] = sp->fcport->d_id.b.domain;
1007 logio->vp_index = sp->fcport->vp_idx;
1008}
1009
1010static void
1011qla2x00_logout_iocb(srb_t *sp, struct mbx_entry *mbx)
1012{
1013 struct qla_hw_data *ha = sp->fcport->vha->hw;
1014
1015 mbx->entry_type = MBX_IOCB_TYPE;;
1016 SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id);
1017 mbx->mb0 = cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
1018 mbx->mb1 = HAS_EXTENDED_IDS(ha) ?
1019 cpu_to_le16(sp->fcport->loop_id):
1020 cpu_to_le16(sp->fcport->loop_id << 8);
1021 mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain);
1022 mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 |
1023 sp->fcport->d_id.b.al_pa);
1024 mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx);
1025 /* Implicit: mbx->mbx10 = 0. */
1026}
1027
1028int
1029qla2x00_start_sp(srb_t *sp)
1030{
1031 int rval;
1032 struct qla_hw_data *ha = sp->fcport->vha->hw;
1033 void *pkt;
1034 struct srb_ctx *ctx = sp->ctx;
1035 unsigned long flags;
1036
1037 rval = QLA_FUNCTION_FAILED;
1038 spin_lock_irqsave(&ha->hardware_lock, flags);
1039 pkt = qla2x00_alloc_iocbs(sp);
1040 if (!pkt)
1041 goto done;
1042
1043 rval = QLA_SUCCESS;
1044 switch (ctx->type) {
1045 case SRB_LOGIN_CMD:
1046 IS_FWI2_CAPABLE(ha) ?
1047 qla24xx_login_iocb(sp, pkt):
1048 qla2x00_login_iocb(sp, pkt);
1049 break;
1050 case SRB_LOGOUT_CMD:
1051 IS_FWI2_CAPABLE(ha) ?
1052 qla24xx_logout_iocb(sp, pkt):
1053 qla2x00_logout_iocb(sp, pkt);
1054 break;
1055 default:
1056 break;
1057 }
1058
1059 wmb();
1060 qla2x00_start_iocbs(sp);
1061done:
1062 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1063 return rval;
1064}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 74fa6f99204..c0fec6914b9 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -919,6 +919,249 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
919 } 919 }
920} 920}
921 921
922static srb_t *
923qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
924 struct req_que *req, void *iocb)
925{
926 struct qla_hw_data *ha = vha->hw;
927 sts_entry_t *pkt = iocb;
928 srb_t *sp = NULL;
929 uint16_t index;
930
931 index = LSW(pkt->handle);
932 if (index >= MAX_OUTSTANDING_COMMANDS) {
933 qla_printk(KERN_WARNING, ha,
934 "%s: Invalid completion handle (%x).\n", func, index);
935 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
936 goto done;
937 }
938 sp = req->outstanding_cmds[index];
939 if (!sp) {
940 qla_printk(KERN_WARNING, ha,
941 "%s: Invalid completion handle (%x) -- timed-out.\n", func,
942 index);
943 return sp;
944 }
945 if (sp->handle != index) {
946 qla_printk(KERN_WARNING, ha,
947 "%s: SRB handle (%x) mismatch %x.\n", func, sp->handle,
948 index);
949 return NULL;
950 }
951 req->outstanding_cmds[index] = NULL;
952done:
953 return sp;
954}
955
956static void
957qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
958 struct mbx_entry *mbx)
959{
960 const char func[] = "MBX-IOCB";
961 const char *type;
962 struct qla_hw_data *ha = vha->hw;
963 fc_port_t *fcport;
964 srb_t *sp;
965 struct srb_logio *lio;
966 uint16_t data[2];
967
968 sp = qla2x00_get_sp_from_handle(vha, func, req, mbx);
969 if (!sp)
970 return;
971
972 type = NULL;
973 lio = sp->ctx;
974 switch (lio->ctx.type) {
975 case SRB_LOGIN_CMD:
976 type = "login";
977 break;
978 case SRB_LOGOUT_CMD:
979 type = "logout";
980 break;
981 default:
982 qla_printk(KERN_WARNING, ha,
983 "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
984 lio->ctx.type);
985 return;
986 }
987
988 del_timer(&lio->ctx.timer);
989 fcport = sp->fcport;
990
991 data[0] = data[1] = 0;
992 if (mbx->entry_status) {
993 DEBUG2(printk(KERN_WARNING
994 "scsi(%ld:%x): Async-%s error entry - entry-status=%x "
995 "status=%x state-flag=%x status-flags=%x.\n",
996 fcport->vha->host_no, sp->handle, type,
997 mbx->entry_status, le16_to_cpu(mbx->status),
998 le16_to_cpu(mbx->state_flags),
999 le16_to_cpu(mbx->status_flags)));
1000 DEBUG2(qla2x00_dump_buffer((uint8_t *)mbx, sizeof(*mbx)));
1001
1002 data[0] = MBS_COMMAND_ERROR;
1003 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
1004 QLA_LOGIO_LOGIN_RETRIED: 0;
1005 goto done_post_logio_done_work;
1006 }
1007
1008 if (!mbx->status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) {
1009 DEBUG2(printk(KERN_DEBUG
1010 "scsi(%ld:%x): Async-%s complete - mbx1=%x.\n",
1011 fcport->vha->host_no, sp->handle, type,
1012 le16_to_cpu(mbx->mb1)));
1013
1014 data[0] = MBS_COMMAND_COMPLETE;
1015 if (lio->ctx.type == SRB_LOGIN_CMD && le16_to_cpu(mbx->mb1) & BIT_1)
1016 fcport->flags |= FCF_TAPE_PRESENT;
1017
1018 goto done_post_logio_done_work;
1019 }
1020
1021 data[0] = le16_to_cpu(mbx->mb0);
1022 switch (data[0]) {
1023 case MBS_PORT_ID_USED:
1024 data[1] = le16_to_cpu(mbx->mb1);
1025 break;
1026 case MBS_LOOP_ID_USED:
1027 break;
1028 default:
1029 data[0] = MBS_COMMAND_ERROR;
1030 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
1031 QLA_LOGIO_LOGIN_RETRIED: 0;
1032 break;
1033 }
1034
1035 DEBUG2(printk(KERN_WARNING
1036 "scsi(%ld:%x): Async-%s failed - status=%x mb0=%x mb1=%x mb2=%x "
1037 "mb6=%x mb7=%x.\n",
1038 fcport->vha->host_no, sp->handle, type, le16_to_cpu(mbx->status),
1039 le16_to_cpu(mbx->mb0), le16_to_cpu(mbx->mb1),
1040 le16_to_cpu(mbx->mb2), le16_to_cpu(mbx->mb6),
1041 le16_to_cpu(mbx->mb7)));
1042
1043done_post_logio_done_work:
1044 lio->ctx.type == SRB_LOGIN_CMD ?
1045 qla2x00_post_async_login_done_work(fcport->vha, fcport, data):
1046 qla2x00_post_async_logout_done_work(fcport->vha, fcport, data);
1047
1048 lio->ctx.free(sp);
1049}
1050
1051static void
1052qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
1053 struct logio_entry_24xx *logio)
1054{
1055 const char func[] = "LOGIO-IOCB";
1056 const char *type;
1057 struct qla_hw_data *ha = vha->hw;
1058 fc_port_t *fcport;
1059 srb_t *sp;
1060 struct srb_logio *lio;
1061 uint16_t data[2];
1062 uint32_t iop[2];
1063
1064 sp = qla2x00_get_sp_from_handle(vha, func, req, logio);
1065 if (!sp)
1066 return;
1067
1068 type = NULL;
1069 lio = sp->ctx;
1070 switch (lio->ctx.type) {
1071 case SRB_LOGIN_CMD:
1072 type = "login";
1073 break;
1074 case SRB_LOGOUT_CMD:
1075 type = "logout";
1076 break;
1077 default:
1078 qla_printk(KERN_WARNING, ha,
1079 "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
1080 lio->ctx.type);
1081 return;
1082 }
1083
1084 del_timer(&lio->ctx.timer);
1085 fcport = sp->fcport;
1086
1087 data[0] = data[1] = 0;
1088 if (logio->entry_status) {
1089 DEBUG2(printk(KERN_WARNING
1090 "scsi(%ld:%x): Async-%s error entry - entry-status=%x.\n",
1091 fcport->vha->host_no, sp->handle, type,
1092 logio->entry_status));
1093 DEBUG2(qla2x00_dump_buffer((uint8_t *)logio, sizeof(*logio)));
1094
1095 data[0] = MBS_COMMAND_ERROR;
1096 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
1097 QLA_LOGIO_LOGIN_RETRIED: 0;
1098 goto done_post_logio_done_work;
1099 }
1100
1101 if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) {
1102 DEBUG2(printk(KERN_DEBUG
1103 "scsi(%ld:%x): Async-%s complete - iop0=%x.\n",
1104 fcport->vha->host_no, sp->handle, type,
1105 le32_to_cpu(logio->io_parameter[0])));
1106
1107 data[0] = MBS_COMMAND_COMPLETE;
1108 if (lio->ctx.type == SRB_LOGOUT_CMD)
1109 goto done_post_logio_done_work;
1110
1111 iop[0] = le32_to_cpu(logio->io_parameter[0]);
1112 if (iop[0] & BIT_4) {
1113 fcport->port_type = FCT_TARGET;
1114 if (iop[0] & BIT_8)
1115 fcport->flags |= FCF_TAPE_PRESENT;
1116 }
1117 if (iop[0] & BIT_5)
1118 fcport->port_type = FCT_INITIATOR;
1119 if (logio->io_parameter[7] || logio->io_parameter[8])
1120 fcport->supported_classes |= FC_COS_CLASS2;
1121 if (logio->io_parameter[9] || logio->io_parameter[10])
1122 fcport->supported_classes |= FC_COS_CLASS3;
1123
1124 goto done_post_logio_done_work;
1125 }
1126
1127 iop[0] = le32_to_cpu(logio->io_parameter[0]);
1128 iop[1] = le32_to_cpu(logio->io_parameter[1]);
1129 switch (iop[0]) {
1130 case LSC_SCODE_PORTID_USED:
1131 data[0] = MBS_PORT_ID_USED;
1132 data[1] = LSW(iop[1]);
1133 break;
1134 case LSC_SCODE_NPORT_USED:
1135 data[0] = MBS_LOOP_ID_USED;
1136 break;
1137 case LSC_SCODE_CMD_FAILED:
1138 if ((iop[1] & 0xff) == 0x05) {
1139 data[0] = MBS_NOT_LOGGED_IN;
1140 break;
1141 }
1142 /* Fall through. */
1143 default:
1144 data[0] = MBS_COMMAND_ERROR;
1145 data[1] = lio->flags & SRB_LOGIN_RETRIED ?
1146 QLA_LOGIO_LOGIN_RETRIED: 0;
1147 break;
1148 }
1149
1150 DEBUG2(printk(KERN_WARNING
1151 "scsi(%ld:%x): Async-%s failed - comp=%x iop0=%x iop1=%x.\n",
1152 fcport->vha->host_no, sp->handle, type,
1153 le16_to_cpu(logio->comp_status),
1154 le32_to_cpu(logio->io_parameter[0]),
1155 le32_to_cpu(logio->io_parameter[1])));
1156
1157done_post_logio_done_work:
1158 lio->ctx.type == SRB_LOGIN_CMD ?
1159 qla2x00_post_async_login_done_work(fcport->vha, fcport, data):
1160 qla2x00_post_async_logout_done_work(fcport->vha, fcport, data);
1161
1162 lio->ctx.free(sp);
1163}
1164
922/** 1165/**
923 * qla2x00_process_response_queue() - Process response queue entries. 1166 * qla2x00_process_response_queue() - Process response queue entries.
924 * @ha: SCSI driver HA context 1167 * @ha: SCSI driver HA context
@@ -980,6 +1223,9 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
980 case STATUS_CONT_TYPE: 1223 case STATUS_CONT_TYPE:
981 qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt); 1224 qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
982 break; 1225 break;
1226 case MBX_IOCB_TYPE:
1227 qla2x00_mbx_iocb_entry(vha, rsp->req,
1228 (struct mbx_entry *)pkt);
983 default: 1229 default:
984 /* Type Not Supported. */ 1230 /* Type Not Supported. */
985 DEBUG4(printk(KERN_WARNING 1231 DEBUG4(printk(KERN_WARNING
@@ -1590,6 +1836,10 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
1590 qla24xx_report_id_acquisition(vha, 1836 qla24xx_report_id_acquisition(vha,
1591 (struct vp_rpt_id_entry_24xx *)pkt); 1837 (struct vp_rpt_id_entry_24xx *)pkt);
1592 break; 1838 break;
1839 case LOGINOUT_PORT_IOCB_TYPE:
1840 qla24xx_logio_entry(vha, rsp->req,
1841 (struct logio_entry_24xx *)pkt);
1842 break;
1593 default: 1843 default:
1594 /* Type Not Supported. */ 1844 /* Type Not Supported. */
1595 DEBUG4(printk(KERN_WARNING 1845 DEBUG4(printk(KERN_WARNING
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 6238be37d7b..a748a95efb1 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -253,6 +253,8 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
253 if (!(ha->current_topology & ISP_CFG_F)) 253 if (!(ha->current_topology & ISP_CFG_F))
254 return 0; 254 return 0;
255 255
256 qla2x00_do_work(vha);
257
256 if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { 258 if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
257 /* VP acquired. complete port configuration */ 259 /* VP acquired. complete port configuration */
258 if (atomic_read(&base_vha->loop_state) == LOOP_READY) { 260 if (atomic_read(&base_vha->loop_state) == LOOP_READY) {
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index b6c088caf35..5fd7adbff30 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1170,6 +1170,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
1170 int que, cnt; 1170 int que, cnt;
1171 unsigned long flags; 1171 unsigned long flags;
1172 srb_t *sp; 1172 srb_t *sp;
1173 struct srb_ctx *ctx;
1173 struct qla_hw_data *ha = vha->hw; 1174 struct qla_hw_data *ha = vha->hw;
1174 struct req_que *req; 1175 struct req_que *req;
1175 1176
@@ -1182,8 +1183,14 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
1182 sp = req->outstanding_cmds[cnt]; 1183 sp = req->outstanding_cmds[cnt];
1183 if (sp) { 1184 if (sp) {
1184 req->outstanding_cmds[cnt] = NULL; 1185 req->outstanding_cmds[cnt] = NULL;
1185 sp->cmd->result = res; 1186 if (!sp->ctx) {
1186 qla2x00_sp_compl(ha, sp); 1187 sp->cmd->result = res;
1188 qla2x00_sp_compl(ha, sp);
1189 } else {
1190 ctx = sp->ctx;
1191 del_timer_sync(&ctx->timer);
1192 ctx->free(sp);
1193 }
1187 } 1194 }
1188 } 1195 }
1189 } 1196 }
@@ -2618,7 +2625,31 @@ qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb)
2618 return qla2x00_post_work(vha, e); 2625 return qla2x00_post_work(vha, e);
2619} 2626}
2620 2627
2621static void 2628#define qla2x00_post_async_work(name, type) \
2629int qla2x00_post_async_##name##_work( \
2630 struct scsi_qla_host *vha, \
2631 fc_port_t *fcport, uint16_t *data) \
2632{ \
2633 struct qla_work_evt *e; \
2634 \
2635 e = qla2x00_alloc_work(vha, type); \
2636 if (!e) \
2637 return QLA_FUNCTION_FAILED; \
2638 \
2639 e->u.logio.fcport = fcport; \
2640 if (data) { \
2641 e->u.logio.data[0] = data[0]; \
2642 e->u.logio.data[1] = data[1]; \
2643 } \
2644 return qla2x00_post_work(vha, e); \
2645}
2646
2647qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN);
2648qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE);
2649qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
2650qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
2651
2652void
2622qla2x00_do_work(struct scsi_qla_host *vha) 2653qla2x00_do_work(struct scsi_qla_host *vha)
2623{ 2654{
2624 struct qla_work_evt *e, *tmp; 2655 struct qla_work_evt *e, *tmp;
@@ -2640,6 +2671,21 @@ qla2x00_do_work(struct scsi_qla_host *vha)
2640 case QLA_EVT_IDC_ACK: 2671 case QLA_EVT_IDC_ACK:
2641 qla81xx_idc_ack(vha, e->u.idc_ack.mb); 2672 qla81xx_idc_ack(vha, e->u.idc_ack.mb);
2642 break; 2673 break;
2674 case QLA_EVT_ASYNC_LOGIN:
2675 qla2x00_async_login(vha, e->u.logio.fcport,
2676 e->u.logio.data);
2677 break;
2678 case QLA_EVT_ASYNC_LOGIN_DONE:
2679 qla2x00_async_login_done(vha, e->u.logio.fcport,
2680 e->u.logio.data);
2681 break;
2682 case QLA_EVT_ASYNC_LOGOUT:
2683 qla2x00_async_logout(vha, e->u.logio.fcport);
2684 break;
2685 case QLA_EVT_ASYNC_LOGOUT_DONE:
2686 qla2x00_async_logout_done(vha, e->u.logio.fcport,
2687 e->u.logio.data);
2688 break;
2643 } 2689 }
2644 if (e->flags & QLA_EVT_FLAG_FREE) 2690 if (e->flags & QLA_EVT_FLAG_FREE)
2645 kfree(e); 2691 kfree(e);
@@ -2655,6 +2701,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
2655 int status; 2701 int status;
2656 uint16_t next_loopid = 0; 2702 uint16_t next_loopid = 0;
2657 struct qla_hw_data *ha = vha->hw; 2703 struct qla_hw_data *ha = vha->hw;
2704 uint16_t data[2];
2658 2705
2659 list_for_each_entry(fcport, &vha->vp_fcports, list) { 2706 list_for_each_entry(fcport, &vha->vp_fcports, list) {
2660 /* 2707 /*
@@ -2664,6 +2711,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
2664 if (atomic_read(&fcport->state) != 2711 if (atomic_read(&fcport->state) !=
2665 FCS_ONLINE && fcport->login_retry) { 2712 FCS_ONLINE && fcport->login_retry) {
2666 2713
2714 fcport->login_retry--;
2667 if (fcport->flags & FCF_FABRIC_DEVICE) { 2715 if (fcport->flags & FCF_FABRIC_DEVICE) {
2668 if (fcport->flags & FCF_TAPE_PRESENT) 2716 if (fcport->flags & FCF_TAPE_PRESENT)
2669 ha->isp_ops->fabric_logout(vha, 2717 ha->isp_ops->fabric_logout(vha,
@@ -2672,13 +2720,22 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
2672 fcport->d_id.b.area, 2720 fcport->d_id.b.area,
2673 fcport->d_id.b.al_pa); 2721 fcport->d_id.b.al_pa);
2674 2722
2675 status = qla2x00_fabric_login(vha, fcport, 2723 if (IS_ALOGIO_CAPABLE(ha)) {
2676 &next_loopid); 2724 data[0] = 0;
2725 data[1] = QLA_LOGIO_LOGIN_RETRIED;
2726 status = qla2x00_post_async_login_work(
2727 vha, fcport, data);
2728 if (status == QLA_SUCCESS)
2729 continue;
2730 /* Attempt a retry. */
2731 status = 1;
2732 } else
2733 status = qla2x00_fabric_login(vha,
2734 fcport, &next_loopid);
2677 } else 2735 } else
2678 status = qla2x00_local_device_login(vha, 2736 status = qla2x00_local_device_login(vha,
2679 fcport); 2737 fcport);
2680 2738
2681 fcport->login_retry--;
2682 if (status == QLA_SUCCESS) { 2739 if (status == QLA_SUCCESS) {
2683 fcport->old_loop_id = fcport->loop_id; 2740 fcport->old_loop_id = fcport->loop_id;
2684 2741
@@ -2851,6 +2908,9 @@ qla2x00_do_dpc(void *data)
2851 */ 2908 */
2852 ha->dpc_active = 0; 2909 ha->dpc_active = 0;
2853 2910
2911 /* Cleanup any residual CTX SRBs. */
2912 qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
2913
2854 return 0; 2914 return 0;
2855} 2915}
2856 2916