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() */ |