Date: Wed, 18 Oct 2006 20:50:41 GMT From: Matt Jacob <mjacob@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 108071 for review Message-ID: <200610182050.k9IKofcJ011804@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=108071 Change 108071 by mjacob@newisp on 2006/10/18 20:50:11 The latest/greatest for target mode for 24XX. Affected files ... .. //depot/projects/newisp/dev/isp/isp_target.c#8 edit .. //depot/projects/newisp/dev/isp/isp_target.h#10 edit Differences ... ==== //depot/projects/newisp/dev/isp/isp_target.c#8 (text+ko) ==== @@ -58,6 +58,7 @@ static void isp_got_msg(ispsoftc_t *, in_entry_t *); static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *); +static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *); static void isp_handle_atio(ispsoftc_t *, at_entry_t *); static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *); static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *); @@ -191,6 +192,13 @@ } } /* + * Check for a task management function + */ + if (at7iop->at_cmnd.fcp_cmnd_task_management) { + isp_got_tmf_24xx(isp, at7iop); + break; + } + /* * Just go straight to outer layer for this one. */ (void) isp_async(isp, ISPASYNC_TARGET_ACTION, local); @@ -311,16 +319,29 @@ isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs"); isp_notify_ack(isp, local); break; - case IN_RESET: /* same as IN24XX_LIP_RESET */ - case IN24XX_LINK_RESET: - (void) isp_target_async(isp, 0, ASYNC_BUS_RESET); + case IN_RESET: + { + /* + * We form the notify structure here because we need + * to mark it as needing a NOTIFY ACK on return. + */ + tmd_notify_t notify; + + MEMZERO(¬ify, sizeof (tmd_notify_t)); + notify.nt_hba = isp; + notify.nt_iid = INI_ANY; + /* nt_tgt set in outer layers */ + notify.nt_lun = LUN_ANY; + notify.nt_tagval = TAG_ANY; + notify.nt_ncode = NT_BUS_RESET; + notify.nt_need_ack = 1; + (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); break; - case IN_PORT_LOGOUT: /* same as IN24XX_PORT_LOGOUT */ + } + case IN_PORT_LOGOUT: case IN_ABORT_TASK: - case IN_PORT_CHANGED: /* same as IN24XX_PORT_CHANGED */ - case IN_GLOBAL_LOGO: /* same as IN24XX_LINK_FAILED */ - case IN24XX_SRR_RCVD: - case IN24XX_ELS_RCVD: + case IN_PORT_CHANGED: + case IN_GLOBAL_LOGO: (void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local); break; default: @@ -528,12 +549,14 @@ (ct2_entry_t *) outp); } break; + case RQSTYPE_CTIO7: + isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp); + break; default: isp_prt(isp, ISP_LOGERR, "Unknown type 0x%x in isp_put_entry", etype); return (-1); } - ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap); ISP_ADD_REQUEST(isp, nxti); return (0); @@ -600,21 +623,42 @@ */ int -isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint16_t hdl) +isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl) { int sts; union { ct_entry_t _ctio; ct2_entry_t _ctio2; ct2e_entry_t _ctio2e; + ct7_entry_t _ctio7; } un; MEMZERO(&un, sizeof un); sts = code & 0xff; if (IS_24XX(isp)) { - isp_prt(isp, ISP_LOGERR, "XXX ISP_ENDCMD NOT DONE YET FOR 24XX"); - return (0); + at7_entry_t *aep = arg; + ct7_entry_t *cto = &un._ctio7; + + cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; + cto->ct_header.rqs_entry_count = 1; +/* XXXX */ cto->ct_nphdl = aep->at_hdr.seq_id; + cto->ct_rxid = aep->at_rxid; + cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) | + aep->at_hdr.s_id[2]; + cto->ct_iid_hi = aep->at_hdr.s_id[0]; + cto->ct_oxid = aep->at_hdr.ox_id; + cto->ct_scsi_status = sts; + cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS; + if (sts == SCSI_CHECK && (code & ECMD_SVALID)) { + cto->rsp.m1.ct_resplen = 16; + cto->rsp.m1.ct_resp[0] = 0xf0; + cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; + cto->rsp.m1.ct_resp[7] = 8; + cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff; + cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff; + } + cto->ct_syshandle = hdl; } else if (IS_FC(isp)) { at2_entry_t *aep = arg; ct2_entry_t *cto = &un._ctio2; @@ -675,6 +719,35 @@ } /* + * Terminate a command + */ +int +isp_terminate_cmd(ispsoftc_t *isp, void *arg) +{ + tmd_cmd_t *tmd = arg; + ct7_entry_t local, *cto = &local;; + + if (!IS_24XX(isp)) { + return (-1); + } + isp_prt(isp, ISP_LOGTDEBUG0, + "isp_terminate_cmd: tag 0x%0x is being terminated", + tmd->cd_tagval); + MEMZERO(&local, sizeof (local)); + cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; + cto->ct_header.rqs_entry_count = 1; + cto->ct_nphdl = tmd->cd_nphdl; + cto->ct_rxid = tmd->cd_tagval; + cto->ct_iid_lo = tmd->cd_portid; + cto->ct_iid_hi = tmd->cd_portid >> 16; + cto->ct_oxid = tmd->cd_oxid; + cto->ct_flags = CT7_TERMINATE; + cto->ct_syshandle = 0; + return (isp_target_put_entry(isp, &local)); +} + + +/* * These are either broadcast events or specifically CTIO fast completion */ int @@ -723,7 +796,13 @@ { uint8_t storage[QENTRY_LEN]; memset(storage, 0, QENTRY_LEN); - if (IS_FC(isp)) { + if (IS_24XX(isp)) { + ct7_entry_t *ct = (ct7_entry_t *) storage; + ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7; + ct->ct_nphdl = CT7_OK; + ct->ct_syshandle = bus; + ct->ct_flags = CT7_SENDSTATUS|CT7_FASTPOST; + } else if (IS_FC(isp)) { /* This should also suffice for 2K login code */ ct2_entry_t *ct = (ct2_entry_t *) storage; ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2; @@ -738,7 +817,7 @@ ct->ct_flags = CT_SENDSTATUS; } (void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage); - return (0); + break; } default: isp_prt(isp, ISP_LOGERR, @@ -818,9 +897,9 @@ isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp) { tmd_notify_t nt; - static const char f1[] = "%s from loop id %d lun %d seq 0x%x"; + static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x"; static const char f2[] = - "unknown %s 0x%x lun %d loop id %d task flags 0x%x seq 0x%x\n"; + "unknown %s 0x%x lun %d N-Port handle 0x%x task flags 0x%x seq 0x%x\n"; uint16_t seqid, loopid; MEMZERO(&nt, sizeof (tmd_notify_t)); @@ -841,6 +920,7 @@ nt.nt_lun = inp->in_lun; } IN_FC_MAKE_TAGID(nt.nt_tagval, 0, seqid); + nt.nt_need_ack = 1; nt.nt_lreserved = inp; if (inp->in_status != IN_MSG_RECEIVED) { @@ -880,6 +960,64 @@ (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt); } +static void +isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep) +{ + tmd_notify_t nt; + static const char f1[] = "%s from PortID 0x%06x lun %d seq 0x%x"; + static const char f2[] = + "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%x\n"; + uint32_t sid; + + MEMZERO(&nt, sizeof (tmd_notify_t)); + nt.nt_hba = isp; + nt.nt_iid = INI_ANY; + nt.nt_lun = + (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | + (aep->at_cmnd.fcp_cmnd_lun[1]); + nt.nt_tagval = aep->at_rxid; + nt.nt_lreserved = aep; + sid = + (aep->at_hdr.s_id[0] << 16) | + (aep->at_hdr.s_id[1] << 8) | + (aep->at_hdr.s_id[2]); + + if (aep->at_cmnd.fcp_cmnd_task_management & + FCP_CMND_TMF_ABORT_TASK_SET) { + isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", + sid, nt.nt_lun, nt.nt_tagval); + nt.nt_ncode = NT_ABORT_TASK_SET; + } else if (aep->at_cmnd.fcp_cmnd_task_management & + FCP_CMND_TMF_CLEAR_TASK_SET) { + isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", + sid, nt.nt_lun, nt.nt_tagval); + nt.nt_ncode = NT_CLEAR_TASK_SET; + } else if (aep->at_cmnd.fcp_cmnd_task_management & + FCP_CMND_TMF_LUN_RESET) { + isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", + sid, nt.nt_lun, nt.nt_tagval); + nt.nt_ncode = NT_LUN_RESET; + } else if (aep->at_cmnd.fcp_cmnd_task_management & + FCP_CMND_TMF_TGT_RESET) { + isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", + sid, nt.nt_lun, nt.nt_tagval); + nt.nt_ncode = NT_TARGET_RESET; + nt.nt_lun = LUN_ANY; + } else if (aep->at_cmnd.fcp_cmnd_task_management & + FCP_CMND_TMF_CLEAR_ACA) { + isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", + sid, nt.nt_lun, nt.nt_tagval); + nt.nt_ncode = NT_CLEAR_ACA; + } else { + isp_prt(isp, ISP_LOGWARN, f2, + aep->at_cmnd.fcp_cmnd_task_management, + nt.nt_lun, sid, nt.nt_tagval); + isp_endcmd(isp, aep, 0, 0); + return; + } + (void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt); +} + void isp_notify_ack(ispsoftc_t *isp, void *arg) { @@ -895,7 +1033,11 @@ MEMZERO(storage, QENTRY_LEN); - if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) { + if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) { + at7_entry_t *aep = arg; + isp_endcmd(isp, aep, 0, 0); + return; + } else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) { abts_rsp_t *abts_rsp = (abts_rsp_t *) storage; /* * The caller will have set response values as appropriate @@ -1519,8 +1661,9 @@ break; case CT7_RESET: - if (fmsg == NULL) + if (fmsg == NULL) { fmsg = "LIP Reset"; + } /*FALLTHROUGH*/ case CT7_ABORTED: /* @@ -1531,14 +1674,14 @@ if (fmsg == NULL) { fmsg = "ABORT"; } - isp_prt(isp, ISP_LOGTDEBUG0, - "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); + "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); break; case CT7_TIMEOUT: - if (fmsg == NULL) + if (fmsg == NULL) { fmsg = "command"; + } isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg); break; @@ -1546,16 +1689,19 @@ fmsg = "Completed with Error"; /*FALLTHROUGH*/ case CT7_LOGOUT: - if (fmsg == NULL) + if (fmsg == NULL) { fmsg = "Port Logout"; + } /*FALLTHROUGH*/ case CT7_PORTUNAVAIL: - if (fmsg == NULL) + if (fmsg == NULL) { fmsg = "Port not available"; + } /*FALLTHROUGH*/ case CT7_PORTCHANGED: - if (fmsg == NULL) + if (fmsg == NULL) { fmsg = "Port Changed"; + } isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg); break; @@ -1565,7 +1711,7 @@ * Just print a message. */ isp_prt(isp, ISP_LOGWARN, - "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid); + "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid); break; case CT7_REASSY_ERR: @@ -1577,7 +1723,7 @@ break; default: - isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x", + isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x", ct->ct_nphdl); break; } @@ -1591,7 +1737,11 @@ * order we got them. */ if (ct->ct_syshandle == 0) { - if ((ct->ct_flags & CT7_SENDSTATUS) == 0) { + if (ct->ct_flags & CT7_TERMINATE) { + isp_prt(isp, ISP_LOGALL, + "termination of 0x%x complete", + ct->ct_rxid); + } else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) { isp_prt(isp, pl, "intermediate CTIO completed ok"); } else { ==== //depot/projects/newisp/dev/isp/isp_target.h#10 (text+ko) ==== @@ -932,10 +932,15 @@ * General routine to send a final CTIO for a command- used mostly for * local responses. */ -int isp_endcmd(ispsoftc_t *, void *, uint32_t, uint16_t); +int isp_endcmd(ispsoftc_t *, void *, uint32_t, uint32_t); #define ECMD_SVALID 0x100 /* + * General routine to terminate an active command + */ +int isp_terminate_cmd(ispsoftc_t *, void *); + +/* * Handle an asynchronous event * * Return nonzero if the interrupt that generated this event has been dismissed.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610182050.k9IKofcJ011804>