示例#1
0
/*
	save the instance resource into the stream
*/
static __bool _save_inst_res_proc(ITreeNode * nd, __bool firstVisit, f8_uint _s)
{
	IBlk * blk;
	ICBlk * cblk;
	struct cblk_link_t * lk;
	struct blk_pin_t  * p;
	struct cblk_pin_t * cp;
	IF8Stream * s;

	s = (IF8Stream*)_s;

	blk = __dcast__(ITreeNode, IBlk, nd);
	
	save_res_stream(&blk->uuid, s);

	if(blk->h.magic == CBLK_MAGIC){
		cblk = __dcast__(IBlk, ICBlk, (blk));
		
		lk = ICBlk_first_link(cblk);
		while(lk){
			save_res_stream(&lk->uuid, s);
			lk = ICBlk_next_link(lk);
		}

		p = __vcall__(blk, first_pin, (blk));
		while(p){
			cp = CONTAINING_RECORD(p, struct cblk_pin_t, p);
			save_res_stream(&cp->uuid, s);
			p = __vcall__(blk, next_pin, (p));
		}
	}
示例#2
0
FBD_API struct cblk_link_t * ICBlk_next_connection(struct blk_pin_t *p, struct cblk_link_t * lk)
{
    IBlk *b;
    ICBlk *cb;
    struct blk_pin_t *rp;

    b = parent_blk(p->blk);
    assert(b);
    assert(b->h.magic == CBLK_MAGIC);
    cb = __dcast__(IBlk, ICBlk, b);

    rp = IBlk_real_pin(p);
    if(rp->_class != PIN_CLASS_DO && rp->_class != PIN_CLASS_EO) {
        return 0;
    }
    // search in the link array
    lk = _next_link(lk);
    while(lk) {
        if(lk->s.pin == p) {
            return lk;
        }
        lk = _next_link(lk);
    }

    return 0;
}
示例#3
0
/*
	return a pin's first logical peer, i.e., pin within the same level in
	the block treelist.
*/
FBD_API struct cblk_link_t * ICBlk_first_connection(struct blk_pin_t *p)
{
    IBlk *b;
    ICBlk *cb;
    int i;
    struct cblk_link_t * lk;

    b = parent_blk(p->blk);
    if(!b) {
        // this is the top-level pin
        return 0;
    }
    assert(b);
    assert(b->h.magic == CBLK_MAGIC);
    cb = __dcast__(IBlk, ICBlk, b);

    // search in the link array
    for(i=0, lk=_first_link(cb); i<b->h.u2.n_links; i++, lk=_next_link(lk)) {
        if(lk->s.pin == p) {
            return lk;
        }
        if(lk->t.pin == p) {
            return lk;
        }
    }

    return 0;
}
示例#4
0
static int ICommPeer_write(IPeer * _this, const void * buf, int len)
{
	ICommPeer * __this;
	__this = __dcast__(IPeer, ICommPeer, _this);
	if(__this->hTty == ERROR){
		return F8_INVALID_OPERATION;
	}
	return write(__this->hTty, (char*)buf, len);
}
示例#5
0
static __bool _alloc_var_proc(ITreeNode * nd, __bool firstVisit, __uint context)
{
	IBlk * b;
	ICBlk * cb;
	struct blk_var_t *v, var;
	int len, i;
	CRegRequirementList * req;

	req = (CRegRequirementList*)context;

	b = __dcast__(ITreeNode, IBlk, nd);
	if(b->h.magic != CBLK_MAGIC){
		return __true;
	}

	//
	//
	//	now unpack the variable definitions
	//
	//

	cb = __dcast__(IBlk, ICBlk, b);
	v = (struct blk_var_t*)get_res_buf(&b->h.uuid, &len, "variables");
	if(!v){
		return __true;
	}
	if(len % sizeof(struct blk_var_t)){
		req->m_errcode = F8_INVALID_DATA;
		return __false;
	}
	len /= sizeof(struct blk_var_t);
	for(i=0; i<len; i++, v++){
		var = *v;
		var.blk = b;
		var.comment = get_res_buf_v(&b->h.uuid, 0, "!v%d!comment", i);
		var.addr.section = MEM_SECTION_INVALID;
		create_f8_uuid(&var.uuid);
		if(!req->Alloc(&var)){
			return __false;
		}
	}

	return __true;
}
示例#6
0
static __bool ICBlk_save(IBlk * _this, IF8Stream * s)
{
    IBlk * sb;
    struct cblk_link_t * l;
    struct cblk_pin_t  * p;
    union blk_pindef_t pd;
    ICBlk * cblk;

    cblk = __dcast__(IBlk, ICBlk, _this);

    // write header
    __vcall__(s, put, (s, &_this->h, sizeof(_this->h)));

    // write guid
    __vcall__(s, put, (s, &_this->uuid, sizeof(f8_uuid)));

    // write sub-blocks
    sb = first_subblk(_this);
    while(sb) {
        if(!__vcall__(sb, save, (sb, s))) {
            return __false;
        }
        sb = next_blk(sb);
    }

    // write link-defs
    l = _first_link(cblk);
    while(l) {
        __vcall__(s, put, (s, &l->uuid, sizeof(l->uuid)));
        pd.id.bid = IBlk_id_by_blk(l->s.pin->blk);
        pd.id.pid = __vcall__(l->s.pin->blk, id_by_pin, (l->s.pin));
        __vcall__(s, put, (s, &pd, sizeof(pd)));
        pd.id.bid = IBlk_id_by_blk(l->t.pin->blk);
        pd.id.pid = __vcall__(l->t.pin->blk, id_by_pin, (l->t.pin));
        __vcall__(s, put, (s, &pd, sizeof(pd)));
        l = _next_link(l);
    }

    // write pins
    p = _first_pin(cblk);
    while(p) {
        __vcall__(s, put, (s, &p->uuid, sizeof(p->uuid)));
        pd.id.bid = IBlk_id_by_blk(p->p.u1.x.id.llink->blk);
        pd.id.pid = __vcall__(p->p.u1.x.id.llink->blk, id_by_pin, (p->p.u1.x.id.llink));
        __vcall__(s, put, (s, &pd, sizeof(pd)));
        p = _next_pin(cblk, p);
    }

    return __true;
}
示例#7
0
static struct blk_pin_t * ICBlk_first_pin(IBlk * _this)
{
    ICBlk * me;
    struct cblk_pin_t * pp;

    me = __dcast__(IBlk, ICBlk, _this);
    assert(_this->h.magic == CBLK_MAGIC);

    pp = _first_pin(me);
    if(pp) {
        return &pp->p;
    }
    return 0;
}
示例#8
0
static struct blk_pin_t * ICBlk_next_pin(struct blk_pin_t * p)
{
    ICBlk * me;
    struct cblk_pin_t * pp;

    assert(p->blk->h.magic == CBLK_MAGIC);
    me = __dcast__(IBlk, ICBlk, p->blk);
    pp = SAFE_CONTAINING_RECORD(p, struct cblk_pin_t, p);
    pp = _next_pin(me, pp);
    if(pp) {
        return &pp->p;
    }
    return 0;
}
示例#9
0
FBD_API struct cblk_pin_t * ICBlk_add_pin(f8_uuid * id, struct blk_pin_t * p)
{
    ICBlk * a;
    IBlk * b;
    struct cblk_pin_t * t;


    b = parent_blk(p->blk);
    if(!b) {
        return 0;
    }
    assert(b->h.magic== CBLK_MAGIC);
    a = __dcast__(IBlk, ICBlk, b);

    // re-export not allowed
    if(p->ulink) {
        return 0;
    }

    // ok, go on
    t = (struct cblk_pin_t *)mm_alloc(
            g_hBlkHeap,
            sizeof(struct cblk_pin_t),
            0
        );
    if( !t ) {
        return 0;
    }

    memset(t, 0, sizeof(struct cblk_pin_t));

    t->uuid = *id;

    // fake a pin structure
    t->p._class = PIN_CLASS_EXP;
    t->p.blk = b;
    t->p.type = 0;
    t->p.flags = 0;

    t->p.ulink = 0;
    t->p.u1.x.id.llink = p;
    t->p.u1.x.real_pin = IBlk_real_pin(p);
    t->p.dp = p->dp;
    p->ulink = &t->p;
    RtkInsertTailList(&a->pins, &t->sibling);
    b->h.n_pins++;

    return t;
}
示例#10
0
static struct blk_pin_t * ICBlk_pin_by_id(IBlk * blk, __u16 id)
{
    ICBlk * cb;
    struct cblk_pin_t * p;

    if(id >= blk->h.n_pins) {
        return 0;
    }
    cb = __dcast__(IBlk, ICBlk, blk);
    p = _first_pin(cb);
    while(p && id) {
        p = _next_pin(cb, p);
        id--;
    }
    return &p->p;
}
示例#11
0
/*
	ICBlk::link(p1, p2)
	allocate data structures to hold this link information, and link the
	corresponding pin structure
*/
FBD_API struct cblk_link_t * ICBlk_link(f8_uuid * id, struct blk_pin_t * s, struct blk_pin_t * t)
{
    ICBlk *a;
    IBlk  *b;
    struct cblk_link_t * lk;

    if(!IBlk_linkable(s, t)) {
        return 0;
    }

    b = parent_blk(s->blk);
    a = __dcast__(IBlk, ICBlk, b);

    if( !IBlk_connect(s, t)) {
        return 0;
    }

    if( !IBlk_is_output(s)) {
        struct blk_pin_t *tmp;
        tmp = s;
        s = t;
        t = tmp;
    }
    // create a new the link object
    lk = (struct cblk_link_t *)mm_alloc(
             g_hBlkHeap,
             sizeof(struct cblk_link_t),
             0
         );
    if(!lk) {
        IBlk_disconnect(t);
        return 0;
    }
    memset(lk, 0, sizeof(struct cblk_link_t));
    lk->blk = a;
    lk->uuid = *id;
    lk->s.pin = s;
    lk->t.pin = t;
    RtkInsertTailList(&a->links, &lk->sibling);
    b->h.u2.n_links++;

    return lk;
}
示例#12
0
static __u16 ICBlk_id_by_pin(struct blk_pin_t * pin)
{
    int i;
    ICBlk * cblk;
    PRTK_LIST_ENTRY le;
    struct cblk_pin_t * cp;

    cblk = __dcast__(IBlk, ICBlk, pin->blk);
    le = cblk->pins.Flink;
    i = 0;
    cp = SAFE_CONTAINING_RECORD(pin, struct cblk_pin_t, p);
    while(le != &cblk->links) {
        if(le == &cp->sibling) {
            return i;
        }
        le = le->Flink;
        i++;
    }

    return -1;
}
示例#13
0
LOCAL int IUdpPeer_write(IPeer * _this, const void * buf, int len)
{
	IUdpPeer * __this = __dcast__(IPeer, IUdpPeer, _this);
	if(__this->vbus){
#if defined(HSP_DEBUG)
		static int lastCmd;
		static int lastCount;
		struct peer_cmd_t * tp;
		tp = (struct peer_cmd_t*)buf;
		if(tp->cmd == lastCmd){
			lastCount++;
		}else{
			hsp_log(("send cmd:%04x, %d times\n", lastCmd, lastCount));
			lastCmd = tp->cmd;
			lastCount = 1;
		}
		/* for sniffer use */
		if(g_kernel.status.state != KERN_S_STANDBY){
			memcpy((void*)buf,"PRIMRY",6);
			if(((struct peer_cmd_t*)buf)->cmd == 0x8002)
				__asm int 3;
		}else{
示例#14
0
static __bool dumpBlk(ITreeNode * nd, __bool firstVisit, __uint context)
{
	IBlk * b;
	FILE * of;
	b = __dcast__(ITreeNode, IBlk, nd);
	of = (FILE*)context;
	static int count;

#if 0
	fprintf(of, "#\n");
	fprintf(of, "#-------BLK NO.%d----------------------\n", count++);
	fprintf(of, "#\n");
#endif

	if(b->h.magic == BBLK_MAGIC){
		dumpBblk(b, of);
	}else{
		dumpCblk(b, firstVisit, of);
	}

	return __true;
}
示例#15
0
static int ICommPeer_read(IPeer * _this, void * buf, int len, int to)
{
	ICommPeer * __this;
	fd_set rset;
	struct timeval timeout;
	int ret;

	__this = __dcast__(IPeer, ICommPeer, _this);
	if(__this->hTty == ERROR){
		return F8_INVALID_OPERATION;
	}
	FD_ZERO(&rset);
	FD_SET(__this->hTty, &rset);
	timeout.tv_sec = 0;
	timeout.tv_usec = to * 1000;
	ret = select(__this->hTty + 1, &rset, NULL, NULL, &timeout);
	if(FD_ISSET(__this->hTty, &rset)){
		ret = read(__this->hTty, (char*)buf, len);
	}else{
		ret = -1;
	}
	return ret;
}
示例#16
0
/*
	errors checked in this procedure
	1) unattached DI with memory binding
	2) DO without memory binding
	3) DO with incorrect memory address
	4) DO with conflicting address
	5) multiple assignments of a variable
*/
__bool CErrorDetector::_fixup_pins(ITreeNode * nd)
{
	IBlk * b;
	struct blk_pin_t * p;
	
	void * o;
	const struct blk_var_t * var;
	struct blk_pin_t * rp;
	int length;

	b = __dcast__(ITreeNode, IBlk, nd);
	for(p = __vcall__(b, first_pin, (b)); p; p = __vcall__(b, next_pin, (p))){
		if(p->ulink){
			continue;
		}

		rp = IBlk_real_pin(p);
		
		if(!(rp->_class == PIN_CLASS_DI || rp->_class == PIN_CLASS_DO)){
			continue;
		}

		if(rp->_class == PIN_CLASS_DO && rp->binding != PIN_B_MEMORY){
			// invalid binding
			CInvalidAddress ia;
			ia.magic = PIN_MAGIC;
			ia.o = rp;
			ia.a = 0; /* DO without MEMORY BINDING */
			m_invalidAddress.insert(m_invalidAddress.end(), ia);
		}

		if(rp->binding != PIN_B_MEMORY){
			continue;
		}

		length = _type_size(rp->type);
		var = (blk_var_t*)query_var_by_pin(p);
		if(!var){
			if(rp->_class == PIN_CLASS_DI){
				if(RtkIsTripleListEmpty(&rp->u1.link)){
					CInvalidAddress ia;
					ia.magic = PIN_MAGIC;
					ia.o = rp;
					ia.a = 1; /* unattached DI with memory binding */
					m_invalidAddress.insert(m_invalidAddress.end(), ia);
				}
			}else{
				if(!is_address_valid(proxy_adapter->kernel, rp, &rp->u2.mem_addr)){
					CInvalidAddress ia;
					ia.magic = PIN_MAGIC;
					ia.o = rp;
					ia.a = 2; /* invalid address */
					m_invalidAddress.insert(m_invalidAddress.end(), ia);
				}
				CAddressConflit ac;
				/* check conflicts */
				o = get_address_owner(&rp->u2.mem_addr, 1, &ac.magic2);
				if(o == rp){
					continue;
				}
				ac.magic1 = PIN_MAGIC;
				ac.o1 = rp;
				ac.o2 = o;
				m_addrConflicts.insert(m_addrConflicts.end(), ac);
			}
		}else{
			// the error is credited to the variable, not check here
		}
	}

	return __true;
}
示例#17
0
static void dumpCblk(IBlk * b, __bool firstVisit, FILE * of)
{
	const char * name;
	char path[F8_MAX_PATH];
	char buf[1024];
	char idName[128];
	struct blk_ent_t be;

	if(firstVisit){
		name = IBlk_name(b);
		IBlk_path_by_blk(parent_blk(b), path, sizeof(path));
		if(parent_blk(b) && !(parent_blk(b)->h.flags & BLK_F_READONLY)){
			if(b->h.flags & BLK_F_READONLY){
				if(blklib_query(&b->h.uuid, &be)){
					sprintf(buf, "mount  path=\"%s\" type=\"%s.%s\" name=\"%s\"", path, be.dir, be.name, name);
				}else{
					f8_uuid_to_string(&b->h.uuid, idName, sizeof(idName));
					sprintf(buf, "mount  path=\"%s\" id=%s name=\"%s\"", path, idName, name);
				}
				if(of==stdout)
					utils_trace("%s\n",buf);
				else
					fprintf(of, "%s\n", buf);
				return;
			}else{
				sprintf(buf, "mount path=\"%s\" file=blank.blk name=\"%s\" rw", path, name);
			}
			if (of==stdout)
				utils_trace("%s\n",buf);
			else
				fprintf(of, "%s\n", buf);
			IBlk_path_by_blk(b, path, sizeof(path));
			sprintf(buf, "place block \"%s\" (%d,%d)", path, get_res_int(&b->uuid, "x", 0), get_res_int(&b->uuid, "y", 0));
			if(of==stdout)
				utils_trace("%s\n",buf);
			else
				fprintf(of, "%s\n", buf);
		}

		enum_variables(b, defineVariable, (__uint)of);
	}else{
		/*
			dump links positions/export pins
		*/
		if(b->h.flags & BLK_F_READONLY){
			return;
		}
		ICBlk * cb = __dcast__(IBlk, ICBlk, b);
		struct cblk_link_t * l;
		for(l=ICBlk_first_link(cb); l; l=ICBlk_next_link(l)){
			char p1[F8_MAX_PATH];
			char p2[F8_MAX_PATH];
			IBlk_path_by_pin(l->s.pin, p1, sizeof(p1));
			IBlk_path_by_pin(l->t.pin, p2, sizeof(p2));
			sprintf(buf, "link \"%s\" \"%s\"", p1, p2);
			if(of==stdout)
				utils_trace("%s\n",buf);
			else
				fprintf(of, "%s\n", buf);

			TLinkMetrics *m;
			m = (TLinkMetrics *)get_res_buf(&l->uuid, 0, "metrics");
			if(m){
				char *p;
				p = buf;
				p += sprintf(p, "place link \"%s\" %d ", p2, m->count);
				int i;
				for(i=0; i<m->count; i++){
					p += sprintf(p, "(%d,%d) ", m->coord[i].x, m->coord[i].y);
				}
				if(of==stdout)
					utils_trace("%s\n",buf);
				else
					fprintf(of, "%s\n", buf);
			}
		}
	}
}
示例#18
0
/*
	patch the memory address in a block hive, and remember
	all register allocated.
*/
static __bool _alloc_reg_proc(ITreeNode * nd, __bool firstVisit, __uint context)
{
	IBlk * b, *pb;
	struct blk_pin_t *p, *rp;
	CRegRequirementList * req;
	char path[1024];
	blk_var_t * v;

	req = (CRegRequirementList*)context;
	b = __dcast__(ITreeNode, IBlk, nd);
	
	pb = parent_blk(b);
		
	for(p = __vcall__(b, first_pin, (b)); 
		p; 
		p = __vcall__(b, next_pin, (p))
	){
		if(p->_class == PIN_CLASS_EI || p->_class == PIN_CLASS_EO){
			continue;
		}

		if(p->ulink){
			// postpone register allocation until the outmost 
			// parent block is being processed
			continue;
		}

		// ok, do allocation
		rp = IBlk_real_pin(p);
		if(rp->binding == PIN_B_CONST){
			if(rp->_class == PIN_CLASS_DI){
				memcpy(rp->dp, p->dp, _type_size(rp->type));
				continue;
			}else{
				req->m_errcode = F8_INVALID_DATA;
				return __false;
			}			
		}else if(rp->binding != PIN_B_MEMORY){
			req->m_errcode = F8_INVALID_DATA;
			return __false;
		}

		if(pb && p->u2.mem_addr.section == MEM_SECTION_VAR){
			//
			// the pin references a variable
			//
			if(v = (blk_var_t * )query_var_by_id(pb, p->u2.mem_addr.addr)){
				// 
				// note!! address is fixed on real pin
				//
				if(v->type != rp->type){
					req->m_errcode = F8_INVALID_DATA;
					return __false;
				}
				rp->u2.mem_addr = v->addr;
				req->Add(v);
			}else{
				IBlk_path_by_pin(p, path, sizeof(path));
				utils_error(
					"%s references undefined variable %d.\n", 
					path, 
					p->u2.mem_addr.addr
					);
				req->m_errcode = F8_UNRESOLVED_REFERENCES;
				return __false;
			}
		}else{
			//
			// the pin has an address on its own
			//
			if(!req->Alloc(rp)){
				return __false;
			}
		}
	}

	return __true;
}
示例#19
0
/*
	finding out registers usage info for the block hive
*/
static __bool _gather_reg_usage(ITreeNode * nd, __bool firstVisit, __uint context)
{
	IBlk * b;
	struct blk_pin_t *p, *rp;
	int length;
	CRegRequirementList * req;
	struct blk_var_t * var;
	char pName[F8_MAX_PATH];

	b = __dcast__(ITreeNode, IBlk, nd);

	req = (CRegRequirementList *)context;

	if(b->h.magic == CBLK_MAGIC && req->m_bGatherForDelete){
		enum_variables(b, _e_var, (__uint)req);
	}	
	
	for(p = __vcall__(b, first_pin, (b)); p; p = __vcall__(b, next_pin, (p))){
		/*
			if the pin is exported, then the variable reference or memory address
			assignment is counted on the exported pins
		*/
		if(p->ulink){
			continue;
		}
		rp = IBlk_real_pin(p);
		if(rp->_class != PIN_CLASS_DI && rp->_class != PIN_CLASS_DO){
			continue;
		}
		if(rp->binding != PIN_B_MEMORY){
			continue;
		}
		length = _type_size(rp->type);
		var = (blk_var_t*)query_var_by_pin(p);
		if(var){
			req->Add(var);
		}else{
			if(rp->_class == PIN_CLASS_DI){
				if(RtkIsTripleListEmpty(&rp->u1.link)){
					/*
					a data input pin can have a memory address only in
					two cases: 1) linked. or 2) connected with variable.
					*/
					IBlk_path_by_pin(p, pName, sizeof(pName));
					utils_error(
						"%s - DI pin address %%%d%05d incorrect.\n", 
						pName, 
						rp->u2.mem_addr.section, 
						rp->u2.mem_addr.addr
						);
					req->m_errcode = F8_INVALID_DATA;
				}
			}else{
				if(!is_address_valid(proxy_adapter->kernel, rp, &rp->u2.mem_addr)){
					req->m_errcode = F8_INVALID_DATA;
					IBlk_path_by_pin(p, pName, sizeof(pName));
					utils_error(
						"%s - DO pin address %%%d%05d incorrect.\n", 
						pName, 
						rp->u2.mem_addr.section, 
						rp->u2.mem_addr.addr
						);
				}else{
					req->Add(rp, &rp->u2.mem_addr, length);
				}
			}
		}
	}

	return __true;
}
示例#20
0
/*
	ICBlk::load(IF8Stream * s)
	this will construct an in-memory composite block object.
	the most exciting part of F8 controller program.
*/
static __bool ICBlk_load(IBlk * blk, IF8Stream * s)
{
    ICBlk * cblk;
    struct blk_hdr_t * h, _h;
    int i;
    IBlk * sb;
    union blk_pindef_t pd, ps, pt;
    f8_uuid uuid;

    cblk = __dcast__(IBlk, ICBlk, blk);
    h = &_h;

    if(__vcall__(s, get, (s, h, sizeof(struct blk_hdr_t)))
            !=
            sizeof(struct blk_hdr_t)
      ) {
        return __false;
    }

    blk->h = *h;
    blk->h.u1.n_subblocks = 0;
    blk->h.u2.n_links = 0;
    blk->h.n_pins = 0;

    if(!__vcall__(s, get, (s, &blk->uuid, sizeof(blk->uuid)))) {
        goto __failed;
    }

    /*
    	load sub-blocks
    */
    for(i=0; i<h->u1.n_subblocks; i++) {
        sb = IBlk_from_stream(s);
        if(!sb) {
            goto __failed;
        }
        if(!ICBlk_add_blk(cblk, sb)) {
            delete_blk(sb);
            return __false;
        }
    }

    /*
    	load links
    */
    for(i=0; i<h->u2.n_links; i++) {
        if(!__vcall__(s, get, (s, &uuid, sizeof(uuid)))) {
            goto __failed;
        }

        if(!__vcall__(s, get, (s, &ps, sizeof(union blk_pindef_t)))) {
            goto __failed;
        }

        if(!__vcall__(s, get, (s, &pt, sizeof(union blk_pindef_t)))) {
            goto __failed;
        }

        locate_pin(blk, ps);
        locate_pin(blk, pt);

        if(!ps.pin || !pt.pin) {
            goto __failed;
        }

        if(!ICBlk_link(&uuid, ps.pin, pt.pin)) {
            goto __failed;
        }
    }

    /*
    	load exports
    */
    for(i=0; i<h->n_pins; i++) {
        if(!__vcall__(s, get, (s, &uuid, sizeof(uuid)))) {
            goto __failed;
        }

        if(!__vcall__(s, get, (s, &pd, sizeof(union blk_pindef_t)))) {
            goto __failed;
        }

        locate_pin(blk, pd);
        if(!pd.pin) {
            return __false;
        }

        if(!ICBlk_add_pin(&uuid, pd.pin)) {
            return __false;
        }
    }

    return __true;

__failed:
    return __false;
}