1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte * CDDL HEADER START
3fcf3ce44SJohn Forte *
4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte *
8*8f23e9faSHans Rosenfeld * You can obtain a copy of the license at
9*8f23e9faSHans Rosenfeld * http://www.opensource.org/licenses/cddl1.txt.
10fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte * and limitations under the License.
12fcf3ce44SJohn Forte *
13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte *
19fcf3ce44SJohn Forte * CDDL HEADER END
20fcf3ce44SJohn Forte */
21fcf3ce44SJohn Forte
22fcf3ce44SJohn Forte /*
23*8f23e9faSHans Rosenfeld * Copyright (c) 2004-2011 Emulex. All rights reserved.
2482527734SSukumar Swaminathan * Use is subject to license terms.
25fcf3ce44SJohn Forte */
26fcf3ce44SJohn Forte
27291a2b48SSukumar Swaminathan #include <emlxs.h>
28fcf3ce44SJohn Forte
29fcf3ce44SJohn Forte
30fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
31fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_NODE_C);
32fcf3ce44SJohn Forte
33*8f23e9faSHans Rosenfeld static void emlxs_node_add(emlxs_port_t *, NODELIST *);
34*8f23e9faSHans Rosenfeld static int emlxs_node_match_did(emlxs_port_t *, NODELIST *, uint32_t);
35*8f23e9faSHans Rosenfeld
36291a2b48SSukumar Swaminathan /* Timeout == -1 will enable the offline timer */
3782527734SSukumar Swaminathan /* Timeout not -1 will apply the timeout */
38fcf3ce44SJohn Forte extern void
emlxs_node_close(emlxs_port_t * port,NODELIST * ndlp,uint32_t channelno,int32_t timeout)3982527734SSukumar Swaminathan emlxs_node_close(emlxs_port_t *port, NODELIST *ndlp, uint32_t channelno,
40291a2b48SSukumar Swaminathan int32_t timeout)
41fcf3ce44SJohn Forte {
42fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
43291a2b48SSukumar Swaminathan emlxs_config_t *cfg = &CFG;
4482527734SSukumar Swaminathan CHANNEL *cp;
45fcf3ce44SJohn Forte NODELIST *prev;
46291a2b48SSukumar Swaminathan uint32_t offline = 0;
47fcf3ce44SJohn Forte
4882527734SSukumar Swaminathan
4982527734SSukumar Swaminathan /* If node is on a channel service queue, then remove it */
5082527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
51fcf3ce44SJohn Forte
52fcf3ce44SJohn Forte /* Return if node destroyed */
53fcf3ce44SJohn Forte if (!ndlp || !ndlp->nlp_active) {
5482527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
55fcf3ce44SJohn Forte
56fcf3ce44SJohn Forte return;
57fcf3ce44SJohn Forte }
58291a2b48SSukumar Swaminathan
59291a2b48SSukumar Swaminathan /* Check offline support */
60291a2b48SSukumar Swaminathan if (timeout == -1) {
61291a2b48SSukumar Swaminathan if (cfg[CFG_OFFLINE_TIMEOUT].current) {
62291a2b48SSukumar Swaminathan timeout = cfg[CFG_OFFLINE_TIMEOUT].current;
63291a2b48SSukumar Swaminathan offline = 1;
64291a2b48SSukumar Swaminathan } else {
65291a2b48SSukumar Swaminathan timeout = 0;
66291a2b48SSukumar Swaminathan }
67291a2b48SSukumar Swaminathan }
68291a2b48SSukumar Swaminathan
6982527734SSukumar Swaminathan if (channelno == hba->channel_ip) {
70fcf3ce44SJohn Forte /* Clear IP XRI */
71fcf3ce44SJohn Forte ndlp->nlp_Xri = 0;
72fcf3ce44SJohn Forte }
73291a2b48SSukumar Swaminathan
74fcf3ce44SJohn Forte /* Check if node is already closed */
7582527734SSukumar Swaminathan if (ndlp->nlp_flag[channelno] & NLP_CLOSED) {
7682527734SSukumar Swaminathan if (ndlp->nlp_flag[channelno] & NLP_OFFLINE) {
7782527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
78291a2b48SSukumar Swaminathan return;
79291a2b48SSukumar Swaminathan }
80291a2b48SSukumar Swaminathan
81291a2b48SSukumar Swaminathan if (offline) {
8282527734SSukumar Swaminathan ndlp->nlp_tics[channelno] = hba->timer_tics + timeout;
8382527734SSukumar Swaminathan ndlp->nlp_flag[channelno] |= NLP_OFFLINE;
8482527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
85291a2b48SSukumar Swaminathan
86291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_closed_msg,
87fe199829SSukumar Swaminathan "node=%p did=%06x channel=%d. offline=%d update.",
8882527734SSukumar Swaminathan ndlp, ndlp->nlp_DID, channelno, timeout);
89291a2b48SSukumar Swaminathan
90291a2b48SSukumar Swaminathan } else if (timeout) {
9182527734SSukumar Swaminathan ndlp->nlp_tics[channelno] = hba->timer_tics + timeout;
9282527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
93291a2b48SSukumar Swaminathan
94291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_closed_msg,
95fe199829SSukumar Swaminathan "node=%p did=%06x channel=%d. timeout=%d update.",
9682527734SSukumar Swaminathan ndlp, ndlp->nlp_DID, channelno, timeout);
97291a2b48SSukumar Swaminathan } else {
9882527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
99fcf3ce44SJohn Forte }
100fcf3ce44SJohn Forte
101fcf3ce44SJohn Forte return;
102fcf3ce44SJohn Forte }
103291a2b48SSukumar Swaminathan
104fcf3ce44SJohn Forte /* Set the node closed */
10582527734SSukumar Swaminathan ndlp->nlp_flag[channelno] |= NLP_CLOSED;
106fcf3ce44SJohn Forte
107291a2b48SSukumar Swaminathan if (offline) {
10882527734SSukumar Swaminathan ndlp->nlp_tics[channelno] = hba->timer_tics + timeout;
10982527734SSukumar Swaminathan ndlp->nlp_flag[channelno] |= NLP_OFFLINE;
110291a2b48SSukumar Swaminathan
111fe199829SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_closed_msg,
112fe199829SSukumar Swaminathan "node=%p did=%06x channel=%d. offline=%d set.",
113fe199829SSukumar Swaminathan ndlp, ndlp->nlp_DID, channelno, timeout);
114fe199829SSukumar Swaminathan
115291a2b48SSukumar Swaminathan } else if (timeout) {
11682527734SSukumar Swaminathan ndlp->nlp_tics[channelno] = hba->timer_tics + timeout;
117fe199829SSukumar Swaminathan
118fe199829SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_closed_msg,
119fe199829SSukumar Swaminathan "node=%p did=%06x channel=%d. timeout=%d set.",
120fe199829SSukumar Swaminathan ndlp, ndlp->nlp_DID, channelno, timeout);
121fe199829SSukumar Swaminathan } else {
122fe199829SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_closed_msg,
123fe199829SSukumar Swaminathan "node=%p did=%06x channel=%d.",
124fe199829SSukumar Swaminathan ndlp, ndlp->nlp_DID, channelno);
125fcf3ce44SJohn Forte }
126fcf3ce44SJohn Forte
12782527734SSukumar Swaminathan
12882527734SSukumar Swaminathan /*
12982527734SSukumar Swaminathan * ndlp->nlp_next[] and cp->nodeq list have to be updated
13082527734SSukumar Swaminathan * simulaneously
13182527734SSukumar Swaminathan */
13282527734SSukumar Swaminathan if (ndlp->nlp_next[channelno]) {
13382527734SSukumar Swaminathan /* Remove node from channel queue */
13482527734SSukumar Swaminathan cp = &hba->chan[channelno];
135fcf3ce44SJohn Forte
136fcf3ce44SJohn Forte /* If this is the only node on list */
13782527734SSukumar Swaminathan if (cp->nodeq.q_first == (void *)ndlp &&
13882527734SSukumar Swaminathan cp->nodeq.q_last == (void *)ndlp) {
13982527734SSukumar Swaminathan cp->nodeq.q_last = NULL;
14082527734SSukumar Swaminathan cp->nodeq.q_first = NULL;
14182527734SSukumar Swaminathan cp->nodeq.q_cnt = 0;
14282527734SSukumar Swaminathan } else if (cp->nodeq.q_first == (void *)ndlp) {
14382527734SSukumar Swaminathan cp->nodeq.q_first = ndlp->nlp_next[channelno];
14482527734SSukumar Swaminathan ((NODELIST *)cp->nodeq.q_last)->nlp_next[channelno] =
14582527734SSukumar Swaminathan cp->nodeq.q_first;
14682527734SSukumar Swaminathan cp->nodeq.q_cnt--;
147fcf3ce44SJohn Forte } else { /* This is a little more difficult */
148291a2b48SSukumar Swaminathan
14982527734SSukumar Swaminathan /* Find the previous node in circular channel queue */
150fcf3ce44SJohn Forte prev = ndlp;
15182527734SSukumar Swaminathan while (prev->nlp_next[channelno] != ndlp) {
15282527734SSukumar Swaminathan prev = prev->nlp_next[channelno];
153fcf3ce44SJohn Forte }
154fcf3ce44SJohn Forte
15582527734SSukumar Swaminathan prev->nlp_next[channelno] = ndlp->nlp_next[channelno];
156fcf3ce44SJohn Forte
15782527734SSukumar Swaminathan if (cp->nodeq.q_last == (void *)ndlp) {
15882527734SSukumar Swaminathan cp->nodeq.q_last = (void *)prev;
159fcf3ce44SJohn Forte }
16082527734SSukumar Swaminathan cp->nodeq.q_cnt--;
161fcf3ce44SJohn Forte
162fcf3ce44SJohn Forte }
163fcf3ce44SJohn Forte
164fcf3ce44SJohn Forte /* Clear node */
16582527734SSukumar Swaminathan ndlp->nlp_next[channelno] = NULL;
166fcf3ce44SJohn Forte }
167291a2b48SSukumar Swaminathan
16882527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
169728bdc9bSSukumar Swaminathan
170291a2b48SSukumar Swaminathan return;
171291a2b48SSukumar Swaminathan
17282527734SSukumar Swaminathan } /* emlxs_node_close() */
173291a2b48SSukumar Swaminathan
174291a2b48SSukumar Swaminathan
175291a2b48SSukumar Swaminathan /* Called by emlxs_timer_check_nodes() */
176291a2b48SSukumar Swaminathan extern void
emlxs_node_timeout(emlxs_port_t * port,NODELIST * ndlp,uint32_t channelno)17782527734SSukumar Swaminathan emlxs_node_timeout(emlxs_port_t *port, NODELIST *ndlp, uint32_t channelno)
178291a2b48SSukumar Swaminathan {
179291a2b48SSukumar Swaminathan emlxs_hba_t *hba = HBA;
180291a2b48SSukumar Swaminathan
18182527734SSukumar Swaminathan /* If node needs servicing, then add it to the channel queues */
18282527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
183291a2b48SSukumar Swaminathan
184291a2b48SSukumar Swaminathan /* Return if node destroyed */
185291a2b48SSukumar Swaminathan if (!ndlp || !ndlp->nlp_active) {
18682527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
187291a2b48SSukumar Swaminathan return;
188291a2b48SSukumar Swaminathan }
189291a2b48SSukumar Swaminathan
190291a2b48SSukumar Swaminathan /* Open the node if not offline */
19182527734SSukumar Swaminathan if (!(ndlp->nlp_flag[channelno] & NLP_OFFLINE)) {
19282527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
193291a2b48SSukumar Swaminathan
194291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_timeout_msg,
19582527734SSukumar Swaminathan "node=%p did=%06x channel=%d Opening.", ndlp, ndlp->nlp_DID,
19682527734SSukumar Swaminathan channelno);
197291a2b48SSukumar Swaminathan
19882527734SSukumar Swaminathan emlxs_node_open(port, ndlp, channelno);
199291a2b48SSukumar Swaminathan return;
200728bdc9bSSukumar Swaminathan }
201fcf3ce44SJohn Forte
202291a2b48SSukumar Swaminathan /* OFFLINE TIMEOUT OCCURRED! */
203291a2b48SSukumar Swaminathan
204291a2b48SSukumar Swaminathan /* Clear the timer */
20582527734SSukumar Swaminathan ndlp->nlp_tics[channelno] = 0;
206291a2b48SSukumar Swaminathan
20782527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
208291a2b48SSukumar Swaminathan
209291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_timeout_msg,
210a9800bebSGarrett D'Amore "node=%p did=%06x channel=%d. Flushing.", ndlp, ndlp->nlp_DID,
21182527734SSukumar Swaminathan channelno);
212291a2b48SSukumar Swaminathan
21382527734SSukumar Swaminathan /* Flush tx queue for this channel */
21482527734SSukumar Swaminathan (void) emlxs_tx_node_flush(port, ndlp, &hba->chan[channelno], 0, 0);
215291a2b48SSukumar Swaminathan
21682527734SSukumar Swaminathan /* Flush chip queue for this channel */
21782527734SSukumar Swaminathan (void) emlxs_chipq_node_flush(port, &hba->chan[channelno], ndlp, 0);
218291a2b48SSukumar Swaminathan
219fcf3ce44SJohn Forte return;
220fcf3ce44SJohn Forte
22182527734SSukumar Swaminathan } /* emlxs_node_timeout() */
222fcf3ce44SJohn Forte
223fcf3ce44SJohn Forte
224fcf3ce44SJohn Forte extern void
emlxs_node_open(emlxs_port_t * port,NODELIST * ndlp,uint32_t channelno)22582527734SSukumar Swaminathan emlxs_node_open(emlxs_port_t *port, NODELIST *ndlp, uint32_t channelno)
226fcf3ce44SJohn Forte {
227fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
22882527734SSukumar Swaminathan CHANNEL *cp;
229fcf3ce44SJohn Forte uint32_t found;
230fcf3ce44SJohn Forte NODELIST *nlp;
231fcf3ce44SJohn Forte MAILBOXQ *mbox;
232fcf3ce44SJohn Forte uint32_t i;
23382527734SSukumar Swaminathan int rc;
234fcf3ce44SJohn Forte
23582527734SSukumar Swaminathan /* If node needs servicing, then add it to the channel queues */
23682527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
237fcf3ce44SJohn Forte
238fcf3ce44SJohn Forte /* Return if node destroyed */
239fcf3ce44SJohn Forte if (!ndlp || !ndlp->nlp_active) {
24082527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
241fcf3ce44SJohn Forte
242fcf3ce44SJohn Forte return;
243fcf3ce44SJohn Forte }
244291a2b48SSukumar Swaminathan
245fcf3ce44SJohn Forte /* Return if node already open */
24682527734SSukumar Swaminathan if (!(ndlp->nlp_flag[channelno] & NLP_CLOSED)) {
24782527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
248fcf3ce44SJohn Forte
249fcf3ce44SJohn Forte return;
250fcf3ce44SJohn Forte }
251fcf3ce44SJohn Forte
252291a2b48SSukumar Swaminathan /* Set the node open (not closed) */
25382527734SSukumar Swaminathan ndlp->nlp_flag[channelno] &= ~(NLP_CLOSED|NLP_OFFLINE);
254fcf3ce44SJohn Forte
255fcf3ce44SJohn Forte /* Clear the timer */
25682527734SSukumar Swaminathan ndlp->nlp_tics[channelno] = 0;
257fcf3ce44SJohn Forte
258fcf3ce44SJohn Forte /*
259291a2b48SSukumar Swaminathan * If the ptx or the tx queue needs servicing and
26082527734SSukumar Swaminathan * the node is not already on the channel queue
261fcf3ce44SJohn Forte */
26282527734SSukumar Swaminathan if ((ndlp->nlp_ptx[channelno].q_first ||
26382527734SSukumar Swaminathan ndlp->nlp_tx[channelno].q_first) && !ndlp->nlp_next[channelno]) {
26482527734SSukumar Swaminathan cp = &hba->chan[channelno];
265fcf3ce44SJohn Forte
26682527734SSukumar Swaminathan /* If so, then add it to the channel queue */
26782527734SSukumar Swaminathan if (cp->nodeq.q_first) {
26882527734SSukumar Swaminathan ((NODELIST *)cp->nodeq.q_last)->nlp_next[channelno] =
269fcf3ce44SJohn Forte (uint8_t *)ndlp;
27082527734SSukumar Swaminathan ndlp->nlp_next[channelno] = cp->nodeq.q_first;
271fcf3ce44SJohn Forte
272291a2b48SSukumar Swaminathan /* If this is not the base node then */
273291a2b48SSukumar Swaminathan /* add it to the tail */
274fcf3ce44SJohn Forte if (!ndlp->nlp_base) {
27582527734SSukumar Swaminathan cp->nodeq.q_last = (uint8_t *)ndlp;
276fcf3ce44SJohn Forte } else { /* Otherwise, add it to the head */
277291a2b48SSukumar Swaminathan
278fcf3ce44SJohn Forte /* The command node always gets priority */
27982527734SSukumar Swaminathan cp->nodeq.q_first = (uint8_t *)ndlp;
280fcf3ce44SJohn Forte }
281fcf3ce44SJohn Forte
28282527734SSukumar Swaminathan cp->nodeq.q_cnt++;
283fcf3ce44SJohn Forte } else {
28482527734SSukumar Swaminathan cp->nodeq.q_first = (uint8_t *)ndlp;
28582527734SSukumar Swaminathan cp->nodeq.q_last = (uint8_t *)ndlp;
28682527734SSukumar Swaminathan ndlp->nlp_next[channelno] = ndlp;
28782527734SSukumar Swaminathan cp->nodeq.q_cnt = 1;
288fcf3ce44SJohn Forte }
289fcf3ce44SJohn Forte }
290291a2b48SSukumar Swaminathan
29182527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
292fcf3ce44SJohn Forte
293291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_opened_msg,
294*8f23e9faSHans Rosenfeld "node=%p did=%06x rpi=%d channel=%d", ndlp, ndlp->nlp_DID,
295a9800bebSGarrett D'Amore ndlp->nlp_Rpi, channelno);
296728bdc9bSSukumar Swaminathan
297fcf3ce44SJohn Forte /* If link attention needs to be cleared */
29882527734SSukumar Swaminathan if ((hba->state == FC_LINK_UP) && (channelno == hba->channel_fcp)) {
29982527734SSukumar Swaminathan if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
30082527734SSukumar Swaminathan goto done;
30182527734SSukumar Swaminathan }
302fcf3ce44SJohn Forte
303fcf3ce44SJohn Forte /* Scan to see if any FCP2 devices are still closed */
304fcf3ce44SJohn Forte found = 0;
305fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_READER);
306fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
307fcf3ce44SJohn Forte nlp = port->node_table[i];
308fcf3ce44SJohn Forte while (nlp != NULL) {
309fcf3ce44SJohn Forte if ((nlp->nlp_fcp_info & NLP_FCP_2_DEVICE) &&
31082527734SSukumar Swaminathan (nlp->nlp_flag[hba->channel_fcp] &
31182527734SSukumar Swaminathan NLP_CLOSED)) {
312fcf3ce44SJohn Forte found = 1;
313fcf3ce44SJohn Forte break;
314291a2b48SSukumar Swaminathan
315fcf3ce44SJohn Forte }
316fcf3ce44SJohn Forte nlp = nlp->nlp_list_next;
317fcf3ce44SJohn Forte }
318fcf3ce44SJohn Forte
319fcf3ce44SJohn Forte if (found) {
320fcf3ce44SJohn Forte break;
321fcf3ce44SJohn Forte }
322fcf3ce44SJohn Forte }
323fcf3ce44SJohn Forte
324fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
325fcf3ce44SJohn Forte
326fcf3ce44SJohn Forte if (!found) {
327fcf3ce44SJohn Forte /* Clear link attention */
328291a2b48SSukumar Swaminathan if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
329*8f23e9faSHans Rosenfeld MEM_MBOX))) {
330fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK);
331fcf3ce44SJohn Forte
332fcf3ce44SJohn Forte /*
333291a2b48SSukumar Swaminathan * If state is not FC_LINK_UP, then either the
334291a2b48SSukumar Swaminathan * link has gone down or a FC_CLEAR_LA has
335291a2b48SSukumar Swaminathan * already been issued
336fcf3ce44SJohn Forte */
337fcf3ce44SJohn Forte if (hba->state != FC_LINK_UP) {
338fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
339a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX,
340a9800bebSGarrett D'Amore (void *)mbox);
341fcf3ce44SJohn Forte goto done;
342fcf3ce44SJohn Forte }
343291a2b48SSukumar Swaminathan
34482527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_CLEAR_LA);
345fcf3ce44SJohn Forte hba->discovery_timer = 0;
346fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
347fcf3ce44SJohn Forte
34882527734SSukumar Swaminathan emlxs_mb_clear_la(hba, mbox);
349fcf3ce44SJohn Forte
35082527734SSukumar Swaminathan rc = EMLXS_SLI_ISSUE_MBOX_CMD(hba,
35182527734SSukumar Swaminathan mbox, MBX_NOWAIT, 0);
35282527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
353a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX,
354a9800bebSGarrett D'Amore (void *)mbox);
355fcf3ce44SJohn Forte }
356fcf3ce44SJohn Forte } else {
357291a2b48SSukumar Swaminathan /* Close the node and try again */
358291a2b48SSukumar Swaminathan /* in a few seconds */
35982527734SSukumar Swaminathan emlxs_node_close(port, ndlp, channelno, 5);
360fcf3ce44SJohn Forte return;
361fcf3ce44SJohn Forte }
362fcf3ce44SJohn Forte }
363fcf3ce44SJohn Forte }
364291a2b48SSukumar Swaminathan
365fcf3ce44SJohn Forte done:
366fcf3ce44SJohn Forte
367fcf3ce44SJohn Forte /* Wake any sleeping threads */
368fcf3ce44SJohn Forte mutex_enter(&EMLXS_PKT_LOCK);
369fcf3ce44SJohn Forte cv_broadcast(&EMLXS_PKT_CV);
370fcf3ce44SJohn Forte mutex_exit(&EMLXS_PKT_LOCK);
371fcf3ce44SJohn Forte
372fcf3ce44SJohn Forte return;
373fcf3ce44SJohn Forte
37482527734SSukumar Swaminathan } /* emlxs_node_open() */
375fcf3ce44SJohn Forte
376fcf3ce44SJohn Forte
377fcf3ce44SJohn Forte static int
emlxs_node_match_did(emlxs_port_t * port,NODELIST * ndlp,uint32_t did)378fcf3ce44SJohn Forte emlxs_node_match_did(emlxs_port_t *port, NODELIST *ndlp, uint32_t did)
379fcf3ce44SJohn Forte {
380fcf3ce44SJohn Forte D_ID mydid;
381fcf3ce44SJohn Forte D_ID odid;
382fcf3ce44SJohn Forte D_ID ndid;
383fcf3ce44SJohn Forte
384291a2b48SSukumar Swaminathan if (ndlp->nlp_DID == did)
385fcf3ce44SJohn Forte return (1);
386fcf3ce44SJohn Forte
387fcf3ce44SJohn Forte /*
388fcf3ce44SJohn Forte * Next check for area/domain == 0 match
389fcf3ce44SJohn Forte */
390fcf3ce44SJohn Forte mydid.un.word = port->did;
391fcf3ce44SJohn Forte if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) {
392fcf3ce44SJohn Forte goto out;
393fcf3ce44SJohn Forte }
394291a2b48SSukumar Swaminathan
395fcf3ce44SJohn Forte ndid.un.word = did;
396fcf3ce44SJohn Forte odid.un.word = ndlp->nlp_DID;
397fcf3ce44SJohn Forte if (ndid.un.b.id == odid.un.b.id) {
398fcf3ce44SJohn Forte if ((mydid.un.b.domain == ndid.un.b.domain) &&
399fcf3ce44SJohn Forte (mydid.un.b.area == ndid.un.b.area)) {
400fcf3ce44SJohn Forte ndid.un.word = ndlp->nlp_DID;
401fcf3ce44SJohn Forte odid.un.word = did;
402291a2b48SSukumar Swaminathan if ((ndid.un.b.domain == 0) && (ndid.un.b.area == 0)) {
403fcf3ce44SJohn Forte return (1);
404fcf3ce44SJohn Forte }
405fcf3ce44SJohn Forte goto out;
406fcf3ce44SJohn Forte }
407291a2b48SSukumar Swaminathan
408fcf3ce44SJohn Forte ndid.un.word = ndlp->nlp_DID;
409fcf3ce44SJohn Forte if ((mydid.un.b.domain == ndid.un.b.domain) &&
410fcf3ce44SJohn Forte (mydid.un.b.area == ndid.un.b.area)) {
411fcf3ce44SJohn Forte odid.un.word = ndlp->nlp_DID;
412fcf3ce44SJohn Forte ndid.un.word = did;
413291a2b48SSukumar Swaminathan if ((ndid.un.b.domain == 0) && (ndid.un.b.area == 0)) {
414fcf3ce44SJohn Forte return (1);
415fcf3ce44SJohn Forte }
416fcf3ce44SJohn Forte }
417fcf3ce44SJohn Forte }
418291a2b48SSukumar Swaminathan
419fcf3ce44SJohn Forte out:
420fcf3ce44SJohn Forte
421fcf3ce44SJohn Forte return (0);
422fcf3ce44SJohn Forte
423*8f23e9faSHans Rosenfeld } /* emlxs_node_match_did() */
424fcf3ce44SJohn Forte
425fcf3ce44SJohn Forte
426fcf3ce44SJohn Forte
427fcf3ce44SJohn Forte extern NODELIST *
emlxs_node_find_mac(emlxs_port_t * port,uint8_t * mac)428fcf3ce44SJohn Forte emlxs_node_find_mac(emlxs_port_t *port, uint8_t *mac)
429fcf3ce44SJohn Forte {
430fcf3ce44SJohn Forte NODELIST *nlp;
431fcf3ce44SJohn Forte uint32_t i;
432fcf3ce44SJohn Forte
433fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_READER);
434fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
435fcf3ce44SJohn Forte nlp = port->node_table[i];
436fcf3ce44SJohn Forte while (nlp != NULL) {
437fcf3ce44SJohn Forte /*
438291a2b48SSukumar Swaminathan * If portname matches mac address,
439291a2b48SSukumar Swaminathan * return NODELIST entry
440fcf3ce44SJohn Forte */
441fcf3ce44SJohn Forte if ((nlp->nlp_portname.IEEE[0] == mac[0])) {
44282527734SSukumar Swaminathan if ((nlp->nlp_DID != BCAST_DID) &&
44382527734SSukumar Swaminathan ((nlp->nlp_DID & FABRIC_DID_MASK) ==
44482527734SSukumar Swaminathan FABRIC_DID_MASK)) {
445291a2b48SSukumar Swaminathan nlp = (NODELIST *)nlp->nlp_list_next;
446fcf3ce44SJohn Forte continue;
447fcf3ce44SJohn Forte }
448291a2b48SSukumar Swaminathan
449fcf3ce44SJohn Forte if ((nlp->nlp_portname.IEEE[1] == mac[1]) &&
450fcf3ce44SJohn Forte (nlp->nlp_portname.IEEE[2] == mac[2]) &&
451fcf3ce44SJohn Forte (nlp->nlp_portname.IEEE[3] == mac[3]) &&
452fcf3ce44SJohn Forte (nlp->nlp_portname.IEEE[4] == mac[4]) &&
453fcf3ce44SJohn Forte (nlp->nlp_portname.IEEE[5] == mac[5])) {
454fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
455fcf3ce44SJohn Forte return (nlp);
456fcf3ce44SJohn Forte }
457291a2b48SSukumar Swaminathan
458fcf3ce44SJohn Forte }
459291a2b48SSukumar Swaminathan
460291a2b48SSukumar Swaminathan nlp = (NODELIST *)nlp->nlp_list_next;
461fcf3ce44SJohn Forte }
462fcf3ce44SJohn Forte }
463fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
464fcf3ce44SJohn Forte
465fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg,
466291a2b48SSukumar Swaminathan "find: MAC=%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2],
467291a2b48SSukumar Swaminathan mac[3], mac[4], mac[5]);
468fcf3ce44SJohn Forte
469fcf3ce44SJohn Forte return (NULL);
470fcf3ce44SJohn Forte
47182527734SSukumar Swaminathan } /* emlxs_node_find_mac() */
472fcf3ce44SJohn Forte
473fcf3ce44SJohn Forte
474fcf3ce44SJohn Forte extern NODELIST *
emlxs_node_find_did(emlxs_port_t * port,uint32_t did,uint32_t lock)475*8f23e9faSHans Rosenfeld emlxs_node_find_did(emlxs_port_t *port, uint32_t did, uint32_t lock)
476fcf3ce44SJohn Forte {
477fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
478fcf3ce44SJohn Forte NODELIST *nlp;
479fcf3ce44SJohn Forte uint32_t hash;
480fcf3ce44SJohn Forte
481fcf3ce44SJohn Forte /* Check for invalid node ids */
482291a2b48SSukumar Swaminathan if ((did == 0) && (!(hba->flag & FC_LOOPBACK_MODE))) {
483291a2b48SSukumar Swaminathan return ((NODELIST *)0);
484291a2b48SSukumar Swaminathan }
485291a2b48SSukumar Swaminathan
486291a2b48SSukumar Swaminathan if (did & 0xff000000) {
487291a2b48SSukumar Swaminathan return ((NODELIST *)0);
488fcf3ce44SJohn Forte }
489291a2b48SSukumar Swaminathan
490fcf3ce44SJohn Forte /* Check for bcast node */
49182527734SSukumar Swaminathan if (did == BCAST_DID) {
492fcf3ce44SJohn Forte /* Use the base node here */
493fcf3ce44SJohn Forte return (&port->node_base);
494fcf3ce44SJohn Forte }
495fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT
496fcf3ce44SJohn Forte /* Check for menlo node */
497fcf3ce44SJohn Forte if (did == EMLXS_MENLO_DID) {
498fcf3ce44SJohn Forte /* Use the base node here */
499fcf3ce44SJohn Forte return (&port->node_base);
500fcf3ce44SJohn Forte }
501291a2b48SSukumar Swaminathan #endif /* MENLO_SUPPORT */
502fcf3ce44SJohn Forte
503fcf3ce44SJohn Forte /* Check for host node */
504fcf3ce44SJohn Forte if (did == port->did && !(hba->flag & FC_LOOPBACK_MODE)) {
505fcf3ce44SJohn Forte /* Use the base node here */
506fcf3ce44SJohn Forte return (&port->node_base);
507fcf3ce44SJohn Forte }
508291a2b48SSukumar Swaminathan
509fcf3ce44SJohn Forte /*
51082527734SSukumar Swaminathan * Convert well known fabric addresses to the FABRIC_DID,
511291a2b48SSukumar Swaminathan * since we don't login to some of them
512fcf3ce44SJohn Forte */
513fcf3ce44SJohn Forte if ((did == SCR_DID)) {
51482527734SSukumar Swaminathan did = FABRIC_DID;
515fcf3ce44SJohn Forte }
516291a2b48SSukumar Swaminathan
517*8f23e9faSHans Rosenfeld if (lock) {
518*8f23e9faSHans Rosenfeld rw_enter(&port->node_rwlock, RW_READER);
519*8f23e9faSHans Rosenfeld }
520fcf3ce44SJohn Forte hash = EMLXS_DID_HASH(did);
521fcf3ce44SJohn Forte nlp = port->node_table[hash];
522fcf3ce44SJohn Forte while (nlp != NULL) {
523fcf3ce44SJohn Forte /* Check for obvious match */
524fcf3ce44SJohn Forte if (nlp->nlp_DID == did) {
525*8f23e9faSHans Rosenfeld if (lock) {
526*8f23e9faSHans Rosenfeld rw_exit(&port->node_rwlock);
527*8f23e9faSHans Rosenfeld }
528fcf3ce44SJohn Forte return (nlp);
529fcf3ce44SJohn Forte }
530291a2b48SSukumar Swaminathan
531fcf3ce44SJohn Forte /* Check for detailed match */
532fcf3ce44SJohn Forte else if (emlxs_node_match_did(port, nlp, did)) {
533*8f23e9faSHans Rosenfeld if (lock) {
534*8f23e9faSHans Rosenfeld rw_exit(&port->node_rwlock);
535*8f23e9faSHans Rosenfeld }
536fcf3ce44SJohn Forte return (nlp);
537fcf3ce44SJohn Forte }
538291a2b48SSukumar Swaminathan
539291a2b48SSukumar Swaminathan nlp = (NODELIST *)nlp->nlp_list_next;
540fcf3ce44SJohn Forte }
541*8f23e9faSHans Rosenfeld
542*8f23e9faSHans Rosenfeld if (lock) {
543*8f23e9faSHans Rosenfeld rw_exit(&port->node_rwlock);
544*8f23e9faSHans Rosenfeld }
545fcf3ce44SJohn Forte
546291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg, "find: did=%x",
547291a2b48SSukumar Swaminathan did);
548fcf3ce44SJohn Forte
549fcf3ce44SJohn Forte /* no match found */
550291a2b48SSukumar Swaminathan return ((NODELIST *)0);
551fcf3ce44SJohn Forte
55282527734SSukumar Swaminathan } /* emlxs_node_find_did() */
553fcf3ce44SJohn Forte
554fcf3ce44SJohn Forte
555fcf3ce44SJohn Forte extern NODELIST *
emlxs_node_find_rpi(emlxs_port_t * port,uint32_t rpi)556fcf3ce44SJohn Forte emlxs_node_find_rpi(emlxs_port_t *port, uint32_t rpi)
557fcf3ce44SJohn Forte {
558fcf3ce44SJohn Forte NODELIST *nlp;
559fcf3ce44SJohn Forte uint32_t i;
560fcf3ce44SJohn Forte
561fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_READER);
562fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
563fcf3ce44SJohn Forte nlp = port->node_table[i];
564fcf3ce44SJohn Forte while (nlp != NULL) {
565fcf3ce44SJohn Forte if (nlp->nlp_Rpi == rpi) {
566fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
567fcf3ce44SJohn Forte return (nlp);
568fcf3ce44SJohn Forte }
569291a2b48SSukumar Swaminathan
570291a2b48SSukumar Swaminathan nlp = (NODELIST *)nlp->nlp_list_next;
571fcf3ce44SJohn Forte }
572fcf3ce44SJohn Forte }
573fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
574fcf3ce44SJohn Forte
575*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg, "find: rpi=%d",
576291a2b48SSukumar Swaminathan rpi);
577fcf3ce44SJohn Forte
578fcf3ce44SJohn Forte /* no match found */
579291a2b48SSukumar Swaminathan return ((NODELIST *)0);
580fcf3ce44SJohn Forte
58182527734SSukumar Swaminathan } /* emlxs_node_find_rpi() */
582fcf3ce44SJohn Forte
583fcf3ce44SJohn Forte
584fcf3ce44SJohn Forte extern NODELIST *
emlxs_node_find_wwpn(emlxs_port_t * port,uint8_t * wwpn,uint32_t lock)585*8f23e9faSHans Rosenfeld emlxs_node_find_wwpn(emlxs_port_t *port, uint8_t *wwpn, uint32_t lock)
586fcf3ce44SJohn Forte {
587fcf3ce44SJohn Forte NODELIST *nlp;
588fcf3ce44SJohn Forte uint32_t i;
589fcf3ce44SJohn Forte uint32_t j;
590fcf3ce44SJohn Forte uint8_t *bptr1;
591fcf3ce44SJohn Forte uint8_t *bptr2;
592fcf3ce44SJohn Forte
593*8f23e9faSHans Rosenfeld if (lock) {
594*8f23e9faSHans Rosenfeld rw_enter(&port->node_rwlock, RW_READER);
595*8f23e9faSHans Rosenfeld }
596*8f23e9faSHans Rosenfeld
597fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
598fcf3ce44SJohn Forte nlp = port->node_table[i];
599fcf3ce44SJohn Forte while (nlp != NULL) {
600fcf3ce44SJohn Forte bptr1 = (uint8_t *)&nlp->nlp_portname;
601fcf3ce44SJohn Forte bptr1 += 7;
602fcf3ce44SJohn Forte bptr2 = (uint8_t *)wwpn;
603fcf3ce44SJohn Forte bptr2 += 7;
604fcf3ce44SJohn Forte
605fcf3ce44SJohn Forte for (j = 0; j < 8; j++) {
606fcf3ce44SJohn Forte if (*bptr1-- != *bptr2--) {
607fcf3ce44SJohn Forte break;
608fcf3ce44SJohn Forte }
609fcf3ce44SJohn Forte }
610fcf3ce44SJohn Forte
611fcf3ce44SJohn Forte if (j == 8) {
612*8f23e9faSHans Rosenfeld if (lock) {
613*8f23e9faSHans Rosenfeld rw_exit(&port->node_rwlock);
614*8f23e9faSHans Rosenfeld }
615fcf3ce44SJohn Forte return (nlp);
616fcf3ce44SJohn Forte }
617291a2b48SSukumar Swaminathan
618291a2b48SSukumar Swaminathan nlp = (NODELIST *)nlp->nlp_list_next;
619fcf3ce44SJohn Forte }
620fcf3ce44SJohn Forte }
621*8f23e9faSHans Rosenfeld
622*8f23e9faSHans Rosenfeld if (lock) {
623*8f23e9faSHans Rosenfeld rw_exit(&port->node_rwlock);
624*8f23e9faSHans Rosenfeld }
625fcf3ce44SJohn Forte
626fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg,
627291a2b48SSukumar Swaminathan "find: wwpn=%02x%02x%02x%02x%02x%02x%02x%02x", wwpn[0], wwpn[1],
628291a2b48SSukumar Swaminathan wwpn[2], wwpn[3], wwpn[4], wwpn[5], wwpn[6], wwpn[7]);
629fcf3ce44SJohn Forte
630fcf3ce44SJohn Forte /* no match found */
631291a2b48SSukumar Swaminathan return ((NODELIST *)0);
632fcf3ce44SJohn Forte
63382527734SSukumar Swaminathan } /* emlxs_node_find_wwpn() */
634fcf3ce44SJohn Forte
635fcf3ce44SJohn Forte
636fcf3ce44SJohn Forte extern NODELIST *
emlxs_node_find_index(emlxs_port_t * port,uint32_t index,uint32_t nports_only)637291a2b48SSukumar Swaminathan emlxs_node_find_index(emlxs_port_t *port, uint32_t index,
638291a2b48SSukumar Swaminathan uint32_t nports_only)
639fcf3ce44SJohn Forte {
640fcf3ce44SJohn Forte NODELIST *nlp;
641fcf3ce44SJohn Forte uint32_t i;
642fcf3ce44SJohn Forte uint32_t count;
643fcf3ce44SJohn Forte
644fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_READER);
645fcf3ce44SJohn Forte
646fcf3ce44SJohn Forte if (index > port->node_count - 1) {
647fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
648fcf3ce44SJohn Forte return (NULL);
649fcf3ce44SJohn Forte }
650291a2b48SSukumar Swaminathan
651fcf3ce44SJohn Forte count = 0;
652fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
653fcf3ce44SJohn Forte nlp = port->node_table[i];
654fcf3ce44SJohn Forte while (nlp != NULL) {
655fcf3ce44SJohn Forte /* Skip fabric ports if requested */
656291a2b48SSukumar Swaminathan if (nports_only &&
657291a2b48SSukumar Swaminathan (nlp->nlp_DID & 0xFFF000) == 0xFFF000) {
658291a2b48SSukumar Swaminathan nlp = (NODELIST *)nlp->nlp_list_next;
659fcf3ce44SJohn Forte continue;
660fcf3ce44SJohn Forte }
661291a2b48SSukumar Swaminathan
662fcf3ce44SJohn Forte if (count == index) {
663fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
664fcf3ce44SJohn Forte return (nlp);
665fcf3ce44SJohn Forte }
666291a2b48SSukumar Swaminathan
667291a2b48SSukumar Swaminathan nlp = (NODELIST *)nlp->nlp_list_next;
668fcf3ce44SJohn Forte count++;
669fcf3ce44SJohn Forte }
670fcf3ce44SJohn Forte }
671fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
672fcf3ce44SJohn Forte
673291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg, "find: index=%d",
674291a2b48SSukumar Swaminathan index);
675fcf3ce44SJohn Forte
676fcf3ce44SJohn Forte /* no match found */
677291a2b48SSukumar Swaminathan return ((NODELIST *)0);
678fcf3ce44SJohn Forte
679a9800bebSGarrett D'Amore } /* emlxs_node_find_index() */
680fcf3ce44SJohn Forte
681fcf3ce44SJohn Forte
682fcf3ce44SJohn Forte extern uint32_t
emlxs_nport_count(emlxs_port_t * port)683fcf3ce44SJohn Forte emlxs_nport_count(emlxs_port_t *port)
684fcf3ce44SJohn Forte {
685fcf3ce44SJohn Forte NODELIST *nlp;
686fcf3ce44SJohn Forte uint32_t i;
687fcf3ce44SJohn Forte uint32_t nport_count = 0;
688fcf3ce44SJohn Forte
689fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_READER);
690fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
691fcf3ce44SJohn Forte nlp = port->node_table[i];
692fcf3ce44SJohn Forte while (nlp != NULL) {
693fcf3ce44SJohn Forte if ((nlp->nlp_DID & 0xFFF000) != 0xFFF000) {
694fcf3ce44SJohn Forte nport_count++;
695fcf3ce44SJohn Forte }
696291a2b48SSukumar Swaminathan
697291a2b48SSukumar Swaminathan nlp = (NODELIST *)nlp->nlp_list_next;
698fcf3ce44SJohn Forte }
699fcf3ce44SJohn Forte }
700fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
701fcf3ce44SJohn Forte
702fcf3ce44SJohn Forte return (nport_count);
703fcf3ce44SJohn Forte
70482527734SSukumar Swaminathan } /* emlxs_nport_count() */
705fcf3ce44SJohn Forte
706fcf3ce44SJohn Forte
707fcf3ce44SJohn Forte
708fcf3ce44SJohn Forte extern void
emlxs_node_destroy_all(emlxs_port_t * port)709fcf3ce44SJohn Forte emlxs_node_destroy_all(emlxs_port_t *port)
710fcf3ce44SJohn Forte {
711fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
712fcf3ce44SJohn Forte NODELIST *next;
713fcf3ce44SJohn Forte NODELIST *ndlp;
714a9800bebSGarrett D'Amore RPIobj_t *rpip;
715fcf3ce44SJohn Forte uint8_t *wwn;
716fcf3ce44SJohn Forte uint32_t i;
717fcf3ce44SJohn Forte
718fcf3ce44SJohn Forte /* Flush and free the nodes */
719fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_WRITER);
720fcf3ce44SJohn Forte for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
721fcf3ce44SJohn Forte ndlp = port->node_table[i];
722fcf3ce44SJohn Forte port->node_table[i] = 0;
723fcf3ce44SJohn Forte while (ndlp != NULL) {
724fcf3ce44SJohn Forte next = ndlp->nlp_list_next;
725fcf3ce44SJohn Forte ndlp->nlp_list_next = NULL;
726fcf3ce44SJohn Forte ndlp->nlp_list_prev = NULL;
727fcf3ce44SJohn Forte ndlp->nlp_active = 0;
728fcf3ce44SJohn Forte
729fcf3ce44SJohn Forte if (port->node_count) {
730fcf3ce44SJohn Forte port->node_count--;
731fcf3ce44SJohn Forte }
732291a2b48SSukumar Swaminathan
733fcf3ce44SJohn Forte wwn = (uint8_t *)&ndlp->nlp_portname;
734291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT,
735291a2b48SSukumar Swaminathan &emlxs_node_destroy_msg, "did=%06x "
736*8f23e9faSHans Rosenfeld "rpi=%d wwpn=%02x%02x%02x%02x%02x%02x%02x%02x "
737291a2b48SSukumar Swaminathan "count=%d", ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
738291a2b48SSukumar Swaminathan wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6],
739291a2b48SSukumar Swaminathan wwn[7], port->node_count);
740fcf3ce44SJohn Forte
741fcf3ce44SJohn Forte (void) emlxs_tx_node_flush(port, ndlp, 0, 0, 0);
742fcf3ce44SJohn Forte
74382527734SSukumar Swaminathan /* Break Node/RPI binding */
744a9800bebSGarrett D'Amore if (ndlp->rpip) {
745a9800bebSGarrett D'Amore rpip = ndlp->rpip;
74682527734SSukumar Swaminathan
747a9800bebSGarrett D'Amore ndlp->rpip = NULL;
748a9800bebSGarrett D'Amore rpip->node = NULL;
749a9800bebSGarrett D'Amore
750a9800bebSGarrett D'Amore (void) emlxs_rpi_free_notify(port, rpip);
75182527734SSukumar Swaminathan }
75282527734SSukumar Swaminathan
753a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_NLP, (void *)ndlp);
754fcf3ce44SJohn Forte
755fcf3ce44SJohn Forte ndlp = next;
756fcf3ce44SJohn Forte }
757fcf3ce44SJohn Forte }
758fcf3ce44SJohn Forte port->node_count = 0;
759fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
760fcf3ce44SJohn Forte
761fcf3ce44SJohn Forte /* Clean the base node */
762fcf3ce44SJohn Forte mutex_enter(&EMLXS_PORT_LOCK);
763fcf3ce44SJohn Forte port->node_base.nlp_list_next = NULL;
764fcf3ce44SJohn Forte port->node_base.nlp_list_prev = NULL;
765fcf3ce44SJohn Forte port->node_base.nlp_active = 1;
766fcf3ce44SJohn Forte mutex_exit(&EMLXS_PORT_LOCK);
767fcf3ce44SJohn Forte
768fcf3ce44SJohn Forte /* Flush the base node */
769fcf3ce44SJohn Forte (void) emlxs_tx_node_flush(port, &port->node_base, 0, 1, 0);
770fcf3ce44SJohn Forte (void) emlxs_chipq_node_flush(port, 0, &port->node_base, 0);
771fcf3ce44SJohn Forte
772fcf3ce44SJohn Forte return;
773fcf3ce44SJohn Forte
77482527734SSukumar Swaminathan } /* emlxs_node_destroy_all() */
775fcf3ce44SJohn Forte
776fcf3ce44SJohn Forte
777a9800bebSGarrett D'Amore extern NODELIST *
emlxs_node_create(emlxs_port_t * port,uint32_t did,uint32_t rpi,SERV_PARM * sp)778a9800bebSGarrett D'Amore emlxs_node_create(emlxs_port_t *port, uint32_t did, uint32_t rpi, SERV_PARM *sp)
779a9800bebSGarrett D'Amore {
780a9800bebSGarrett D'Amore emlxs_hba_t *hba = HBA;
781*8f23e9faSHans Rosenfeld NODELIST *ndlp, *ndlp_wwn;
782a9800bebSGarrett D'Amore uint8_t *wwn;
783a9800bebSGarrett D'Amore emlxs_vvl_fmt_t vvl;
784a9800bebSGarrett D'Amore RPIobj_t *rpip;
785a9800bebSGarrett D'Amore
786*8f23e9faSHans Rosenfeld rw_enter(&port->node_rwlock, RW_WRITER);
787*8f23e9faSHans Rosenfeld
788*8f23e9faSHans Rosenfeld ndlp = emlxs_node_find_did(port, did, 0);
789*8f23e9faSHans Rosenfeld ndlp_wwn = emlxs_node_find_wwpn(port, (uint8_t *)&sp->portName, 0);
790*8f23e9faSHans Rosenfeld
791*8f23e9faSHans Rosenfeld /* Zero out the stale node worldwide names */
792*8f23e9faSHans Rosenfeld if (ndlp_wwn && (ndlp != ndlp_wwn)) {
793*8f23e9faSHans Rosenfeld bzero((uint8_t *)&ndlp_wwn->nlp_nodename, sizeof (NAME_TYPE));
794*8f23e9faSHans Rosenfeld bzero((uint8_t *)&ndlp_wwn->nlp_portname, sizeof (NAME_TYPE));
795*8f23e9faSHans Rosenfeld }
796a9800bebSGarrett D'Amore
797a9800bebSGarrett D'Amore /* Update the node */
798a9800bebSGarrett D'Amore if (ndlp) {
799a9800bebSGarrett D'Amore ndlp->nlp_Rpi = (uint16_t)rpi;
800a9800bebSGarrett D'Amore ndlp->nlp_DID = did;
801a9800bebSGarrett D'Amore
802a9800bebSGarrett D'Amore bcopy((uint8_t *)sp, (uint8_t *)&ndlp->sparm,
803a9800bebSGarrett D'Amore sizeof (SERV_PARM));
804a9800bebSGarrett D'Amore
805a9800bebSGarrett D'Amore bcopy((uint8_t *)&sp->nodeName,
806a9800bebSGarrett D'Amore (uint8_t *)&ndlp->nlp_nodename,
807a9800bebSGarrett D'Amore sizeof (NAME_TYPE));
808a9800bebSGarrett D'Amore
809a9800bebSGarrett D'Amore bcopy((uint8_t *)&sp->portName,
810a9800bebSGarrett D'Amore (uint8_t *)&ndlp->nlp_portname,
811a9800bebSGarrett D'Amore sizeof (NAME_TYPE));
812a9800bebSGarrett D'Amore
813a9800bebSGarrett D'Amore /* Add Node/RPI binding */
814a9800bebSGarrett D'Amore if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
815a9800bebSGarrett D'Amore rpip = emlxs_rpi_find(port, rpi);
816a9800bebSGarrett D'Amore
817a9800bebSGarrett D'Amore if (rpip) {
818a9800bebSGarrett D'Amore rpip->node = ndlp;
819a9800bebSGarrett D'Amore ndlp->rpip = rpip;
820a9800bebSGarrett D'Amore } else {
821a9800bebSGarrett D'Amore ndlp->rpip = NULL;
822a9800bebSGarrett D'Amore
823a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT,
824a9800bebSGarrett D'Amore &emlxs_node_create_msg,
825*8f23e9faSHans Rosenfeld "Unable to find RPI. did=%x rpi=%d",
826a9800bebSGarrett D'Amore did, rpi);
827a9800bebSGarrett D'Amore }
828a9800bebSGarrett D'Amore } else {
829a9800bebSGarrett D'Amore ndlp->rpip = NULL;
830a9800bebSGarrett D'Amore }
831a9800bebSGarrett D'Amore
832a9800bebSGarrett D'Amore wwn = (uint8_t *)&ndlp->nlp_portname;
833a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_update_msg,
834*8f23e9faSHans Rosenfeld "node=%p did=%06x rpi=%d "
835a9800bebSGarrett D'Amore "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
836a9800bebSGarrett D'Amore ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
837a9800bebSGarrett D'Amore wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
838a9800bebSGarrett D'Amore
839a9800bebSGarrett D'Amore goto done;
840a9800bebSGarrett D'Amore }
841a9800bebSGarrett D'Amore
842a9800bebSGarrett D'Amore /* Allocate a new node */
843*8f23e9faSHans Rosenfeld ndlp = (NODELIST *)emlxs_mem_get(hba, MEM_NLP);
844a9800bebSGarrett D'Amore
845a9800bebSGarrett D'Amore if (ndlp) {
846a9800bebSGarrett D'Amore ndlp->nlp_Rpi = (uint16_t)rpi;
847a9800bebSGarrett D'Amore ndlp->nlp_DID = did;
848a9800bebSGarrett D'Amore
849a9800bebSGarrett D'Amore bcopy((uint8_t *)sp, (uint8_t *)&ndlp->sparm,
850a9800bebSGarrett D'Amore sizeof (SERV_PARM));
851a9800bebSGarrett D'Amore
852a9800bebSGarrett D'Amore bcopy((uint8_t *)&sp->nodeName,
853a9800bebSGarrett D'Amore (uint8_t *)&ndlp->nlp_nodename,
854a9800bebSGarrett D'Amore sizeof (NAME_TYPE));
855a9800bebSGarrett D'Amore
856a9800bebSGarrett D'Amore bcopy((uint8_t *)&sp->portName,
857a9800bebSGarrett D'Amore (uint8_t *)&ndlp->nlp_portname,
858a9800bebSGarrett D'Amore sizeof (NAME_TYPE));
859a9800bebSGarrett D'Amore
860a9800bebSGarrett D'Amore ndlp->nlp_active = 1;
861a9800bebSGarrett D'Amore ndlp->nlp_flag[hba->channel_ct] |= NLP_CLOSED;
862a9800bebSGarrett D'Amore ndlp->nlp_flag[hba->channel_els] |= NLP_CLOSED;
863a9800bebSGarrett D'Amore ndlp->nlp_flag[hba->channel_fcp] |= NLP_CLOSED;
864a9800bebSGarrett D'Amore ndlp->nlp_flag[hba->channel_ip] |= NLP_CLOSED;
865a9800bebSGarrett D'Amore
866a9800bebSGarrett D'Amore /* Add Node/RPI binding */
867a9800bebSGarrett D'Amore if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
868a9800bebSGarrett D'Amore rpip = emlxs_rpi_find(port, rpi);
869a9800bebSGarrett D'Amore
870a9800bebSGarrett D'Amore if (rpip) {
871a9800bebSGarrett D'Amore rpip->node = ndlp;
872a9800bebSGarrett D'Amore ndlp->rpip = rpip;
873a9800bebSGarrett D'Amore } else {
874a9800bebSGarrett D'Amore ndlp->rpip = NULL;
875a9800bebSGarrett D'Amore
876a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT,
877a9800bebSGarrett D'Amore &emlxs_node_create_msg,
878*8f23e9faSHans Rosenfeld "Unable to find RPI. did=%x rpi=%d",
879a9800bebSGarrett D'Amore did, rpi);
880a9800bebSGarrett D'Amore }
881a9800bebSGarrett D'Amore } else {
882a9800bebSGarrett D'Amore ndlp->rpip = NULL;
883a9800bebSGarrett D'Amore }
884*8f23e9faSHans Rosenfeld
885*8f23e9faSHans Rosenfeld #ifdef NODE_THROTTLE_SUPPORT
886*8f23e9faSHans Rosenfeld emlxs_node_throttle_set(port, ndlp);
887*8f23e9faSHans Rosenfeld #endif /* NODE_THROTTLE_SUPPORT */
888a9800bebSGarrett D'Amore
889a9800bebSGarrett D'Amore /* Add the node */
890a9800bebSGarrett D'Amore emlxs_node_add(port, ndlp);
891a9800bebSGarrett D'Amore
892a9800bebSGarrett D'Amore goto done;
893a9800bebSGarrett D'Amore }
894a9800bebSGarrett D'Amore
895*8f23e9faSHans Rosenfeld rw_exit(&port->node_rwlock);
896a9800bebSGarrett D'Amore wwn = (uint8_t *)&sp->portName;
897a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT,
898a9800bebSGarrett D'Amore &emlxs_node_create_failed_msg,
899a9800bebSGarrett D'Amore "Unable to allocate node. did=%06x "
900a9800bebSGarrett D'Amore "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
901a9800bebSGarrett D'Amore did, wwn[0], wwn[1], wwn[2],
902a9800bebSGarrett D'Amore wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
903a9800bebSGarrett D'Amore
904a9800bebSGarrett D'Amore return (NULL);
905a9800bebSGarrett D'Amore
906a9800bebSGarrett D'Amore done:
907*8f23e9faSHans Rosenfeld rw_exit(&port->node_rwlock);
908a9800bebSGarrett D'Amore if (sp->VALID_VENDOR_VERSION) {
909a9800bebSGarrett D'Amore bcopy((caddr_t *)&sp->vendorVersion[0],
910a9800bebSGarrett D'Amore (caddr_t *)&vvl, sizeof (emlxs_vvl_fmt_t));
911a9800bebSGarrett D'Amore
912a9800bebSGarrett D'Amore vvl.un0.word0 = LE_SWAP32(vvl.un0.word0);
913a9800bebSGarrett D'Amore vvl.un1.word1 = LE_SWAP32(vvl.un1.word1);
914a9800bebSGarrett D'Amore
915a9800bebSGarrett D'Amore if ((vvl.un0.w0.oui == 0x0000C9) &&
916a9800bebSGarrett D'Amore (vvl.un1.w1.vport)) {
917a9800bebSGarrett D'Amore ndlp->nlp_fcp_info |= NLP_EMLX_VPORT;
918a9800bebSGarrett D'Amore }
919a9800bebSGarrett D'Amore }
920a9800bebSGarrett D'Amore
921a9800bebSGarrett D'Amore /* Open the node */
922a9800bebSGarrett D'Amore emlxs_node_open(port, ndlp, hba->channel_ct);
923a9800bebSGarrett D'Amore emlxs_node_open(port, ndlp, hba->channel_els);
924a9800bebSGarrett D'Amore emlxs_node_open(port, ndlp, hba->channel_ip);
925a9800bebSGarrett D'Amore emlxs_node_open(port, ndlp, hba->channel_fcp);
926a9800bebSGarrett D'Amore
927*8f23e9faSHans Rosenfeld EMLXS_SET_DFC_STATE(ndlp, NODE_LOGIN);
928*8f23e9faSHans Rosenfeld
929a9800bebSGarrett D'Amore return (ndlp);
930a9800bebSGarrett D'Amore
931a9800bebSGarrett D'Amore } /* emlxs_node_create() */
932a9800bebSGarrett D'Amore
933a9800bebSGarrett D'Amore
934*8f23e9faSHans Rosenfeld /* node_rwlock must be held when calling this routine */
935*8f23e9faSHans Rosenfeld static void
emlxs_node_add(emlxs_port_t * port,NODELIST * ndlp)936fcf3ce44SJohn Forte emlxs_node_add(emlxs_port_t *port, NODELIST *ndlp)
937fcf3ce44SJohn Forte {
938fcf3ce44SJohn Forte NODELIST *np;
939fcf3ce44SJohn Forte uint8_t *wwn;
940fcf3ce44SJohn Forte uint32_t hash;
941fcf3ce44SJohn Forte
942fcf3ce44SJohn Forte hash = EMLXS_DID_HASH(ndlp->nlp_DID);
943fcf3ce44SJohn Forte np = port->node_table[hash];
944fcf3ce44SJohn Forte
945fcf3ce44SJohn Forte /*
946fcf3ce44SJohn Forte * Insert node pointer to the head
947fcf3ce44SJohn Forte */
948fcf3ce44SJohn Forte port->node_table[hash] = ndlp;
949fcf3ce44SJohn Forte if (!np) {
950fcf3ce44SJohn Forte ndlp->nlp_list_next = NULL;
951fcf3ce44SJohn Forte } else {
952fcf3ce44SJohn Forte ndlp->nlp_list_next = np;
953fcf3ce44SJohn Forte }
954fcf3ce44SJohn Forte port->node_count++;
955fcf3ce44SJohn Forte
956fcf3ce44SJohn Forte wwn = (uint8_t *)&ndlp->nlp_portname;
957fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_msg,
958*8f23e9faSHans Rosenfeld "node=%p did=%06x rpi=%d wwpn=%02x%02x%02x%02x%02x%02x%02x%02x "
959291a2b48SSukumar Swaminathan "count=%d", ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0], wwn[1],
960291a2b48SSukumar Swaminathan wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7], port->node_count);
961fcf3ce44SJohn Forte
962fcf3ce44SJohn Forte return;
963fcf3ce44SJohn Forte
96482527734SSukumar Swaminathan } /* emlxs_node_add() */
965fcf3ce44SJohn Forte
966fcf3ce44SJohn Forte
967fcf3ce44SJohn Forte extern void
emlxs_node_rm(emlxs_port_t * port,NODELIST * ndlp)968fcf3ce44SJohn Forte emlxs_node_rm(emlxs_port_t *port, NODELIST *ndlp)
969fcf3ce44SJohn Forte {
970fcf3ce44SJohn Forte emlxs_hba_t *hba = HBA;
971fcf3ce44SJohn Forte NODELIST *np;
972fcf3ce44SJohn Forte NODELIST *prevp;
973a9800bebSGarrett D'Amore RPIobj_t *rpip;
974fcf3ce44SJohn Forte uint8_t *wwn;
975fcf3ce44SJohn Forte uint32_t hash;
976fcf3ce44SJohn Forte
977fcf3ce44SJohn Forte rw_enter(&port->node_rwlock, RW_WRITER);
978fcf3ce44SJohn Forte hash = EMLXS_DID_HASH(ndlp->nlp_DID);
979fcf3ce44SJohn Forte np = port->node_table[hash];
980fcf3ce44SJohn Forte prevp = NULL;
981fcf3ce44SJohn Forte while (np != NULL) {
982fcf3ce44SJohn Forte if (np->nlp_DID == ndlp->nlp_DID) {
983fcf3ce44SJohn Forte if (prevp == NULL) {
984fcf3ce44SJohn Forte port->node_table[hash] = np->nlp_list_next;
985fcf3ce44SJohn Forte } else {
986fcf3ce44SJohn Forte prevp->nlp_list_next = np->nlp_list_next;
987fcf3ce44SJohn Forte }
988fcf3ce44SJohn Forte
989fcf3ce44SJohn Forte if (port->node_count) {
990fcf3ce44SJohn Forte port->node_count--;
991fcf3ce44SJohn Forte }
992291a2b48SSukumar Swaminathan
993fcf3ce44SJohn Forte wwn = (uint8_t *)&ndlp->nlp_portname;
994291a2b48SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT,
995291a2b48SSukumar Swaminathan &emlxs_node_destroy_msg, "did=%06x "
996*8f23e9faSHans Rosenfeld "rpi=%d wwpn=%02x%02x%02x%02x%02x%02x%02x%02x "
997291a2b48SSukumar Swaminathan "count=%d", ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
998291a2b48SSukumar Swaminathan wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6],
999291a2b48SSukumar Swaminathan wwn[7], port->node_count);
1000fcf3ce44SJohn Forte
1001fcf3ce44SJohn Forte (void) emlxs_tx_node_flush(port, ndlp, 0, 1, 0);
1002fcf3ce44SJohn Forte
1003fcf3ce44SJohn Forte ndlp->nlp_active = 0;
100482527734SSukumar Swaminathan
100582527734SSukumar Swaminathan /* Break Node/RPI binding */
1006a9800bebSGarrett D'Amore if (ndlp->rpip) {
1007a9800bebSGarrett D'Amore rpip = ndlp->rpip;
100882527734SSukumar Swaminathan
1009a9800bebSGarrett D'Amore ndlp->rpip = NULL;
1010a9800bebSGarrett D'Amore rpip->node = NULL;
1011a9800bebSGarrett D'Amore
1012a9800bebSGarrett D'Amore (void) emlxs_rpi_free_notify(port, rpip);
101382527734SSukumar Swaminathan }
101482527734SSukumar Swaminathan
1015a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_NLP, (void *)ndlp);
1016fcf3ce44SJohn Forte
1017fcf3ce44SJohn Forte break;
1018fcf3ce44SJohn Forte }
1019fcf3ce44SJohn Forte prevp = np;
1020fcf3ce44SJohn Forte np = np->nlp_list_next;
1021fcf3ce44SJohn Forte }
1022fcf3ce44SJohn Forte rw_exit(&port->node_rwlock);
1023fcf3ce44SJohn Forte
1024fcf3ce44SJohn Forte return;
1025fcf3ce44SJohn Forte
102682527734SSukumar Swaminathan } /* emlxs_node_rm() */
1027*8f23e9faSHans Rosenfeld
1028*8f23e9faSHans Rosenfeld
1029*8f23e9faSHans Rosenfeld extern void
emlxs_node_throttle_set(emlxs_port_t * port,NODELIST * ndlp)1030*8f23e9faSHans Rosenfeld emlxs_node_throttle_set(emlxs_port_t *port, NODELIST *ndlp)
1031*8f23e9faSHans Rosenfeld {
1032*8f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA;
1033*8f23e9faSHans Rosenfeld emlxs_config_t *cfg = &CFG;
1034*8f23e9faSHans Rosenfeld char prop[64];
1035*8f23e9faSHans Rosenfeld char buf1[32];
1036*8f23e9faSHans Rosenfeld uint32_t throttle;
1037*8f23e9faSHans Rosenfeld
1038*8f23e9faSHans Rosenfeld /* Set global default */
1039*8f23e9faSHans Rosenfeld throttle = (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)?
1040*8f23e9faSHans Rosenfeld cfg[CFG_TGT_DEPTH].current:0;
1041*8f23e9faSHans Rosenfeld
1042*8f23e9faSHans Rosenfeld /* Check per wwpn default */
1043*8f23e9faSHans Rosenfeld (void) snprintf(prop, sizeof (prop), "w%s-depth",
1044*8f23e9faSHans Rosenfeld emlxs_wwn_xlate(buf1, sizeof (buf1),
1045*8f23e9faSHans Rosenfeld (uint8_t *)&ndlp->nlp_portname));
1046*8f23e9faSHans Rosenfeld
1047*8f23e9faSHans Rosenfeld throttle = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY,
1048*8f23e9faSHans Rosenfeld (void *)hba->dip, DDI_PROP_DONTPASS, prop, throttle);
1049*8f23e9faSHans Rosenfeld
1050*8f23e9faSHans Rosenfeld /* Check per driver/wwpn default */
1051*8f23e9faSHans Rosenfeld (void) snprintf(prop, sizeof (prop), "%s%d-w%s-depth", DRIVER_NAME,
1052*8f23e9faSHans Rosenfeld hba->ddiinst, emlxs_wwn_xlate(buf1, sizeof (buf1),
1053*8f23e9faSHans Rosenfeld (uint8_t *)&ndlp->nlp_portname));
1054*8f23e9faSHans Rosenfeld
1055*8f23e9faSHans Rosenfeld throttle = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY,
1056*8f23e9faSHans Rosenfeld (void *)hba->dip, DDI_PROP_DONTPASS, prop, throttle);
1057*8f23e9faSHans Rosenfeld
1058*8f23e9faSHans Rosenfeld /* Check limit */
1059*8f23e9faSHans Rosenfeld throttle = MIN(throttle, MAX_NODE_THROTTLE);
1060*8f23e9faSHans Rosenfeld
1061*8f23e9faSHans Rosenfeld ndlp->io_throttle = throttle;
1062*8f23e9faSHans Rosenfeld
1063*8f23e9faSHans Rosenfeld return;
1064*8f23e9faSHans Rosenfeld
1065*8f23e9faSHans Rosenfeld } /* emlxs_node_throttle_set() */
1066