diff options
Diffstat (limited to 'sys/dev/isp/isp_freebsd.c')
-rw-r--r-- | sys/dev/isp/isp_freebsd.c | 1196 |
1 files changed, 169 insertions, 1027 deletions
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 1ff64e1..6d7033a 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -54,7 +54,6 @@ int isp_fabric_hysteresis = 5; int isp_loop_down_limit = 60; /* default loop down limit */ int isp_quickboot_time = 7; /* don't wait more than N secs for loop up */ int isp_gone_device_time = 30; /* grace time before reporting device lost */ -int isp_autoconfig = 1; /* automatically attach/detach devices */ static const char prom3[] = "Chan %d [%u] PortID 0x%06x Departed because of %s"; static void isp_freeze_loopdown(ispsoftc_t *, int, char *); @@ -69,10 +68,6 @@ static timeout_t isp_ldt; static task_fn_t isp_ldt_task; static void isp_kthread(void *); static void isp_action(struct cam_sim *, union ccb *); -#ifdef ISP_INTERNAL_TARGET -static void isp_target_thread_pi(void *); -static void isp_target_thread_fc(void *); -#endif static int isp_timer_count; static void isp_timer(void *); @@ -160,14 +155,6 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan) struct isp_spi *spi = ISP_SPI_PC(isp, chan); spi->sim = sim; spi->path = path; -#ifdef ISP_INTERNAL_TARGET - ISP_SET_PC(isp, chan, proc_active, 1); - if (THREAD_CREATE(isp_target_thread_pi, spi, &spi->target_proc, 0, 0, "%s: isp_test_tgt%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) { - ISP_SET_PC(isp, chan, proc_active, 0); - isp_prt(isp, ISP_LOGERR, "cannot create test target thread"); - } - ISP_SPI_PC(isp, chan)->num_threads += 1; -#endif } else { fcparam *fcp = FCPARAM(isp, chan); struct isp_fc *fc = ISP_FC_PC(isp, chan); @@ -205,47 +192,52 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan) cam_sim_free(fc->sim, FALSE); return (ENOMEM); } - ISP_FC_PC(isp, chan)->num_threads += 1; -#ifdef ISP_INTERNAL_TARGET - ISP_SET_PC(isp, chan, proc_active, 1); - if (THREAD_CREATE(isp_target_thread_fc, fc, &fc->target_proc, 0, 0, "%s: isp_test_tgt%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) { - ISP_SET_PC(isp, chan, proc_active, 0); - isp_prt(isp, ISP_LOGERR, "cannot create test target thread"); - } - ISP_FC_PC(isp, chan)->num_threads += 1; -#endif + fc->num_threads += 1; if (chan > 0) { snprintf(name, sizeof(name), "chan%d", chan); tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, name, CTLFLAG_RW, 0, "Virtual channel"); } - SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "wwnn", CTLFLAG_RD, &FCPARAM(isp, chan)->isp_wwnn, "World Wide Node Name"); - SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "wwpn", CTLFLAG_RD, &FCPARAM(isp, chan)->isp_wwpn, "World Wide Port Name"); - SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "loop_down_limit", CTLFLAG_RW, &ISP_FC_PC(isp, chan)->loop_down_limit, 0, "Loop Down Limit"); - SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "gone_device_time", CTLFLAG_RW, &ISP_FC_PC(isp, chan)->gone_device_time, 0, "Gone Device Time"); + SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "wwnn", CTLFLAG_RD, &fcp->isp_wwnn, + "World Wide Node Name"); + SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "wwpn", CTLFLAG_RD, &fcp->isp_wwpn, + "World Wide Port Name"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "loop_down_limit", CTLFLAG_RW, &fc->loop_down_limit, 0, + "Loop Down Limit"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "gone_device_time", CTLFLAG_RW, &fc->gone_device_time, 0, + "Gone Device Time"); #if defined(ISP_TARGET_MODE) && defined(DEBUG) - SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "inject_lost_data_frame", CTLFLAG_RW, &ISP_FC_PC(isp, chan)->inject_lost_data_frame, 0, "Cause a Lost Frame on a Read"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "inject_lost_data_frame", CTLFLAG_RW, &fc->inject_lost_data_frame, 0, + "Cause a Lost Frame on a Read"); #endif SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "role", CTLTYPE_INT | CTLFLAG_RW, isp, chan, isp_role_sysctl, "I", "Current role"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "speed", CTLFLAG_RD, &fcp->isp_gbspeed, 0, + "Connection speed in gigabits"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "linkstate", CTLFLAG_RD, &fcp->isp_linkstate, 0, + "Link state"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "fwstate", CTLFLAG_RD, &fcp->isp_fwstate, 0, + "Firmware state"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "loopstate", CTLFLAG_RD, &fcp->isp_loopstate, 0, + "Loop state"); + SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, + "topo", CTLFLAG_RD, &fcp->isp_topo, 0, + "Connection topology"); } return (0); } static void -isp_detach_internal_target(ispsoftc_t *isp, int chan) -{ -#ifdef ISP_INTERNAL_TARGET - void *wchan; - - ISP_GET_PC(isp, chan, target_proc, wchan); - ISP_SET_PC(isp, chan, proc_active, 0); - wakeup(wchan); -#endif -} - -static void isp_detach_chan(ispsoftc_t *isp, int chan) { struct cam_sim *sim; @@ -269,7 +261,6 @@ isp_detach_chan(ispsoftc_t *isp, int chan) /* Wait for the channel's spawned threads to exit. */ wakeup(isp->isp_osinfo.pc.ptr); - isp_detach_internal_target(isp, chan); while (*num_threads != 0) mtx_sleep(isp, &isp->isp_osinfo.lock, PRIBIO, "isp_reap", 100); } @@ -391,11 +382,16 @@ isp_freeze_loopdown(ispsoftc_t *isp, int chan, char *msg) if (IS_FC(isp)) { struct isp_fc *fc = ISP_FC_PC(isp, chan); if (fc->simqfrozen == 0) { - isp_prt(isp, ISP_LOGDEBUG0, "%s: freeze simq (loopdown) chan %d", msg, chan); + isp_prt(isp, ISP_LOGDEBUG0, + "Chan %d %s -- freeze simq (loopdown)", chan, msg); fc->simqfrozen = SIMQFRZ_LOOPDOWN; +#if __FreeBSD_version >= 1000039 + xpt_hold_boot(); +#endif xpt_freeze_simq(fc->sim, 1); } else { - isp_prt(isp, ISP_LOGDEBUG0, "%s: mark frozen (loopdown) chan %d", msg, chan); + isp_prt(isp, ISP_LOGDEBUG0, + "Chan %d %s -- mark frozen (loopdown)", chan, msg); fc->simqfrozen |= SIMQFRZ_LOOPDOWN; } } @@ -411,6 +407,9 @@ isp_unfreeze_loopdown(ispsoftc_t *isp, int chan) if (wasfrozen && fc->simqfrozen == 0) { isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d releasing simq", __func__, chan); xpt_release_simq(fc->sim, 1); +#if __FreeBSD_version >= 1000039 + xpt_release_boot(); +#endif } } } @@ -1156,7 +1155,7 @@ create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rsl lun = xpt_path_lun_id(path); if (lun != CAM_LUN_WILDCARD) { - if (lun >= ISP_MAX_LUNS(isp)) { + if (ISP_MAX_LUNS(isp) > 0 && lun >= ISP_MAX_LUNS(isp)) { return (CAM_LUN_INVALID); } } @@ -1241,7 +1240,8 @@ isp_enable_lun(ispsoftc_t *isp, union ccb *ccb) bus = XS_CHANNEL(ccb); target = ccb->ccb_h.target_id; lun = ccb->ccb_h.target_lun; - ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, "enabling lun %u\n", lun); + ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, + "enabling lun %jx\n", (uintmax_t)lun); if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) { ccb->ccb_h.status = CAM_LUN_INVALID; xpt_done(ccb); @@ -1254,7 +1254,8 @@ isp_enable_lun(ispsoftc_t *isp, union ccb *ccb) return; } if (isp->isp_dblev & ISP_LOGTDEBUG0) { - xpt_print(ccb->ccb_h.path, "enabling lun 0x%x on channel %d\n", lun, bus); + xpt_print(ccb->ccb_h.path, + "enabling lun 0x%jx on channel %d\n", (uintmax_t)lun, bus); } /* @@ -1453,7 +1454,8 @@ isp_disable_lun(ispsoftc_t *isp, union ccb *ccb) bus = XS_CHANNEL(ccb); target = ccb->ccb_h.target_id; lun = ccb->ccb_h.target_lun; - ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, "disabling lun %u\n", lun); + ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, + "disabling lun %jx\n", (uintmax_t)lun); if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) { ccb->ccb_h.status = CAM_LUN_INVALID; xpt_done(ccb); @@ -2184,6 +2186,10 @@ isp_target_putback_atio(union ccb *ccb) at->at_header.rqs_entry_count = 1; if (ISP_CAP_SCCFW(isp)) { at->at_scclun = (uint16_t) ccb->ccb_h.target_lun; +#if __FreeBSD_version < 1000700 + if (at->at_scclun >= 256) + at->at_scclun |= 0x4000; +#endif } else { at->at_lun = (uint8_t) ccb->ccb_h.target_lun; } @@ -2369,6 +2375,9 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) if (ISP_CAP_SCCFW(isp)) { lun = aep->at_scclun; +#if __FreeBSD_version < 1000700 + lun &= 0x3fff; +#endif } else { lun = aep->at_lun; } @@ -2450,12 +2459,13 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) else { if ((isp_find_pdb_by_handle(isp, 0, nphdl, &lp) == 0 || lp->state == FC_PORTDB_STATE_ZOMBIE)) { - uint64_t iid = + uint64_t wwpn = (((uint64_t) aep->at_wwpn[0]) << 48) | (((uint64_t) aep->at_wwpn[1]) << 32) | (((uint64_t) aep->at_wwpn[2]) << 16) | (((uint64_t) aep->at_wwpn[3]) << 0); - isp_add_wwn_entry(isp, 0, iid, nphdl, PORT_ANY, 0); + isp_add_wwn_entry(isp, 0, wwpn, INI_NONE, + nphdl, PORT_ANY, 0); isp_find_pdb_by_handle(isp, 0, nphdl, &lp); } atiop->init_id = FC_PORTDB_TGT(isp, 0, lp); @@ -2514,7 +2524,8 @@ static void isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) { int cdbxlen; - uint16_t lun, chan, nphdl = NIL_HANDLE; + lun_id_t lun; + uint16_t chan, nphdl = NIL_HANDLE; uint32_t did, sid; fcportdb_t *lp; tstate_t *tptr; @@ -2525,7 +2536,12 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2]; sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2]; - lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | aep->at_cmnd.fcp_cmnd_lun[1]; +#if __FreeBSD_version >= 1000700 + lun = CAM_EXTLUN_BYTE_SWIZZLE(be64dec(aep->at_cmnd.fcp_cmnd_lun)); +#else + lun = (aep->at_cmnd.fcp_cmnd_lun[0] & 0x3f << 8) | + aep->at_cmnd.fcp_cmnd_lun[1]; +#endif /* * Find the N-port handle, and Virtual Port Index for this command. @@ -2591,7 +2607,9 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) if (tptr == NULL) { tptr = get_lun_statep(isp, chan, CAM_LUN_WILDCARD); if (tptr == NULL) { - isp_prt(isp, ISP_LOGWARN, "%s: [0x%x] no state pointer for lun %d or wildcard", __func__, aep->at_rxid, lun); + isp_prt(isp, ISP_LOGWARN, + "%s: [0x%x] no state pointer for lun %jx or wildcard", + __func__, aep->at_rxid, (uintmax_t)lun); if (lun == 0) { isp_endcmd(isp, aep, nphdl, SCSI_STATUS_BUSY, 0); } else { @@ -2713,7 +2731,8 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) atp->cdb0 = atiop->cdb_io.cdb_bytes[0]; atp->tattr = aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK; atp->state = ATPD_STATE_CAM; - isp_prt(isp, ISP_LOGTDEBUG0, "ATIO7[0x%x] CDB=0x%x lun %d datalen %u", aep->at_rxid, atp->cdb0, lun, atp->orig_datalen); + isp_prt(isp, ISP_LOGTDEBUG0, "ATIO7[0x%x] CDB=0x%x lun %jx datalen %u", + aep->at_rxid, atp->cdb0, (uintmax_t)lun, atp->orig_datalen); xpt_done((union ccb *)atiop); rls_lun_statep(isp, tptr); return; @@ -3001,7 +3020,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg) resid = ct->ct_resid; moved_data = data_requested - resid; } - isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO[%x] seq %u nc %d tag %x S_ID 0x%x lun %d sts %x flg %x resid %d %s", __func__, ct->ct_fwhandle, ATPD_GET_SEQNO(ct), + isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO[%x] seq %u nc %d tag %x S_ID 0x%x lun %x sts %x flg %x resid %d %s", __func__, ct->ct_fwhandle, ATPD_GET_SEQNO(ct), notify_cam, ct->ct_tag_val, ct->ct_iid, ct->ct_lun, ct->ct_status, ct->ct_flags, resid, sentstatus? "FIN" : "MID"); } if (ok) { @@ -3092,6 +3111,9 @@ isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp) if (ISP_CAP_SCCFW(isp)) { lun = inp->in_scclun; +#if __FreeBSD_version < 1000700 + lun &= 0x3fff; +#endif } else { lun = inp->in_lun; } @@ -3165,8 +3187,9 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) uint16_t prli_options = 0; uint32_t portid; fcportdb_t *lp; - uint8_t *ptr = NULL; - uint64_t wwn; + char *msg = NULL; + uint8_t *ptr = (uint8_t *)inot; + uint64_t wwpn = INI_NONE, wwnn = INI_NONE; nphdl = inot->in_nphdl; if (nphdl != NIL_HANDLE) { @@ -3178,7 +3201,7 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) switch (inot->in_status) { case IN24XX_ELS_RCVD: { - char buf[16], *msg; + char buf[16]; int chan = ISP_GET_VPIDX(isp, inot->in_vpidx); /* @@ -3189,49 +3212,27 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) switch (inot->in_status_subcode) { case LOGO: msg = "LOGO"; - if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) { - ptr = (uint8_t *)inot; /* point to unswizzled entry! */ - wwn = (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF]) << 56) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+1]) << 48) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+2]) << 40) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+3]) << 32) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+4]) << 24) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+5]) << 16) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+6]) << 8) | - (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+7])); - } else { - wwn = INI_ANY; - } - isp_del_wwn_entry(isp, chan, wwn, nphdl, portid); + wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]); + isp_del_wwn_entry(isp, chan, wwpn, nphdl, portid); break; case PRLO: msg = "PRLO"; break; case PLOGI: + msg = "PLOGI"; + wwnn = be64dec(&ptr[IN24XX_PLOGI_WWNN_OFF]); + wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]); + isp_add_wwn_entry(isp, chan, wwpn, wwnn, + nphdl, portid, prli_options); + break; case PRLI: - /* - * Treat PRLI the same as PLOGI and make a database entry for it. - */ - if (inot->in_status_subcode == PLOGI) { - msg = "PLOGI"; - } else { - prli_options = inot->in_prli_options; - msg = "PRLI"; - } - if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) { - ptr = (uint8_t *)inot; /* point to unswizzled entry! */ - wwn = (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF]) << 56) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+1]) << 48) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+2]) << 40) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+3]) << 32) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+4]) << 24) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+5]) << 16) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+6]) << 8) | - (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+7])); - } else { - wwn = INI_NONE; - } - isp_add_wwn_entry(isp, chan, wwn, nphdl, portid, prli_options); + msg = "PRLI"; + prli_options = inot->in_prli_options; + if (inot->in_flags & IN24XX_FLAG_PN_NN_VALID) + wwnn = be64dec(&ptr[IN24XX_PRLI_WWNN_OFF]); + wwpn = be64dec(&ptr[IN24XX_PRLI_WWPN_OFF]); + isp_add_wwn_entry(isp, chan, wwpn, wwnn, + nphdl, portid, prli_options); break; case PDISC: msg = "PDISC"; @@ -3255,21 +3256,19 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) } case IN24XX_PORT_LOGOUT: - ptr = "PORT LOGOUT"; + msg = "PORT LOGOUT"; if (isp_find_pdb_by_handle(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, &lp)) { isp_del_wwn_entry(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), lp->port_wwn, nphdl, lp->portid); } /* FALLTHROUGH */ case IN24XX_PORT_CHANGED: - if (ptr == NULL) { - ptr = "PORT CHANGED"; - } + if (msg == NULL) + msg = "PORT CHANGED"; /* FALLTHROUGH */ - case IN24XX_LIP_RESET: - if (ptr == NULL) { - ptr = "LIP RESET"; - } - isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for N-port handle 0x%x", ISP_GET_VPIDX(isp, inot->in_vpidx), ptr, inot->in_status_subcode, nphdl); + case IN24XX_LIP_RESET: + if (msg == NULL) + msg = "LIP RESET"; + isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for N-port handle 0x%x", ISP_GET_VPIDX(isp, inot->in_vpidx), msg, inot->in_status_subcode, nphdl); /* * All subcodes here are irrelevant. What is relevant @@ -3285,21 +3284,18 @@ isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) isp_handle_srr_notify(isp, inot); break; #else - if (ptr == NULL) { - ptr = "SRR RCVD"; - } + if (msg == NULL) + msg = "SRR RCVD"; /* FALLTHROUGH */ #endif case IN24XX_LINK_RESET: - if (ptr == NULL) { - ptr = "LINK RESET"; - } + if (msg == NULL) + msg = "LINK RESET"; case IN24XX_LINK_FAILED: - if (ptr == NULL) { - ptr = "LINK FAILED"; - } + if (msg == NULL) + msg = "LINK FAILED"; default: - isp_prt(isp, ISP_LOGWARN, "Chan %d %s", ISP_GET_VPIDX(isp, inot->in_vpidx), ptr); + isp_prt(isp, ISP_LOGWARN, "Chan %d %s", ISP_GET_VPIDX(isp, inot->in_vpidx), msg); isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); break; } @@ -3479,6 +3475,12 @@ isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify) case NT_TARGET_RESET: inot->arg = MSG_TARGET_RESET; break; + case NT_QUERY_TASK_SET: + inot->arg = MSG_QUERY_TASK_SET; + break; + case NT_QUERY_ASYNC_EVENT: + inot->arg = MSG_QUERY_ASYNC_EVENT; + break; default: isp_prt(isp, ISP_LOGWARN, "%s: unknown TMF code 0x%x for chan %d lun 0x%x", __func__, notify->nt_ncode, notify->nt_channel, lun); goto bad; @@ -3587,859 +3589,6 @@ isp_target_mark_aborted_early(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id) } } } - - -#ifdef ISP_INTERNAL_TARGET -//#define ISP_SEPARATE_STATUS 1 -#define ISP_MULTI_CCBS 1 -#if defined(ISP_MULTI_CCBS) && !defined(ISP_SEPARATE_STATUS) -#define ISP_SEPARATE_STATUS 1 -#endif - -typedef struct periph_private_data_t { - union ccb *ccb; /* original ATIO or Immediate Notify */ - unsigned long offset; /* current offset */ - int sequence; /* current CTIO sequence */ - int ctio_cnt; /* current # of ctio's outstanding */ - int - status_sent : 1, - on_queue : 1; /* on restart queue */ -} ppd_t; -/* - * Each ATIO we allocate will have periph private data associated with it - * that maintains per-command state. This private to each ATIO. - */ -#define ATIO_PPD(ccb) ((ppd_t *)(((struct ccb_hdr *)ccb)->ppriv_ptr0)) -/* - * Each CTIO we send downstream will get a pointer to the ATIO itself - * so that on completion we can retrieve that pointer. - */ -#define ccb_atio ppriv_ptr1 -#define ccb_inot ppriv_ptr1 - -/* - * Each CTIO we send downstream will contain a sequence number - */ -#define CTIO_SEQ(ccb) ccb->ccb_h.ppriv_field0 - -#define MAX_ISP_TARG_TRANSFER (2 << 20) -#define NISP_TARG_CMDS 64 -#define NISP_TARG_NOTIFIES 64 -#define DISK_SHIFT 9 -#define JUNK_SIZE 256 -#define MULTI_CCB_DATA_LIM 8192 -//#define MULTI_CCB_DATA_CNT 64 -#define MULTI_CCB_DATA_CNT 8 - -extern u_int vm_kmem_size; -static int ca; -static uint32_t disk_size; -static uint8_t *disk_data = NULL; -static uint8_t *junk_data; -static MALLOC_DEFINE(M_ISPTARG, "ISPTARG", "ISP TARGET data"); -struct isptarg_softc { - /* CCBs (CTIOs, ATIOs, INOTs) pending on the controller */ - struct isp_ccbq work_queue; - struct isp_ccbq rework_queue; - struct isp_ccbq running_queue; - struct isp_ccbq inot_queue; - struct cam_periph *periph; - struct cam_path *path; - ispsoftc_t *isp; -}; -static periph_ctor_t isptargctor; -static periph_dtor_t isptargdtor; -static periph_start_t isptargstart; -static periph_init_t isptarginit; -static void isptarg_done(struct cam_periph *, union ccb *); -static void isptargasync(void *, u_int32_t, struct cam_path *, void *); - - -static int isptarg_rwparm(uint8_t *, uint8_t *, uint64_t, uint32_t, uint8_t **, uint32_t *, int *); - -static struct periph_driver isptargdriver = -{ - isptarginit, "isptarg", TAILQ_HEAD_INITIALIZER(isptargdriver.units), 0 -}; - -static void -isptarginit(void) -{ -} - -static void -isptargnotify(ispsoftc_t *isp, union ccb *iccb, struct ccb_immediate_notify *inot) -{ - struct ccb_notify_acknowledge *ack = &iccb->cna2; - - ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, inot->ccb_h.path, "%s: [0x%x] immediate notify for 0x%x from 0x%x status 0x%x arg 0x%x\n", __func__, - inot->tag_id, inot->initiator_id, inot->seq_id, inot->ccb_h.status, inot->arg); - ack->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE; - ack->ccb_h.flags = 0; - ack->ccb_h.retry_count = 0; - ack->ccb_h.cbfcnp = isptarg_done; - ack->ccb_h.timeout = 0; - ack->ccb_h.ccb_inot = inot; - ack->tag_id = inot->tag_id; - ack->seq_id = inot->seq_id; - ack->initiator_id = inot->initiator_id; - xpt_action(iccb); -} - -static void -isptargstart(struct cam_periph *periph, union ccb *iccb) -{ - const uint8_t niliqd[SHORT_INQUIRY_LENGTH] = { - 0x7f, 0x0, 0x5, 0x2, 32, 0, 0, 0x32, - 'F', 'R', 'E', 'E', 'B', 'S', 'D', ' ', - 'S', 'C', 'S', 'I', ' ', 'N', 'U', 'L', - 'L', ' ', 'D', 'E', 'V', 'I', 'C', 'E', - '0', '0', '0', '1' - }; - const uint8_t iqd[SHORT_INQUIRY_LENGTH] = { - 0, 0x0, 0x5, 0x2, 32, 0, 0, 0x32, - 'F', 'R', 'E', 'E', 'B', 'S', 'D', ' ', - 'S', 'C', 'S', 'I', ' ', 'M', 'E', 'M', - 'O', 'R', 'Y', ' ', 'D', 'I', 'S', 'K', - '0', '0', '0', '1' - }; - int r, i, more = 0, last, is_data_cmd = 0, is_write; - char *queue; - struct isptarg_softc *softc = periph->softc; - struct ccb_scsiio *csio; - lun_id_t return_lun; - struct ccb_accept_tio *atio; - uint8_t *cdb, *ptr, status; - uint8_t *data_ptr; - uint32_t data_len, flags; - struct ccb_hdr *ccbh; - - mtx_assert(periph->sim->mtx, MA_OWNED); - ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG1, iccb->ccb_h.path, "%s: function code 0x%x INOTQ=%c WORKQ=%c REWORKQ=%c\n", __func__, iccb->ccb_h.func_code, - TAILQ_FIRST(&softc->inot_queue)? 'y' : 'n', TAILQ_FIRST(&softc->work_queue)? 'y' : 'n', TAILQ_FIRST(&softc->rework_queue)? 'y' : 'n'); - /* - * Check for immediate notifies first - */ - ccbh = TAILQ_FIRST(&softc->inot_queue); - if (ccbh) { - TAILQ_REMOVE(&softc->inot_queue, ccbh, periph_links.tqe); - if (TAILQ_FIRST(&softc->inot_queue) || TAILQ_FIRST(&softc->work_queue) || TAILQ_FIRST(&softc->rework_queue)) { - xpt_schedule(periph, 1); - } - isptargnotify(softc->isp, iccb, (struct ccb_immediate_notify *)ccbh); - return; - } - - /* - * Check the rework (continuation) work queue first. - */ - ccbh = TAILQ_FIRST(&softc->rework_queue); - if (ccbh) { - atio = (struct ccb_accept_tio *)ccbh; - TAILQ_REMOVE(&softc->rework_queue, ccbh, periph_links.tqe); - more = TAILQ_FIRST(&softc->work_queue) || TAILQ_FIRST(&softc->rework_queue); - queue = "rework"; - } else { - ccbh = TAILQ_FIRST(&softc->work_queue); - if (ccbh == NULL) { - xpt_release_ccb(iccb); - return; - } - atio = (struct ccb_accept_tio *)ccbh; - TAILQ_REMOVE(&softc->work_queue, ccbh, periph_links.tqe); - more = TAILQ_FIRST(&softc->work_queue) != NULL; - queue = "work"; - } - ATIO_PPD(atio)->on_queue = 0; - - if (atio->tag_id == 0xffffffff || atio->ccb_h.func_code != XPT_ACCEPT_TARGET_IO) { - panic("BAD ATIO"); - } - - data_len = is_write = 0; - data_ptr = NULL; - csio = &iccb->csio; - status = SCSI_STATUS_OK; - flags = CAM_SEND_STATUS; - memset(&atio->sense_data, 0, sizeof (atio->sense_data)); - cdb = atio->cdb_io.cdb_bytes; - ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, ccbh->path, "%s: [0x%x] processing ATIO from %s queue initiator 0x%x CDB=0x%x data_offset=%u\n", __func__, atio->tag_id, - queue, atio->init_id, cdb[0], ATIO_PPD(atio)->offset); - - return_lun = XS_LUN(atio); - if (return_lun != 0) { - xpt_print(atio->ccb_h.path, "[0x%x] Non-Zero Lun %d: cdb0=0x%x\n", atio->tag_id, return_lun, cdb[0]); - if (cdb[0] != INQUIRY && cdb[0] != REPORT_LUNS && cdb[0] != REQUEST_SENSE) { - status = SCSI_STATUS_CHECK_COND; - SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; - SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST; - SDFIXED(atio->sense_data)->add_sense_code = 0x25; /* LOGICAL UNIT NOT SUPPORTED */ - atio->sense_len = SSD_MIN_SIZE; - } - return_lun = CAM_LUN_WILDCARD; - } - - switch (cdb[0]) { - case REQUEST_SENSE: - flags |= CAM_DIR_IN; - data_len = sizeof (atio->sense_data); - junk_data[0] = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_NO_SENSE; - memset(junk_data+1, 0, data_len-1); - if (data_len > cdb[4]) { - data_len = cdb[4]; - } - if (data_len) { - data_ptr = junk_data; - } - break; - case WRITE_6: - case WRITE_10: - case WRITE_12: - case WRITE_16: - is_write = 1; - /* FALLTHROUGH */ - case READ_6: - case READ_10: - case READ_12: - case READ_16: - is_data_cmd = 1; - r = isptarg_rwparm(cdb, disk_data, disk_size, ATIO_PPD(atio)->offset, &data_ptr, &data_len, &last); - if (r != 0) { - status = SCSI_STATUS_CHECK_COND; - SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; - SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST; - if (r == -1) { - SDFIXED(atio->sense_data)->add_sense_code = 0x21; /* LOGICAL BLOCK ADDRESS OUT OF RANGE */ - } else { - SDFIXED(atio->sense_data)->add_sense_code = 0x20; /* INVALID COMMAND OPERATION CODE */ - } - atio->sense_len = SSD_MIN_SIZE; - } else { -#ifdef ISP_SEPARATE_STATUS - if (last && data_len) { - last = 0; - } -#endif - if (last == 0) { - flags &= ~CAM_SEND_STATUS; - } - if (data_len) { - ATIO_PPD(atio)->offset += data_len; - if (is_write) - flags |= CAM_DIR_OUT; - else - flags |= CAM_DIR_IN; - } else { - flags |= CAM_DIR_NONE; - } - } - break; - case INQUIRY: - flags |= CAM_DIR_IN; - if (cdb[1] || cdb[2] || cdb[3]) { - status = SCSI_STATUS_CHECK_COND; - SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; - SDFIXED(atio->sense_data)->flags = SSD_KEY_UNIT_ATTENTION; - SDFIXED(atio->sense_data)->add_sense_code = 0x24; /* INVALID FIELD IN CDB */ - atio->sense_len = SSD_MIN_SIZE; - break; - } - data_len = sizeof (iqd); - if (data_len > cdb[4]) { - data_len = cdb[4]; - } - if (data_len) { - if (XS_LUN(iccb) != 0) { - memcpy(junk_data, niliqd, sizeof (iqd)); - } else { - memcpy(junk_data, iqd, sizeof (iqd)); - } - data_ptr = junk_data; - } - break; - case TEST_UNIT_READY: - flags |= CAM_DIR_NONE; - if (ca) { - ca = 0; - status = SCSI_STATUS_CHECK_COND; - SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; - SDFIXED(atio->sense_data)->flags = SSD_KEY_UNIT_ATTENTION; - SDFIXED(atio->sense_data)->add_sense_code = 0x29; /* POWER ON, RESET, OR BUS DEVICE RESET OCCURRED */ - atio->sense_len = SSD_MIN_SIZE; - } - break; - case SYNCHRONIZE_CACHE: - case START_STOP: - case RESERVE: - case RELEASE: - case VERIFY_10: - flags |= CAM_DIR_NONE; - break; - - case READ_CAPACITY: - flags |= CAM_DIR_IN; - if (cdb[2] || cdb[3] || cdb[4] || cdb[5]) { - status = SCSI_STATUS_CHECK_COND; - SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; - SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST; - SDFIXED(atio->sense_data)->add_sense_code = 0x24; /* INVALID FIELD IN CDB */ - atio->sense_len = SSD_MIN_SIZE; - break; - } - if (cdb[8] & 0x1) { /* PMI */ - junk_data[0] = 0xff; - junk_data[1] = 0xff; - junk_data[2] = 0xff; - junk_data[3] = 0xff; - } else { - uint64_t last_blk = (disk_size >> DISK_SHIFT) - 1; - if (last_blk < 0xffffffffULL) { - junk_data[0] = (last_blk >> 24) & 0xff; - junk_data[1] = (last_blk >> 16) & 0xff; - junk_data[2] = (last_blk >> 8) & 0xff; - junk_data[3] = (last_blk) & 0xff; - } else { - junk_data[0] = 0xff; - junk_data[1] = 0xff; - junk_data[2] = 0xff; - junk_data[3] = 0xff; - } - } - junk_data[4] = ((1 << DISK_SHIFT) >> 24) & 0xff; - junk_data[5] = ((1 << DISK_SHIFT) >> 16) & 0xff; - junk_data[6] = ((1 << DISK_SHIFT) >> 8) & 0xff; - junk_data[7] = ((1 << DISK_SHIFT)) & 0xff; - data_ptr = junk_data; - data_len = 8; - break; - case REPORT_LUNS: - flags |= CAM_DIR_IN; - memset(junk_data, 0, JUNK_SIZE); - junk_data[0] = (1 << 3) >> 24; - junk_data[1] = (1 << 3) >> 16; - junk_data[2] = (1 << 3) >> 8; - junk_data[3] = (1 << 3); - ptr = NULL; - for (i = 0; i < 1; i++) { - ptr = &junk_data[8 + (i << 3)]; - if (i >= 256) { - ptr[0] = 0x40 | ((i >> 8) & 0x3f); - } - ptr[1] = i; - } - data_ptr = junk_data; - data_len = (ptr + 8) - junk_data; - break; - - default: - flags |= CAM_DIR_NONE; - status = SCSI_STATUS_CHECK_COND; - SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; - SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST; - SDFIXED(atio->sense_data)->add_sense_code = 0x20; /* INVALID COMMAND OPERATION CODE */ - atio->sense_len = SSD_MIN_SIZE; - break; - } - - /* - * If we are done with the transaction, tell the - * controller to send status and perform a CMD_CMPLT. - * If we have associated sense data, see if we can - * send that too. - */ - if (status == SCSI_STATUS_CHECK_COND) { - flags |= CAM_SEND_SENSE; - csio->sense_len = atio->sense_len; - csio->sense_data = atio->sense_data; - flags &= ~CAM_DIR_MASK; - data_len = 0; - data_ptr = NULL; - } - cam_fill_ctio(csio, 0, isptarg_done, flags, MSG_SIMPLE_Q_TAG, atio->tag_id, atio->init_id, status, data_ptr, data_len, 30 * hz); - iccb->ccb_h.target_id = atio->ccb_h.target_id; - iccb->ccb_h.target_lun = return_lun; - iccb->ccb_h.ccb_atio = atio; - CTIO_SEQ(iccb) = ATIO_PPD(atio)->sequence++; - ATIO_PPD(atio)->ctio_cnt++; - if (flags & CAM_SEND_STATUS) { - KASSERT((ATIO_PPD(atio)->status_sent == 0), ("we have already sent status for 0x%x in %s", atio->tag_id, __func__)); - ATIO_PPD(atio)->status_sent = 1; - } - ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, atio->ccb_h.path, "%s: sending downstream for 0x%x sequence %u len %u flags %x\n", __func__, atio->tag_id, CTIO_SEQ(iccb), data_len, flags); - xpt_action(iccb); - - if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) { - cam_release_devq(periph->path, 0, 0, 0, 0); - atio->ccb_h.status &= ~CAM_DEV_QFRZN; - } -#ifdef ISP_MULTI_CCBS - if (is_data_cmd && ATIO_PPD(atio)->status_sent == 0 && ATIO_PPD(atio)->ctio_cnt < MULTI_CCB_DATA_CNT && ATIO_PPD(atio)->on_queue == 0) { - ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, atio->ccb_h.path, "%s: more still to do for 0x%x\n", __func__, atio->tag_id); - TAILQ_INSERT_TAIL(&softc->rework_queue, &atio->ccb_h, periph_links.tqe); - ATIO_PPD(atio)->on_queue = 1; - more = 1; - } -#endif - if (more) { - xpt_schedule(periph, 1); - } -} - -static cam_status -isptargctor(struct cam_periph *periph, void *arg) -{ - struct isptarg_softc *softc; - - softc = (struct isptarg_softc *)arg; - periph->softc = softc; - softc->periph = periph; - softc->path = periph->path; - ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG1, periph->path, "%s called\n", __func__); - return (CAM_REQ_CMP); -} - -static void -isptargdtor(struct cam_periph *periph) -{ - struct isptarg_softc *softc; - softc = (struct isptarg_softc *)periph->softc; - ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG1, periph->path, "%s called\n", __func__); - softc->periph = NULL; - softc->path = NULL; - periph->softc = NULL; -} - -static void -isptarg_done(struct cam_periph *periph, union ccb *ccb) -{ - struct isptarg_softc *softc; - ispsoftc_t *isp; - uint32_t newoff; - struct ccb_accept_tio *atio; - struct ccb_immediate_notify *inot; - cam_status status; - - softc = (struct isptarg_softc *)periph->softc; - isp = softc->isp; - status = ccb->ccb_h.status & CAM_STATUS_MASK; - - switch (ccb->ccb_h.func_code) { - case XPT_ACCEPT_TARGET_IO: - atio = (struct ccb_accept_tio *) ccb; - ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] ATIO seen in %s\n", atio->tag_id, __func__); - memset(ATIO_PPD(atio), 0, sizeof (ppd_t)); - TAILQ_INSERT_TAIL(&softc->work_queue, &ccb->ccb_h, periph_links.tqe); - ATIO_PPD(atio)->on_queue = 1; - xpt_schedule(periph, 1); - break; - case XPT_IMMEDIATE_NOTIFY: - inot = (struct ccb_immediate_notify *) ccb; - ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] INOT for 0x%x seen in %s\n", inot->tag_id, inot->seq_id, __func__); - TAILQ_INSERT_TAIL(&softc->inot_queue, &ccb->ccb_h, periph_links.tqe); - xpt_schedule(periph, 1); - break; - case XPT_CONT_TARGET_IO: - atio = ccb->ccb_h.ccb_atio; - KASSERT((ATIO_PPD(atio)->ctio_cnt != 0), ("ctio zero when finishing a CTIO")); - ATIO_PPD(atio)->ctio_cnt--; - if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { - switch (ccb->ccb_h.status & CAM_STATUS_MASK) { - case CAM_MESSAGE_RECV: - newoff = (ccb->csio.msg_ptr[3] << 24) | (ccb->csio.msg_ptr[4] << 16) | (ccb->csio.msg_ptr[5] << 8) | (ccb->csio.msg_ptr[6]); - ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "[0x%x] got message to return to reset offset to 0x%x at sequence %u\n", atio->tag_id, newoff, CTIO_SEQ(ccb)); - ATIO_PPD(atio)->offset = newoff; - ATIO_PPD(atio)->status_sent = 0; - if (ATIO_PPD(atio)->on_queue == 0) { - TAILQ_INSERT_TAIL(&softc->rework_queue, &atio->ccb_h, periph_links.tqe); - ATIO_PPD(atio)->on_queue = 1; - } - xpt_schedule(periph, 1); - break; - default: - cam_error_print(ccb, CAM_ESF_ALL, CAM_EPF_ALL); - xpt_action((union ccb *)atio); - break; - } - } else if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) { - ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] MID CTIO sequence %u seen in %s\n", atio->tag_id, CTIO_SEQ(ccb), __func__); - if (ATIO_PPD(atio)->status_sent == 0 && ATIO_PPD(atio)->on_queue == 0) { - TAILQ_INSERT_TAIL(&softc->rework_queue, &atio->ccb_h, periph_links.tqe); - ATIO_PPD(atio)->on_queue = 1; - } - xpt_schedule(periph, 1); - } else { - KASSERT((ATIO_PPD(atio)->ctio_cnt == 0), ("ctio count still %d when we think we've sent the STATUS ctio", ATIO_PPD(atio)->ctio_cnt)); - ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] FINAL CTIO sequence %u seen in %s\n", atio->tag_id, CTIO_SEQ(ccb), __func__); - xpt_action((union ccb *)atio); - } - if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { - cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0); - ccb->ccb_h.status &= ~CAM_DEV_QFRZN; - } - xpt_release_ccb(ccb); - break; - case XPT_NOTIFY_ACKNOWLEDGE: - if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { - cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0); - ccb->ccb_h.status &= ~CAM_DEV_QFRZN; - } - inot = ccb->ccb_h.ccb_inot; - ISP_PATH_PRT(isp, ISP_LOGTDEBUG1, inot->ccb_h.path, "[0x%x] recycle notify for tag 0x%x\n", inot->tag_id, inot->seq_id); - xpt_release_ccb(ccb); - xpt_action((union ccb *)inot); - break; - default: - xpt_print(ccb->ccb_h.path, "unexpected code 0x%x\n", ccb->ccb_h.func_code); - break; - } -} - -static void -isptargasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) -{ - struct ac_contract *acp = arg; - struct ac_device_changed *fc = (struct ac_device_changed *) acp->contract_data; - - if (code != AC_CONTRACT) { - return; - } - xpt_print(path, "0x%016llx Port ID 0x%06x %s\n", (unsigned long long) fc->wwpn, fc->port, fc->arrived? "arrived" : "departed"); -} - -static void -isp_target_thread(ispsoftc_t *isp, int chan) -{ - union ccb *ccb = NULL; - int i; - void *wchan; - cam_status status; - struct isptarg_softc *softc = NULL; - struct cam_periph *periph = NULL, *wperiph = NULL; - struct cam_path *path, *wpath; - struct cam_sim *sim; - - if (disk_data == NULL) { - disk_size = roundup2(vm_kmem_size >> 1, (1ULL << 20)); - if (disk_size < (50 << 20)) { - disk_size = 50 << 20; - } - disk_data = malloc(disk_size, M_ISPTARG, M_WAITOK | M_ZERO); - if (disk_data == NULL) { - isp_prt(isp, ISP_LOGERR, "%s: could not allocate disk data", __func__); - goto out; - } - isp_prt(isp, ISP_LOGINFO, "allocated a %ju MiB disk", (uintmax_t) (disk_size >> 20)); - } - junk_data = malloc(JUNK_SIZE, M_ISPTARG, M_WAITOK | M_ZERO); - if (junk_data == NULL) { - isp_prt(isp, ISP_LOGERR, "%s: could not allocate junk", __func__); - goto out; - } - - - softc = malloc(sizeof (*softc), M_ISPTARG, M_WAITOK | M_ZERO); - if (softc == NULL) { - isp_prt(isp, ISP_LOGERR, "%s: could not allocate softc", __func__); - goto out; - } - TAILQ_INIT(&softc->work_queue); - TAILQ_INIT(&softc->rework_queue); - TAILQ_INIT(&softc->running_queue); - TAILQ_INIT(&softc->inot_queue); - softc->isp = isp; - - periphdriver_register(&isptargdriver); - ISP_GET_PC(isp, chan, sim, sim); - ISP_GET_PC(isp, chan, path, path); - status = xpt_create_path(&wpath, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); - if (status != CAM_REQ_CMP) { - isp_prt(isp, ISP_LOGERR, "%s: could not allocate wildcard path", __func__); - return; - } - status = xpt_create_path(&path, NULL, cam_sim_path(sim), 0, 0); - if (status != CAM_REQ_CMP) { - xpt_free_path(wpath); - isp_prt(isp, ISP_LOGERR, "%s: could not allocate path", __func__); - return; - } - - ISP_LOCK(isp); - status = cam_periph_alloc(isptargctor, NULL, isptargdtor, isptargstart, "isptarg", CAM_PERIPH_BIO, wpath, NULL, 0, softc); - if (status != CAM_REQ_CMP) { - ISP_UNLOCK(isp); - isp_prt(isp, ISP_LOGERR, "%s: cam_periph_alloc for wildcard failed", __func__); - goto out; - } - wperiph = cam_periph_find(wpath, "isptarg"); - if (wperiph == NULL) { - ISP_UNLOCK(isp); - isp_prt(isp, ISP_LOGERR, "%s: wildcard periph already allocated but doesn't exist", __func__); - goto out; - } - - status = cam_periph_alloc(isptargctor, NULL, isptargdtor, isptargstart, "isptarg", CAM_PERIPH_BIO, path, NULL, 0, softc); - if (status != CAM_REQ_CMP) { - ISP_UNLOCK(isp); - isp_prt(isp, ISP_LOGERR, "%s: cam_periph_alloc failed", __func__); - goto out; - } - - periph = cam_periph_find(path, "isptarg"); - if (periph == NULL) { - ISP_UNLOCK(isp); - isp_prt(isp, ISP_LOGERR, "%s: periph already allocated but doesn't exist", __func__); - goto out; - } - - status = xpt_register_async(AC_CONTRACT, isptargasync, isp, wpath); - if (status != CAM_REQ_CMP) { - ISP_UNLOCK(isp); - isp_prt(isp, ISP_LOGERR, "%s: xpt_register_async failed", __func__); - goto out; - } - - ISP_UNLOCK(isp); - - ccb = xpt_alloc_ccb(); - - /* - * Make sure role is none. - */ - xpt_setup_ccb(&ccb->ccb_h, periph->path, 10); - ccb->ccb_h.func_code = XPT_SET_SIM_KNOB; - ccb->knob.xport_specific.fc.role = KNOB_ROLE_NONE; - ccb->knob.xport_specific.fc.valid = KNOB_VALID_ROLE; - - ISP_LOCK(isp); - xpt_action(ccb); - ISP_UNLOCK(isp); - - /* - * Now enable luns - */ - xpt_setup_ccb(&ccb->ccb_h, periph->path, 10); - ccb->ccb_h.func_code = XPT_EN_LUN; - ccb->cel.enable = 1; - ISP_LOCK(isp); - xpt_action(ccb); - ISP_UNLOCK(isp); - if (ccb->ccb_h.status != CAM_REQ_CMP) { - xpt_free_ccb(ccb); - xpt_print(periph->path, "failed to enable lun (0x%x)\n", ccb->ccb_h.status); - goto out; - } - - xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 10); - ccb->ccb_h.func_code = XPT_EN_LUN; - ccb->cel.enable = 1; - ISP_LOCK(isp); - xpt_action(ccb); - ISP_UNLOCK(isp); - if (ccb->ccb_h.status != CAM_REQ_CMP) { - xpt_free_ccb(ccb); - xpt_print(wperiph->path, "failed to enable lun (0x%x)\n", ccb->ccb_h.status); - goto out; - } - xpt_free_ccb(ccb); - - /* - * Add resources - */ - ISP_GET_PC(isp, chan, target_proc, wchan); - for (i = 0; i < 4; i++) { - ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO); - xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 1); - ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO; - ccb->ccb_h.cbfcnp = isptarg_done; - ccb->ccb_h.ppriv_ptr0 = malloc(sizeof (ppd_t), M_ISPTARG, M_WAITOK | M_ZERO); - ISP_LOCK(isp); - xpt_action(ccb); - ISP_UNLOCK(isp); - } - for (i = 0; i < NISP_TARG_CMDS; i++) { - ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO); - xpt_setup_ccb(&ccb->ccb_h, periph->path, 1); - ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO; - ccb->ccb_h.cbfcnp = isptarg_done; - ccb->ccb_h.ppriv_ptr0 = malloc(sizeof (ppd_t), M_ISPTARG, M_WAITOK | M_ZERO); - ISP_LOCK(isp); - xpt_action(ccb); - ISP_UNLOCK(isp); - } - for (i = 0; i < 4; i++) { - ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO); - xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 1); - ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY; - ccb->ccb_h.cbfcnp = isptarg_done; - ISP_LOCK(isp); - xpt_action(ccb); - ISP_UNLOCK(isp); - } - for (i = 0; i < NISP_TARG_NOTIFIES; i++) { - ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO); - xpt_setup_ccb(&ccb->ccb_h, periph->path, 1); - ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY; - ccb->ccb_h.cbfcnp = isptarg_done; - ISP_LOCK(isp); - xpt_action(ccb); - ISP_UNLOCK(isp); - } - - /* - * Now turn it all back on - */ - xpt_setup_ccb(&ccb->ccb_h, periph->path, 10); - ccb->ccb_h.func_code = XPT_SET_SIM_KNOB; - ccb->knob.xport_specific.fc.valid = KNOB_VALID_ROLE; - ccb->knob.xport_specific.fc.role = KNOB_ROLE_TARGET; - ISP_LOCK(isp); - xpt_action(ccb); - ISP_UNLOCK(isp); - - /* - * Okay, while things are still active, sleep... - */ - ISP_LOCK(isp); - for (;;) { - ISP_GET_PC(isp, chan, proc_active, i); - if (i == 0) { - break; - } - msleep(wchan, &isp->isp_lock, PUSER, "tsnooze", 0); - } - ISP_UNLOCK(isp); - -out: - if (wperiph) { - cam_periph_invalidate(wperiph); - } - if (periph) { - cam_periph_invalidate(periph); - } - if (junk_data) { - free(junk_data, M_ISPTARG); - } - if (disk_data) { - free(disk_data, M_ISPTARG); - } - if (softc) { - free(softc, M_ISPTARG); - } - xpt_free_path(path); - xpt_free_path(wpath); -} - -static void -isp_target_thread_pi(void *arg) -{ - struct isp_spi *pi = arg; - ispsoftc_t *isp = cam_sim_softc(pi->sim); - int chan = cam_sim_bus(pi->sim); - - isp_target_thread(isp, chan); - ISP_SPI_PC(isp, chan)->num_threads -= 1; - kthread_exit(); -} - -static void -isp_target_thread_fc(void *arg) -{ - struct isp_fc *fc = arg; - ispsoftc_t *isp = cam_sim_softc(pi->sim); - int chan = cam_sim_bus(pi->sim); - - isp_target_thread(isp, chan); - ISP_FC_PC(isp, chan)->num_threads -= 1; - kthread_exit(); -} - -static int -isptarg_rwparm(uint8_t *cdb, uint8_t *dp, uint64_t dl, uint32_t offset, uint8_t **kp, uint32_t *tl, int *lp) -{ - uint32_t cnt, curcnt; - uint64_t lba; - - switch (cdb[0]) { - case WRITE_16: - case READ_16: - cnt = (((uint32_t)cdb[10]) << 24) | - (((uint32_t)cdb[11]) << 16) | - (((uint32_t)cdb[12]) << 8) | - ((uint32_t)cdb[13]); - - lba = (((uint64_t)cdb[2]) << 56) | - (((uint64_t)cdb[3]) << 48) | - (((uint64_t)cdb[4]) << 40) | - (((uint64_t)cdb[5]) << 32) | - (((uint64_t)cdb[6]) << 24) | - (((uint64_t)cdb[7]) << 16) | - (((uint64_t)cdb[8]) << 8) | - ((uint64_t)cdb[9]); - break; - case WRITE_12: - case READ_12: - cnt = (((uint32_t)cdb[6]) << 16) | - (((uint32_t)cdb[7]) << 8) | - ((u_int32_t)cdb[8]); - - lba = (((uint32_t)cdb[2]) << 24) | - (((uint32_t)cdb[3]) << 16) | - (((uint32_t)cdb[4]) << 8) | - ((uint32_t)cdb[5]); - break; - case WRITE_10: - case READ_10: - cnt = (((uint32_t)cdb[7]) << 8) | - ((u_int32_t)cdb[8]); - - lba = (((uint32_t)cdb[2]) << 24) | - (((uint32_t)cdb[3]) << 16) | - (((uint32_t)cdb[4]) << 8) | - ((uint32_t)cdb[5]); - break; - case WRITE_6: - case READ_6: - cnt = cdb[4]; - if (cnt == 0) { - cnt = 256; - } - lba = (((uint32_t)cdb[1] & 0x1f) << 16) | - (((uint32_t)cdb[2]) << 8) | - ((uint32_t)cdb[3]); - break; - default: - return (-1); - } - - cnt <<= DISK_SHIFT; - lba <<= DISK_SHIFT; - - if (offset == cnt) { - *lp = 1; - return (0); - } - - if (lba + cnt > dl) { - return (-2); - } - - curcnt = MAX_ISP_TARG_TRANSFER; - if (offset + curcnt >= cnt) { - curcnt = cnt - offset; - *lp = 1; - } else { - *lp = 0; - } -#ifdef ISP_MULTI_CCBS - if (curcnt > MULTI_CCB_DATA_LIM) - curcnt = MULTI_CCB_DATA_LIM; -#endif - *tl = curcnt; - *kp = &dp[lba + offset]; - return (0); -} - -#endif #endif static void @@ -4489,12 +3638,10 @@ static void isp_poll(struct cam_sim *sim) { ispsoftc_t *isp = cam_sim_softc(sim); - uint32_t isr; - uint16_t sema, mbox; + uint16_t isr, sema, info; - if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) { - isp_intr(isp, isr, sema, mbox); - } + if (ISP_READ_ISR(isp, &isr, &sema, &info)) + isp_intr(isp, isr, sema, info); } @@ -4513,11 +3660,9 @@ isp_watchdog(void *arg) * Hand crank the interrupt code just to be sure the command isn't stuck somewhere. */ if (handle != ISP_HANDLE_FREE) { - uint32_t isr; - uint16_t sema, mbox; - if (ISP_READ_ISR(isp, &isr, &sema, &mbox) != 0) { - isp_intr(isp, isr, sema, mbox); - } + uint16_t isr, sema, info; + if (ISP_READ_ISR(isp, &isr, &sema, &info) != 0) + isp_intr(isp, isr, sema, info); ohandle = handle; handle = isp_find_handle(isp, xs); } @@ -4575,10 +3720,6 @@ isp_make_here(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt) union ccb *ccb; struct isp_fc *fc = ISP_FC_PC(isp, chan); - if (isp_autoconfig == 0) { - return; - } - /* * Allocate a CCB, create a wildcard path for this target and schedule a rescan. */ @@ -4602,9 +3743,6 @@ isp_make_gone(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt) struct cam_path *tp; struct isp_fc *fc = ISP_FC_PC(isp, chan); - if (isp_autoconfig == 0) { - return; - } if (xpt_create_path(&tp, NULL, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) == CAM_REQ_CMP) { xpt_async(AC_LOST_DEVICE, tp, NULL); xpt_free_path(tp); @@ -4735,8 +3873,9 @@ isp_ldt_task(void *arg, int pending) if (dbidx != XS_TGT(xs)) { continue; } - isp_prt(isp, ISP_LOGWARN, "command handle 0x%x for %d.%d.%d orphaned by loop down timeout", - isp->isp_xflist[i].handle, chan, XS_TGT(xs), XS_LUN(xs)); + isp_prt(isp, ISP_LOGWARN, "command handle 0x%x for %d.%d.%jx orphaned by loop down timeout", + isp->isp_xflist[i].handle, chan, XS_TGT(xs), + (uintmax_t)XS_LUN(xs)); } isp_prt(isp, ISP_LOGCONFIG, prom3, chan, dbidx, lp->portid, "Loop Down Timeout"); @@ -4892,19 +4031,6 @@ isp_action(struct cam_sim *sim, union ccb *ccb) isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code); ISP_PCMD(ccb) = NULL; - if (isp->isp_state != ISP_RUNSTATE && ccb->ccb_h.func_code == XPT_SCSI_IO) { - isp_init(isp); - if (isp->isp_state != ISP_INITSTATE) { - /* - * Lie. Say it was a selection timeout. - */ - ccb->ccb_h.status = CAM_SEL_TIMEOUT; - isp_done((struct ccb_scsiio *) ccb); - return; - } - isp->isp_state = ISP_RUNSTATE; - } - switch (ccb->ccb_h.func_code) { case XPT_SCSI_IO: /* Execute the requested I/O operation */ bus = XS_CHANNEL(ccb); @@ -4920,10 +4046,11 @@ isp_action(struct cam_sim *sim, union ccb *ccb) } ccb->csio.req_map = NULL; #ifdef DIAGNOSTIC - if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) { + if (ccb->ccb_h.target_id >= ISP_MAX_TARGETS(isp)) { xpt_print(ccb->ccb_h.path, "invalid target\n"); ccb->ccb_h.status = CAM_PATH_INVALID; - } else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) { + } else if (ISP_MAX_LUNS(isp) > 0 && + ccb->ccb_h.target_lun >= ISP_MAX_LUNS(isp)) { xpt_print(ccb->ccb_h.path, "invalid lun\n"); ccb->ccb_h.status = CAM_PATH_INVALID; } @@ -4966,15 +4093,23 @@ isp_action(struct cam_sim *sim, union ccb *ccb) lim = ISP_FC_PC(isp, bus)->loop_down_limit; if (FCPARAM(isp, bus)->loop_seen_once == 0 || ISP_FC_PC(isp, bus)->loop_down_time >= lim) { if (FCPARAM(isp, bus)->loop_seen_once == 0) { - isp_prt(isp, ISP_LOGDEBUG0, "%d.%d loop not seen yet @ %lu", XS_TGT(ccb), XS_LUN(ccb), (unsigned long) time_uptime); + isp_prt(isp, ISP_LOGDEBUG0, + "%d.%jx loop not seen yet @ %lu", + XS_TGT(ccb), (uintmax_t)XS_LUN(ccb), + (unsigned long) time_uptime); } else { - isp_prt(isp, ISP_LOGDEBUG0, "%d.%d downtime (%d) > lim (%d)", XS_TGT(ccb), XS_LUN(ccb), ISP_FC_PC(isp, bus)->loop_down_time, lim); + isp_prt(isp, ISP_LOGDEBUG0, + "%d.%jx downtime (%d) > lim (%d)", + XS_TGT(ccb), (uintmax_t)XS_LUN(ccb), + ISP_FC_PC(isp, bus)->loop_down_time, + lim); } ccb->ccb_h.status = CAM_SEL_TIMEOUT; isp_done((struct ccb_scsiio *) ccb); break; } - isp_prt(isp, ISP_LOGDEBUG0, "%d.%d retry later", XS_TGT(ccb), XS_LUN(ccb)); + isp_prt(isp, ISP_LOGDEBUG0, "%d.%jx retry later", + XS_TGT(ccb), (uintmax_t)XS_LUN(ccb)); cam_freeze_devq(ccb->ccb_h.path); cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0); ccb->ccb_h.status = CAM_REQUEUE_REQ; @@ -5477,7 +4612,8 @@ isp_action(struct cam_sim *sim, union ccb *ccb) #endif cpi->hba_eng_cnt = 0; cpi->max_target = ISP_MAX_TARGETS(isp) - 1; - cpi->max_lun = ISP_MAX_LUNS(isp) - 1; + cpi->max_lun = ISP_MAX_LUNS(isp) == 0 ? + 255 : ISP_MAX_LUNS(isp) - 1; cpi->bus_id = cam_sim_bus(sim); if (isp->isp_osinfo.sixtyfourbit) cpi->maxio = (ISP_NSEG64_MAX - 1) * PAGE_SIZE; @@ -5489,6 +4625,12 @@ isp_action(struct cam_sim *sim, union ccb *ccb) fcparam *fcp = FCPARAM(isp, bus); cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED; +#if __FreeBSD_version >= 1000700 + cpi->hba_misc |= PIM_EXTLUNS; +#endif +#if __FreeBSD_version >= 1000039 + cpi->hba_misc |= PIM_NOSCAN; +#endif /* * Because our loop ID can shift from time to time, @@ -5565,7 +4707,10 @@ isp_done(XS_T *sccb) status = sccb->ccb_h.status & CAM_STATUS_MASK; if (status != CAM_REQ_CMP) { if (status != CAM_SEL_TIMEOUT) - isp_prt(isp, ISP_LOGDEBUG0, "target %d lun %d CAM status 0x%x SCSI status 0x%x", XS_TGT(sccb), XS_LUN(sccb), sccb->ccb_h.status, sccb->scsi_status); + isp_prt(isp, ISP_LOGDEBUG0, + "target %d lun %jx CAM status 0x%x SCSI status 0x%x", + XS_TGT(sccb), (uintmax_t)XS_LUN(sccb), + sccb->ccb_h.status, sccb->scsi_status); else if ((IS_FC(isp)) && (XS_TGT(sccb) < MAX_FC_TARG)) { fcparam *fcp; @@ -5676,25 +4821,22 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) break; } case ISPASYNC_LIP: - if (msg == NULL) { + if (msg == NULL) msg = "LIP Received"; - } /* FALLTHROUGH */ case ISPASYNC_LOOP_RESET: - if (msg == NULL) { + if (msg == NULL) msg = "LOOP Reset"; - } /* FALLTHROUGH */ case ISPASYNC_LOOP_DOWN: { - if (msg == NULL) { + if (msg == NULL) msg = "LOOP Down"; - } va_start(ap, cmd); bus = va_arg(ap, int); va_end(ap); - FCPARAM(isp, bus)->link_active = 0; + FCPARAM(isp, bus)->isp_linkstate = 0; fc = ISP_FC_PC(isp, bus); if (cmd == ISPASYNC_LOOP_DOWN && fc->ready) { @@ -5727,7 +4869,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) * Change Notify before activating the FC cleanup * thread to look at the state of the loop again. */ - FCPARAM(isp, bus)->link_active = 1; + FCPARAM(isp, bus)->isp_linkstate = 1; fc->loop_dead = 0; fc->loop_down_time = 0; isp_prt(isp, ISP_LOGINFO, "Chan %d Loop UP", bus); @@ -5848,11 +4990,11 @@ changed: fc = ISP_FC_PC(isp, bus); if (evt == ISPASYNC_CHANGE_PDB) { - msg = "Chan %d Port Database Changed"; + msg = "Port Database Changed"; } else if (evt == ISPASYNC_CHANGE_SNS) { - msg = "Chan %d Name Server Database Changed"; + msg = "Name Server Database Changed"; } else { - msg = "Chan %d Other Change Notify"; + msg = "Other Change Notify"; } /* @@ -5862,7 +5004,7 @@ changed: isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Stopping Loop Down Timer @ %lu", (unsigned long) time_uptime); callout_stop(&fc->ldt); } - isp_prt(isp, ISP_LOGINFO, msg, bus); + isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg); if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) { isp_freeze_loopdown(isp, bus, msg); } @@ -5883,6 +5025,8 @@ changed: case NT_CLEAR_TASK_SET: case NT_LUN_RESET: case NT_TARGET_RESET: + case NT_QUERY_TASK_SET: + case NT_QUERY_ASYNC_EVENT: /* * These are task management functions. */ @@ -6244,13 +5388,12 @@ isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp) } else { for (olim = 0; olim < max; olim++) { for (ilim = 0; ilim < usecs; ilim += 100) { - uint32_t isr; - uint16_t sema, mbox; + uint16_t isr, sema, info; if (isp->isp_osinfo.mboxcmd_done) { break; } - if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) { - isp_intr(isp, isr, sema, mbox); + if (ISP_READ_ISR(isp, &isr, &sema, &info)) { + isp_intr(isp, isr, sema, info); if (isp->isp_osinfo.mboxcmd_done) { break; } @@ -6318,16 +5461,14 @@ void isp_platform_intr(void *arg) { ispsoftc_t *isp = arg; - uint32_t isr; - uint16_t sema, mbox; + uint16_t isr, sema, info; ISP_LOCK(isp); isp->isp_intcnt++; - if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) { + if (ISP_READ_ISR(isp, &isr, &sema, &info)) + isp_intr(isp, isr, sema, info); + else isp->isp_intbogus++; - } else { - isp_intr(isp, isr, sema, mbox); - } ISP_UNLOCK(isp); } @@ -6372,7 +5513,8 @@ isp_fcp_reset_crn(struct isp_fc *fc, uint32_t tgt, int tgt_set) int isp_fcp_next_crn(ispsoftc_t *isp, uint8_t *crnp, XS_T *cmd) { - uint32_t chan, tgt, lun; + lun_id_t lun; + uint32_t chan, tgt; struct isp_fc *fc; struct isp_nexus *nxp; int idx; |