Author: mav
Date: Wed Dec 30 11:51:35 2015
New Revision: 292924
URL: https://svnweb.freebsd.org/changeset/base/292924

Log:
  MFC r292741: Make port logins asynchronous, following r292739 logic.
  
  This is even more important since it involves more network operations and
  more prone to delays and timeouts.

Modified:
  stable/10/sys/dev/isp/isp.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/isp/isp.c
==============================================================================
--- stable/10/sys/dev/isp/isp.c Wed Dec 30 11:51:13 2015        (r292923)
+++ stable/10/sys/dev/isp/isp.c Wed Dec 30 11:51:35 2015        (r292924)
@@ -108,7 +108,7 @@ static void isp_fibre_init(ispsoftc_t *)
 static void isp_fibre_init_2400(ispsoftc_t *);
 static void isp_clear_portdb(ispsoftc_t *, int);
 static void isp_mark_portdb(ispsoftc_t *, int);
-static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int);
+static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int);
 static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
 static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int);
@@ -2550,13 +2550,11 @@ isp_mark_portdb(ispsoftc_t *isp, int cha
  * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
  */
 static int
-isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int 
flags, int gs)
+isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int 
flags)
 {
-       mbreg_t mbs;
-       uint8_t q[QENTRY_LEN];
-       isp_plogx_t *plp;
-       fcparam *fcp;
-       uint8_t *scp;
+       isp_plogx_t pl;
+       void *reqp;
+       uint8_t resp[QENTRY_LEN];
        uint32_t sst, parm1;
        int rval, lev;
        const char *msg;
@@ -2576,64 +2574,58 @@ isp_plogx(ispsoftc_t *isp, int chan, uin
                }
        }
 
-       ISP_MEMZERO(q, QENTRY_LEN);
-       plp = (isp_plogx_t *) q;
-       plp->plogx_header.rqs_entry_count = 1;
-       plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
-       plp->plogx_handle = 0xffffffff;
-       plp->plogx_nphdl = handle;
-       plp->plogx_vphdl = chan;
-       plp->plogx_portlo = portid;
-       plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
-       plp->plogx_flags = flags;
+       ISP_MEMZERO(&pl, sizeof(pl));
+       pl.plogx_header.rqs_entry_count = 1;
+       pl.plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
+       pl.plogx_nphdl = handle;
+       pl.plogx_vphdl = chan;
+       pl.plogx_portlo = portid;
+       pl.plogx_rspsz_porthi = (portid >> 16) & 0xff;
+       pl.plogx_flags = flags;
 
-       if (isp->isp_dblev & ISP_LOGDEBUG1) {
-               isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp);
-       }
-
-       if (gs == 0) {
-               if (FC_SCRATCH_ACQUIRE(isp, chan)) {
-                       isp_prt(isp, ISP_LOGERR, sacq);
-                       return (-1);
-               }
+       /* Prepare space for response in memory */
+       memset(resp, 0xff, sizeof(resp));
+       pl.plogx_handle = isp_allocate_handle(isp, resp, ISP_HANDLE_CTRL);
+       if (pl.plogx_handle == 0) {
+               isp_prt(isp, ISP_LOGERR,
+                   "%s: PLOGX of Chan %d out of handles", __func__, chan);
+               return (-1);
        }
-       fcp = FCPARAM(isp, chan);
-       scp = fcp->isp_scratch;
-       isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
 
-       MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL,
-           MBCMD_DEFAULT_TIMEOUT + ICB_LOGIN_TOV * 1000000);
-       mbs.param[1] = QENTRY_LEN;
-       mbs.param[2] = DMA_WD1(fcp->isp_scdma);
-       mbs.param[3] = DMA_WD0(fcp->isp_scdma);
-       mbs.param[6] = DMA_WD3(fcp->isp_scdma);
-       mbs.param[7] = DMA_WD2(fcp->isp_scdma);
-       MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
-       isp_mboxcmd(isp, &mbs);
-       if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-               rval = mbs.param[0];
-               goto out;
+       /* Send request and wait for response. */
+       reqp = isp_getrqentry(isp);
+       if (reqp == NULL) {
+               isp_prt(isp, ISP_LOGERR,
+                   "%s: PLOGX of Chan %d out of rqent", __func__, chan);
+               isp_destroy_handle(isp, pl.plogx_handle);
+               return (-1);
        }
-       MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
-       scp += QENTRY_LEN;
-       isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
-       if (isp->isp_dblev & ISP_LOGDEBUG1) {
-               isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
+       if (isp->isp_dblev & ISP_LOGDEBUG1)
+               isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, &pl);
+       isp_put_plogx(isp, &pl, (isp_plogx_t *)reqp);
+       ISP_SYNC_REQUEST(isp);
+       if (msleep(resp, &isp->isp_lock, 0, "PLOGX", 3 * ICB_LOGIN_TOV * hz)
+           == EWOULDBLOCK) {
+               isp_prt(isp, ISP_LOGERR,
+                   "%s: PLOGX of Chan %d timed out", __func__, chan);
+               isp_destroy_handle(isp, pl.plogx_handle);
+               return (-1);
        }
