emlxs_ip.c (291a2b48) emlxs_ip.c (82527734)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 7 unchanged lines hidden (view full) ---

16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2009 Emulex. All rights reserved.
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 7 unchanged lines hidden (view full) ---

16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2009 Emulex. All rights reserved.
24 * Use is subject to License terms.
24 * Use is subject to license terms.
25 */
26
25 */
26
27
27#include <emlxs.h>
28
29/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
30EMLXS_MSG_DEF(EMLXS_IP_C);
31
32
33extern int32_t
28#include <emlxs.h>
29
30/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
31EMLXS_MSG_DEF(EMLXS_IP_C);
32
33
34extern int32_t
34emlxs_ip_handle_event(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq)
35emlxs_ip_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
35{
36 emlxs_port_t *port = &PPORT;
37 IOCB *cmd;
38 emlxs_buf_t *sbp;
39 NODELIST *ndlp;
40
41 cmd = &iocbq->iocb;
42
43 HBASTATS.IpEvent++;
44
45 sbp = (emlxs_buf_t *)iocbq->sbp;
46
47 if (!sbp) {
48 HBASTATS.IpStray++;
49
50 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg,
51 "cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
36{
37 emlxs_port_t *port = &PPORT;
38 IOCB *cmd;
39 emlxs_buf_t *sbp;
40 NODELIST *ndlp;
41
42 cmd = &iocbq->iocb;
43
44 HBASTATS.IpEvent++;
45
46 sbp = (emlxs_buf_t *)iocbq->sbp;
47
48 if (!sbp) {
49 HBASTATS.IpStray++;
50
51 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg,
52 "cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
52 (uint32_t)cmd->ulpCommand, (uint32_t)cmd->ulpIoTag,
53 cmd->ulpStatus, cmd->un.ulpWord[4]);
53 (uint32_t)cmd->ULPCOMMAND, (uint32_t)cmd->ULPIOTAG,
54 cmd->ULPSTATUS, cmd->un.ulpWord[4]);
54
55 return (EIO);
56 }
57
55
56 return (EIO);
57 }
58
58 if (rp->ringno != FC_IP_RING) {
59 if (cp->channelno != hba->channel_ip) {
59 HBASTATS.IpStray++;
60
61 return (0);
62 }
63
64 port = sbp->iocbq.port;
65
60 HBASTATS.IpStray++;
61
62 return (0);
63 }
64
65 port = sbp->iocbq.port;
66
66 switch (cmd->ulpCommand) {
67 switch (cmd->ULPCOMMAND) {
67 /*
68 * Error: Abnormal BCAST command completion (Local error)
69 */
70 case CMD_XMIT_BCAST_CN:
71 case CMD_XMIT_BCAST64_CN:
72
73 HBASTATS.IpBcastCompleted++;
74 HBASTATS.IpBcastError++;
75
76 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
77 "XMIT BCAST completion error cmd=0x%x status=0x%x "
68 /*
69 * Error: Abnormal BCAST command completion (Local error)
70 */
71 case CMD_XMIT_BCAST_CN:
72 case CMD_XMIT_BCAST64_CN:
73
74 HBASTATS.IpBcastCompleted++;
75 HBASTATS.IpBcastError++;
76
77 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
78 "XMIT BCAST completion error cmd=0x%x status=0x%x "
78 "[%08x,%08x]", cmd->ulpCommand, cmd->ulpStatus,
79 "[%08x,%08x]", cmd->ULPCOMMAND, cmd->ULPSTATUS,
79 cmd->un.ulpWord[4], cmd->un.ulpWord[5]);
80
80 cmd->un.ulpWord[4], cmd->un.ulpWord[5]);
81
81 emlxs_pkt_complete(sbp, cmd->ulpStatus,
82 emlxs_pkt_complete(sbp, cmd->ULPSTATUS,
82 cmd->un.grsp.perr.statLocalError, 1);
83
84 break;
85
86 /*
87 * Error: Abnormal XMIT SEQUENCE command completion
88 * (Local error)
89 */
90 case CMD_XMIT_SEQUENCE_CR:
91 case CMD_XMIT_SEQUENCE64_CR:
92
93 HBASTATS.IpSeqCompleted++;
94 HBASTATS.IpSeqError++;
95
96 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
97 "XMIT SEQUENCE CR completion error: cmd=%x status=0x%x "
83 cmd->un.grsp.perr.statLocalError, 1);
84
85 break;
86
87 /*
88 * Error: Abnormal XMIT SEQUENCE command completion
89 * (Local error)
90 */
91 case CMD_XMIT_SEQUENCE_CR:
92 case CMD_XMIT_SEQUENCE64_CR:
93
94 HBASTATS.IpSeqCompleted++;
95 HBASTATS.IpSeqError++;
96
97 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
98 "XMIT SEQUENCE CR completion error: cmd=%x status=0x%x "
98 "[%08x,%08x]", cmd->ulpCommand, cmd->ulpStatus,
99 "[%08x,%08x]", cmd->ULPCOMMAND, cmd->ULPSTATUS,
99 cmd->un.ulpWord[4], cmd->un.ulpWord[5]);
100
100 cmd->un.ulpWord[4], cmd->un.ulpWord[5]);
101
101 emlxs_pkt_complete(sbp, cmd->ulpStatus,
102 emlxs_pkt_complete(sbp, cmd->ULPSTATUS,
102 cmd->un.grsp.perr.statLocalError, 1);
103
104 break;
105
106 /*
107 * Normal BCAST completion
108 */
109 case CMD_XMIT_BCAST_CX:
110 case CMD_XMIT_BCAST64_CX:
111
112 HBASTATS.IpBcastCompleted++;
113 HBASTATS.IpBcastGood++;
114
115 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
116 "XMIT BCAST CN completion: cmd=%x status=0x%x [%08x,%08x]",
103 cmd->un.grsp.perr.statLocalError, 1);
104
105 break;
106
107 /*
108 * Normal BCAST completion
109 */
110 case CMD_XMIT_BCAST_CX:
111 case CMD_XMIT_BCAST64_CX:
112
113 HBASTATS.IpBcastCompleted++;
114 HBASTATS.IpBcastGood++;
115
116 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
117 "XMIT BCAST CN completion: cmd=%x status=0x%x [%08x,%08x]",
117 cmd->ulpCommand, cmd->ulpStatus, cmd->un.ulpWord[4],
118 cmd->ULPCOMMAND, cmd->ULPSTATUS, cmd->un.ulpWord[4],
118 cmd->un.ulpWord[5]);
119
119 cmd->un.ulpWord[5]);
120
120 emlxs_pkt_complete(sbp, cmd->ulpStatus,
121 emlxs_pkt_complete(sbp, cmd->ULPSTATUS,
121 cmd->un.grsp.perr.statLocalError, 1);
122
123 break;
124
125 /*
126 * Normal XMIT SEQUENCE completion
127 */
128 case CMD_XMIT_SEQUENCE_CX:
129 case CMD_XMIT_SEQUENCE64_CX:
130
131 HBASTATS.IpSeqCompleted++;
132
133 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
134 "XMIT SEQUENCE CR completion: cmd=%x status=0x%x"
122 cmd->un.grsp.perr.statLocalError, 1);
123
124 break;
125
126 /*
127 * Normal XMIT SEQUENCE completion
128 */
129 case CMD_XMIT_SEQUENCE_CX:
130 case CMD_XMIT_SEQUENCE64_CX:
131
132 HBASTATS.IpSeqCompleted++;
133
134 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
135 "XMIT SEQUENCE CR completion: cmd=%x status=0x%x"
135 "[%08x,%08x]", cmd->ulpCommand, cmd->ulpStatus,
136 "[%08x,%08x]", cmd->ULPCOMMAND, cmd->ULPSTATUS,
136 cmd->un.ulpWord[4], cmd->un.ulpWord[5]);
137
137 cmd->un.ulpWord[4], cmd->un.ulpWord[5]);
138
138 if (cmd->ulpStatus) {
139 if (cmd->ULPSTATUS) {
139 HBASTATS.IpSeqError++;
140
140 HBASTATS.IpSeqError++;
141
141 if ((cmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
142 if ((cmd->ULPSTATUS == IOSTAT_LOCAL_REJECT) &&
142 ((cmd->un.ulpWord[4] & 0xff) == IOERR_NO_XRI)) {
143 ndlp = (NODELIST *)sbp->node;
143 ((cmd->un.ulpWord[4] & 0xff) == IOERR_NO_XRI)) {
144 ndlp = (NODELIST *)sbp->node;
144 if ((cmd->ulpContext == ndlp->nlp_Xri) &&
145 !(ndlp->nlp_flag[FC_IP_RING] &
145 if ((cmd->ULPCONTEXT == ndlp->nlp_Xri) &&
146 !(ndlp->nlp_flag[hba->channel_ip] &
146 NLP_RPI_XRI)) {
147 ndlp->nlp_Xri = 0;
147 NLP_RPI_XRI)) {
148 ndlp->nlp_Xri = 0;
148 (void) emlxs_create_xri(port, rp, ndlp);
149 (void) emlxs_create_xri(port, cp, ndlp);
149 }
150 }
151 } else {
152 HBASTATS.IpSeqGood++;
153 }
154
150 }
151 }
152 } else {
153 HBASTATS.IpSeqGood++;
154 }
155
155 emlxs_pkt_complete(sbp, cmd->ulpStatus,
156 emlxs_pkt_complete(sbp, cmd->ULPSTATUS,
156 cmd->un.grsp.perr.statLocalError, 1);
157
158 break;
159
160 default:
161
162 HBASTATS.IpStray++;
163
164 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ip_msg,
157 cmd->un.grsp.perr.statLocalError, 1);
158
159 break;
160
161 default:
162
163 HBASTATS.IpStray++;
164
165 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ip_msg,
165 "Invalid iocb: cmd=0x%x", cmd->ulpCommand);
166 "Invalid iocb: cmd=0x%x", cmd->ULPCOMMAND);
166
167 break;
168
167
168 break;
169
169 } /* switch(cmd->ulpCommand) */
170 } /* switch(cmd->ULPCOMMAND) */
170
171
172 return (0);
173
171
172
173 return (0);
174
174} /* emlxs_ip_handle_event() */
175} /* emlxs_ip_handle_event() */
175
176
177extern int32_t
176
177
178extern int32_t
178emlxs_ip_handle_unsol_req(emlxs_port_t *port, RING *rp, IOCBQ *iocbq,
179emlxs_ip_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
179 MATCHMAP *mp, uint32_t size)
180{
181 emlxs_hba_t *hba = HBA;
182 fc_unsol_buf_t *ubp;
183 IOCB *cmd;
184 NETHDR *nd;
185 NODELIST *ndlp;
186 uint8_t *mac;

--- 22 unchanged lines hidden (view full) ---

209 if (!ubp) {
210 /* Theoretically we should never get here. */
211 /* There should be one DMA buffer for every ub */
212 /* buffer. If we are out of ub buffers */
213 /* then some how this matching has been corrupted */
214
215 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ip_dropped_msg,
216 "Buffer not found. paddr=%lx",
180 MATCHMAP *mp, uint32_t size)
181{
182 emlxs_hba_t *hba = HBA;
183 fc_unsol_buf_t *ubp;
184 IOCB *cmd;
185 NETHDR *nd;
186 NODELIST *ndlp;
187 uint8_t *mac;

--- 22 unchanged lines hidden (view full) ---

210 if (!ubp) {
211 /* Theoretically we should never get here. */
212 /* There should be one DMA buffer for every ub */
213 /* buffer. If we are out of ub buffers */
214 /* then some how this matching has been corrupted */
215
216 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ip_dropped_msg,
217 "Buffer not found. paddr=%lx",
217 getPaddr(cmd->un.cont64[0].addrHigh,
218 PADDR(cmd->un.cont64[0].addrHigh,
218 cmd->un.cont64[0].addrLow));
219
220 continue;
221 }
222
223 bcopy(mp->virt, ubp->ub_buffer, size);
224
225 ub_priv = ubp->ub_fca_private;
226 nd = (NETHDR *)ubp->ub_buffer;
227 mac = nd->fc_srcname.IEEE;
228 ndlp = emlxs_node_find_mac(port, mac);
229
230 if (ndlp) {
231 sid = ndlp->nlp_DID;
232
233 if ((ndlp->nlp_Xri == 0) &&
219 cmd->un.cont64[0].addrLow));
220
221 continue;
222 }
223
224 bcopy(mp->virt, ubp->ub_buffer, size);
225
226 ub_priv = ubp->ub_fca_private;
227 nd = (NETHDR *)ubp->ub_buffer;
228 mac = nd->fc_srcname.IEEE;
229 ndlp = emlxs_node_find_mac(port, mac);
230
231 if (ndlp) {
232 sid = ndlp->nlp_DID;
233
234 if ((ndlp->nlp_Xri == 0) &&
234 !(ndlp->nlp_flag[FC_IP_RING] & NLP_RPI_XRI)) {
235 (void) emlxs_create_xri(port, rp, ndlp);
235 !(ndlp->nlp_flag[hba->channel_ip] & NLP_RPI_XRI)) {
236 (void) emlxs_create_xri(port, cp, ndlp);
236 }
237 }
238
239 /*
240 * If no node is found, then check if this is a
241 * broadcast frame
242 */
243 else if (cmd->un.xrseq.w5.hcsw.Fctl & BC) {

--- 21 unchanged lines hidden (view full) ---

265
266 /*
267 * Setup frame header
268 */
269 ubp->ub_frame.r_ctl = cmd->un.xrseq.w5.hcsw.Rctl;
270 ubp->ub_frame.type = cmd->un.xrseq.w5.hcsw.Type;
271 ubp->ub_frame.s_id = sid;
272 ubp->ub_frame.ox_id = ub_priv->token;
237 }
238 }
239
240 /*
241 * If no node is found, then check if this is a
242 * broadcast frame
243 */
244 else if (cmd->un.xrseq.w5.hcsw.Fctl & BC) {

--- 21 unchanged lines hidden (view full) ---

266
267 /*
268 * Setup frame header
269 */
270 ubp->ub_frame.r_ctl = cmd->un.xrseq.w5.hcsw.Rctl;
271 ubp->ub_frame.type = cmd->un.xrseq.w5.hcsw.Type;
272 ubp->ub_frame.s_id = sid;
273 ubp->ub_frame.ox_id = ub_priv->token;
273 ubp->ub_frame.rx_id = cmd->ulpContext;
274 ubp->ub_frame.rx_id = cmd->ULPCONTEXT;
274 ubp->ub_class = FC_TRAN_CLASS3;
275
276 emlxs_ub_callback(port, ubp);
277 IpDropped = 0;
278 }
279 port = &PPORT;
280
281out:

