static int piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2)
{
	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();

	int r;
	piv_private_data_t * priv = PIV_DATA(card);

	/* may be called before piv_init  has allocated priv */
	if (priv) {
		/* need to save sw1 and sw2 if trying to determine card_state from pin_cmd */
		if (priv->pin_cmd_verify) {
			priv->pin_cmd_verify_sw1 = sw1;
			priv->pin_cmd_verify_sw2 = sw2;
		} else {
			/* a command has completed and it is not verify */
			/* If we are in a context_specific sequence, unlock */
			if (priv->context_specific) {
				sc_log(card->ctx,"Clearing CONTEXT_SPECIFIC lock");
				priv->context_specific = 0;
				sc_unlock(card);
			}
		}

		if (priv->card_issues & CI_VERIFY_630X) {

		/* Handle the Yubikey NEO or any other PIV card which returns in response to a verify
		 * 63 0X rather than 63 CX indicate the number of remaining PIN retries.
		 * Perhaps they misread the spec and thought 0xCX meant "clear" or "don't care", not a literal 0xC!
		 */
			if (priv->pin_cmd_verify && sw1 == 0x63U) {
				priv->pin_cmd_verify_sw2 |= 0xC0U; /* make it easier to test in other code */
				if ((sw2 & ~0x0fU) == 0x00U) {
					sc_log(card->ctx, "Verification failed (remaining tries: %d)", (sw2 & 0x0f));
					return SC_ERROR_PIN_CODE_INCORRECT;
					/* this is what the iso_check_sw returns for 63 C0 */
				}
			}
		}
	}
	r = iso_drv->ops->check_sw(card, sw1, sw2);
	return r;
}
static int piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2)
{
	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();

	int r;
	piv_private_data_t * priv = PIV_DATA(card);

	 
	if (priv) {
		 
		if (priv->pin_cmd_verify) {
			priv->pin_cmd_verify_sw1 = sw1;
			priv->pin_cmd_verify_sw2 = sw2;
		} else {
			 
			 
			if (priv->context_specific) {
				sc_log(card->ctx,"Clearing CONTEXT_SPECIFIC lock");
				priv->context_specific = 0;
				sc_unlock(card);
			}
		}

		if (priv->card_issues & CI_VERIFY_630X) {

		 
			if (priv->pin_cmd_verify && sw1 == 0x63U) {
				priv->pin_cmd_verify_sw2 |= 0xC0U;  
				if ((sw2 & ~0x0fU) == 0x00U) {
					sc_log(card->ctx, "Verification failed (remaining tries: %d)", (sw2 & 0x0f));
					return SC_ERROR_PIN_CODE_INCORRECT;
					 
				}
			}
		}
	}
	r = iso_drv->ops->check_sw(card, sw1, sw2);
	return r;
}