emlxs_node.c (a9800beb) emlxs_node.c (8f23e9fa)
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 *
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
9 * or http://www.opensolaris.org/os/licensing.
8 * You can obtain a copy of the license at
9 * http://www.opensource.org/licenses/cddl1.txt.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
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/*
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
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 2010 Emulex. All rights reserved.
23 * Copyright (c) 2004-2011 Emulex. All rights reserved.
24 * Use is subject to license terms.
25 */
26
24 * Use is subject to license terms.
25 */
26
27
28#include <emlxs.h>
29
30
31/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
32EMLXS_MSG_DEF(EMLXS_NODE_C);
33
27#include <emlxs.h>
28
29
30/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
31EMLXS_MSG_DEF(EMLXS_NODE_C);
32
33static void emlxs_node_add(emlxs_port_t *, NODELIST *);
34static int emlxs_node_match_did(emlxs_port_t *, NODELIST *, uint32_t);
35
34/* Timeout == -1 will enable the offline timer */
35/* Timeout not -1 will apply the timeout */
36extern void
37emlxs_node_close(emlxs_port_t *port, NODELIST *ndlp, uint32_t channelno,
38 int32_t timeout)
39{
40 emlxs_hba_t *hba = HBA;
41 emlxs_config_t *cfg = &CFG;

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

284 ndlp->nlp_next[channelno] = ndlp;
285 cp->nodeq.q_cnt = 1;
286 }
287 }
288
289 mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
290
291 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_opened_msg,
36/* Timeout == -1 will enable the offline timer */
37/* Timeout not -1 will apply the timeout */
38extern void
39emlxs_node_close(emlxs_port_t *port, NODELIST *ndlp, uint32_t channelno,
40 int32_t timeout)
41{
42 emlxs_hba_t *hba = HBA;
43 emlxs_config_t *cfg = &CFG;

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

286 ndlp->nlp_next[channelno] = ndlp;
287 cp->nodeq.q_cnt = 1;
288 }
289 }
290
291 mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
292
293 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_opened_msg,
292 "node=%p did=%06x rpi=%x channel=%d", ndlp, ndlp->nlp_DID,
294 "node=%p did=%06x rpi=%d channel=%d", ndlp, ndlp->nlp_DID,
293 ndlp->nlp_Rpi, channelno);
294
295 /* If link attention needs to be cleared */
296 if ((hba->state == FC_LINK_UP) && (channelno == hba->channel_fcp)) {
297 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
298 goto done;
299 }
300

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

319 }
320 }
321
322 rw_exit(&port->node_rwlock);
323
324 if (!found) {
325 /* Clear link attention */
326 if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
295 ndlp->nlp_Rpi, channelno);
296
297 /* If link attention needs to be cleared */
298 if ((hba->state == FC_LINK_UP) && (channelno == hba->channel_fcp)) {
299 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
300 goto done;
301 }
302

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

