src/sys/cam/ctl/ctl_ha.c
/*
 * Send a message of the specified size.
 */
Send a message of the specified size.
Send a message of the specified size .
ctl_ha_status
ctl_ha_msg_send2(ctl_ha_channel channel, const void *addr, size_t len,
    const void *addr2, size_t len2, int wait)
{
	struct ha_softc *softc = &ha_softc;
	struct mbuf *mb, *newmb;
	struct ha_msg_wire hdr;
	size_t copylen, off;
	if (!softc->ha_connected)
		return (CTL_HA_STATUS_DISCONNECT);
	newmb = m_getm2(NULL, sizeof(hdr) + len + len2, wait, MT_DATA,
	    M_PKTHDR);
	if (newmb == NULL) {
		mtx_lock(&softc->ha_lock);
		if (softc->ha_connected) {
			softc->ha_disconnect = 1;
			softc->ha_wakeup = 1;
			wakeup(&softc->ha_wakeup);
		}
		mtx_unlock(&softc->ha_lock);
		printf("%s: Can't allocate mbuf chain\n", __func__);
		return (CTL_HA_STATUS_ERROR);
	}
	hdr.channel = channel;
	hdr.length = len + len2;
	mb = newmb;
	memcpy(mtodo(mb, 0), &hdr, sizeof(hdr));
	mb->m_len += sizeof(hdr);
	off = 0;
	for (; mb != NULL && off < len; mb = mb->m_next) {
		copylen = min(M_TRAILINGSPACE(mb), len - off);
		memcpy(mtodo(mb, mb->m_len), (const char *)addr + off, copylen);
		mb->m_len += copylen;
		off += copylen;
		if (off == len)
			break;
	}
	KASSERT(off == len, ("%s: off (%zu) != len (%zu)", __func__,
	    off, len));
	off = 0;
	for (; mb != NULL && off < len2; mb = mb->m_next) {
		copylen = min(M_TRAILINGSPACE(mb), len2 - off);
		memcpy(mtodo(mb, mb->m_len), (const char *)addr2 + off, copylen);
		mb->m_len += copylen;
		off += copylen;
	}
	KASSERT(off == len2, ("%s: off (%zu) != len2 (%zu)", __func__,
	    off, len2));
	newmb->m_pkthdr.len = sizeof(hdr) + len + len2;
	mtx_lock(&softc->ha_lock);
	if (!softc->ha_connected) {
		mtx_unlock(&softc->ha_lock);
		m_freem(newmb);
		return (CTL_HA_STATUS_DISCONNECT);
	}
	mbufq_enqueue(&softc->ha_sendq, newmb);
	softc->ha_wakeup = 1;
	mtx_unlock(&softc->ha_lock);
	wakeup(&softc->ha_wakeup);
	return (CTL_HA_STATUS_SUCCESS);
}
ctl_ha_status ctl_ha_msg_send2 ( ctl_ha_channel channel , const void * addr , size_t len , const void * addr2 , size_t len2 , int wait ) { struct ha_softc * softc = & ha_softc ; struct mbuf * mb , * newmb ; struct ha_msg_wire hdr ; size_t copylen , off ; if ( ! softc -> ha_connected ) return ( CTL_HA_STATUS_DISCONNECT ) ; newmb = m_getm2 ( NULL , sizeof ( hdr ) + len + len2 , wait , MT_DATA , M_PKTHDR ) ; if ( newmb == NULL ) { mtx_lock ( & softc -> ha_lock ) ; if ( softc -> ha_connected ) { softc -> ha_disconnect = 1 ; softc -> ha_wakeup = 1 ; wakeup ( & softc -> ha_wakeup ) ; } mtx_unlock ( & softc -> ha_lock ) ; printf ( " \n " , __func__ ) ; return ( CTL_HA_STATUS_ERROR ) ; } hdr . channel = channel ; hdr . length = len + len2 ; mb = newmb ; memcpy ( mtodo ( mb , 0 ) , & hdr , sizeof ( hdr ) ) ; mb -> m_len += sizeof ( hdr ) ; off = 0 ; for ( ; mb != NULL && off < len ; mb = mb -> m_next ) { copylen = min ( M_TRAILINGSPACE ( mb ) , len - off ) ; memcpy ( mtodo ( mb , mb -> m_len ) , ( const char * ) addr + off , copylen ) ; mb -> m_len += copylen ; off += copylen ; if ( off == len ) break ; } KASSERT ( off == len , ( " " , __func__ , off , len ) ) ; off = 0 ; for ( ; mb != NULL && off < len2 ; mb = mb -> m_next ) { copylen = min ( M_TRAILINGSPACE ( mb ) , len2 - off ) ; memcpy ( mtodo ( mb , mb -> m_len ) , ( const char * ) addr2 + off , copylen ) ; mb -> m_len += copylen ; off += copylen ; } KASSERT ( off == len2 , ( " " , __func__ , off , len2 ) ) ; newmb -> m_pkthdr . len = sizeof ( hdr ) + len + len2 ; mtx_lock ( & softc -> ha_lock ) ; if ( ! softc -> ha_connected ) { mtx_unlock ( & softc -> ha_lock ) ; m_freem ( newmb ) ; return ( CTL_HA_STATUS_DISCONNECT ) ; } mbufq_enqueue ( & softc -> ha_sendq , newmb ) ; softc -> ha_wakeup = 1 ; mtx_unlock ( & softc -> ha_lock ) ; wakeup ( & softc -> ha_wakeup ) ; return ( CTL_HA_STATUS_SUCCESS ) ; }
Send a message of the specified size.
Send a message of the specified size .
/* Consider all errors fatal for HA sanity. */