+       isp_get_plogx(isp, (isp_plogx_t *)resp, &pl);
+       if (isp->isp_dblev & ISP_LOGDEBUG1)
+               isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, &pl);
 
-       if (plp->plogx_status == PLOGX_STATUS_OK) {
-               rval = 0;
-               goto out;
-       } else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
+       if (pl.plogx_status == PLOGX_STATUS_OK) {
+               return (0);
+       } else if (pl.plogx_status != PLOGX_STATUS_IOCBERR) {
                isp_prt(isp, ISP_LOGWARN,
                    "status 0x%x on port login IOCB channel %d",
-                   plp->plogx_status, chan);
-               rval = -1;
-               goto out;
+                   pl.plogx_status, chan);
+               return (-1);
        }
 
-       sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
-       parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
+       sst = pl.plogx_ioparm[0].lo16 | (pl.plogx_ioparm[0].hi16 << 16);
+       parm1 = pl.plogx_ioparm[1].lo16 | (pl.plogx_ioparm[1].hi16 << 16);
 
        rval = -1;
        lev = ISP_LOGERR;
@@ -2694,17 +2686,13 @@ isp_plogx(ispsoftc_t *isp, int chan, uin
                msg = "no FLOGI_ACC";
                break;
        default:
-               ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", 
plp->plogx_status, flags);
+               ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", 
pl.plogx_status, flags);
                msg = buf;
                break;
        }
        if (msg) {
                isp_prt(isp, ISP_LOGERR, "Chan %d PLOGX PortID 0x%06x to N-Port 
handle 0x%x: %s", chan, portid, handle, msg);
        }
-out:
-       if (gs == 0) {
-               FC_SCRATCH_RELEASE(isp, chan);
-       }
        return (rval);
 }
 
@@ -3196,7 +3184,7 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
                                    lp->portid,
                                    PLOGX_FLG_CMD_LOGO |
                                    PLOGX_FLG_IMPLICIT |
-                                   PLOGX_FLG_FREE_NPHDL, 0);
+                                   PLOGX_FLG_FREE_NPHDL);
                        }
                        /*
                         * Note that we might come out of this with our state
@@ -3883,7 +3871,7 @@ isp_login_device(ispsoftc_t *isp, int ch
                /*
                 * Now try and log into the device
                 */
-               r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 
1);
+               r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
                if (r == 0) {
                        break;
                } else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
@@ -3892,12 +3880,12 @@ isp_login_device(ispsoftc_t *isp, int ch
                         * handle. We need to break that association. We used 
to try and just substitute the handle, but then
                         * failed to get any data via isp_getpdb (below).
                         */
-                       if (isp_plogx(isp, chan, r >> 16, portid, 
PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1)) {
+                       if (isp_plogx(isp, chan, r >> 16, portid, 
PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL)) {
                                isp_prt(isp, ISP_LOGERR, "baw... logout of %x 
failed", r >> 16);
                        }
                        if (FCPARAM(isp, chan)->isp_loopstate != 
LOOP_SCANNING_FABRIC)
                                return (-1);
-                       r = isp_plogx(isp, chan, handle, portid, 
PLOGX_FLG_CMD_PLOGI, 1);
+                       r = isp_plogx(isp, chan, handle, portid, 
PLOGX_FLG_CMD_PLOGI);
                        if (r != 0)
                                i = lim;
                        break;
@@ -4937,11 +4925,11 @@ isp_control(ispsoftc_t *isp, ispctl_t ct
                va_end(ap);
 
                if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || 
(p->handle != NIL_HANDLE)) {
-                       return (isp_plogx(isp, p->channel, p->handle, 
p->portid, p->flags, 0));
+                       return (isp_plogx(isp, p->channel, p->handle, 
p->portid, p->flags));
                }
                do {
                        isp_next_handle(isp, &p->handle);
-                       r = isp_plogx(isp, p->channel, p->handle, p->portid, 
p->flags, 0);
+                       r = isp_plogx(isp, p->channel, p->handle, p->portid, 
p->flags);
                        if ((r & 0xffff) == MBOX_PORT_ID_USED) {
                                p->handle = r >> 16;
                                r = 0;
@@ -6170,6 +6158,7 @@ isp_handle_other_response(ispsoftc_t *is
                return (1);
        case RQSTYPE_VP_MODIFY:
        case RQSTYPE_VP_CTRL:
+       case RQSTYPE_LOGIN:
                ISP_IOXGET_32(isp, (uint32_t *)(hp + 1), hdl);
                ptr = isp_find_xs(isp, hdl);
                if (ptr != NULL) {
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to