321 }
322 }
323
324 rw_exit(&port->node_rwlock);
325
326 if (!found) {
327 /* Clear link attention */
328 if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
327 MEM_MBOX, 1))) {
329 MEM_MBOX))) {
328 mutex_enter(&EMLXS_PORT_LOCK);
329
330 /*
331 * If state is not FC_LINK_UP, then either the
332 * link has gone down or a FC_CLEAR_LA has
333 * already been issued
334 */
335 if (hba->state != FC_LINK_UP) {

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

413 }
414 }
415 }
416
417out:
418
419 return (0);
420
330 mutex_enter(&EMLXS_PORT_LOCK);
331
332 /*
333 * If state is not FC_LINK_UP, then either the
334 * link has gone down or a FC_CLEAR_LA has
335 * already been issued
336 */
337 if (hba->state != FC_LINK_UP) {

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

415 }
416 }
417 }
418
419out:
420
421 return (0);
422
421} /* End emlxs_node_match_did */
423} /* emlxs_node_match_did() */
422
423
424
425extern NODELIST *
426emlxs_node_find_mac(emlxs_port_t *port, uint8_t *mac)
427{
428 NODELIST *nlp;
429 uint32_t i;

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

465 mac[3], mac[4], mac[5]);
466
467 return (NULL);
468
469} /* emlxs_node_find_mac() */
470
471
472extern NODELIST *
424
425
426
427extern NODELIST *
428emlxs_node_find_mac(emlxs_port_t *port, uint8_t *mac)
429{
430 NODELIST *nlp;
431 uint32_t i;

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

467 mac[3], mac[4], mac[5]);
468
469 return (NULL);
470
471} /* emlxs_node_find_mac() */
472
473
474extern NODELIST *
473emlxs_node_find_did(emlxs_port_t *port, uint32_t did)
475emlxs_node_find_did(emlxs_port_t *port, uint32_t did, uint32_t lock)
474{
475 emlxs_hba_t *hba = HBA;
476 NODELIST *nlp;
477 uint32_t hash;
478
479 /* Check for invalid node ids */
480 if ((did == 0) && (!(hba->flag & FC_LOOPBACK_MODE))) {
481 return ((NODELIST *)0);

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

507 /*
508 * Convert well known fabric addresses to the FABRIC_DID,
509 * since we don't login to some of them
510 */
511 if ((did == SCR_DID)) {
512 did = FABRIC_DID;
513 }
514
476{
477 emlxs_hba_t *hba = HBA;
478 NODELIST *nlp;
479 uint32_t hash;
480
481 /* Check for invalid node ids */
482 if ((did == 0) && (!(hba->flag & FC_LOOPBACK_MODE))) {
483 return ((NODELIST *)0);

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

509 /*
510 * Convert well known fabric addresses to the FABRIC_DID,
511 * since we don't login to some of them
512 */
513 if ((did == SCR_DID)) {
514 did = FABRIC_DID;
515 }
516
515 rw_enter(&port->node_rwlock, RW_READER);
517 if (lock) {
518 rw_enter(&port->node_rwlock, RW_READER);
519 }
516 hash = EMLXS_DID_HASH(did);
517 nlp = port->node_table[hash];
518 while (nlp != NULL) {
519 /* Check for obvious match */
520 if (nlp->nlp_DID == did) {
520 hash = EMLXS_DID_HASH(did);
521 nlp = port->node_table[hash];
522 while (nlp != NULL) {
523 /* Check for obvious match */
524 if (nlp->nlp_DID == did) {
521 rw_exit(&port->node_rwlock);
525 if (lock) {
526 rw_exit(&port->node_rwlock);
527 }
522 return (nlp);
523 }
524
525 /* Check for detailed match */
526 else if (emlxs_node_match_did(port, nlp, did)) {
528 return (nlp);
529 }
530
531 /* Check for detailed match */
532 else if (emlxs_node_match_did(port, nlp, did)) {
527 rw_exit(&port->node_rwlock);
533 if (lock) {
534 rw_exit(&port->node_rwlock);
535 }
528 return (nlp);
529 }
530
531 nlp = (NODELIST *)nlp->nlp_list_next;
532 }
536 return (nlp);
537 }
538
539 nlp = (NODELIST *)nlp->nlp_list_next;
540 }
533 rw_exit(&port->node_rwlock);
534
541
542 if (lock) {
543 rw_exit(&port->node_rwlock);
544 }
545
535 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg, "find: did=%x",
536 did);
537
538 /* no match found */
539 return ((NODELIST *)0);
540
541} /* emlxs_node_find_did() */
542

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

556 return (nlp);
557 }
558
559 nlp = (NODELIST *)nlp->nlp_list_next;
560 }
561 }
562 rw_exit(&port->node_rwlock);
563
546 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg, "find: did=%x",
547 did);
548
549 /* no match found */
550 return ((NODELIST *)0);
551
552} /* emlxs_node_find_did() */
553

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

