Exemple #1
0
/*
 * pm_pc6_exit:
 *
 * Execute pc6 exit for a node.
 * mic_ctx: The driver context of the node.
 */
int pm_pc6_exit(mic_ctx_t *mic_ctx)
{

	int err = 0;

	sbox_host_pm_state_t hpmstate_regval;
	sbox_pcu_ctrl_t ctrl_regval;
	uint8_t tdp_vid = 0;
	uint8_t is_pll_locked;
	uint32_t wait_cnt;
	int i;


	if (!check_host_state(mic_ctx, PM_IDLE_STATE_PC6)) {
		PM_DEBUG("Wrong Host PM state. State = %d\n",
				 get_host_state(mic_ctx));
		err = -EINVAL;
		goto restore_registers;
	}

	hpmstate_regval.value = pm_reg_read(mic_ctx, SBOX_HOST_PMSTATE);
	tdp_vid = hpmstate_regval.bits.tdp_vid;
	PM_DEBUG("TDP_VID value obtained from Host PM Register = %d",tdp_vid);

	PM_DEBUG("Setting voltage to %dV using SVID Control\n",tdp_vid);
	err = set_vid_knc(mic_ctx, tdp_vid);
	if (err != 0) {
		printk(KERN_ERR "%s Failed PC6 entry...error in setting VID\n", 
				__func__);
		goto restore_registers;
	}

	ctrl_regval.value = pm_reg_read(mic_ctx, SBOX_PCU_CONTROL);

	program_mclk_shutdown(mic_ctx, false);
	program_prevent_C3Exit(mic_ctx, false);

	for(wait_cnt = 0; wait_cnt < 200; wait_cnt++) {
		ctrl_regval.value = pm_reg_read(mic_ctx,SBOX_PCU_CONTROL);
		is_pll_locked = ctrl_regval.bits.mclk_pll_lock;
		if(likely(is_pll_locked))
				break;
		msleep(10);
	}

	if(wait_cnt >= 200) {
		PM_DEBUG("mclk_pll_locked bit is not set.\n");
		err = -EAGAIN;
		goto restore_registers;
	}

	ctrl_regval.bits.grpB_pwrgood_mask = 0;
	pm_reg_write(ctrl_regval.value, mic_ctx, SBOX_PCU_CONTROL);

	if (!hw_active(mic_ctx)) {
		PM_DEBUG("Timing out waiting for hw to become active");
		goto restore_registers;
	}

	for(wait_cnt = 0; wait_cnt < 200; wait_cnt++) {
		if ((get_card_state(mic_ctx)) == PM_IDLE_STATE_PC0)
			break;
		msleep(10);
	}

	if(wait_cnt >= 200) {
		PM_DEBUG("PC6 Exit not complete.\n");
		err = -EFAULT;
		goto restore_registers;
	}

	mic_ctx->micpm_ctx.idle_state = PM_IDLE_STATE_PC0;

	for (i = 0; i <= mic_data.dd_numdevs; i++) {
		if (micscif_get_nodedep(mic_get_scifnode_id(mic_ctx), i) ==
				DEP_STATE_DISCONNECTED) {
			micscif_set_nodedep(mic_get_scifnode_id(mic_ctx), i,
					DEP_STATE_DEPENDENT);
		}
	}

	PM_PRINT("Node %d exited PC6\n",
			mic_get_scifnode_id(mic_ctx));
	goto exit;

restore_registers:
	restore_pc6_registers(mic_ctx, false);
exit:
	atomic_set(&mic_ctx->gate_interrupt, 0);
	tasklet_schedule(&mic_ctx->bi_dpc);
	return err;
}
Exemple #2
0
int check_card_state(mic_ctx_t *mic_ctx, PM_IDLE_STATE state) {
	PM_IDLE_STATE card_state = get_card_state(mic_ctx);
	return (state == card_state) ? 1 : 0;
}
Exemple #3
0
int pm_pc3_to_pc6_entry(mic_ctx_t *mic_ctx)
{
	int err;
	sbox_pcu_ctrl_t ctrl_regval;
	gbox_pm_control pmctrl_reg;
	sbox_core_freq_t core_freq_reg;

	if ((get_card_state(mic_ctx)) != PM_IDLE_STATE_PC3) {
		PM_DEBUG("Card not ready to go to PC6. \n");
		err = -EAGAIN;
		goto exit;
	}

	if (atomic_cmpxchg(&mic_ctx->gate_interrupt, 0, 1) == 1) {
		PM_DEBUG("Cannot gate interrupt handler while it is in use\n");
		err = -EFAULT;
		goto exit;
	}

	program_prevent_C3Exit(mic_ctx, true);
	program_mclk_shutdown(mic_ctx, true);

	/* Wait for uos to become idle. */
	if (!hw_idle(mic_ctx)) {
		program_mclk_shutdown(mic_ctx, false);
		if (!hw_idle(mic_ctx)) {
			program_prevent_C3Exit(mic_ctx, false);
			PM_DEBUG("Card not ready to go to PC6. \n");
			err = -EAGAIN;
			goto intr_ungate;
		} else {
			program_mclk_shutdown(mic_ctx, true);
		}
	}

	pmctrl_reg.value = pm_reg_read(mic_ctx, GBOX_PM_CTRL);
	pmctrl_reg.bits.in_pckgc6 = 1;
	pm_reg_write(pmctrl_reg.value, mic_ctx, GBOX_PM_CTRL);

	core_freq_reg.value = pm_reg_read(mic_ctx, SBOX_COREFREQ);
	core_freq_reg.bits.booted = 0;
	pm_reg_write(core_freq_reg.value, mic_ctx, SBOX_COREFREQ);

	udelay(500);

	ctrl_regval.value = pm_reg_read(mic_ctx, SBOX_PCU_CONTROL);
	ctrl_regval.bits.grpB_pwrgood_mask = 1;
	pm_reg_write(ctrl_regval.value, mic_ctx, SBOX_PCU_CONTROL);

	err = set_vid_knc(mic_ctx, 0);
	if (err != 0) {
		PM_DEBUG("Aborting PC6 entry...Failed to set VID\n");
		restore_pc6_registers(mic_ctx, true);
		goto intr_ungate;
	}

	mic_ctx->micpm_ctx.idle_state = PM_IDLE_STATE_PC6;
	set_host_state(mic_ctx, PM_IDLE_STATE_PC6);

	dma_prep_suspend(mic_ctx->dma_handle);

	PM_PRINT("Node %d entered PC6\n",
		mic_get_scifnode_id(mic_ctx));

	return err;

intr_ungate:
	atomic_set(&mic_ctx->gate_interrupt, 0);
	tasklet_schedule(&mic_ctx->bi_dpc);
exit:
	return err;
}
Exemple #4
0
int
sctest(void) {
    SCARDCONTEXT ctx;
    SCARDHANDLE card;
    int rc;
    char *readers = NULL;
    char *reader_dev_name = NULL;
    struct card_state card_state;
    enum conventions {
        DIRECT,
        INVERSE
    } convention = DIRECT;
    struct c_apdu c_apdu;
    struct r_apdu r_apdu;

    printf("creating context... ");
    
    if (SCardEstablishContext(opts.scope, NULL, NULL, &ctx) != SCARD_S_SUCCESS)
        return fail(1, "failed\n");
    else
        printf("ok\n");
    
    if ((rc = get_card_readers(ctx, &readers)) != SCARD_S_SUCCESS) {
        if (rc == SCARD_E_NO_READERS_AVAILABLE)
            return fail(-1, "no card readers present in the system\n");
        else
            return fail(-1, "SCardListReaders error %d", rc);
    }
    
    switch (opts.mode) {
    case LIST_READERS:
        print_readers(readers);
        break;
    case NORMAL:
    default:
        if ((reader_dev_name = get_multistring(readers, opts.reader)) == NULL) {
            SCardReleaseContext(ctx);
            return fail(-1, "no such card reader\n");
        } else
            printf("using card reader \"%s\"\n", reader_dev_name);
        
        printf("connecting to card reader... ");
        if ((rc = SCardConnect(ctx, reader_dev_name, SCARD_SHARE_DIRECT, 0, &card, SCARD_PROTOCOL_UNDEFINED)) != SCARD_S_SUCCESS) {
            SCardReleaseContext(ctx);
            switch (rc) {
            case SCARD_E_NO_SMARTCARD:
                return fail(-1, "no smart card in device\n");
                break;
            default:
                return fail(-1, "SCardConnect: error %d", rc);
                break;
            }
        } else
            printf("ok\n");
        
        if ((rc = get_card_state(card, &card_state)) != SCARD_S_SUCCESS) {
            SCardDisconnect(card, DEFAULT_DISCONNECT_ACTION);
            SCardReleaseContext(ctx);
            switch (rc) {
            default:
                return fail(-1, "SCardStatus: error %d\n");
            }
        }
        print_card_state(&card_state);
        
        printf("checking atr for conformance to emv... ");
        if (is_emv_atr(1, &card_state))
            printf("ok\n");
        
#       define FILE_STR "1PAY.SYS.DDF01"
        /* TODO */
        if (card_state.proto == SCARD_PROTOCOL_T0) {
            c_apdu.cla = 0x0;
            c_apdu.ins = 0xb2;
            c_apdu.p1 = 0x4;
            c_apdu.p2 = 0x0;
            c_apdu.body.len = strlen(FILE_STR);
            strcpy(c_apdu.body.data, FILE_STR);
            c_apdu.body.max_r_len = 0;
            
            if (ttl_io(card, card_state.proto, &c_apdu, &r_apdu) == -1)
                printf("ttl_io failed\n");
            else {
                printf("ttl_io finished ok\n");            
                print_r_apdu(NULL, &r_apdu);
            }
            
        } else if (card_state.proto == SCARD_PROTOCOL_T1) {
        }
        
        SCardDisconnect(card, DEFAULT_DISCONNECT_ACTION);
        break;
    }
    
    SCardReleaseContext(ctx);
    return 0;
}