From owner-p4-projects@FreeBSD.ORG Tue Nov 21 17:17:04 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7416B16A51F; Tue, 21 Nov 2006 17:17:04 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 41EC216A417 for ; Tue, 21 Nov 2006 17:17:04 +0000 (UTC) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3403243F17 for ; Tue, 21 Nov 2006 17:08:01 +0000 (GMT) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kALH8GLi064467 for ; Tue, 21 Nov 2006 17:08:16 GMT (envelope-from mjacob@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kALH8Fhf064461 for perforce@freebsd.org; Tue, 21 Nov 2006 17:08:15 GMT (envelope-from mjacob@freebsd.org) Date: Tue, 21 Nov 2006 17:08:15 GMT Message-Id: <200611211708.kALH8Fhf064461@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mjacob@freebsd.org using -f From: Matt Jacob To: Perforce Change Reviews Cc: Subject: PERFORCE change 110183 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Nov 2006 17:17:04 -0000 http://perforce.freebsd.org/chv.cgi?CH=110183 Change 110183 by mjacob@newisp on 2006/11/18 03:35:24 Make the SAN login/logout stuff more common between different chipsets and provied an isp_control entry point so that the outer layers can do PLOGI/LOGO explicitly. Add MS IOCB support. This completes the cycle for base support for SMI-S. Affected files ... .. //depot/projects/newisp/dev/bge/if_bge.c#10 edit .. //depot/projects/newisp/dev/isp/isp.c#38 edit .. //depot/projects/newisp/dev/isp/isp_library.c#21 edit .. //depot/projects/newisp/dev/isp/isp_library.h#13 edit .. //depot/projects/newisp/dev/isp/ispmbox.h#14 edit .. //depot/projects/newisp/dev/isp/ispvar.h#17 edit Differences ... ==== //depot/projects/newisp/dev/bge/if_bge.c#10 (text+ko) ==== @@ -2499,12 +2499,6 @@ } } - /* - * Write the magic number to the firmware mailbox at 0xb50 - * so that the driver can synchronize with the firmware. - */ - bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER); - /* Issue global reset */ bge_writereg_ind(sc, BGE_MISC_CFG, reset); @@ -2541,6 +2535,11 @@ CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE); /* + * Prevent PXE restart: write a magic number to the + * general communications memory at 0xB50. + */ + bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER); + /* * Poll the value location we just wrote until * we see the 1's complement of the magic number. * This indicates that the firmware initialization ==== //depot/projects/newisp/dev/isp/isp.c#38 (text+ko) ==== @@ -114,9 +114,9 @@ static void isp_fibre_init(ispsoftc_t *); static void isp_fibre_init_2400(ispsoftc_t *); static void isp_mark_portdb(ispsoftc_t *, int); -static void isp_plogx_24xx(ispsoftc_t *, uint16_t, uint32_t, int *); +static int isp_plogx(ispsoftc_t *, uint16_t, uint32_t, int, int); static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t); -static void isp_port_logout(ispsoftc_t *, uint16_t, uint32_t); +static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t); static int isp_getpdb(ispsoftc_t *, uint16_t, isp_pdb_t *, int); static uint64_t isp_get_portname(ispsoftc_t *, int, int); static int isp_fclink_test(ispsoftc_t *, int); @@ -2083,36 +2083,47 @@ /* * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards + * or via FABRIC LOGIN/FABRIC LOGOUT for other cards. */ -static void -isp_plogx_24xx(ispsoftc_t *isp, uint16_t handle, uint32_t portid, int *log_ret) +static int +isp_plogx(ispsoftc_t *isp, uint16_t handle, uint32_t portid, int flags, int gs) { mbreg_t mbs; uint8_t q[QENTRY_LEN]; - isp_plogx_t *plp = (isp_plogx_t *) q; - uint8_t *scp = FCPARAM(isp)->isp_scratch; + isp_plogx_t *plp; + uint8_t *scp; uint32_t sst, parm1; - int junk; + int rval; + + if (!IS_24XX(isp)) { + int action = flags & PLOGX_FLG_CMD_MASK; + if (action == PLOGX_FLG_CMD_PLOGI) { + return (isp_port_login(isp, handle, portid)); + } else if (action == PLOGX_FLG_CMD_LOGO) { + return (isp_port_logout(isp, handle, portid)); + } else { + return (MBOX_INVALID_COMMAND); + } + } 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_portlo = portid; plp->plogx_rspsz_porthi = (portid >> 16) & 0xff; - if (log_ret) { - plp->plogx_flags = *log_ret; - } else { - log_ret = &junk; - } + plp->plogx_flags = flags; if (isp->isp_dblev & ISP_LOGDEBUG1) { isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp); } - /* - * XXX: We're going to assume somebody has acquired SCRATCH for us - */ + + if (gs == 0) { + FC_SCRATCH_ACQUIRE(isp); + } + scp = FCPARAM(isp)->isp_scratch; isp_put_plogx(isp, plp, (isp_plogx_t *) scp); @@ -2128,7 +2139,8 @@ MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { - *log_ret = mbs.param[0]; + rval = mbs.param[0]; + goto out; } MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN); scp += QENTRY_LEN; @@ -2138,19 +2150,19 @@ } if (plp->plogx_status == PLOGX_STATUS_OK) { - *log_ret = 0; - return; + rval = 0; + goto out; } else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) { isp_prt(isp, ISP_LOGWARN, "status 0x%x on port login IOCB", plp->plogx_status); - *log_ret = -1; - return; + rval = -1; + goto out; } sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16); parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16); - *log_ret = -1; + rval = -1; switch (sst) { case PLOGX_IOCBERR_NOLINK: @@ -2166,8 +2178,8 @@ case PLOGX_IOCBERR_FAILED: isp_prt(isp, ISP_LOGERR, "PLOGX(0x%x) of Port 0x%06x failed: reason 0x%x (last LOGIN" - " state 0x%x)", *log_ret, portid, - parm1 & 0xff, (parm1 >> 8) & 0xff); + " state 0x%x)", flags, portid, parm1 & 0xff, + (parm1 >> 8) & 0xff); break; case PLOGX_IOCBERR_NOFABRIC: isp_prt(isp, ISP_LOGERR, "PLOGX failed- no fabric"); @@ -2179,7 +2191,7 @@ isp_prt(isp, ISP_LOGERR, "PLOGX failed- not logged in (last LOGIN state 0x%x)", parm1); - *log_ret = MBOX_NOT_LOGGED_IN; + rval = MBOX_NOT_LOGGED_IN; break; case PLOGX_IOCBERR_REJECT: isp_prt(isp, ISP_LOGERR, "PLOGX failed: LS_RJT = 0x%x", parm1); @@ -2195,13 +2207,13 @@ isp_prt(isp, ISP_LOGDEBUG0, "portid 0x%x already logged in with N-port handle 0x%x", portid, parm1); - *log_ret = MBOX_PORT_ID_USED | (handle << 16); + rval = MBOX_PORT_ID_USED | (handle << 16); break; case PLOGX_IOCBERR_HNDLUSED: isp_prt(isp, ISP_LOGDEBUG0, "N-port handle 0x%x already used for portid 0x%x", handle, parm1); - *log_ret = MBOX_LOOP_ID_USED; + rval = MBOX_LOOP_ID_USED; break; case PLOGX_IOCBERR_NOHANDLE: isp_prt(isp, ISP_LOGERR, "PLOGX failed- no handle allocated"); @@ -2210,11 +2222,16 @@ isp_prt(isp, ISP_LOGERR, "PLOGX failed- no FLOGI_ACC"); break; default: - isp_prt(isp, ISP_LOGERR, "status %x from %s", plp->plogx_status, - (*log_ret)? "PLOGI" : "LOGO"); - *log_ret = -1; + isp_prt(isp, ISP_LOGERR, "status %x from %x", plp->plogx_status, + flags); + rval = -1; break; } +out: + if (gs == 0) { + FC_SCRATCH_RELEASE(isp); + } + return (rval); } static int @@ -2239,14 +2256,14 @@ switch (mbs.param[0]) { case MBOX_PORT_ID_USED: isp_prt(isp, ISP_LOGDEBUG0, - "isp_port_login: portid 0x%06x already logged in as %u", + "isp_plogi_old: portid 0x%06x already logged in as %u", portid, mbs.param[1]); return (MBOX_PORT_ID_USED | (mbs.param[1] << 16)); break; case MBOX_LOOP_ID_USED: isp_prt(isp, ISP_LOGDEBUG0, - "isp_port_login: handle %u in use for port id 0x%02xXXXX", + "isp_plogi_old: handle %u in use for port id 0x%02xXXXX", handle, mbs.param[1] & 0xff); return (MBOX_LOOP_ID_USED); @@ -2255,24 +2272,24 @@ case MBOX_COMMAND_ERROR: isp_prt(isp, ISP_LOGINFO, - "isp_port_login: error 0x%x in PLOGI to port 0x%06x", + "isp_plogi_old: error 0x%x in PLOGI to port 0x%06x", mbs.param[1], portid); return (MBOX_COMMAND_ERROR); case MBOX_ALL_IDS_USED: isp_prt(isp, ISP_LOGINFO, - "isp_port_login: all IDs used for fabric login"); + "isp_plogi_old: all IDs used for fabric login"); return (MBOX_ALL_IDS_USED); default: isp_prt(isp, ISP_LOGINFO, - "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x", + "isp_plogi_old: error 0x%x on port login of 0x%06x@0x%0x", mbs.param[0], portid, handle); return (mbs.param[0]); } } -static void +static int isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid) { mbreg_t mbs; @@ -2288,6 +2305,7 @@ mbs.logval = MBLOGNONE; mbs.timeout = 100000; isp_mboxcmd(isp, &mbs); + return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]); } static int @@ -2725,19 +2743,10 @@ lp->state = FC_PORTDB_STATE_NIL; isp_async(isp, ISPASYNC_DEV_GONE, lp); if (lp->autologin == 0) { - if (IS_24XX(isp)) { - int action = - PLOGX_FLG_CMD_LOGO | - PLOGX_FLG_IMPLICIT | - PLOGX_FLG_FREE_NPHDL; - FC_SCRATCH_ACQUIRE(isp); - isp_plogx_24xx(isp, lp->handle, - lp->portid, &action); - FC_SCRATCH_RELEASE(isp); - } else { - isp_port_logout(isp, lp->handle, - lp->portid); - } + (void) isp_plogx(isp, lp->handle, lp->portid, + PLOGX_FLG_CMD_LOGO | + PLOGX_FLG_IMPLICIT | + PLOGX_FLG_FREE_NPHDL, 0); } else { lp->autologin = 0; } @@ -2987,7 +2996,7 @@ lp->new_roles = tmp.roles; lp->state = FC_PORTDB_STATE_PENDING_VALID; isp_prt(isp, ISP_LOGSANCFG, - "Loop Port 0x%06x@0x%x Pending Valid", + "Loop Port 0x%02x@0x%x Pending Valid", tmp.portid, tmp.handle); break; } @@ -3686,7 +3695,7 @@ static int isp_login_device(ispsoftc_t *isp, uint32_t portid, isp_pdb_t *p, uint16_t *ohp) { - int lim, i, r, logval; + int lim, i, r; uint16_t handle; if (IS_24XX(isp)) { @@ -3704,14 +3713,8 @@ */ r = isp_getpdb(isp, handle, p, 0); if (r == 0 && p->portid != portid) { - if (IS_24XX(isp)) { - logval = - PLOGX_FLG_CMD_LOGO | - PLOGX_FLG_IMPLICIT; - isp_plogx_24xx(isp, handle, portid, &logval); - } else { - isp_port_logout(isp, handle, portid); - } + (void) isp_plogx(isp, handle,portid, + PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT, 1); } else if (r == 0) { break; } @@ -3721,22 +3724,17 @@ /* * Now try and log into the device */ - if (IS_24XX(isp)) { - logval = PLOGX_FLG_CMD_PLOGI; - isp_plogx_24xx(isp, handle, portid, &logval); - } else { - logval = isp_port_login(isp, handle, portid); - } + r = isp_plogx(isp, handle, portid, PLOGX_FLG_CMD_PLOGI, 1); if (FCPARAM(isp)->isp_loopstate != LOOP_SCANNING_FABRIC) { return (-1); } - if (logval == 0) { + if (r == 0) { *ohp = handle; break; - } else if ((logval & 0xffff) == MBOX_PORT_ID_USED) { - handle = logval >> 16; + } else if ((r & 0xffff) == MBOX_PORT_ID_USED) { + handle = r >> 16; break; - } else if (logval != MBOX_LOOP_ID_USED) { + } else if (r != MBOX_LOOP_ID_USED) { i = lim; break; } else { @@ -3929,6 +3927,9 @@ } } else { handle += 1; + if (handle == NPH_MGT_ID) { + handle++; + } if (handle >= FL_ID && handle <= SNS_ID) { handle = SNS_ID+1; } else if (IS_24XX(isp)) { @@ -4423,6 +4424,11 @@ isp_mboxcmd(isp, arg); return(0); + case ISPCTL_PLOGX: + { + isp_plcmd_t *p = arg; + return (isp_plogx(isp, p->handle, p->portid, p->flags, 0)); + } #ifdef ISP_TARGET_MODE case ISPCTL_TOGGLE_TMODE: { ==== //depot/projects/newisp/dev/isp/isp_library.c#21 (text) ==== @@ -1038,6 +1038,36 @@ } void +isp_get_ms(ispsoftc_t *isp, isp_ms_t *src, isp_ms_t *dst) +{ + int i; + + isp_get_hdr(isp, &src->ms_header, &dst->ms_header); + ISP_IOXGET_32(isp, &src->ms_handle, dst->ms_handle); + ISP_IOXGET_16(isp, &src->ms_nphdl, dst->ms_nphdl); + ISP_IOXGET_16(isp, &src->ms_status, dst->ms_status); + ISP_IOXGET_16(isp, &src->ms_flags, dst->ms_flags); + ISP_IOXGET_16(isp, &src->ms_reserved1, dst->ms_reserved1); + ISP_IOXGET_16(isp, &src->ms_time, dst->ms_time); + ISP_IOXGET_16(isp, &src->ms_cmd_cnt, dst->ms_cmd_cnt); + ISP_IOXGET_16(isp, &src->ms_tot_cnt, dst->ms_tot_cnt); + ISP_IOXGET_8(isp, &src->ms_type, dst->ms_type); + ISP_IOXGET_8(isp, &src->ms_r_ctl, dst->ms_r_ctl); + ISP_IOXGET_16(isp, &src->ms_rxid, dst->ms_rxid); + ISP_IOXGET_16(isp, &src->ms_reserved2, dst->ms_reserved2); + ISP_IOXGET_32(isp, &src->ms_rsp_bcnt, dst->ms_rsp_bcnt); + ISP_IOXGET_32(isp, &src->ms_cmd_bcnt, dst->ms_cmd_bcnt); + for (i = 0; i < 2; i++) { + ISP_IOXGET_32(isp, &src->ms_dataseg[i].ds_base, + dst->ms_dataseg[i].ds_base); + ISP_IOXGET_32(isp, &src->ms_dataseg[i].ds_basehi, + dst->ms_dataseg[i].ds_basehi); + ISP_IOXGET_32(isp, &src->ms_dataseg[i].ds_count, + dst->ms_dataseg[i].ds_count); + } +} + +void isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *src, isp_ct_pt_t *dst) { int i; @@ -1067,6 +1097,36 @@ } } +void +isp_put_ms(ispsoftc_t *isp, isp_ms_t *src, isp_ms_t *dst) +{ + int i; + + isp_put_hdr(isp, &src->ms_header, &dst->ms_header); + ISP_IOXPUT_32(isp, src->ms_handle, &dst->ms_handle); + ISP_IOXPUT_16(isp, src->ms_nphdl, &dst->ms_nphdl); + ISP_IOXPUT_16(isp, src->ms_status, &dst->ms_status); + ISP_IOXPUT_16(isp, src->ms_flags, &dst->ms_flags); + ISP_IOXPUT_16(isp, src->ms_reserved1, &dst->ms_reserved1); + ISP_IOXPUT_16(isp, src->ms_time, &dst->ms_time); + ISP_IOXPUT_16(isp, src->ms_cmd_cnt, &dst->ms_cmd_cnt); + ISP_IOXPUT_16(isp, src->ms_tot_cnt, &dst->ms_tot_cnt); + ISP_IOXPUT_8(isp, src->ms_type, &dst->ms_type); + ISP_IOXPUT_8(isp, src->ms_r_ctl, &dst->ms_r_ctl); + ISP_IOXPUT_16(isp, src->ms_rxid, &dst->ms_rxid); + ISP_IOXPUT_16(isp, src->ms_reserved2, &dst->ms_reserved2); + ISP_IOXPUT_32(isp, src->ms_rsp_bcnt, &dst->ms_rsp_bcnt); + ISP_IOXPUT_32(isp, src->ms_cmd_bcnt, &dst->ms_cmd_bcnt); + for (i = 0; i < 2; i++) { + ISP_IOXPUT_32(isp, src->ms_dataseg[i].ds_base, + &dst->ms_dataseg[i].ds_base); + ISP_IOXPUT_32(isp, src->ms_dataseg[i].ds_basehi, + &dst->ms_dataseg[i].ds_basehi); + ISP_IOXPUT_32(isp, src->ms_dataseg[i].ds_count, + &dst->ms_dataseg[i].ds_count); + } +} + /* * Generic SNS request - not particularly useful since the per-command data * isn't always 16 bit words. ==== //depot/projects/newisp/dev/isp/isp_library.h#13 (text) ==== @@ -91,8 +91,12 @@ extern void isp_get_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *); extern void +isp_get_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *); +extern void isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *); extern void +isp_put_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *); +extern void isp_put_sns_request(ispsoftc_t *, sns_screq_t *, sns_screq_t *); extern void isp_put_gid_ft_request(ispsoftc_t *, sns_gid_ft_req_t *, ==== //depot/projects/newisp/dev/isp/ispmbox.h#14 (text+ko) ==== @@ -329,6 +329,7 @@ #define RQSTYPE_IP_RECV 0x23 #define RQSTYPE_IP_RECV_CONT 0x24 #define RQSTYPE_CT_PASSTHRU 0x29 +#define RQSTYPE_MS_PASSTHRU 0x29 #define RQSTYPE_ABORT_IO 0x33 #define RQSTYPE_T6RQS 0x48 #define RQSTYPE_LOGIN 0x52 @@ -631,6 +632,29 @@ ispds64_t ctp_dataseg[2]; } isp_ct_pt_t; +/* + * MS Passthru IOCB + */ +typedef struct { + isphdr_t ms_header; + uint32_t ms_handle; + uint16_t ms_nphdl; /* XXX: Note, this is for 2K Logins only */ + uint16_t ms_status; + uint16_t ms_flags; + uint16_t ms_reserved1; /* low 8 bits */ + uint16_t ms_time; + uint16_t ms_cmd_cnt; /* Command DSD count */; + uint16_t ms_tot_cnt; /* Total DSD Count */ + uint8_t ms_type; /* MS type */ + uint8_t ms_r_ctl; /* R_CTL */ + uint16_t ms_rxid; /* RX_ID */ + uint16_t ms_reserved2; + uint32_t ms_handle2; + uint32_t ms_rsp_bcnt; /* Response byte count */ + uint32_t ms_cmd_bcnt; /* Command byte count */ + ispds64_t ms_dataseg[2]; +} isp_ms_t; + /* * Completion Status Codes. */ @@ -1108,6 +1132,17 @@ } isp_pdb_t; /* + * Genericized Port Login/Logout software structure + */ +typedef struct { + uint16_t handle; + uint32_t + flags : 8, + portid : 24; +} isp_plcmd_t; +/* the flags to use are those for PLOGX_FLG_* below */ + +/* * ISP24XX- Login/Logout Port IOCB */ typedef struct { ==== //depot/projects/newisp/dev/isp/ispvar.h#17 (text+ko) ==== @@ -791,7 +791,8 @@ ISPCTL_GET_PORTNAME, /* get portname from an N-port handle */ ISPCTL_RUN_MBOXCMD, /* run a mailbox command */ ISPCTL_TOGGLE_TMODE, /* toggle target mode */ - ISPCTL_GET_PDB /* get a single port database entry */ + ISPCTL_GET_PDB, /* get a single port database entry */ + ISPCTL_PLOGX /* do a port login/logout */ } ispctl_t; int isp_control(ispsoftc_t *, ispctl_t, void *);