FreeBSD/sys/dev/isp/isp.c
/*
 * Handle other response entries. A pointer to the request queue output
 * index is here in case we want to eat several entries at once, although
 * this is not used currently.
 */
Handle other response entries. A pointer to the request queue output
index is here in case we want to eat several entries at once, although
this is not used currently.
Handle other response entries . A pointer to the request queue output index is here in case we want to eat several entries at once although this is not used currently .
static int
isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp)
{
	isp_ridacq_t rid;
	int chan, c;
	uint32_t hdl, portid;
	void *ptr;
	switch (type) {
	case RQSTYPE_STATUS_CONT:
		isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response");
		return (1);
	case RQSTYPE_MARKER:
		isp_prt(isp, ISP_LOG_WARN1, "Marker Response");
		return (1);
	case RQSTYPE_RPT_ID_ACQ:
		isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
		portid = (uint32_t)rid.ridacq_vp_port_hi << 16 |
		    rid.ridacq_vp_port_lo;
		if (rid.ridacq_format == 0) {
			GET_NANOTIME(&isp->isp_init_time);
			for (chan = 0; chan < isp->isp_nchan; chan++) {
				fcparam *fcp = FCPARAM(isp, chan);
				if (fcp->role == ISP_ROLE_NONE)
					continue;
				c = (chan == 0) ? 127 : (chan - 1);
				if (rid.ridacq_map[c / 16] & (1 << (c % 16)) ||
				    chan == 0) {
					fcp->isp_loopstate = LOOP_HAVE_LINK;
					isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
					    chan, ISPASYNC_CHANGE_OTHER);
				} else {
					fcp->isp_loopstate = LOOP_NIL;
					isp_async(isp, ISPASYNC_LOOP_DOWN,
					    chan);
				}
			}
		} else {
			fcparam *fcp = FCPARAM(isp, rid.ridacq_vp_index);
			if (rid.ridacq_vp_status == RIDACQ_STS_COMPLETE ||
			    rid.ridacq_vp_status == RIDACQ_STS_CHANGED) {
				fcp->isp_topo = (rid.ridacq_map[0] >> 9) & 0x7;
				fcp->isp_portid = portid;
				fcp->isp_loopstate = LOOP_HAVE_ADDR;
				isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
				    rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER);
			} else {
				fcp->isp_loopstate = LOOP_NIL;
				isp_async(isp, ISPASYNC_LOOP_DOWN,
				    rid.ridacq_vp_index);
			}
		}
		return (1);
	case RQSTYPE_CT_PASSTHRU:
	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) {
			isp_destroy_handle(isp, hdl);
			memcpy(ptr, hp, QENTRY_LEN);
			wakeup(ptr);
		}
		return (1);
	case RQSTYPE_ATIO:
	case RQSTYPE_CTIO:
	case RQSTYPE_ENABLE_LUN:
	case RQSTYPE_MODIFY_LUN:
	case RQSTYPE_NOTIFY:
	case RQSTYPE_NOTIFY_ACK:
	case RQSTYPE_CTIO1:
	case RQSTYPE_ATIO2:
	case RQSTYPE_CTIO2:
	case RQSTYPE_CTIO3:
	case RQSTYPE_CTIO7:
	case RQSTYPE_ABTS_RCVD:
	case RQSTYPE_ABTS_RSP:
		isp->isp_rsltccmplt++;	
#ifdef	ISP_TARGET_MODE
		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
			return (1);
		}
