sc->sc_sc1394.sc1394_link_speed = IEEE1394_GET_LINK_SPD(ntohl(sc->sc_configrom->data[0]));
val = IEEE1394_GET_LINK_SPD(ntohl(sc->sc_configrom->data[0])); DPRINTFN(1, ("%s: ConfigRom Link Speed: %s", sc->sc_sc1394.sc1394_dev.dv_xname, ieee1394_speeds[val]));
fwnode_configrom_input(struct ieee1394_abuf *ab, int rcode){	struct fwnode_softc *sc = (struct fwnode_softc *)ab->ab_req;	struct cfgrom_cbarg *cc = NULL;	u_int32_t val, *cbuf;	if (ab->ab_cbarg != NULL) {		cc = (struct cfgrom_cbarg *) ab->ab_cbarg;		if (cc->cc_type != 0x31333934)			panic("Got an invalid abuf on callback");		DPRINTF(("(cc_num:%d/0x%02x) ", cc->cc_num, cc->cc_num));	}	if (rcode != IEEE1394_RCODE_COMPLETE) {		DPRINTF(("Aborting configrom input, rcode: %d\n", rcode));#ifdef	FWNODE_DEBUG		fwnode_dump_rom(sc, ab->ab_data, ab->ab_retlen);#endif	/* FWNODE_DEBUG */		if (cc != NULL) {			FREE(cc, M_1394DATA);			MPRINTF("FREE(1394DATA)", cc);			cc = NULL;	/* XXX */		}		free(ab->ab_data, M_1394DATA);		MPRINTF("free(1394DATA)", ab->ab_data);		ab->ab_data = NULL;		FREE(ab, M_1394DATA);		MPRINTF("FREE(1394DATA)", ab);		ab = NULL;	/* XXX */		return;	}	if (ab->ab_length != ab->ab_retlen) {		DPRINTF(("%s: config rom short read. Expected :%d, received: "		    "%d. Not attaching\n", sc->sc_sc1394.sc1394_dev.dv_xname,		    ab->ab_length, ab->ab_retlen));		free(ab->ab_data, M_1394DATA);		MPRINTF("free(1394DATA)", ab->ab_data);		ab->ab_data = NULL;		FREE(ab, M_1394DATA);		MPRINTF("FREE(1394DATA)", ab);		ab = NULL;	/* XXX */		return;	}	if (ab->ab_retlen % 4) {		DPRINTF(("%s: configrom read of invalid length: %d\n",		    sc->sc_sc1394.sc1394_dev.dv_xname, ab->ab_retlen));		free(ab->ab_data, M_1394DATA);		MPRINTF("free(1394DATA)", ab->ab_data);		ab->ab_data = NULL;		FREE(ab, M_1394DATA);		MPRINTF("FREE(1394DATA)", ab);		ab = NULL;	/* XXX */		return;	}	ab->ab_retlen = ab->ab_retlen / 4;	if (cc != NULL) {		cc->cc_buf[cc->cc_num++] = ab->ab_data[0];		ab->ab_data[0] = 0;		if (cc->cc_num < cc->cc_retlen) {			ab->ab_addr = CSR_BASE + CSR_CONFIG_ROM +			    cc->cc_num * 4;			ab->ab_length = 4;			ab->ab_retlen = 0;			ab->ab_cb = fwnode_configrom_input;			ab->ab_cbarg = cc;			sc->sc1394_read(ab);			return;		} else {			free(ab->ab_data, M_1394DATA);			MPRINTF("free(1394DATA)", ab->ab_data);			ab->ab_data = NULL;			ab->ab_data = &cc->cc_buf[0];			ab->ab_retlen = cc->cc_retlen;			ab->ab_length = cc->cc_retlen * 4;			FREE(cc, M_1394DATA);			MPRINTF("FREE(1394DATA)", cc);			cc = NULL;	/* XXX */			ab->ab_cbarg = NULL;		}	}	if (p1212_iscomplete(ab->ab_data, &ab->ab_retlen) == -1) {		DPRINTF(("%s: configrom parse error\n",		    sc->sc_sc1394.sc1394_dev.dv_xname));		free(ab->ab_data, M_1394DATA);		MPRINTF("free(1394DATA)", ab->ab_data);		ab->ab_data = NULL;	/* XXX */		FREE(ab, M_1394DATA);		MPRINTF("FREE(1394DATA)", ab);		ab = NULL;	/* XXX */		return;	}#ifdef DIAGNOSTIC	if (ab->ab_retlen < (ab->ab_length / 4))		panic("Configrom shrank during iscomplete check?");#endif	if (ab->ab_retlen > (ab->ab_length / 4)) {		if (cc != NULL) {	/* Should never occur here */			DPRINTF(("%s: cbarg not NULL\n",			    sc->sc_sc1394.sc1394_dev.dv_xname));			free(ab->ab_data, M_1394DATA);			MPRINTF("free(1394DATA)", ab->ab_data);			ab->ab_data = NULL;	/* XXX */			FREE(ab, M_1394DATA);			MPRINTF("FREE(1394DATA)", ab);			ab = NULL;	/* XXX */			return;		}		free(ab->ab_data, M_1394DATA);		MPRINTF("free(1394DATA)", ab->ab_data);		ab->ab_data = NULL;	/* XXX */		if (ab->ab_length == 4) {	/* reread whole rom */#ifdef	M_ZERO			ab->ab_data = malloc(ab->ab_retlen * 4, M_1394DATA,			    M_WAITOK|M_ZERO);			MPRINTF("malloc(1394DATA)",ab->ab_data);#else			ab->ab_data = malloc(ab->ab_retlen * 4,			    M_1394DATA, M_WAITOK);			MPRINTF("malloc(1394DATA)",ab->ab_data);			bzero(ab->ab_data, ab->ab_retlen * 4);#endif			ab->ab_addr = CSR_BASE + CSR_CONFIG_ROM;			ab->ab_length = ab->ab_retlen * 4;			ab->ab_retlen = 0;			ab->ab_cbarg = NULL;			ab->ab_cb = fwnode_configrom_input;			sc->sc1394_read(ab);		} else {			/* reread quadlet-wise */			DPRINTF(("%s: configrom re-read %d(0x%02x) quadlets"			    " - 0x%08x\n", sc->sc_sc1394.sc1394_dev.dv_xname,			    ab->ab_retlen, ab->ab_retlen, ab->ab_data[0]));#ifdef	M_ZERO			cbuf = malloc(ab->ab_retlen * 4, M_1394DATA,			    M_WAITOK|M_ZERO);			MPRINTF("malloc(1394DATA)", cbuf);			MALLOC(cc, struct cfgrom_cbarg *, sizeof(*cc),			    M_1394DATA, M_WAITOK|M_ZERO);			MPRINTF("MALLOC(1394DATA)", cc);#else			cbuf = malloc(ab->ab_retlen * 4, M_1394DATA, M_WAITOK);			MPRINTF("malloc(1394DATA)", cbuf);			bzero(cbuf, ab->ab_retlen * 4);			MALLOC(cc, struct cfgrom_cbarg *, sizeof(*cc),			    M_1394DATA, M_WAITOK);			MPRINTF("MALLOC(1394DATA)", cc);			bzero(cc, sizeof(*cc));#endif			cc->cc_type = 0x31333934;			cc->cc_retlen = ab->ab_retlen;			cc->cc_num = 0;			cc->cc_buf = cbuf;			ab->ab_data = malloc(4, M_1394DATA, M_WAITOK);			MPRINTF("malloc(1394DATA)", ab->ab_data);			ab->ab_data[0] = 0;			ab->ab_addr = CSR_BASE + CSR_CONFIG_ROM;			ab->ab_length = 4;			ab->ab_retlen = 0;			ab->ab_cb = fwnode_configrom_input;			ab->ab_cbarg = cc;			sc->sc1394_read(ab);		}		return;	} else {		DPRINTF(("configrom loaded...\n"));		sc->sc_sc1394.sc1394_configrom_len = ab->ab_retlen;		sc->sc_sc1394.sc1394_configrom = ab->ab_data;		ab->ab_data = NULL;		FREE(ab, M_1394DATA);		MPRINTF("FREE(1394DATA)", ab);		ab = NULL;	/* XXX */		/*		 * Set P1212_ALLOW_DEPENDENT_INFO_OFFSET_TYPE and		 * P1212_ALLOW_DEPENDENT_INFO_IMMED_TYPE as some protocols		 * such as SBP2 need it.		 */		val = P1212_ALLOW_DEPENDENT_INFO_OFFSET_TYPE;		val |= P1212_ALLOW_DEPENDENT_INFO_IMMED_TYPE;		val |= P1212_ALLOW_VENDOR_DIRECTORY_TYPE;		sc->sc_configrom =		    p1212_parse(sc->sc_sc1394.sc1394_configrom,		    sc->sc_sc1394.sc1394_configrom_len, val);		if ((sc->sc_configrom == NULL) ||		    (sc->sc_configrom->len != IEEE1394_BUSINFO_LEN)) {#ifdef	FWNODE_DEBUG			DPRINTF(("Parse error with config rom\n"));			fwnode_dump_rom(sc, sc->sc_sc1394.sc1394_configrom,				sc->sc_sc1394.sc1394_configrom_len);#endif	/* FWNODE_DEBUG */			if (sc->sc_configrom)				p1212_free(sc->sc_configrom);			free(sc->sc_sc1394.sc1394_configrom, M_1394DATA);			MPRINTF("free(1394DATA)", sc->sc_sc1394.sc1394_configrom);			sc->sc_sc1394.sc1394_configrom = NULL;			sc->sc_sc1394.sc1394_configrom_len = 0;			return;		}		val = htonl(IEEE1394_SIGNATURE);		if (memcmp(sc->sc_configrom->name, &val, 4)) {#ifdef	FWNODE_DEBUG			DPRINTF(("Invalid signature found in bus info block: "				    "%s\n", sc->sc_configrom->name));			fwnode_dump_rom(sc, sc->sc_sc1394.sc1394_configrom,				sc->sc_sc1394.sc1394_configrom_len);#endif	/* FWNODE_DEBUG */			p1212_free(sc->sc_configrom);			free(sc->sc_sc1394.sc1394_configrom, M_1394DATA);			MPRINTF("free(1394DATA)", sc->sc_sc1394.sc1394_configrom);			sc->sc_sc1394.sc1394_configrom = NULL;			sc->sc_sc1394.sc1394_configrom_len = 0;			return;		}		sc->sc_sc1394.sc1394_max_receive =		    IEEE1394_GET_MAX_REC(ntohl(sc->sc_configrom->data[0]));		sc->sc_sc1394.sc1394_link_speed =		    IEEE1394_GET_LINK_SPD(ntohl(sc->sc_configrom->data[0]));		printf("%s: Link Speed: %s, max_rec: %d bytes\n",		    sc->sc_sc1394.sc1394_dev.dv_xname,		    ieee1394_speeds[sc->sc_sc1394.sc1394_link_speed],		    IEEE1394_MAX_REC(sc->sc_sc1394.sc1394_max_receive));#ifdef	FWNODE_DEBUG		if (fwnodedebug) {			fwnode_dump_rom(sc, sc->sc_sc1394.sc1394_configrom,			    sc->sc_sc1394.sc1394_configrom_len);			p1212_print(sc->sc_configrom->root);		}#endif	/* FWNODE_DEBUG */		sc->sc_children = p1212_match_units(&sc->sc_sc1394.sc1394_dev,			sc->sc_configrom->root, fwnode_print);	}}