//int create_res_hndl_afu_reset(char *dev, dev64_t devno, __u64 chunk)
int create_res_hndl_afu_reset(bool do_recover, bool last)
{
    int rc;
    struct ctx my_ctx;
    struct ctx *p_ctx = &my_ctx;
    //int i;
    pthread_t thread;
    __u64 chunk = 0x1;
    __u64 stride= 0x1;
    int msgid;
    struct mymsgbuf msg_buf;
    pthread_t ioThreadId;
    do_io_thread_arg_t ioThreadData;
    do_io_thread_arg_t * p_ioThreadData=&ioThreadData;
    // we have to export "NO_IO; if we want to avoid IO
    char * noIOP   = getenv("NO_IO");

    pid = getpid();
#ifdef _AIX
    memset(p_ctx,0,sizeof(my_ctx));
    strcpy(p_ctx->dev,cflash_path);
    if ((p_ctx->fd = open_dev(p_ctx->dev, O_RDWR)) < 0)
    {
        fprintf(stderr,"open failed %s, errno %d\n",p_ctx->dev, errno);
        return -1;
    }
    rc = ioctl_dk_capi_query_path(p_ctx);
    CHECK_RC(rc, "ioctl_dk_capi_query_path failed...\n");
    rc = ctx_init_internal(p_ctx, 0, p_ctx->devno);
#else
    rc = ctx_init(p_ctx);
#endif
    CHECK_RC(rc, "Context init failed");

    //thread to handle AFU interrupt & events
    if ( noIOP == NULL )
        pthread_create(&thread, NULL, ctx_rrq_rx, p_ctx);

    //create 0 vlun size & later call resize ioctl
    rc = create_resource(p_ctx, chunk * (p_ctx->chunk_size),
                         0, LUN_VIRTUAL);
    CHECK_RC(rc, "create LUN_VIRTUAL failed");

    //last new process send message to waiting process
    //that new ctx created now you can try to reattach
    msgid = msgget(key, IPC_CREAT | 0666);
    if (msgid < 0 )
    {
        fprintf(stderr, "%d: msgget() failed before msgsnd()\n", pid);
        return -1;
    }
    memset(&msg_buf, 0, sizeof(struct mymsgbuf));
    if (last)
    {
        goto end;
    }
    if ( noIOP == NULL )
    {
        p_ioThreadData->p_ctx=p_ctx;
        p_ioThreadData->stride=stride;
        p_ioThreadData->loopCount=0x100000; // Need this to go on 10 secs
        debug("%d: things look good, doing IO...\n",pid);
        rc =pthread_create(&ioThreadId,NULL, do_io_thread, (void *)p_ioThreadData);
        CHECK_RC(rc, "do_io_thread() pthread_create failed");
    }
#ifdef _AIX
    rc = do_eeh(p_ctx);
#else
    rc = do_poll_eeh(p_ctx);
#endif
    g_error=0; //reset any prev error might caught while EEH
    if ( noIOP == NULL )
    {
        pthread_join(ioThreadId, NULL);
    }
#ifndef _AIX //for linux
    if ( noIOP == NULL )
        pthread_cancel(thread);
#endif

    //We here after EEH done
    if (do_recover)
    {
        //do if recover true
        debug("%d: woow EEH is done recovering...\n",pid);
        rc = ioctl_dk_capi_recover_ctx(p_ctx);
        CHECK_RC(rc, "ctx reattached failed");
        msg_buf.mtype =2;
        strcpy(msg_buf.mtext, "K");
        if (msgsnd(msgid, &msg_buf, 2, IPC_NOWAIT) < 0)
        {
            fprintf(stderr, "%d: msgsnd failed\n", pid);
            return -1;
        }
#ifdef _AIX
        if (p_ctx->return_flags != DK_RF_REATTACHED)
            CHECK_RC(1, "recover ctx, expected DK_RF_REATTACHED");
        p_ctx->flags = DK_VF_HC_TUR;
        p_ctx->hint = DK_HINT_SENSE;
#endif
        fflush(stdout);
        ctx_reinit(p_ctx);
#ifdef _AIX
        p_ctx->hint=DK_HINT_SENSE;
#else
        p_ctx->hint=DK_CXLFLASH_VERIFY_HINT_SENSE;
        // if dummy_sense_flag is set;
        // a dummy sense data will be copied into ioctl input
        p_ctx->dummy_sense_flag=1; // if dummy_sense_flag is set;
#endif
        rc = ioctl_dk_capi_verify(p_ctx);
        CHECK_RC(rc, "ioctl_dk_capi_verify failed");
#ifndef _AIX //for linux
        pthread_create(&thread, NULL, ctx_rrq_rx, p_ctx);
#endif
    }
    else
    {
        //last one is
        /*msgid = msgget(key, IPC_CREAT | 0666);
           if(msgid < 0 ){
                   fprintf(stderr, "%d: msgget() failed before msgrcv()\n", pid);
                   return -1;
           }
           debug("%d: Going to wait at msgrcv()..\n", pid);
           fflush(stdout);
           if(msgrcv(msgid, &msg_buf, 2, 1, 0) < 0) {
                   fprintf(stderr, "%d: msgrcv failed with errno %d\n", pid, errno);
                   return -1;
           }

           debug("%d: Got out of msgrcv()..EEH is done, Try to recover....\n",pid);
         */
        //as per today(9/28/2015) discussion with Sanket that
        //new attach will fail until holding context not exited
        //hope same apply for Linux as well
        return 100;
        /*rc = ioctl_dk_capi_recover_ctx(p_ctx);
           if(rc) return 100; //this to make sure recover failed
           else {
                   fprintf(stderr,"%d:com'on recover should fail here...\n",pid);
                   return 1; // we don't want to try IO anyway
           }*/
    }

end:
    if ( noIOP == NULL )
    {
        stride=0x1;
        rc = do_io(p_ctx, stride);
        CHECK_RC(rc, "IO failed after EEH/recover");
    }
    if ( noIOP == NULL )
        pthread_cancel(thread);
    sleep(1);
    fflush(stdout);
    sleep(5); // additional time to be safe !
    rc=close_res(p_ctx);

    sleep(5); // Don't let child exit to keep max ctx alive
    rc |= ctx_close(p_ctx);
    CHECK_RC(rc,"ctx close or close_res failed\n");
    return rc;
}
// 7.1.185 : EEH while super-pipe IO(VIRTUAL)(root user)
int test_vSpio_eehRecovery(int cmd)
{
    int rc;
    struct ctx myctx;
    struct ctx *p_ctx = &myctx;
    pthread_t threadId, ioThreadId, thread2;
    do_io_thread_arg_t ioThreadData;
    do_io_thread_arg_t * p_ioThreadData=&ioThreadData;
    __u64 chunk;
    __u64 nlba;
    __u64 stride= 0x1000;
    __u64 last_lba;

    // pid used to create unique data patterns & logging from util !
    pid = getpid();

    //ctx_init with default flash disk & devno
    rc = ctx_init(p_ctx);
    CHECK_RC(rc, "Context init failed");

    //thread to handle AFU interrupt & events
    rc = pthread_create(&threadId, NULL, ctx_rrq_rx, p_ctx);
    CHECK_RC(rc, "pthread_create failed");

    chunk = (p_ctx->last_phys_lba+1)/p_ctx->chunk_size;
    nlba = chunk * p_ctx->chunk_size;
    //create vlun
    rc = create_resource(p_ctx, nlba, DK_UVF_ALL_PATHS, LUN_VIRTUAL);
    CHECK_RC(rc, "create LUN_VIRTUAL failed");

    // We wish to do IO in a different thread... Setting up for that !
    p_ioThreadData->p_ctx=p_ctx;
    p_ioThreadData->stride=stride;
    p_ioThreadData->loopCount=1000;
    rc = pthread_create(&ioThreadId,NULL, do_io_thread, (void *)p_ioThreadData);
    CHECK_RC(rc, "do_io_thread() pthread_create failed");

    //Trigger EEH
    rc = do_eeh(p_ctx);
    CHECK_RC(rc, "do_eeh() failed");

    // Wait for IO thread to complete
    pthread_join(ioThreadId, NULL);
#ifndef _AIX
    pthread_cancel(threadId);
#endif

    // Heading for context recovery using ioctl !
    //p_ctx->flags = DK_CAPI_REATTACHED;
    rc = ioctl_dk_capi_recover_ctx(p_ctx);
    CHECK_RC(rc, "ioctl_dk_capi_recover_ctx failed");

#ifdef _AIX
    if ( DK_RF_REATTACHED != p_ctx->return_flags )
#else
    if ( DK_CXLFLASH_RECOVER_AFU_CONTEXT_RESET != p_ctx->return_flags )
#endif
        CHECK_RC(1, "ioctl_dk_capi_recover_ctx flag verification failed");

    rc = ctx_reinit(p_ctx);
    CHECK_RC(rc, "ctx_reinit() failed");
#ifndef _AIX
    pthread_create(&thread2, NULL, ctx_rrq_rx, p_ctx);
#endif

    rc = do_io(p_ctx, stride);
    if ( rc == 2) rc=0;
    else CHECK_RC(rc, "1st IO attempt didn't fail");

#ifdef _AIX
    last_lba = p_ctx->last_phys_lba;
#else
    last_lba = p_ctx->last_lba;
#endif

#ifdef _AIX
    p_ctx->flags = DK_VF_HC_TUR;
    p_ctx->hint = DK_HINT_SENSE;
#else
    p_ctx->hint = DK_CXLFLASH_VERIFY_HINT_SENSE;
#endif

    rc = ioctl_dk_capi_verify(p_ctx);
    CHECK_RC(rc, "ioctl_dk_capi_verify failed\n");

#ifdef _AIX
    if ( 0 != p_ctx->return_flags )
        CHECK_RC(1, "ioctl_dk_capi_verify flag verification failed");
#endif
    if ( p_ctx->verify_last_lba != last_lba )
        CHECK_RC(1, "ioctl_dk_capi_verify last_lba verification failed");


    // After adapter reset,
    //  AFU interrupt monitoring thread need to be restarted.
    //rc = pthread_create(&threadId, NULL, ctx_rrq_rx, p_ctx);
    //CHECK_RC(rc, "pthread_create failed");

    // Re-start the io using new context
    if (2 == cmd)
    {
        //its for long run
#ifndef _AIX
        pthread_cancel(thread2);
#endif
        rc = keep_doing_eeh_test(p_ctx);
    }
    else
    {
        //its for one attempt, sanity check of eeh
        debug("%d:Try once more IO & expecting to pass this time..\n",pid);
        rc = do_io(p_ctx, stride);
        CHECK_RC(rc, "do_io() failed");
    }

#ifndef _AIX
    pthread_cancel(thread2);
#endif

    cleanup(p_ctx, threadId);

    return rc;
}