示例#1
0
static void
test_varbuf_addc(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 1);

	varbuf_add_char(&vb, 'a');
	test_pass(vb.used == 1);
	test_pass(vb.size >= vb.used);
	test_pass(vb.buf[0] == 'a');

	varbuf_add_char(&vb, 'b');
	test_pass(vb.used == 2);
	test_pass(vb.size >= vb.used);
	test_mem(vb.buf, ==, "ab", 2);

	varbuf_add_char(&vb, 'c');
	test_pass(vb.used == 3);
	test_pass(vb.size >= vb.used);
	test_mem(vb.buf, ==, "abc", 3);

	varbuf_add_char(&vb, 'd');
	test_pass(vb.used == 4);
	test_pass(vb.size >= vb.used);
	test_mem(vb.buf, ==, "abcd", 4);

	varbuf_destroy(&vb);
}
示例#2
0
void extractDebPackageInfo(const struct pkginfo *pkg, QueryData &results) {
  Row r;

  struct varbuf vb;
  varbuf_init(&vb, 20);

  // Iterate over the desired fieldinfos, calling their fwritefunctions
  // to extract the package's information.
  const struct fieldinfo *fip = nullptr;
  for (fip = fieldinfos; fip->name; fip++) {
    fip->wcall(&vb, pkg, &pkg->installed, fw_printheader, fip);

    std::string line = vb.string();
    if (!line.empty()) {
      size_t separator_position = line.find(':');

      std::string key = line.substr(0, separator_position);
      std::string value = line.substr(separator_position + 1, line.length());
      auto it = kFieldMappings.find(key);
      if (it != kFieldMappings.end()) {
        boost::algorithm::trim(value);
        r[it->second] = std::move(value);
      }
    }
    varbuf_reset(&vb);
  }
  varbuf_destroy(&vb);

  results.push_back(r);
}
示例#3
0
static void
test_varbuf_grow(void)
{
	struct varbuf vb;
	size_t old_size;
	int i;

	varbuf_init(&vb, 10);

	/* Test that we grow when needed. */
	varbuf_grow(&vb, 100);
	test_pass(vb.used == 0);
	test_pass(vb.size >= 100);

	old_size = vb.size;

	/* Test that we are not leaking. */
	for (i = 0; i < 10; i++) {
		varbuf_grow(&vb, 100);
		test_pass(vb.used == 0);
		test_pass(vb.size >= 100);
		test_pass(vb.size == old_size);
	}

	/* Test that we grow when needed, with used space. */
	vb.used = 10;
	varbuf_grow(&vb, 100);
	test_pass(vb.used == 10);
	test_pass(vb.size >= 110);

	varbuf_destroy(&vb);
}
示例#4
0
文件: varbuf.c 项目: guillemj/dpkg
struct varbuf *
varbuf_new(size_t size)
{
  struct varbuf *v;

  v = m_malloc(sizeof(*v));
  varbuf_init(v, size);

  return v;
}
enum modstatdb_rw
modstatdb_open(enum modstatdb_rw readwritereq)
{
    modstatdb_init();

    cflags = readwritereq & msdbrw_available_mask;
    readwritereq &= ~msdbrw_available_mask;

    switch (readwritereq) {
    case msdbrw_needsuperuser:
    case msdbrw_needsuperuserlockonly:
        if (getuid() || geteuid())
            ohshit(_("requested operation requires superuser privilege"));
    /* Fall through. */
    case msdbrw_write:
    case msdbrw_writeifposs:
        if (access(dpkg_db_get_dir(), W_OK)) {
            if (errno != EACCES)
                ohshite(_("unable to access dpkg status area"));
            else if (readwritereq == msdbrw_write)
                ohshit(_("operation requires read/write access to dpkg status area"));
            cstatus= msdbrw_readonly;
        } else {
            modstatdb_lock();
            cstatus= (readwritereq == msdbrw_needsuperuserlockonly ?
                      msdbrw_needsuperuserlockonly :
                      msdbrw_write);
        }
        break;
    case msdbrw_readonly:
        cstatus= msdbrw_readonly;
        break;
    default:
        internerr("unknown modstatdb_rw '%d'", readwritereq);
    }

    dpkg_arch_load_list();

    if (cstatus != msdbrw_needsuperuserlockonly) {
        cleanupdates();
        if (cflags >= msdbrw_available_readonly)
            parsedb(availablefile, pdb_parse_available, NULL);
    }

    if (cstatus >= msdbrw_write) {
        createimptmp();
        varbuf_init(&uvb, 10240);
    }

    trig_fixup_awaiters(cstatus);
    trig_incorporate(cstatus);

    return cstatus;
}
示例#6
0
static void
test_varbuf_prealloc(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 10);
	test_pass(vb.used == 0);
	test_pass(vb.size >= 10);
	test_pass(vb.buf != NULL);

	varbuf_destroy(&vb);
	test_pass(vb.used == 0);
	test_pass(vb.size == 0);
	test_pass(vb.buf == NULL);
}
示例#7
0
static void
test_varbuf_init(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 0);
	test_pass(vb.used == 0);
	test_pass(vb.size == 0);
	test_pass(vb.buf == NULL);

	varbuf_destroy(&vb);
	test_pass(vb.used == 0);
	test_pass(vb.size == 0);
	test_pass(vb.buf == NULL);
}
示例#8
0
static void
test_varbuf_map_char(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 5);

	varbuf_add_buf(&vb, "1234a5678a9012a", 15);

	varbuf_map_char(&vb, 'a', 'z');
	test_pass(vb.used == 15);
	test_pass(vb.size >= vb.used);
	test_mem(vb.buf, ==, "1234z5678z9012z", 15);

	varbuf_destroy(&vb);
}
示例#9
0
static void
test_varbuf_trunc(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 50);

	/* Test that we truncate (grow). */
	varbuf_trunc(&vb, 20);
	test_pass(vb.used == 20);
	test_pass(vb.size >= 50);

	/* Test that we truncate (shrink). */
	varbuf_trunc(&vb, 10);
	test_pass(vb.used == 10);
	test_pass(vb.size >= 50);

	varbuf_destroy(&vb);
}
示例#10
0
static void
test_varbuf_detach(void)
{
	struct varbuf vb;
	char *str;

	varbuf_init(&vb, 0);

	varbuf_add_buf(&vb, "1234567890", 10);

	str = varbuf_detach(&vb);

	test_mem(str, ==, "1234567890", 10);
	test_pass(vb.used == 0);
	test_pass(vb.size == 0);
	test_pass(vb.buf == NULL);

	free(str);
}
示例#11
0
static void
test_varbuf_dup_char(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 5);

	varbuf_dup_char(&vb, 'z', 10);
	test_pass(vb.used == 10);
	test_pass(vb.size >= vb.used);
	test_mem(vb.buf, ==, "zzzzzzzzzz", 10);

	varbuf_dup_char(&vb, 'y', 5);
	test_pass(vb.used == 15);
	test_pass(vb.size >= vb.used);
	test_mem(vb.buf, ==, "zzzzzzzzzzyyyyy", 15);

	varbuf_destroy(&vb);
}
示例#12
0
static void
test_varbuf_addbuf(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 5);

	varbuf_add_buf(&vb, "1234567890", 10);
	test_pass(vb.used == 10);
	test_pass(vb.size >= vb.used);
	test_mem(vb.buf, ==, "1234567890", 10);

	varbuf_add_buf(&vb, "abcde", 5);
	test_pass(vb.used == 15);
	test_pass(vb.size >= vb.used);
	test_mem(vb.buf, ==, "1234567890abcde", 15);

	varbuf_destroy(&vb);
}
示例#13
0
static void
test_varbuf_reset(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 10);

	varbuf_add_buf(&vb, "1234567890", 10);

	varbuf_reset(&vb);
	test_pass(vb.used == 0);
	test_pass(vb.size >= vb.used);

	varbuf_add_buf(&vb, "abcdefghijklmno", 15);
	test_pass(vb.used == 15);
	test_pass(vb.size >= vb.used);
	test_mem(vb.buf, ==, "abcdefghijklmno", 15);

	varbuf_destroy(&vb);
}
示例#14
0
static void
test_varbuf_end_str(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 10);

	varbuf_add_buf(&vb, "1234567890X", 11);
	test_pass(vb.used == 11);
	test_pass(vb.size >= vb.used);
	test_mem(vb.buf, ==, "1234567890X", 11);

	varbuf_trunc(&vb, 10);

	varbuf_end_str(&vb);
	test_pass(vb.used == 10);
	test_pass(vb.size >= vb.used + 1);
	test_pass(vb.buf[10] == '\0');
	test_str(vb.buf, ==, "1234567890");

	varbuf_destroy(&vb);
}
示例#15
0
static void
test_varbuf_printf(void)
{
	struct varbuf vb;

	varbuf_init(&vb, 5);

	/* Test normal format printing. */
	varbuf_printf(&vb, "format %s number %d", "string", 10);
	test_pass(vb.used == strlen("format string number 10"));
	test_pass(vb.size >= vb.used);
	test_str(vb.buf, ==, "format string number 10");

	varbuf_reset(&vb);

	/* Test concatenated format printing. */
	varbuf_printf(&vb, "format %s number %d", "string", 10);
	varbuf_printf(&vb, " extra %s", "string");
	test_pass(vb.used == strlen("format string number 10 extra string"));
	test_pass(vb.size >= vb.used);
	test_str(vb.buf, ==, "format string number 10 extra string");

	varbuf_destroy(&vb);
}
示例#16
0
int srom_parsecis(u8 *pcis[], uint ciscnt, char **vars,
		  uint *count)
{
	char eabuf[32];
	char *base;
	varbuf_t b;
	u8 *cis, tup, tlen, sromrev = 1;
	int i, j;
	bool ag_init = false;
	u32 w32;
	uint funcid;
	uint cisnum;
	s32 boardnum;
	int err;
	bool standard_cis;

	ASSERT(vars != NULL);
	ASSERT(count != NULL);

	boardnum = -1;

	base = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
	ASSERT(base != NULL);
	if (!base)
		return -2;

	varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
	memset(base, 0, MAXSZ_NVRAM_VARS);
	eabuf[0] = '\0';
	for (cisnum = 0; cisnum < ciscnt; cisnum++) {
		cis = *pcis++;
		i = 0;
		funcid = 0;
		standard_cis = true;
		do {
			if (standard_cis) {
				tup = cis[i++];
				if (tup == CISTPL_NULL || tup == CISTPL_END)
					tlen = 0;
				else
					tlen = cis[i++];
			} else {
				if (cis[i] == CISTPL_NULL
				    || cis[i] == CISTPL_END) {
					tlen = 0;
					tup = cis[i];
				} else {
					tlen = cis[i];
					tup = CISTPL_BRCM_HNBU;
				}
				++i;
			}
			if ((i + tlen) >= CIS_SIZE)
				break;

			switch (tup) {
			case CISTPL_VERS_1:
				/* assume the strings are good if the version field checks out */
				if (((cis[i + 1] << 8) + cis[i]) >= 0x0008) {
					varbuf_append(&b, vstr_manf,
						      &cis[i + 2]);
					varbuf_append(&b, vstr_productname,
						      &cis[i + 3 +
							   strlen((char *)
								  &cis[i +
								       2])]);
					break;
				}

			case CISTPL_MANFID:
				varbuf_append(&b, vstr_manfid,
					      (cis[i + 1] << 8) + cis[i]);
				varbuf_append(&b, vstr_prodid,
					      (cis[i + 3] << 8) + cis[i + 2]);
				break;

			case CISTPL_FUNCID:
				funcid = cis[i];
				break;

			case CISTPL_FUNCE:
				switch (funcid) {
				case CISTPL_FID_SDIO:
#ifdef BCMSDIO
					if (cis[i] == 0) {
						u8 spd = cis[i + 3];
						static int base[] = {
							-1, 10, 12, 13, 15, 20,
							    25, 30,
							35, 40, 45, 50, 55, 60,
							    70, 80
						};
						static int mult[] = {
							10, 100, 1000, 10000,
							-1, -1, -1, -1
						};
						ASSERT((mult[spd & 0x7] != -1)
						       &&
						       (base
							[(spd >> 3) & 0x0f]));
						varbuf_append(&b,
							      vstr_sdmaxblk[0],
							      (cis[i + 2] << 8)
							      + cis[i + 1]);
						varbuf_append(&b,
							      vstr_sdmaxspeed,
							      (mult[spd & 0x7] *
							       base[(spd >> 3) &
								    0x0f]));
					} else if (cis[i] == 1) {
						varbuf_append(&b,
							      vstr_sdmaxblk
							      [cisnum],
							      (cis[i + 13] << 8)
							      | cis[i + 12]);
					}
#endif				/* BCMSDIO */
					funcid = 0;
					break;
				default:
					/* set macaddr if HNBU_MACADDR not seen yet */
					if (eabuf[0] == '\0' &&
					    cis[i] == LAN_NID &&
					    !is_zero_ether_addr(&cis[i + 2]) &&
					    !is_multicast_ether_addr(&cis[i + 2])) {
						ASSERT(cis[i + 1] ==
						       ETH_ALEN);
						snprintf(eabuf, sizeof(eabuf),
							"%pM", &cis[i + 2]);

						/* set boardnum if HNBU_BOARDNUM not seen yet */
						if (boardnum == -1)
							boardnum =
							    (cis[i + 6] << 8) +
							    cis[i + 7];
					}
					break;
				}
				break;

			case CISTPL_CFTABLE:
				varbuf_append(&b, vstr_regwindowsz,
					      (cis[i + 7] << 8) | cis[i + 6]);
				break;

			case CISTPL_BRCM_HNBU:
				switch (cis[i]) {
				case HNBU_SROMREV:
					sromrev = cis[i + 1];
					varbuf_append(&b, vstr_sromrev,
						      sromrev);
					break;

				case HNBU_XTALFREQ:
					varbuf_append(&b, vstr_xtalfreq,
						      (cis[i + 4] << 24) |
						      (cis[i + 3] << 16) |
						      (cis[i + 2] << 8) |
						      cis[i + 1]);
					break;

				case HNBU_CHIPID:
					varbuf_append(&b, vstr_vendid,
						      (cis[i + 2] << 8) +
						      cis[i + 1]);
					varbuf_append(&b, vstr_devid,
						      (cis[i + 4] << 8) +
						      cis[i + 3]);
					if (tlen >= 7) {
						varbuf_append(&b, vstr_chiprev,
							      (cis[i + 6] << 8)
							      + cis[i + 5]);
					}
					if (tlen >= 9) {
						varbuf_append(&b,
							      vstr_subvendid,
							      (cis[i + 8] << 8)
							      + cis[i + 7]);
					}
					if (tlen >= 11) {
						varbuf_append(&b, vstr_subdevid,
							      (cis[i + 10] << 8)
							      + cis[i + 9]);
						/* subdevid doubles for boardtype */
						varbuf_append(&b,
							      vstr_boardtype,
							      (cis[i + 10] << 8)
							      + cis[i + 9]);
					}
					break;

				case HNBU_BOARDNUM:
					boardnum =
					    (cis[i + 2] << 8) + cis[i + 1];
					break;

				case HNBU_PATCH:
					{
						char vstr_paddr[16];
						char vstr_pdata[16];

						/* retrieve the patch pairs
						 * from tlen/6; where 6 is
						 * sizeof(patch addr(2)) +
						 * sizeof(patch data(4)).
						 */
						patch_pair = tlen / 6;

						for (j = 0; j < patch_pair; j++) {
							snprintf(vstr_paddr,
								 sizeof
								 (vstr_paddr),
								 "pa%d=0x%%x",
								 j);
							snprintf(vstr_pdata,
								 sizeof
								 (vstr_pdata),
								 "pd%d=0x%%x",
								 j);

							varbuf_append(&b,
								      vstr_paddr,
								      (cis
								       [i +
									(j *
									 6) +
									2] << 8)
								      | cis[i +
									    (j *
									     6)
									    +
									    1]);

							varbuf_append(&b,
								      vstr_pdata,
								      (cis
								       [i +
									(j *
									 6) +
									6] <<
								       24) |
								      (cis
								       [i +
									(j *
									 6) +
									5] <<
								       16) |
								      (cis
								       [i +
									(j *
									 6) +
									4] << 8)
								      | cis[i +
									    (j *
									     6)
									    +
									    3]);
						}
					}
					break;

				case HNBU_BOARDREV:
					if (tlen == 2)
						varbuf_append(&b, vstr_boardrev,
							      cis[i + 1]);
					else
						varbuf_append(&b, vstr_boardrev,
							      (cis[i + 2] << 8)
							      + cis[i + 1]);
					break;

				case HNBU_BOARDFLAGS:
					w32 = (cis[i + 2] << 8) + cis[i + 1];
					if (tlen >= 5)
						w32 |=
						    ((cis[i + 4] << 24) +
						     (cis[i + 3] << 16));
					varbuf_append(&b, vstr_boardflags, w32);

					if (tlen >= 7) {
						w32 =
						    (cis[i + 6] << 8) + cis[i +
									    5];
						if (tlen >= 9)
							w32 |=
							    ((cis[i + 8] << 24)
							     +
							     (cis[i + 7] <<
							      16));
						varbuf_append(&b,
							      vstr_boardflags2,
							      w32);
					}
					break;

				case HNBU_USBFS:
					varbuf_append(&b, vstr_usbfs,
						      cis[i + 1]);
					break;

				case HNBU_BOARDTYPE:
					varbuf_append(&b, vstr_boardtype,
						      (cis[i + 2] << 8) +
						      cis[i + 1]);
					break;

				case HNBU_HNBUCIS:
					/*
					 * what follows is a nonstandard HNBU CIS
					 * that lacks CISTPL_BRCM_HNBU tags
					 *
					 * skip 0xff (end of standard CIS)
					 * after this tuple
					 */
					tlen++;
					standard_cis = false;
					break;

				case HNBU_USBEPNUM:
					varbuf_append(&b, vstr_usbepnum,
						      (cis[i + 2] << 8) | cis[i
									      +
									      1]);
					break;

				case HNBU_AA:
					varbuf_append(&b, vstr_aa2g,
						      cis[i + 1]);
					if (tlen >= 3)
						varbuf_append(&b, vstr_aa5g,
							      cis[i + 2]);
					break;

				case HNBU_AG:
					varbuf_append(&b, vstr_ag, 0,
						      cis[i + 1]);
					if (tlen >= 3)
						varbuf_append(&b, vstr_ag, 1,
							      cis[i + 2]);
					if (tlen >= 4)
						varbuf_append(&b, vstr_ag, 2,
							      cis[i + 3]);
					if (tlen >= 5)
						varbuf_append(&b, vstr_ag, 3,
							      cis[i + 4]);
					ag_init = true;
					break;

				case HNBU_ANT5G:
					varbuf_append(&b, vstr_aa5g,
						      cis[i + 1]);
					varbuf_append(&b, vstr_ag, 1,
						      cis[i + 2]);
					break;

				case HNBU_CC:
					ASSERT(sromrev == 1);
					varbuf_append(&b, vstr_cc, cis[i + 1]);
					break;

				case HNBU_PAPARMS:
					switch (tlen) {
					case 2:
						ASSERT(sromrev == 1);
						varbuf_append(&b,
							      vstr_pa0maxpwr,
							      cis[i + 1]);
						break;
					case 10:
						ASSERT(sromrev >= 2);
						varbuf_append(&b, vstr_opo,
							      cis[i + 9]);
						/* FALLTHROUGH */
					case 9:
						varbuf_append(&b,
							      vstr_pa0maxpwr,
							      cis[i + 8]);
						/* FALLTHROUGH */
						BCMDONGLECASE(8)
						    varbuf_append(&b,
								  vstr_pa0itssit,
								  cis[i + 7]);
						/* FALLTHROUGH */
						BCMDONGLECASE(7)
						    for (j = 0; j < 3; j++) {
							varbuf_append(&b,
								      vstr_pa0b
								      [j],
								      (cis
								       [i +
									(j *
									 2) +
									2] << 8)
								      + cis[i +
									    (j *
									     2)
									    +
									    1]);
						}
						break;
					default:
						ASSERT((tlen == 2)
						       || (tlen == 9)
						       || (tlen == 10));
						break;
					}
					break;

				case HNBU_PAPARMS5G:
					ASSERT((sromrev == 2)
					       || (sromrev == 3));
					switch (tlen) {
					case 23:
						varbuf_append(&b,
							      vstr_pa1himaxpwr,
							      cis[i + 22]);
						varbuf_append(&b,
							      vstr_pa1lomaxpwr,
							      cis[i + 21]);
						varbuf_append(&b,
							      vstr_pa1maxpwr,
							      cis[i + 20]);
						/* FALLTHROUGH */
					case 20:
						varbuf_append(&b,
							      vstr_pa1itssit,
							      cis[i + 19]);
						/* FALLTHROUGH */
					case 19:
						for (j = 0; j < 3; j++) {
							varbuf_append(&b,
								      vstr_pa1b
								      [j],
								      (cis
								       [i +
									(j *
									 2) +
									2] << 8)
								      + cis[i +
									    (j *
									     2)
									    +
									    1]);
						}
						for (j = 3; j < 6; j++) {
							varbuf_append(&b,
								      vstr_pa1lob
								      [j - 3],
								      (cis
								       [i +
									(j *
									 2) +
									2] << 8)
								      + cis[i +
									    (j *
									     2)
									    +
									    1]);
						}
						for (j = 6; j < 9; j++) {
							varbuf_append(&b,
								      vstr_pa1hib
								      [j - 6],
								      (cis
								       [i +
									(j *
									 2) +
									2] << 8)
								      + cis[i +
									    (j *
									     2)
									    +
									    1]);
						}
						break;
					default:
						ASSERT((tlen == 19) ||
						       (tlen == 20)
						       || (tlen == 23));
						break;
					}
					break;

				case HNBU_OEM:
					ASSERT(sromrev == 1);
					varbuf_append(&b, vstr_oem,
						      cis[i + 1], cis[i + 2],
						      cis[i + 3], cis[i + 4],
						      cis[i + 5], cis[i + 6],
						      cis[i + 7], cis[i + 8]);
					break;

				case HNBU_LEDS:
					for (j = 1; j <= 4; j++) {
						if (cis[i + j] != 0xff) {
							varbuf_append(&b,
								      vstr_ledbh,
								      j - 1,
								      cis[i +
									  j]);
						}
					}
					break;

				case HNBU_CCODE:
					ASSERT(sromrev > 1);
					if ((cis[i + 1] == 0)
					    || (cis[i + 2] == 0))
						varbuf_append(&b, vstr_noccode);
					else
						varbuf_append(&b, vstr_ccode,
							      cis[i + 1],
							      cis[i + 2]);
					varbuf_append(&b, vstr_cctl,
						      cis[i + 3]);
					break;

				case HNBU_CCKPO:
					ASSERT(sromrev > 2);
					varbuf_append(&b, vstr_cckpo,
						      (cis[i + 2] << 8) | cis[i
									      +
									      1]);
					break;

				case HNBU_OFDMPO:
					ASSERT(sromrev > 2);
					varbuf_append(&b, vstr_ofdmpo,
						      (cis[i + 4] << 24) |
						      (cis[i + 3] << 16) |
						      (cis[i + 2] << 8) |
						      cis[i + 1]);
					break;

				case HNBU_WPS:
					varbuf_append(&b, vstr_wpsgpio,
						      cis[i + 1]);
					if (tlen >= 3)
						varbuf_append(&b, vstr_wpsled,
							      cis[i + 2]);
					break;

				case HNBU_RSSISMBXA2G:
					ASSERT(sromrev == 3);
					varbuf_append(&b, vstr_rssismf2g,
						      cis[i + 1] & 0xf);
					varbuf_append(&b, vstr_rssismc2g,
						      (cis[i + 1] >> 4) & 0xf);
					varbuf_append(&b, vstr_rssisav2g,
						      cis[i + 2] & 0x7);
					varbuf_append(&b, vstr_bxa2g,
						      (cis[i + 2] >> 3) & 0x3);
					break;

				case HNBU_RSSISMBXA5G:
					ASSERT(sromrev == 3);
					varbuf_append(&b, vstr_rssismf5g,
						      cis[i + 1] & 0xf);
					varbuf_append(&b, vstr_rssismc5g,
						      (cis[i + 1] >> 4) & 0xf);
					varbuf_append(&b, vstr_rssisav5g,
						      cis[i + 2] & 0x7);
					varbuf_append(&b, vstr_bxa5g,
						      (cis[i + 2] >> 3) & 0x3);
					break;

				case HNBU_TRI2G:
					ASSERT(sromrev == 3);
					varbuf_append(&b, vstr_tri2g,
						      cis[i + 1]);
					break;

				case HNBU_TRI5G:
					ASSERT(sromrev == 3);
					varbuf_append(&b, vstr_tri5gl,
						      cis[i + 1]);
					varbuf_append(&b, vstr_tri5g,
						      cis[i + 2]);
					varbuf_append(&b, vstr_tri5gh,
						      cis[i + 3]);
					break;

				case HNBU_RXPO2G:
					ASSERT(sromrev == 3);
					varbuf_append(&b, vstr_rxpo2g,
						      cis[i + 1]);
					break;

				case HNBU_RXPO5G:
					ASSERT(sromrev == 3);
					varbuf_append(&b, vstr_rxpo5g,
						      cis[i + 1]);
					break;

				case HNBU_MACADDR:
					if (!is_zero_ether_addr(&cis[i + 1]) &&
					    !is_multicast_ether_addr(&cis[i + 1])) {
						snprintf(eabuf, sizeof(eabuf),
							"%pM", &cis[i + 1]);

						/* set boardnum if HNBU_BOARDNUM not seen yet */
						if (boardnum == -1)
							boardnum =
							    (cis[i + 5] << 8) +
							    cis[i + 6];
					}
					break;

				case HNBU_LEDDC:
					/* CIS leddc only has 16bits, convert it to 32bits */
					w32 = ((cis[i + 2] << 24) |	/* oncount */
					       (cis[i + 1] << 8));	/* offcount */
					varbuf_append(&b, vstr_leddc, w32);
					break;

				case HNBU_CHAINSWITCH:
					varbuf_append(&b, vstr_txchain,
						      cis[i + 1]);
					varbuf_append(&b, vstr_rxchain,
						      cis[i + 2]);
					varbuf_append(&b, vstr_antswitch,
						      (cis[i + 4] << 8) +
						      cis[i + 3]);
					break;

				case HNBU_REGREV:
					varbuf_append(&b, vstr_regrev,
						      cis[i + 1]);
					break;

				case HNBU_FEM:{
						u16 fem =
						    (cis[i + 2] << 8) + cis[i +
									    1];
						varbuf_append(&b,
							      vstr_antswctl2g,
							      (fem &
							       SROM8_FEM_ANTSWLUT_MASK)
							      >>
							      SROM8_FEM_ANTSWLUT_SHIFT);
						varbuf_append(&b, vstr_triso2g,
							      (fem &
							       SROM8_FEM_TR_ISO_MASK)
							      >>
							      SROM8_FEM_TR_ISO_SHIFT);
						varbuf_append(&b,
							      vstr_pdetrange2g,
							      (fem &
							       SROM8_FEM_PDET_RANGE_MASK)
							      >>
							      SROM8_FEM_PDET_RANGE_SHIFT);
						varbuf_append(&b,
							      vstr_extpagain2g,
							      (fem &
							       SROM8_FEM_EXTPA_GAIN_MASK)
							      >>
							      SROM8_FEM_EXTPA_GAIN_SHIFT);
						varbuf_append(&b,
							      vstr_tssipos2g,
							      (fem &
							       SROM8_FEM_TSSIPOS_MASK)
							      >>
							      SROM8_FEM_TSSIPOS_SHIFT);
						if (tlen < 5)
							break;

						fem =
						    (cis[i + 4] << 8) + cis[i +
									    3];
						varbuf_append(&b,
							      vstr_antswctl5g,
							      (fem &
							       SROM8_FEM_ANTSWLUT_MASK)
							      >>
							      SROM8_FEM_ANTSWLUT_SHIFT);
						varbuf_append(&b, vstr_triso5g,
							      (fem &
							       SROM8_FEM_TR_ISO_MASK)
							      >>
							      SROM8_FEM_TR_ISO_SHIFT);
						varbuf_append(&b,
							      vstr_pdetrange5g,
							      (fem &
							       SROM8_FEM_PDET_RANGE_MASK)
							      >>
							      SROM8_FEM_PDET_RANGE_SHIFT);
						varbuf_append(&b,
							      vstr_extpagain5g,
							      (fem &
							       SROM8_FEM_EXTPA_GAIN_MASK)
							      >>
							      SROM8_FEM_EXTPA_GAIN_SHIFT);
						varbuf_append(&b,
							      vstr_tssipos5g,
							      (fem &
							       SROM8_FEM_TSSIPOS_MASK)
							      >>
							      SROM8_FEM_TSSIPOS_SHIFT);
						break;
					}

				case HNBU_PAPARMS_C0:
					varbuf_append(&b, vstr_maxp2ga0,
						      cis[i + 1]);
					varbuf_append(&b, vstr_itt2ga0,
						      cis[i + 2]);
					varbuf_append(&b, vstr_pa, 2, 0, 0,
						      (cis[i + 4] << 8) +
						      cis[i + 3]);
					varbuf_append(&b, vstr_pa, 2, 1, 0,
						      (cis[i + 6] << 8) +
						      cis[i + 5]);
					varbuf_append(&b, vstr_pa, 2, 2, 0,
						      (cis[i + 8] << 8) +
						      cis[i + 7]);
					if (tlen < 31)
						break;

					varbuf_append(&b, vstr_maxp5ga0,
						      cis[i + 9]);
					varbuf_append(&b, vstr_itt5ga0,
						      cis[i + 10]);
					varbuf_append(&b, vstr_maxp5gha0,
						      cis[i + 11]);
					varbuf_append(&b, vstr_maxp5gla0,
						      cis[i + 12]);
					varbuf_append(&b, vstr_pa, 5, 0, 0,
						      (cis[i + 14] << 8) +
						      cis[i + 13]);
					varbuf_append(&b, vstr_pa, 5, 1, 0,
						      (cis[i + 16] << 8) +
						      cis[i + 15]);
					varbuf_append(&b, vstr_pa, 5, 2, 0,
						      (cis[i + 18] << 8) +
						      cis[i + 17]);
					varbuf_append(&b, vstr_pahl, 5, 'l', 0,
						      0,
						      (cis[i + 20] << 8) +
						      cis[i + 19]);
					varbuf_append(&b, vstr_pahl, 5, 'l', 1,
						      0,
						      (cis[i + 22] << 8) +
						      cis[i + 21]);
					varbuf_append(&b, vstr_pahl, 5, 'l', 2,
						      0,
						      (cis[i + 24] << 8) +
						      cis[i + 23]);
					varbuf_append(&b, vstr_pahl, 5, 'h', 0,
						      0,
						      (cis[i + 26] << 8) +
						      cis[i + 25]);
					varbuf_append(&b, vstr_pahl, 5, 'h', 1,
						      0,
						      (cis[i + 28] << 8) +
						      cis[i + 27]);
					varbuf_append(&b, vstr_pahl, 5, 'h', 2,
						      0,
						      (cis[i + 30] << 8) +
						      cis[i + 29]);
					break;

				case HNBU_PAPARMS_C1:
					varbuf_append(&b, vstr_maxp2ga1,
						      cis[i + 1]);
					varbuf_append(&b, vstr_itt2ga1,
						      cis[i + 2]);
					varbuf_append(&b, vstr_pa, 2, 0, 1,
						      (cis[i + 4] << 8) +
						      cis[i + 3]);
					varbuf_append(&b, vstr_pa, 2, 1, 1,
						      (cis[i + 6] << 8) +
						      cis[i + 5]);
					varbuf_append(&b, vstr_pa, 2, 2, 1,
						      (cis[i + 8] << 8) +
						      cis[i + 7]);
					if (tlen < 31)
						break;

					varbuf_append(&b, vstr_maxp5ga1,
						      cis[i + 9]);
					varbuf_append(&b, vstr_itt5ga1,
						      cis[i + 10]);
					varbuf_append(&b, vstr_maxp5gha1,
						      cis[i + 11]);
					varbuf_append(&b, vstr_maxp5gla1,
						      cis[i + 12]);
					varbuf_append(&b, vstr_pa, 5, 0, 1,
						      (cis[i + 14] << 8) +
						      cis[i + 13]);
					varbuf_append(&b, vstr_pa, 5, 1, 1,
						      (cis[i + 16] << 8) +
						      cis[i + 15]);
					varbuf_append(&b, vstr_pa, 5, 2, 1,
						      (cis[i + 18] << 8) +
						      cis[i + 17]);
					varbuf_append(&b, vstr_pahl, 5, 'l', 0,
						      1,
						      (cis[i + 20] << 8) +
						      cis[i + 19]);
					varbuf_append(&b, vstr_pahl, 5, 'l', 1,
						      1,
						      (cis[i + 22] << 8) +
						      cis[i + 21]);
					varbuf_append(&b, vstr_pahl, 5, 'l', 2,
						      1,
						      (cis[i + 24] << 8) +
						      cis[i + 23]);
					varbuf_append(&b, vstr_pahl, 5, 'h', 0,
						      1,
						      (cis[i + 26] << 8) +
						      cis[i + 25]);
					varbuf_append(&b, vstr_pahl, 5, 'h', 1,
						      1,
						      (cis[i + 28] << 8) +
						      cis[i + 27]);
					varbuf_append(&b, vstr_pahl, 5, 'h', 2,
						      1,
						      (cis[i + 30] << 8) +
						      cis[i + 29]);
					break;

				case HNBU_PO_CCKOFDM:
					varbuf_append(&b, vstr_cck2gpo,
						      (cis[i + 2] << 8) +
						      cis[i + 1]);
					varbuf_append(&b, vstr_ofdm2gpo,
						      (cis[i + 6] << 24) +
						      (cis[i + 5] << 16) +
						      (cis[i + 4] << 8) +
						      cis[i + 3]);
					if (tlen < 19)
						break;

					varbuf_append(&b, vstr_ofdm5gpo,
						      (cis[i + 10] << 24) +
						      (cis[i + 9] << 16) +
						      (cis[i + 8] << 8) +
						      cis[i + 7]);
					varbuf_append(&b, vstr_ofdm5glpo,
						      (cis[i + 14] << 24) +
						      (cis[i + 13] << 16) +
						      (cis[i + 12] << 8) +
						      cis[i + 11]);
					varbuf_append(&b, vstr_ofdm5ghpo,
						      (cis[i + 18] << 24) +
						      (cis[i + 17] << 16) +
						      (cis[i + 16] << 8) +
						      cis[i + 15]);
					break;

				case HNBU_PO_MCS2G:
					for (j = 0; j <= (tlen / 2); j++) {
						varbuf_append(&b, vstr_mcspo, 2,
							      j,
							      (cis
							       [i + 2 +
								2 * j] << 8) +
							      cis[i + 1 +
								  2 * j]);
					}
					break;

				case HNBU_PO_MCS5GM:
					for (j = 0; j <= (tlen / 2); j++) {
						varbuf_append(&b, vstr_mcspo, 5,
							      j,
							      (cis
							       [i + 2 +
								2 * j] << 8) +
							      cis[i + 1 +
								  2 * j]);
					}
					break;

				case HNBU_PO_MCS5GLH:
					for (j = 0; j <= (tlen / 4); j++) {
						varbuf_append(&b, vstr_mcspohl,
							      5, 'l', j,
							      (cis
							       [i + 2 +
								2 * j] << 8) +
							      cis[i + 1 +
								  2 * j]);
					}

					for (j = 0; j <= (tlen / 4); j++) {
						varbuf_append(&b, vstr_mcspohl,
							      5, 'h', j,
							      (cis
							       [i +
								((tlen / 2) +
								 2) +
								2 * j] << 8) +
							      cis[i +
								  ((tlen / 2) +
								   1) + 2 * j]);
					}

					break;

				case HNBU_PO_CDD:
					varbuf_append(&b, vstr_cddpo,
						      (cis[i + 2] << 8) +
						      cis[i + 1]);
					break;

				case HNBU_PO_STBC:
					varbuf_append(&b, vstr_stbcpo,
						      (cis[i + 2] << 8) +
						      cis[i + 1]);
					break;

				case HNBU_PO_40M:
					varbuf_append(&b, vstr_bw40po,
						      (cis[i + 2] << 8) +
						      cis[i + 1]);
					break;

				case HNBU_PO_40MDUP:
					varbuf_append(&b, vstr_bwduppo,
						      (cis[i + 2] << 8) +
						      cis[i + 1]);
					break;

				case HNBU_OFDMPO5G:
					varbuf_append(&b, vstr_ofdm5gpo,
						      (cis[i + 4] << 24) +
						      (cis[i + 3] << 16) +
						      (cis[i + 2] << 8) +
						      cis[i + 1]);
					varbuf_append(&b, vstr_ofdm5glpo,
						      (cis[i + 8] << 24) +
						      (cis[i + 7] << 16) +
						      (cis[i + 6] << 8) +
						      cis[i + 5]);
					varbuf_append(&b, vstr_ofdm5ghpo,
						      (cis[i + 12] << 24) +
						      (cis[i + 11] << 16) +
						      (cis[i + 10] << 8) +
						      cis[i + 9]);
					break;

				case HNBU_CUSTOM1:
					varbuf_append(&b, vstr_custom, 1,
						      ((cis[i + 4] << 24) +
						       (cis[i + 3] << 16) +
						       (cis[i + 2] << 8) +
						       cis[i + 1]));
					break;

#if defined(BCMSDIO)
				case HNBU_SROM3SWRGN:
					if (tlen >= 73) {
						u16 srom[35];
						u8 srev = cis[i + 1 + 70];
						ASSERT(srev == 3);
						/* make tuple value 16-bit aligned and parse it */
						memcpy(srom, &cis[i + 1],
						       sizeof(srom));
						_initvars_srom_pci(srev, srom,
								   SROM3_SWRGN_OFF,
								   &b);
						/* 2.4G antenna gain is included in SROM */
						ag_init = true;
						/* Ethernet MAC address is included in SROM */
						eabuf[0] = 0;
						boardnum = -1;
					}
					/* create extra variables */
					if (tlen >= 75)
						varbuf_append(&b, vstr_vendid,
							      (cis[i + 1 + 73]
							       << 8) + cis[i +
									   1 +
									   72]);
					if (tlen >= 77)
						varbuf_append(&b, vstr_devid,
							      (cis[i + 1 + 75]
							       << 8) + cis[i +
									   1 +
									   74]);
					if (tlen >= 79)
						varbuf_append(&b, vstr_xtalfreq,
							      (cis[i + 1 + 77]
							       << 8) + cis[i +
									   1 +
									   76]);
					break;
#endif				/* defined(BCMSDIO) */

				case HNBU_CCKFILTTYPE:
					varbuf_append(&b, vstr_cckdigfilttype,
						      (cis[i + 1]));
					break;
				}

				break;
			}
			i += tlen;
		} while (tup != CISTPL_END);