567 return (nlp);
568 }
569
570 nlp = (NODELIST *)nlp->nlp_list_next;
571 }
572 }
573 rw_exit(&port->node_rwlock);
574
564 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg, "find: rpi=%x",
575 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg, "find: rpi=%d",
565 rpi);
566
567 /* no match found */
568 return ((NODELIST *)0);
569
570} /* emlxs_node_find_rpi() */
571
572
573extern NODELIST *
576 rpi);
577
578 /* no match found */
579 return ((NODELIST *)0);
580
581} /* emlxs_node_find_rpi() */
582
583
584extern NODELIST *
574emlxs_node_find_wwpn(emlxs_port_t *port, uint8_t *wwpn)
585emlxs_node_find_wwpn(emlxs_port_t *port, uint8_t *wwpn, uint32_t lock)
575{
576 NODELIST *nlp;
577 uint32_t i;
578 uint32_t j;
579 uint8_t *bptr1;
580 uint8_t *bptr2;
581
586{
587 NODELIST *nlp;
588 uint32_t i;
589 uint32_t j;
590 uint8_t *bptr1;
591 uint8_t *bptr2;
592
582 rw_enter(&port->node_rwlock, RW_READER);
593 if (lock) {
594 rw_enter(&port->node_rwlock, RW_READER);
595 }
596
583 for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
584 nlp = port->node_table[i];
585 while (nlp != NULL) {
586 bptr1 = (uint8_t *)&nlp->nlp_portname;
587 bptr1 += 7;
588 bptr2 = (uint8_t *)wwpn;
589 bptr2 += 7;
590
591 for (j = 0; j < 8; j++) {
592 if (*bptr1-- != *bptr2--) {
593 break;
594 }
595 }
596
597 if (j == 8) {
597 for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
598 nlp = port->node_table[i];
599 while (nlp != NULL) {
600 bptr1 = (uint8_t *)&nlp->nlp_portname;
601 bptr1 += 7;
602 bptr2 = (uint8_t *)wwpn;
603 bptr2 += 7;
604
605 for (j = 0; j < 8; j++) {
606 if (*bptr1-- != *bptr2--) {
607 break;
608 }
609 }
610
611 if (j == 8) {
598 rw_exit(&port->node_rwlock);
612 if (lock) {
613 rw_exit(&port->node_rwlock);
614 }
599 return (nlp);
600 }
601
602 nlp = (NODELIST *)nlp->nlp_list_next;
603 }
604 }
615 return (nlp);
616 }
617
618 nlp = (NODELIST *)nlp->nlp_list_next;
619 }
620 }
605 rw_exit(&port->node_rwlock);
606
621
622 if (lock) {
623 rw_exit(&port->node_rwlock);
624 }
625
607 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg,
608 "find: wwpn=%02x%02x%02x%02x%02x%02x%02x%02x", wwpn[0], wwpn[1],
609 wwpn[2], wwpn[3], wwpn[4], wwpn[5], wwpn[6], wwpn[7]);
610
611 /* no match found */
612 return ((NODELIST *)0);
613
614} /* emlxs_node_find_wwpn() */

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

709
710 if (port->node_count) {
711 port->node_count--;
712 }
713
714 wwn = (uint8_t *)&ndlp->nlp_portname;
715 EMLXS_MSGF(EMLXS_CONTEXT,
716 &emlxs_node_destroy_msg, "did=%06x "
626 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_not_found_msg,
627 "find: wwpn=%02x%02x%02x%02x%02x%02x%02x%02x", wwpn[0], wwpn[1],
628 wwpn[2], wwpn[3], wwpn[4], wwpn[5], wwpn[6], wwpn[7]);
629
630 /* no match found */
631 return ((NODELIST *)0);
632
633} /* emlxs_node_find_wwpn() */

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

