int dcb_outp_foreach(struct nouveau_bios *bios, void *data, int (*exec)(struct nouveau_bios *, void *, int, u16)) { int ret, idx = -1; u8 ver, len; u16 outp; while ((outp = dcb_outp(bios, ++idx, &ver, &len))) { if (nv_ro32(bios, outp) == 0x00000000) break; /* seen on an NV11 with DCB v1.5 */ if (nv_ro32(bios, outp) == 0xffffffff) break; /* seen on an NV17 with DCB v2.0 */ if (nv_ro08(bios, outp) == DCB_OUTPUT_UNUSED) continue; if (nv_ro08(bios, outp) == DCB_OUTPUT_EOL) break; ret = exec(bios, data, idx, outp); if (ret) return ret; } return 0; }
u16 dcb_outp_parse(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len, struct dcb_output *outp) { u16 dcb = dcb_outp(bios, idx, ver, len); if (dcb) { if (*ver >= 0x20) { u32 conn = nv_ro32(bios, dcb + 0x00); outp->or = (conn & 0x0f000000) >> 24; outp->location = (conn & 0x00300000) >> 20; outp->bus = (conn & 0x000f0000) >> 16; outp->connector = (conn & 0x0000f000) >> 12; outp->heads = (conn & 0x00000f00) >> 8; outp->i2c_index = (conn & 0x000000f0) >> 4; outp->type = (conn & 0x0000000f); outp->link = 0; } else {