#endif
	case RQSTYPE_REQUEST:
	default:
		ISP_DELAY(100);
		if (type != isp_get_response_type(isp, hp)) {
			isp_prt(isp, ISP_LOGINFO,
				"unstable type in response queue");
			return (-1);
		}
		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
		    isp_get_response_type(isp, hp));
		return (0);
	}
}
static int isp_handle_other_response ( ispsoftc_t * isp , int type , isphdr_t * hp , uint32_t * optrp ) { isp_ridacq_t rid ; int chan , c ; uint32_t hdl , portid ; void * ptr ; switch ( type ) { case RQSTYPE_STATUS_CONT : isp_prt ( isp , ISP_LOG_WARN1 , " " ) ; return ( 1 ) ; case RQSTYPE_MARKER : isp_prt ( isp , ISP_LOG_WARN1 , " " ) ; return ( 1 ) ; case RQSTYPE_RPT_ID_ACQ : isp_get_ridacq ( isp , ( isp_ridacq_t * ) hp , & rid ) ; portid = ( uint32_t ) rid . ridacq_vp_port_hi << 16 | rid . ridacq_vp_port_lo ; if ( rid . ridacq_format == 0 ) { GET_NANOTIME ( & isp -> isp_init_time ) ; for ( chan = 0 ; chan < isp -> isp_nchan ; chan ++ ) { fcparam * fcp = FCPARAM ( isp , chan ) ; if ( fcp -> role == ISP_ROLE_NONE ) continue ; c = ( chan == 0 ) ? 127 : ( chan - 1 ) ; if ( rid . ridacq_map [ c / 16 ] & ( 1 << ( c % 16 ) ) || chan == 0 ) { fcp -> isp_loopstate = LOOP_HAVE_LINK ; isp_async ( isp , ISPASYNC_CHANGE_NOTIFY , chan , ISPASYNC_CHANGE_OTHER ) ; } else { fcp -> isp_loopstate = LOOP_NIL ; isp_async ( isp , ISPASYNC_LOOP_DOWN , chan ) ; } } } else { fcparam * fcp = FCPARAM ( isp , rid . ridacq_vp_index ) ; if ( rid . ridacq_vp_status == RIDACQ_STS_COMPLETE || rid . ridacq_vp_status == RIDACQ_STS_CHANGED ) { fcp -> isp_topo = ( rid . ridacq_map [ 0 ] >> 9 ) & 0x7 ; fcp -> isp_portid = portid ; fcp -> isp_loopstate = LOOP_HAVE_ADDR ; isp_async ( isp , ISPASYNC_CHANGE_NOTIFY , rid . ridacq_vp_index , ISPASYNC_CHANGE_OTHER ) ; } else { fcp -> isp_loopstate = LOOP_NIL ; isp_async ( isp , ISPASYNC_LOOP_DOWN , rid . ridacq_vp_index ) ; } } return ( 1 ) ; case RQSTYPE_CT_PASSTHRU : 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 ) { isp_destroy_handle ( isp , hdl ) ; memcpy ( ptr , hp , QENTRY_LEN ) ; wakeup ( ptr ) ; } return ( 1 ) ; case RQSTYPE_ATIO : case RQSTYPE_CTIO : case RQSTYPE_ENABLE_LUN : case RQSTYPE_MODIFY_LUN : case RQSTYPE_NOTIFY : case RQSTYPE_NOTIFY_ACK : case RQSTYPE_CTIO1 : case RQSTYPE_ATIO2 : case RQSTYPE_CTIO2 : case RQSTYPE_CTIO3 : case RQSTYPE_CTIO7 : case RQSTYPE_ABTS_RCVD : case RQSTYPE_ABTS_RSP : isp -> isp_rsltccmplt ++ ; #ifdef ISP_TARGET_MODE if ( isp_target_notify ( isp , ( ispstatusreq_t * ) hp , optrp ) ) { return ( 1 ) ; } #endif case RQSTYPE_REQUEST : default : ISP_DELAY ( 100 ) ; if ( type != isp_get_response_type ( isp , hp ) ) { isp_prt ( isp , ISP_LOGINFO , " " ) ; return ( -1 ) ; } isp_prt ( isp , ISP_LOGWARN , " " , isp_get_response_type ( isp , hp ) ) ; return ( 0 ) ; } }
Handle other response entries.
Handle other response entries .
/* count as a response completion */ /* FALLTHROUGH */ /*
			 * This is questionable- we're just papering over
			 * something we've seen on SMP linux in target
			 * mode- we don't really know what's happening
			 * here that causes us to think we've gotten
			 * an entry, but that either the entry isn't
			 * filled out yet or our CPU read data is stale.
			 */