728
729 if (port->node_count) {
730 port->node_count--;
731 }
732
733 wwn = (uint8_t *)&ndlp->nlp_portname;
734 EMLXS_MSGF(EMLXS_CONTEXT,
735 &emlxs_node_destroy_msg, "did=%06x "
717 "rpi=%x wwpn=%02x%02x%02x%02x%02x%02x%02x%02x "
736 "rpi=%d wwpn=%02x%02x%02x%02x%02x%02x%02x%02x "
718 "count=%d", ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
719 wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6],
720 wwn[7], port->node_count);
721
722 (void) emlxs_tx_node_flush(port, ndlp, 0, 0, 0);
723
724 /* Break Node/RPI binding */
725 if (ndlp->rpip) {

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

754
755} /* emlxs_node_destroy_all() */
756
757
758extern NODELIST *
759emlxs_node_create(emlxs_port_t *port, uint32_t did, uint32_t rpi, SERV_PARM *sp)
760{
761 emlxs_hba_t *hba = HBA;
737 "count=%d", ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
738 wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6],
739 wwn[7], port->node_count);
740
741 (void) emlxs_tx_node_flush(port, ndlp, 0, 0, 0);
742
743 /* Break Node/RPI binding */
744 if (ndlp->rpip) {

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

773
774} /* emlxs_node_destroy_all() */
775
776
777extern NODELIST *
778emlxs_node_create(emlxs_port_t *port, uint32_t did, uint32_t rpi, SERV_PARM *sp)
779{
780 emlxs_hba_t *hba = HBA;
762 NODELIST *ndlp;
781 NODELIST *ndlp, *ndlp_wwn;
763 uint8_t *wwn;
764 emlxs_vvl_fmt_t vvl;
765 RPIobj_t *rpip;
766
782 uint8_t *wwn;
783 emlxs_vvl_fmt_t vvl;
784 RPIobj_t *rpip;
785
767 ndlp = emlxs_node_find_did(port, did);
786 rw_enter(&port->node_rwlock, RW_WRITER);
768
787
788 ndlp = emlxs_node_find_did(port, did, 0);
789 ndlp_wwn = emlxs_node_find_wwpn(port, (uint8_t *)&sp->portName, 0);
790
791 /* Zero out the stale node worldwide names */
792 if (ndlp_wwn && (ndlp != ndlp_wwn)) {
793 bzero((uint8_t *)&ndlp_wwn->nlp_nodename, sizeof (NAME_TYPE));
794 bzero((uint8_t *)&ndlp_wwn->nlp_portname, sizeof (NAME_TYPE));
795 }
796
769 /* Update the node */
770 if (ndlp) {
797 /* Update the node */
798 if (ndlp) {
771 rw_enter(&port->node_rwlock, RW_WRITER);
772
773 ndlp->nlp_Rpi = (uint16_t)rpi;
774 ndlp->nlp_DID = did;
775
776 bcopy((uint8_t *)sp, (uint8_t *)&ndlp->sparm,
777 sizeof (SERV_PARM));
778
779 bcopy((uint8_t *)&sp->nodeName,
780 (uint8_t *)&ndlp->nlp_nodename,

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

791 if (rpip) {
792 rpip->node = ndlp;
793 ndlp->rpip = rpip;
794 } else {
795 ndlp->rpip = NULL;
796
797 EMLXS_MSGF(EMLXS_CONTEXT,
798 &emlxs_node_create_msg,
799 ndlp->nlp_Rpi = (uint16_t)rpi;
800 ndlp->nlp_DID = did;
801
802 bcopy((uint8_t *)sp, (uint8_t *)&ndlp->sparm,
803 sizeof (SERV_PARM));
804
805 bcopy((uint8_t *)&sp->nodeName,
806 (uint8_t *)&ndlp->nlp_nodename,

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

817 if (rpip) {
818 rpip->node = ndlp;
819 ndlp->rpip = rpip;
820 } else {
821 ndlp->rpip = NULL;
822
823 EMLXS_MSGF(EMLXS_CONTEXT,
824 &emlxs_node_create_msg,
799 "Unable to find RPI. did=%x rpi=%x",
825 "Unable to find RPI. did=%x rpi=%d",
800 did, rpi);
801 }
802 } else {
803 ndlp->rpip = NULL;
804 }
826 did, rpi);
827 }
828 } else {
829 ndlp->rpip = NULL;
830 }
805 rw_exit(&port->node_rwlock);
806
807 wwn = (uint8_t *)&ndlp->nlp_portname;
808 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_update_msg,
831
832 wwn = (uint8_t *)&ndlp->nlp_portname;
833 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_update_msg,
809 "node=%p did=%06x rpi=%x "
834 "node=%p did=%06x rpi=%d "
810 "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
811 ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
812 wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
813
814 goto done;
815 }
816
817 /* Allocate a new node */
835 "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
836 ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
837 wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
838
839 goto done;
840 }
841
842 /* Allocate a new node */
818 ndlp = (NODELIST *)emlxs_mem_get(hba, MEM_NLP, 0);
843 ndlp = (NODELIST *)emlxs_mem_get(hba, MEM_NLP);
819
820 if (ndlp) {
844
845 if (ndlp) {
821 rw_enter(&port->node_rwlock, RW_WRITER);
822
823 ndlp->nlp_Rpi = (uint16_t)rpi;
824 ndlp->nlp_DID = did;
825
826 bcopy((uint8_t *)sp, (uint8_t *)&ndlp->sparm,
827 sizeof (SERV_PARM));
828
829 bcopy((uint8_t *)&sp->nodeName,
830 (uint8_t *)&ndlp->nlp_nodename,

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

847 if (rpip) {
848 rpip->node = ndlp;
849 ndlp->rpip = rpip;
850 } else {
851 ndlp->rpip = NULL;
852
853 EMLXS_MSGF(EMLXS_CONTEXT,
854 &emlxs_node_create_msg,
846 ndlp->nlp_Rpi = (uint16_t)rpi;
847 ndlp->nlp_DID = did;
848
849 bcopy((uint8_t *)sp, (uint8_t *)&ndlp->sparm,
850 sizeof (SERV_PARM));
851
852 bcopy((uint8_t *)&sp->nodeName,
853 (uint8_t *)&ndlp->nlp_nodename,

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

870 if (rpip) {
871 rpip->node = ndlp;
872 ndlp->rpip = rpip;
873 } else {
874 ndlp->rpip = NULL;
875
876 EMLXS_MSGF(EMLXS_CONTEXT,
877 &emlxs_node_create_msg,
855 "Unable to find RPI. did=%x rpi=%x",
878 "Unable to find RPI. did=%x rpi=%d",
856 did, rpi);
857 }
858 } else {
859 ndlp->rpip = NULL;
860 }
879 did, rpi);
880 }
881 } else {
882 ndlp->rpip = NULL;
883 }
861 rw_exit(&port->node_rwlock);
862
884
885#ifdef NODE_THROTTLE_SUPPORT
886 emlxs_node_throttle_set(port, ndlp);
887#endif /* NODE_THROTTLE_SUPPORT */
888
863 /* Add the node */
864 emlxs_node_add(port, ndlp);
865
866 goto done;
867 }
868
889 /* Add the node */
890 emlxs_node_add(port, ndlp);
891
892 goto done;
893 }
894
895 rw_exit(&port->node_rwlock);
869 wwn = (uint8_t *)&sp->portName;
870 EMLXS_MSGF(EMLXS_CONTEXT,
871 &emlxs_node_create_failed_msg,
872 "Unable to allocate node. did=%06x "
873 "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
874 did, wwn[0], wwn[1], wwn[2],
875 wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
876
877 return (NULL);
878
879done:
896 wwn = (uint8_t *)&sp->portName;
897 EMLXS_MSGF(EMLXS_CONTEXT,
898 &emlxs_node_create_failed_msg,
899 "Unable to allocate node. did=%06x "
900 "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
901 did, wwn[0], wwn[1], wwn[2],
902 wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
903
904 return (NULL);
905
906done:
907 rw_exit(&port->node_rwlock);
880 if (sp->VALID_VENDOR_VERSION) {
881 bcopy((caddr_t *)&sp->vendorVersion[0],
882 (caddr_t *)&vvl, sizeof (emlxs_vvl_fmt_t));
883
884 vvl.un0.word0 = LE_SWAP32(vvl.un0.word0);
885 vvl.un1.word1 = LE_SWAP32(vvl.un1.word1);
886
887 if ((vvl.un0.w0.oui == 0x0000C9) &&
888 (vvl.un1.w1.vport)) {
889 ndlp->nlp_fcp_info |= NLP_EMLX_VPORT;
890 }
891 }
892
893 /* Open the node */
894 emlxs_node_open(port, ndlp, hba->channel_ct);
895 emlxs_node_open(port, ndlp, hba->channel_els);
896 emlxs_node_open(port, ndlp, hba->channel_ip);
897 emlxs_node_open(port, ndlp, hba->channel_fcp);
898
908 if (sp->VALID_VENDOR_VERSION) {
909 bcopy((caddr_t *)&sp->vendorVersion[0],
910 (caddr_t *)&vvl, sizeof (emlxs_vvl_fmt_t));
911
912 vvl.un0.word0 = LE_SWAP32(vvl.un0.word0);
913 vvl.un1.word1 = LE_SWAP32(vvl.un1.word1);
914
915 if ((vvl.un0.w0.oui == 0x0000C9) &&
916 (vvl.un1.w1.vport)) {
917 ndlp->nlp_fcp_info |= NLP_EMLX_VPORT;
918 }
919 }
920
921 /* Open the node */
922 emlxs_node_open(port, ndlp, hba->channel_ct);
923 emlxs_node_open(port, ndlp, hba->channel_els);
924 emlxs_node_open(port, ndlp, hba->channel_ip);
925 emlxs_node_open(port, ndlp, hba->channel_fcp);
926
927 EMLXS_SET_DFC_STATE(ndlp, NODE_LOGIN);
928
899 return (ndlp);
900
901} /* emlxs_node_create() */
902
903
929 return (ndlp);
930
931} /* emlxs_node_create() */
932
933
904extern void
934/* node_rwlock must be held when calling this routine */
935static void
905emlxs_node_add(emlxs_port_t *port, NODELIST *ndlp)
906{
907 NODELIST *np;
908 uint8_t *wwn;
909 uint32_t hash;
910
936emlxs_node_add(emlxs_port_t *port, NODELIST *ndlp)
937{
938 NODELIST *np;
939 uint8_t *wwn;
940 uint32_t hash;
941
911 rw_enter(&port->node_rwlock, RW_WRITER);
912 hash = EMLXS_DID_HASH(ndlp->nlp_DID);
913 np = port->node_table[hash];
914
915 /*
916 * Insert node pointer to the head
917 */
918 port->node_table[hash] = ndlp;
919 if (!np) {
920 ndlp->nlp_list_next = NULL;
921 } else {
922 ndlp->nlp_list_next = np;
923 }
924 port->node_count++;
925
926 wwn = (uint8_t *)&ndlp->nlp_portname;
927 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_msg,
942 hash = EMLXS_DID_HASH(ndlp->nlp_DID);
943 np = port->node_table[hash];
944
945 /*
946 * Insert node pointer to the head
947 */
948 port->node_table[hash] = ndlp;
949 if (!np) {
950 ndlp->nlp_list_next = NULL;
951 } else {
952 ndlp->nlp_list_next = np;
953 }
954 port->node_count++;
955
956 wwn = (uint8_t *)&ndlp->nlp_portname;
957 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_msg,
928 "node=%p did=%06x rpi=%x wwpn=%02x%02x%02x%02x%02x%02x%02x%02x "
958 "node=%p did=%06x rpi=%d wwpn=%02x%02x%02x%02x%02x%02x%02x%02x "
929 "count=%d", ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0], wwn[1],
930 wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7], port->node_count);
931
959 "count=%d", ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0], wwn[1],
960 wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7], port->node_count);
961
932 rw_exit(&port->node_rwlock);
933
934 return;
935
936} /* emlxs_node_add() */
937
938
939extern void
940emlxs_node_rm(emlxs_port_t *port, NODELIST *ndlp)
941{

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

960
961 if (port->node_count) {
962 port->node_count--;
963 }
964
965 wwn = (uint8_t *)&ndlp->nlp_portname;
966 EMLXS_MSGF(EMLXS_CONTEXT,
967 &emlxs_node_destroy_msg, "did=%06x "
962 return;
963
964} /* emlxs_node_add() */
965
966
967extern void
968emlxs_node_rm(emlxs_port_t *port, NODELIST *ndlp)
969{

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

988
989 if (port->node_count) {
990 port->node_count--;
991 }
992
993 wwn = (uint8_t *)&ndlp->nlp_portname;
994 EMLXS_MSGF(EMLXS_CONTEXT,
995 &emlxs_node_destroy_msg, "did=%06x "
968 "rpi=%x wwpn=%02x%02x%02x%02x%02x%02x%02x%02x "
996 "rpi=%d wwpn=%02x%02x%02x%02x%02x%02x%02x%02x "
969 "count=%d", ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
970 wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6],
971 wwn[7], port->node_count);
972
973 (void) emlxs_tx_node_flush(port, ndlp, 0, 1, 0);
974
975 ndlp->nlp_active = 0;
976

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

991 prevp = np;
992 np = np->nlp_list_next;
993 }
994 rw_exit(&port->node_rwlock);
995
996 return;
997
998} /* emlxs_node_rm() */
997 "count=%d", ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
998 wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6],
999 wwn[7], port->node_count);
1000
1001 (void) emlxs_tx_node_flush(port, ndlp, 0, 1, 0);
1002
1003 ndlp->nlp_active = 0;
1004

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

