// File: KinderRiven[P]rdma_demo/client.cc
// Function: open_device(rdma_context_t*)
static void open_device(rdma_context_t* context)
{
    printf("|open_device.\n");
    int _res;
    int _num_dev = 0;
    struct ibv_device* _dev = NULL;
    struct ibv_device** _dev_list = NULL;

    // 获得RDMA列表
    _dev_list = ibv_get_device_list(&_num_dev);
    if (_num_dev == 0) {
        printf("|--ibv_get_device_list failed.\n");
        exit(1);
    }
    printf("|--ibv_get_device_list ok.[%d]\n", _num_dev);

    _dev = _dev_list[0]; // used first
    // 打开RDMA设备
    context->ctx = ibv_open_device(_dev);
    if (context->ctx == NULL) {
        printf("|--ibv_open_device failed.\n");
        exit(1);
    }
    printf("|--ibv_open_device ok [%s].\n", ibv_get_device_name(_dev));

    _res = ibv_query_port(context->ctx, 1, &context->port_attr);
    if (_res) {
        printf("|--ibv_query_port failed.\n");
        exit(1);
    }
    printf("|--ibv_query_port ok.\n");
    printf("|----[lid:%d]\n", context->port_attr.lid);

    _res = ibv_query_gid(context->ctx, 1, 2, &context->gid);
    if (_res) {
        printf("|--ibv_query_gid failed.\n");
        exit(1);
    }
    for (int i = 0; i < 16; i++) {
        printf("%02x", context->gid.raw[i]);
        if (i & 1) {
            printf(":");
        }
    }
    printf("\n");

    _res = ibv_query_device(context->ctx, &context->dev_attr);
    if (_res) {
        printf("|--ibv_query_device failed.\n");
        exit(1);
    }
    printf("|--ibv_query_device ok.\n");
    printf("|----[VERSION:%d]\n", context->dev_attr.hw_ver);
    printf("|----[MAX_NUM_CQ:%d][MAX_CQE:%d]\n", context->dev_attr.max_cq, context->dev_attr.max_cqe);
    printf("|----[MAX_QP_WR:%d]\n", context->dev_attr.max_qp_wr);
    printf("|----[MAX_NUM_MR:%dMB][MR_SIZE:%lluGB]\n", context->dev_attr.max_mr / (1024 * 1024), context->dev_attr.max_mr_size / (1024UL * 1024 * 1024));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
leaq 0x1502(%rip), %rdi      # 0x3055
movb $0x0, %al
callq 0x1050
movl $0x0, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
leaq -0x10(%rbp), %rdi
callq 0x1170
movq %rax, -0x20(%rbp)
cmpl $0x0, -0x10(%rbp)
jne 0x1b9c
leaq 0x14d9(%rip), %rdi      # 0x3064
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1120
movl -0x10(%rbp), %esi
leaq 0x14de(%rip), %rdi      # 0x3084
movb $0x0, %al
callq 0x1050
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0x1100
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x1bef
leaq 0x14c6(%rip), %rdi      # 0x30a4
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1120
movq -0x18(%rbp), %rdi
callq 0x10c0
movq %rax, %rsi
leaq 0x14be(%rip), %rdi      # 0x30c0
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x8(%rbp), %rdx
addq $0x430, %rdx            # imm = 0x430
movl $0x1, %esi
callq 0x2150
movl %eax, -0xc(%rbp)
cmpl $0x0, -0xc(%rbp)
je 0x1c47
leaq 0x14a7(%rip), %rdi      # 0x30dd
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1120
leaq 0x14aa(%rip), %rdi      # 0x30f8
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movzwl 0x452(%rax), %esi
leaq 0x14a8(%rip), %rdi      # 0x310f
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x8(%rbp), %rcx
addq $0x550, %rcx            # imm = 0x550
movl $0x1, %esi
movl $0x2, %edx
callq 0x1110
movl %eax, -0xc(%rbp)
cmpl $0x0, -0xc(%rbp)
je 0x1cb1
leaq 0x147e(%rip), %rdi      # 0x311e
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1120
movl $0x0, -0x24(%rbp)
cmpl $0x10, -0x24(%rbp)
jge 0x1d02
movq -0x8(%rbp), %rax
movslq -0x24(%rbp), %rcx
movzbl 0x550(%rax,%rcx), %esi
leaq 0x1463(%rip), %rdi      # 0x3138
movb $0x0, %al
callq 0x1050
movl -0x24(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x1cf5
leaq 0x16e0(%rip), %rdi      # 0x33ce
movb $0x0, %al
callq 0x1050
jmp 0x1cf7
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x1cb8
leaq 0x15d6(%rip), %rdi      # 0x32df
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x8(%rbp), %rsi
addq $0x468, %rsi            # imm = 0x468
callq 0x1190
movl %eax, -0xc(%rbp)
cmpl $0x0, -0xc(%rbp)
je 0x1d49
leaq 0x1405(%rip), %rdi      # 0x313d
movb $0x0, %al
callq 0x1050
movl $0x1, %edi
callq 0x1120
leaq 0x140a(%rip), %rdi      # 0x315a
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movl 0x4d0(%rax), %esi
leaq 0x140b(%rip), %rdi      # 0x3173
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movl 0x4e8(%rax), %esi
movq -0x8(%rbp), %rax
movl 0x4ec(%rax), %edx
leaq 0x13fc(%rip), %rdi      # 0x3186
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movl 0x4d8(%rax), %esi
leaq 0x1406(%rip), %rdi      # 0x31a8
movb $0x0, %al
callq 0x1050
movq -0x8(%rbp), %rax
movl 0x4f0(%rax), %eax
movl $0x100000, %ecx         # imm = 0x100000
cltd
idivl %ecx
movl %eax, %esi
movq -0x8(%rbp), %rax
movq 0x4b8(%rax), %rdx
shrq $0x1e, %rdx
leaq 0x13ea(%rip), %rdi      # 0x31bd
movb $0x0, %al
callq 0x1050
addq $0x30, %rsp
popq %rbp
retq