isp.c (291099) | isp.c (291144) |
---|---|
1/*- 2 * Copyright (c) 1997-2009 by Matthew Jacob 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * --- 33 unchanged lines hidden (view full) --- 42 */ 43#ifdef __NetBSD__ 44#include <sys/cdefs.h> 45__KERNEL_RCSID(0, "$NetBSD$"); 46#include <dev/ic/isp_netbsd.h> 47#endif 48#ifdef __FreeBSD__ 49#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997-2009 by Matthew Jacob 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * --- 33 unchanged lines hidden (view full) --- 42 */ 43#ifdef __NetBSD__ 44#include <sys/cdefs.h> 45__KERNEL_RCSID(0, "$NetBSD$"); 46#include <dev/ic/isp_netbsd.h> 47#endif 48#ifdef __FreeBSD__ 49#include <sys/cdefs.h> |
50__FBSDID("$FreeBSD: head/sys/dev/isp/isp.c 291099 2015-11-20 14:20:24Z mav $"); | 50__FBSDID("$FreeBSD: head/sys/dev/isp/isp.c 291144 2015-11-21 21:01:00Z mav $"); |
51#include <dev/isp/isp_freebsd.h> 52#endif 53#ifdef __OpenBSD__ 54#include <dev/ic/isp_openbsd.h> 55#endif 56#ifdef __linux__ 57#include "isp_linux.h" 58#endif --- 2256 unchanged lines hidden (view full) --- 2315 fcparam *fcp = FCPARAM(isp, chan); 2316 fcportdb_t *lp; 2317 int i; 2318 2319 for (i = 0; i < MAX_FC_TARG; i++) { 2320 lp = &fcp->portdb[i]; 2321 if (lp->state == FC_PORTDB_STATE_NIL) 2322 continue; | 51#include <dev/isp/isp_freebsd.h> 52#endif 53#ifdef __OpenBSD__ 54#include <dev/ic/isp_openbsd.h> 55#endif 56#ifdef __linux__ 57#include "isp_linux.h" 58#endif --- 2256 unchanged lines hidden (view full) --- 2315 fcparam *fcp = FCPARAM(isp, chan); 2316 fcportdb_t *lp; 2317 int i; 2318 2319 for (i = 0; i < MAX_FC_TARG; i++) { 2320 lp = &fcp->portdb[i]; 2321 if (lp->state == FC_PORTDB_STATE_NIL) 2322 continue; |
2323 if ((lp->portid & 0xfffc00) == 0xfffc00) | 2323 if (lp->portid >= DOMAIN_CONTROLLER_BASE && 2324 lp->portid <= DOMAIN_CONTROLLER_END) |
2324 continue; 2325 fcp->portdb[i].probational = 1; 2326 } 2327} 2328 2329/* 2330 * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards 2331 * or via FABRIC LOGIN/FABRIC LOGOUT for other cards. --- 450 unchanged lines hidden (view full) --- 2782 int i, r; 2783 uint16_t nphdl; 2784 fcparam *fcp; 2785 isp_pdb_t pdb; 2786 NANOTIME_T hra, hrb; 2787 2788 fcp = FCPARAM(isp, chan); 2789 | 2325 continue; 2326 fcp->portdb[i].probational = 1; 2327 } 2328} 2329 2330/* 2331 * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards 2332 * or via FABRIC LOGIN/FABRIC LOGOUT for other cards. --- 450 unchanged lines hidden (view full) --- 2783 int i, r; 2784 uint16_t nphdl; 2785 fcparam *fcp; 2786 isp_pdb_t pdb; 2787 NANOTIME_T hra, hrb; 2788 2789 fcp = FCPARAM(isp, chan); 2790 |
2790 /* Mark port database entries probational for following scan. */ 2791 isp_mark_portdb(isp, chan); 2792 | |
2793 if (fcp->isp_loopstate >= LOOP_LTEST_DONE) 2794 return (0); 2795 2796 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test", chan); 2797 fcp->isp_loopstate = LOOP_TESTING_LINK; 2798 2799 /* 2800 * Wait up to N microseconds for F/W to go to a ready state. --- 273 unchanged lines hidden (view full) --- 3074 lp->handle = pdb->handle; 3075 lp->port_wwn = wwpn; 3076 lp->node_wwn = wwnn; 3077 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x@0x%04x is new", 3078 chan, pdb->portid, pdb->handle); 3079} 3080 3081/* | 2791 if (fcp->isp_loopstate >= LOOP_LTEST_DONE) 2792 return (0); 2793 2794 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test", chan); 2795 fcp->isp_loopstate = LOOP_TESTING_LINK; 2796 2797 /* 2798 * Wait up to N microseconds for F/W to go to a ready state. --- 273 unchanged lines hidden (view full) --- 3072 lp->handle = pdb->handle; 3073 lp->port_wwn = wwpn; 3074 lp->node_wwn = wwnn; 3075 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x@0x%04x is new", 3076 chan, pdb->portid, pdb->handle); 3077} 3078 3079/* |
3080 * Fix port IDs for logged-in initiators on pre-2400 chips. 3081 * For those chips we are not receiving login events, adding initiators 3082 * based on ATIO requests, but there is no port ID in that structure. 3083 */ 3084static void 3085isp_fix_portids(ispsoftc_t *isp, int chan) 3086{ 3087 fcparam *fcp = FCPARAM(isp, chan); 3088 isp_pdb_t pdb; 3089 uint64_t wwpn; 3090 int i, r; 3091 3092 for (i = 0; i < MAX_FC_TARG; i++) { 3093 fcportdb_t *lp = &fcp->portdb[i]; 3094 3095 if (lp->state == FC_PORTDB_STATE_NIL || 3096 lp->state == FC_PORTDB_STATE_ZOMBIE) 3097 continue; 3098 if (VALID_PORT(lp->portid)) 3099 continue; 3100 3101 r = isp_getpdb(isp, chan, lp->handle, &pdb, 1); 3102 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) 3103 return; 3104 if (r != 0) { 3105 isp_prt(isp, ISP_LOGDEBUG1, 3106 "Chan %d FC Scan Loop handle %d returned %x", 3107 chan, lp->handle, r); 3108 continue; 3109 } 3110 3111 MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname); 3112 if (lp->port_wwn != wwpn) 3113 continue; 3114 lp->portid = lp->new_portid = pdb.portid; 3115 isp_prt(isp, ISP_LOG_SANCFG, 3116 "Chan %d Port 0x%06x@0x%04x is fixed", 3117 chan, pdb.portid, pdb.handle); 3118 } 3119} 3120 3121/* |
|
3082 * Scan local loop for devices. 3083 */ 3084static int 3085isp_scan_loop(ispsoftc_t *isp, int chan) 3086{ 3087 fcparam *fcp = FCPARAM(isp, chan); 3088 int idx, lim, r; 3089 isp_pdb_t pdb; 3090 uint16_t handles[LOCAL_LOOP_LIM]; 3091 uint16_t handle; 3092 3093 if (fcp->isp_loopstate < LOOP_LTEST_DONE) { 3094 return (-1); 3095 } 3096 if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) { 3097 return (0); 3098 } 3099 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan); | 3122 * Scan local loop for devices. 3123 */ 3124static int 3125isp_scan_loop(ispsoftc_t *isp, int chan) 3126{ 3127 fcparam *fcp = FCPARAM(isp, chan); 3128 int idx, lim, r; 3129 isp_pdb_t pdb; 3130 uint16_t handles[LOCAL_LOOP_LIM]; 3131 uint16_t handle; 3132 3133 if (fcp->isp_loopstate < LOOP_LTEST_DONE) { 3134 return (-1); 3135 } 3136 if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) { 3137 return (0); 3138 } 3139 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan); |
3140 fcp->isp_loopstate = LOOP_SCANNING_LOOP; |
|
3100 if (TOPO_IS_FABRIC(fcp->isp_topo)) { | 3141 if (TOPO_IS_FABRIC(fcp->isp_topo)) { |
3142 if (!IS_24XX(isp)) { 3143 isp_fix_portids(isp, chan); 3144 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) 3145 goto abort; 3146 } |
|
3101 isp_prt(isp, ISP_LOG_SANCFG, 3102 "Chan %d FC loop scan done (no loop)", chan); 3103 fcp->isp_loopstate = LOOP_LSCAN_DONE; 3104 return (0); 3105 } | 3147 isp_prt(isp, ISP_LOG_SANCFG, 3148 "Chan %d FC loop scan done (no loop)", chan); 3149 fcp->isp_loopstate = LOOP_LSCAN_DONE; 3150 return (0); 3151 } |
3106 fcp->isp_loopstate = LOOP_SCANNING_LOOP; | |
3107 3108 lim = LOCAL_LOOP_LIM; 3109 r = isp_gethandles(isp, chan, handles, &lim, 1, 1); 3110 if (r != 0) { 3111 isp_prt(isp, ISP_LOG_SANCFG, 3112 "Chan %d Getting list of handles failed with %x", chan, r); 3113 isp_prt(isp, ISP_LOG_SANCFG, 3114 "Chan %d FC loop scan done (bad)", chan); 3115 return (-1); 3116 } 3117 3118 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Got %d handles", 3119 chan, lim); 3120 3121 /* 3122 * Run through the list and get the port database info for each one. 3123 */ | 3152 3153 lim = LOCAL_LOOP_LIM; 3154 r = isp_gethandles(isp, chan, handles, &lim, 1, 1); 3155 if (r != 0) { 3156 isp_prt(isp, ISP_LOG_SANCFG, 3157 "Chan %d Getting list of handles failed with %x", chan, r); 3158 isp_prt(isp, ISP_LOG_SANCFG, 3159 "Chan %d FC loop scan done (bad)", chan); 3160 return (-1); 3161 } 3162 3163 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Got %d handles", 3164 chan, lim); 3165 3166 /* 3167 * Run through the list and get the port database info for each one. 3168 */ |
3169 isp_mark_portdb(isp, chan); |
|
3124 for (idx = 0; idx < lim; idx++) { 3125 handle = handles[idx]; 3126 3127 /* 3128 * Don't scan "special" ids. 3129 */ 3130 if (ISP_CAP_2KLOGIN(isp)) { 3131 if (handle >= NPH_RESERVED) --- 25 unchanged lines hidden (view full) --- 3157 */ 3158 r = isp_getpdb(isp, chan, handle, &pdb, 1); 3159 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) 3160 goto abort; 3161 if (r != 0) { 3162 isp_prt(isp, ISP_LOGDEBUG1, 3163 "Chan %d FC Scan Loop handle %d returned %x", 3164 chan, handle, r); | 3170 for (idx = 0; idx < lim; idx++) { 3171 handle = handles[idx]; 3172 3173 /* 3174 * Don't scan "special" ids. 3175 */ 3176 if (ISP_CAP_2KLOGIN(isp)) { 3177 if (handle >= NPH_RESERVED) --- 25 unchanged lines hidden (view full) --- 3203 */ 3204 r = isp_getpdb(isp, chan, handle, &pdb, 1); 3205 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) 3206 goto abort; 3207 if (r != 0) { 3208 isp_prt(isp, ISP_LOGDEBUG1, 3209 "Chan %d FC Scan Loop handle %d returned %x", 3210 chan, handle, r); |
3165 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) 3166 goto abort; | |
3167 continue; 3168 } 3169 3170 isp_pdb_add_update(isp, chan, &pdb); 3171 } 3172 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) 3173 goto abort; 3174 fcp->isp_loopstate = LOOP_LSCAN_DONE; --- 183 unchanged lines hidden (view full) --- 3358 3359 if (fcp->isp_loopstate < LOOP_LSCAN_DONE) { 3360 return (-1); 3361 } 3362 if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) { 3363 return (0); 3364 } 3365 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan); | 3211 continue; 3212 } 3213 3214 isp_pdb_add_update(isp, chan, &pdb); 3215 } 3216 if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) 3217 goto abort; 3218 fcp->isp_loopstate = LOOP_LSCAN_DONE; --- 183 unchanged lines hidden (view full) --- 3402 3403 if (fcp->isp_loopstate < LOOP_LSCAN_DONE) { 3404 return (-1); 3405 } 3406 if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) { 3407 return (0); 3408 } 3409 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan); |
3410 fcp->isp_loopstate = LOOP_SCANNING_FABRIC; |
|
3366 if (!TOPO_IS_FABRIC(fcp->isp_topo)) { 3367 fcp->isp_loopstate = LOOP_FSCAN_DONE; 3368 isp_prt(isp, ISP_LOG_SANCFG, 3369 "Chan %d FC fabric scan done (no fabric)", chan); 3370 return (0); 3371 } | 3411 if (!TOPO_IS_FABRIC(fcp->isp_topo)) { 3412 fcp->isp_loopstate = LOOP_FSCAN_DONE; 3413 isp_prt(isp, ISP_LOG_SANCFG, 3414 "Chan %d FC fabric scan done (no fabric)", chan); 3415 return (0); 3416 } |
3372 fcp->isp_loopstate = LOOP_SCANNING_FABRIC; | |
3373 3374 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 3375 isp_prt(isp, ISP_LOGERR, sacq); 3376fail: 3377 isp_prt(isp, ISP_LOG_SANCFG, 3378 "Chan %d FC fabric scan done (bad)", chan); 3379 return (-1); 3380 } --- 107 unchanged lines hidden (view full) --- 3488 * maybe still this one. We get some information to find out. 3489 * 3490 * Otherwise, it's a new fabric device, and we log into it 3491 * (unconditionally). After searching the entire database 3492 * again to make sure that we never ever ever ever have more 3493 * than one entry that has the same PortID or the same 3494 * WWNN/WWPN duple, we enter the device into our database. 3495 */ | 3417 3418 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 3419 isp_prt(isp, ISP_LOGERR, sacq); 3420fail: 3421 isp_prt(isp, ISP_LOG_SANCFG, 3422 "Chan %d FC fabric scan done (bad)", chan); 3423 return (-1); 3424 } --- 107 unchanged lines hidden (view full) --- 3532 * maybe still this one. We get some information to find out. 3533 * 3534 * Otherwise, it's a new fabric device, and we log into it 3535 * (unconditionally). After searching the entire database 3536 * again to make sure that we never ever ever ever have more 3537 * than one entry that has the same PortID or the same 3538 * WWNN/WWPN duple, we enter the device into our database. 3539 */ |
3496 | 3540 isp_mark_portdb(isp, chan); |
3497 for (portidx = 0; portidx < portlim; portidx++) { 3498 portid = ((rs1->snscb_ports[portidx].portid[0]) << 16) | 3499 ((rs1->snscb_ports[portidx].portid[1]) << 8) | 3500 ((rs1->snscb_ports[portidx].portid[2])); 3501 isp_prt(isp, ISP_LOG_SANCFG, 3502 "Chan %d Checking fabric port 0x%06x", chan, portid); 3503 if (portid == 0) { 3504 isp_prt(isp, ISP_LOG_SANCFG, | 3541 for (portidx = 0; portidx < portlim; portidx++) { 3542 portid = ((rs1->snscb_ports[portidx].portid[0]) << 16) | 3543 ((rs1->snscb_ports[portidx].portid[1]) << 8) | 3544 ((rs1->snscb_ports[portidx].portid[2])); 3545 isp_prt(isp, ISP_LOG_SANCFG, 3546 "Chan %d Checking fabric port 0x%06x", chan, portid); 3547 if (portid == 0) { 3548 isp_prt(isp, ISP_LOG_SANCFG, |
3505 "Chan %d Skipping null PortID at idx %d", | 3549 "Chan %d Port at idx %d is zero", |
3506 chan, portidx); 3507 continue; 3508 } 3509 if (portid == fcp->isp_portid) { 3510 isp_prt(isp, ISP_LOG_SANCFG, | 3550 chan, portidx); 3551 continue; 3552 } 3553 if (portid == fcp->isp_portid) { 3554 isp_prt(isp, ISP_LOG_SANCFG, |
3511 "Chan %d Skipping our PortID 0x%06x", chan, portid); | 3555 "Chan %d Port 0x%06x is our", chan, portid); |
3512 continue; 3513 } 3514 3515 /* Now search the entire port database for the same portid. */ 3516 if (isp_find_pdb_by_portid(isp, chan, portid, &lp)) { 3517 if (!lp->probational) { 3518 isp_prt(isp, ISP_LOGERR, 3519 "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)", --- 30 unchanged lines hidden (view full) --- 3550 goto relogin; 3551 } 3552 3553 isp_pdb_add_update(isp, chan, &pdb); 3554 continue; 3555 } 3556 3557relogin: | 3556 continue; 3557 } 3558 3559 /* Now search the entire port database for the same portid. */ 3560 if (isp_find_pdb_by_portid(isp, chan, portid, &lp)) { 3561 if (!lp->probational) { 3562 isp_prt(isp, ISP_LOGERR, 3563 "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)", --- 30 unchanged lines hidden (view full) --- 3594 goto relogin; 3595 } 3596 3597 isp_pdb_add_update(isp, chan, &pdb); 3598 continue; 3599 } 3600 3601relogin: |
3558 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) | 3602 if ((fcp->role & ISP_ROLE_INITIATOR) == 0) { 3603 isp_prt(isp, ISP_LOG_SANCFG, 3604 "Chan %d Port 0x%06x is not logged in", chan, portid); |
3559 continue; | 3605 continue; |
3606 } |
|
3560 3561 if (isp_login_device(isp, chan, portid, &pdb, 3562 &FCPARAM(isp, 0)->isp_lasthdl)) { 3563 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) 3564 goto abort; 3565 continue; 3566 } 3567 --- 2277 unchanged lines hidden (view full) --- 5845 case RQSTYPE_RPT_ID_ACQ: 5846 isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid); 5847 if (rid.ridacq_format == 0) { 5848 for (chan = 0; chan < isp->isp_nchan; chan++) { 5849 fcparam *fcp = FCPARAM(isp, chan); 5850 if (fcp->role == ISP_ROLE_NONE) 5851 continue; 5852 c = (chan == 0) ? 127 : (chan - 1); | 3607 3608 if (isp_login_device(isp, chan, portid, &pdb, 3609 &FCPARAM(isp, 0)->isp_lasthdl)) { 3610 if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) 3611 goto abort; 3612 continue; 3613 } 3614 --- 2277 unchanged lines hidden (view full) --- 5892 case RQSTYPE_RPT_ID_ACQ: 5893 isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid); 5894 if (rid.ridacq_format == 0) { 5895 for (chan = 0; chan < isp->isp_nchan; chan++) { 5896 fcparam *fcp = FCPARAM(isp, chan); 5897 if (fcp->role == ISP_ROLE_NONE) 5898 continue; 5899 c = (chan == 0) ? 127 : (chan - 1); |
5853 if (rid.ridacq_map[c / 16] & (1 << (c % 16))) | 5900 if (rid.ridacq_map[c / 16] & (1 << (c % 16))) { 5901 fcp->isp_loopstate = LOOP_NIL; |
5854 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, 5855 chan, ISPASYNC_CHANGE_OTHER); | 5902 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, 5903 chan, ISPASYNC_CHANGE_OTHER); |
5904 } |
|
5856 } 5857 } else { | 5905 } 5906 } else { |
5907 FCPARAM(isp, rid.ridacq_vp_index)->isp_loopstate = LOOP_NIL; |
|
5858 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, 5859 rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER); 5860 } 5861 return (1); 5862 case RQSTYPE_ATIO: 5863 case RQSTYPE_CTIO: 5864 case RQSTYPE_ENABLE_LUN: 5865 case RQSTYPE_MODIFY_LUN: --- 2336 unchanged lines hidden --- | 5908 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, 5909 rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER); 5910 } 5911 return (1); 5912 case RQSTYPE_ATIO: 5913 case RQSTYPE_CTIO: 5914 case RQSTYPE_ENABLE_LUN: 5915 case RQSTYPE_MODIFY_LUN: --- 2336 unchanged lines hidden --- |