1019 prevp = np;
1020 np = np->nlp_list_next;
1021 }
1022 rw_exit(&port->node_rwlock);
1023
1024 return;
1025
1026} /* emlxs_node_rm() */
1027
1028
1029extern void
1030emlxs_node_throttle_set(emlxs_port_t *port, NODELIST *ndlp)
1031{
1032 emlxs_hba_t *hba = HBA;
1033 emlxs_config_t *cfg = &CFG;
1034 char prop[64];
1035 char buf1[32];
1036 uint32_t throttle;
1037
1038 /* Set global default */
1039 throttle = (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)?
1040 cfg[CFG_TGT_DEPTH].current:0;
1041
1042 /* Check per wwpn default */
1043 (void) snprintf(prop, sizeof (prop), "w%s-depth",
1044 emlxs_wwn_xlate(buf1, sizeof (buf1),
1045 (uint8_t *)&ndlp->nlp_portname));
1046
1047 throttle = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY,
1048 (void *)hba->dip, DDI_PROP_DONTPASS, prop, throttle);
1049
1050 /* Check per driver/wwpn default */
1051 (void) snprintf(prop, sizeof (prop), "%s%d-w%s-depth", DRIVER_NAME,
1052 hba->ddiinst, emlxs_wwn_xlate(buf1, sizeof (buf1),
1053 (uint8_t *)&ndlp->nlp_portname));
1054
1055 throttle = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY,
1056 (void *)hba->dip, DDI_PROP_DONTPASS, prop, throttle);
1057
1058 /* Check limit */
1059 throttle = MIN(throttle, MAX_NODE_THROTTLE);
1060
1061 ndlp->io_throttle = throttle;
1062
1063 return;
1064
1065} /* emlxs_node_throttle_set() */