--- 7 unchanged lines hidden (view full) ---

289 }
290
291 if (IpSeqReceived) {
292 HBASTATS.IpSeqReceived++;
293 }
294
295 return (0);
296
275 ubp->ub_class = FC_TRAN_CLASS3;
276
277 emlxs_ub_callback(port, ubp);
278 IpDropped = 0;
279 }
280 port = &PPORT;
281
282out:

--- 7 unchanged lines hidden (view full) ---

290 }
291
292 if (IpSeqReceived) {
293 HBASTATS.IpSeqReceived++;
294 }
295
296 return (0);
297
297} /* emlxs_ip_handle_unsol_req() */
298} /* emlxs_ip_handle_unsol_req() */
298
299
300extern int32_t
299
300
301extern int32_t
301emlxs_ip_handle_rcv_seq_list(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq)
302emlxs_ip_handle_rcv_seq_list(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
302{
303 emlxs_port_t *port = &PPORT;
304 IOCB *cmd;
305 uint64_t bdeAddr;
306 MATCHMAP *mp = NULL;
303{
304 emlxs_port_t *port = &PPORT;
305 IOCB *cmd;
306 uint64_t bdeAddr;
307 MATCHMAP *mp = NULL;
307#ifdef SLI3_SUPPORT
308 HBQE_t *hbqE;
309 uint32_t hbq_id;
310 uint32_t hbqe_tag;
308 HBQE_t *hbqE;
309 uint32_t hbq_id;
310 uint32_t hbqe_tag;
311#endif /* SLI3_SUPPORT */
311 RING *rp;
312
313 /*
314 * No action required for now.
315 */
316 cmd = &iocbq->iocb;
312
313 /*
314 * No action required for now.
315 */
316 cmd = &iocbq->iocb;
317 rp = &hba->sli.sli3.ring[cp->channelno];
317
318 HBASTATS.IpRcvEvent++;
319
320 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
321 "Receive sequence list: cmd=0x%x iotag=0x%x status=0x%x "
318
319 HBASTATS.IpRcvEvent++;
320
321 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
322 "Receive sequence list: cmd=0x%x iotag=0x%x status=0x%x "
322 "w4=0x%x ringno=0x%x", cmd->ulpCommand, cmd->ulpIoTag,
323 cmd->ulpStatus, cmd->un.ulpWord[4], rp->ringno);
323 "w4=0x%x channelno=0x%x", cmd->ULPCOMMAND, cmd->ULPIOTAG,
324 cmd->ULPSTATUS, cmd->un.ulpWord[4], cp->channelno);
324
325
325 if (cmd->ulpStatus) {
326 if (cmd->ULPSTATUS) {
326 goto out;
327 }
327 goto out;
328 }
328#ifdef SLI3_SUPPORT
329
329 hbqE = (HBQE_t *)&iocbq->iocb;
330 hbq_id = hbqE->unt.ext.HBQ_tag;
331 hbqe_tag = hbqE->unt.ext.HBQE_tag;
332
333 if (hba->flag & FC_HBQ_ENABLED) {
334 HBQ_INIT_t *hbq;
335
330 hbqE = (HBQE_t *)&iocbq->iocb;
331 hbq_id = hbqE->unt.ext.HBQ_tag;
332 hbqe_tag = hbqE->unt.ext.HBQE_tag;
333
334 if (hba->flag & FC_HBQ_ENABLED) {
335 HBQ_INIT_t *hbq;
336
336 hbq = &hba->hbq_table[hbq_id];
337 hbq = &hba->sli.sli3.hbq_table[hbq_id];
337
338 HBASTATS.IpUbPosted--;
339
340 if (hbqe_tag >= hbq->HBQ_numEntries) {
341 mp = NULL;
342 } else {
338
339 HBASTATS.IpUbPosted--;
340
341 if (hbqe_tag >= hbq->HBQ_numEntries) {
342 mp = NULL;
343 } else {
343 mp = hba->hbq_table[hbq_id].HBQ_PostBufs[hbqe_tag];
344 mp = hba->sli.sli3.hbq_table
345 [hbq_id].HBQ_PostBufs[hbqe_tag];
344 }
346 }
345 } else
346#endif /* SLI3_SUPPORT */
347 {
347 } else {
348 /* Check for valid buffer */
349 if (!(cmd->un.cont64[0].tus.f.bdeFlags & BUFF_TYPE_INVALID)) {
350 bdeAddr =
348 /* Check for valid buffer */
349 if (!(cmd->un.cont64[0].tus.f.bdeFlags & BUFF_TYPE_INVALID)) {
350 bdeAddr =
351 getPaddr(cmd->un.cont64[0].addrHigh,
351 PADDR(cmd->un.cont64[0].addrHigh,
352 cmd->un.cont64[0].addrLow);
353 mp = emlxs_mem_get_vaddr(hba, rp, bdeAddr);
354 }
355 }
356
357out:
358
352 cmd->un.cont64[0].addrLow);
353 mp = emlxs_mem_get_vaddr(hba, rp, bdeAddr);
354 }
355 }
356
357out:
358
359#ifdef SLI3_SUPPORT
360 if (hba->flag & FC_HBQ_ENABLED) {
361 emlxs_update_HBQ_index(hba, hbq_id);
359 if (hba->flag & FC_HBQ_ENABLED) {
360 emlxs_update_HBQ_index(hba, hbq_id);
362 } else
363#endif /* SLI3_SUPPORT */
364 {
361 } else {
365 if (mp) {
366 (void) emlxs_mem_put(hba, MEM_IPBUF, (uint8_t *)mp);
367 }
368 (void) emlxs_post_buffer(hba, rp, 1);
369 }
370
371 HBASTATS.IpDropped++;
372
373 return (0);
374
362 if (mp) {
363 (void) emlxs_mem_put(hba, MEM_IPBUF, (uint8_t *)mp);
364 }
365 (void) emlxs_post_buffer(hba, rp, 1);
366 }
367
368 HBASTATS.IpDropped++;
369
370 return (0);
371
375} /* emlxs_ip_handle_rcv_seq_list() */
372} /* emlxs_ip_handle_rcv_seq_list() */
376
377
378
379/*
380 * Process a create_xri command completion.
381 */
382extern int32_t
373
374
375
376/*
377 * Process a create_xri command completion.
378 */
379extern int32_t
383emlxs_handle_create_xri(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq)
380emlxs_handle_create_xri(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
384{
385 emlxs_port_t *port = &PPORT;
386 IOCB *cmd;
387 NODELIST *ndlp;
388 fc_packet_t *pkt;
389 emlxs_buf_t *sbp;
390
391 cmd = &iocbq->iocb;
392
393 sbp = (emlxs_buf_t *)iocbq->sbp;
394
395 if (!sbp) {
396 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg,
397 "create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x",
381{
382 emlxs_port_t *port = &PPORT;
383 IOCB *cmd;
384 NODELIST *ndlp;
385 fc_packet_t *pkt;
386 emlxs_buf_t *sbp;
387
388 cmd = &iocbq->iocb;
389
390 sbp = (emlxs_buf_t *)iocbq->sbp;
391
392 if (!sbp) {
393 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ip_completion_msg,
394 "create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x",
398 cmd->ulpCommand, cmd->ulpIoTag, cmd->ulpStatus,
395 cmd->ULPCOMMAND, cmd->ULPIOTAG, cmd->ULPSTATUS,
399 cmd->un.ulpWord[4]);
400
401 return (EIO);
402 }
403
404 /* check for first xmit completion in sequence */
405 ndlp = (NODELIST *)sbp->node;
406
396 cmd->un.ulpWord[4]);
397
398 return (EIO);
399 }
400
401 /* check for first xmit completion in sequence */
402 ndlp = (NODELIST *)sbp->node;
403
407 if (cmd->ulpStatus) {
404 if (cmd->ULPSTATUS) {
408 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_bad_ip_completion_msg,
409 "create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x",
405 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_bad_ip_completion_msg,
406 "create_xri: cmd=0x%x iotag=0x%x status=0x%x w4=0x%x",
410 cmd->ulpCommand, cmd->ulpIoTag, cmd->ulpStatus,
407 cmd->ULPCOMMAND, cmd->ULPIOTAG, cmd->ULPSTATUS,
411 cmd->un.ulpWord[4]);
412
408 cmd->un.ulpWord[4]);
409
413 mutex_enter(&EMLXS_RINGTX_LOCK);
414 ndlp->nlp_flag[rp->ringno] &= ~NLP_RPI_XRI;
415 mutex_exit(&EMLXS_RINGTX_LOCK);
410 mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
411 ndlp->nlp_flag[cp->channelno] &= ~NLP_RPI_XRI;
412 mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
416
417 return (EIO);
418 }
419
413
414 return (EIO);
415 }
416
420 mutex_enter(&EMLXS_RINGTX_LOCK);
421 ndlp->nlp_Xri = cmd->ulpContext;
422 ndlp->nlp_flag[rp->ringno] &= ~NLP_RPI_XRI;
423 mutex_exit(&EMLXS_RINGTX_LOCK);
417 mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
418 ndlp->nlp_Xri = cmd->ULPCONTEXT;
419 ndlp->nlp_flag[cp->channelno] &= ~NLP_RPI_XRI;
420 mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
424
425 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
426 "create_xri completed: DID=0x%x Xri=0x%x iotag=0x%x",
421
422 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
423 "create_xri completed: DID=0x%x Xri=0x%x iotag=0x%x",
427 ndlp->nlp_DID, ndlp->nlp_Xri, cmd->ulpIoTag);
424 ndlp->nlp_DID, ndlp->nlp_Xri, cmd->ULPIOTAG);
428
429 pkt = sbp->pkt;
430 emlxs_pkt_free(pkt);
431
432 return (0);
433
425
426 pkt = sbp->pkt;
427 emlxs_pkt_free(pkt);
428
429 return (0);
430
434} /* emlxs_handle_create_xri() */
431} /* emlxs_handle_create_xri() */
435
436
437/*
438 * Issue an iocb command to create an exchange with the remote Nport
439 * specified by the NODELIST entry.
440 */
441extern int32_t
432
433
434/*
435 * Issue an iocb command to create an exchange with the remote Nport
436 * specified by the NODELIST entry.
437 */
438extern int32_t
442emlxs_create_xri(emlxs_port_t *port, RING *rp, NODELIST *ndlp)
439emlxs_create_xri(emlxs_port_t *port, CHANNEL *cp, NODELIST *ndlp)
443{
444 emlxs_hba_t *hba = HBA;
445 IOCB *icmd;
446 IOCBQ *iocbq;
447 fc_packet_t *pkt;
448 emlxs_buf_t *sbp;
449 uint16_t iotag;
450
451 /* Check if an XRI has already been requested */
440{
441 emlxs_hba_t *hba = HBA;
442 IOCB *icmd;
443 IOCBQ *iocbq;
444 fc_packet_t *pkt;
445 emlxs_buf_t *sbp;
446 uint16_t iotag;
447
448 /* Check if an XRI has already been requested */
452 mutex_enter(&EMLXS_RINGTX_LOCK);
453 if (ndlp->nlp_Xri != 0 || (ndlp->nlp_flag[rp->ringno] & NLP_RPI_XRI)) {
454 mutex_exit(&EMLXS_RINGTX_LOCK);
449 mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
450 if (ndlp->nlp_Xri != 0 ||
451 (ndlp->nlp_flag[cp->channelno] & NLP_RPI_XRI)) {
452 mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
455 return (0);
456 }
453 return (0);
454 }
457 ndlp->nlp_flag[rp->ringno] |= NLP_RPI_XRI;
458 mutex_exit(&EMLXS_RINGTX_LOCK);
455 ndlp->nlp_flag[cp->channelno] |= NLP_RPI_XRI;
456 mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
459
460 if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) {
461 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
462 "create_xri failed: Unable to allocate pkt. did=0x%x",
463 ndlp->nlp_DID);
464
465 goto fail;
466 }
467
468 sbp = (emlxs_buf_t *)pkt->pkt_fca_private;
469 iocbq = &sbp->iocbq;
470
457
458 if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) {
459 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
460 "create_xri failed: Unable to allocate pkt. did=0x%x",
461 ndlp->nlp_DID);
462
463 goto fail;
464 }
465
466 sbp = (emlxs_buf_t *)pkt->pkt_fca_private;
467 iocbq = &sbp->iocbq;
468
469 /* Clear the PACKET_ULP_OWNED flag */
470 sbp->pkt_flags &= ~PACKET_ULP_OWNED;
471
471 /* Get the iotag by registering the packet */
472 /* Get the iotag by registering the packet */
472 iotag = emlxs_register_pkt(rp, sbp);
473 iotag = emlxs_register_pkt(cp, sbp);
473
474 if (!iotag) {
475 /*
476 * No more command slots available, retry later
477 */
478 emlxs_pkt_free(pkt);
479
480 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
481 "create_xri failed: Unable to allocate IOTAG. did=0x%x",
482 ndlp->nlp_DID);
483
484 goto fail;
485 }
486
487 icmd = &iocbq->iocb;
474
475 if (!iotag) {
476 /*
477 * No more command slots available, retry later
478 */
479 emlxs_pkt_free(pkt);
480
481 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
482 "create_xri failed: Unable to allocate IOTAG. did=0x%x",
483 ndlp->nlp_DID);
484
485 goto fail;
486 }
487
488 icmd = &iocbq->iocb;
488 icmd->ulpIoTag = iotag;
489 icmd->ulpContext = ndlp->nlp_Rpi;
490 icmd->ulpLe = 1;
491 icmd->ulpCommand = CMD_CREATE_XRI_CR;
492 icmd->ulpOwner = OWN_CHIP;
489 icmd->ULPIOTAG = iotag;
490 icmd->ULPCONTEXT = ndlp->nlp_Rpi;
491 icmd->ULPLE = 1;
492 icmd->ULPCOMMAND = CMD_CREATE_XRI_CR;
493 icmd->ULPOWNER = OWN_CHIP;
493
494 /* Initalize iocbq */
495 iocbq->port = (void *)port;
496 iocbq->node = (void *)ndlp;
494
495 /* Initalize iocbq */
496 iocbq->port = (void *)port;
497 iocbq->node = (void *)ndlp;
497 iocbq->ring = (void *)rp;
498 iocbq->channel = (void *)cp;
498
499 mutex_enter(&sbp->mtx);
500 sbp->node = (void *)ndlp;
499
500 mutex_enter(&sbp->mtx);
501 sbp->node = (void *)ndlp;
501 sbp->ring = rp;
502 sbp->channel = cp;
502 mutex_exit(&sbp->mtx);
503
504 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
505 "create_xri sent: DID=0x%x Xri=0x%x iotag=0x%x", ndlp->nlp_DID,
506 ndlp->nlp_Xri, iotag);
507
503 mutex_exit(&sbp->mtx);
504
505 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ip_detail_msg,
506 "create_xri sent: DID=0x%x Xri=0x%x iotag=0x%x", ndlp->nlp_DID,
507 ndlp->nlp_Xri, iotag);
508
508 emlxs_sli_issue_iocb_cmd(hba, rp, iocbq);
509 EMLXS_SLI_ISSUE_IOCB_CMD(hba, cp, iocbq);
509
510 return (0);
511
512fail:
513
514 /* Clear the XRI flag */
510
511 return (0);
512
513fail:
514
515 /* Clear the XRI flag */
515 mutex_enter(&EMLXS_RINGTX_LOCK);
516 ndlp->nlp_flag[rp->ringno] &= ~NLP_RPI_XRI;
517 mutex_exit(&EMLXS_RINGTX_LOCK);
516 mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
517 ndlp->nlp_flag[cp->channelno] &= ~NLP_RPI_XRI;
518 mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
518
519 return (1);
520
519
520 return (1);
521
521} /* emlxs_create_xri() */
522} /* emlxs_create_xri() */