scd: Fix for inactive card at start by internal CCID driver.
authorNIIBE Yutaka <gniibe@fsij.org>
Wed, 27 Dec 2017 08:20:03 +0000 (17:20 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Wed, 27 Dec 2017 08:20:03 +0000 (17:20 +0900)
* scd/ccid-driver.c (do_close_reader): Set NULL on close.
(bulk_in): Move DEBUGOUT and check by EP_INTR.
(ccid_get_atr): Clear powered_off flag after initial status check.

--

Many card readers automatically turn on inserted card, but some
defaults to turning off at start.

GnuPG-bug-id: 3508
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
scd/ccid-driver.c

index 4f4a32d..5046da5 100644 (file)
@@ -1778,6 +1778,7 @@ do_close_reader (ccid_driver_t handle)
         }
 
       libusb_free_transfer (handle->transfer);
+      handle->transfer = NULL;
     }
   libusb_release_interface (handle->idev, handle->ifc_no);
   --ccid_usb_thread_is_alive;
@@ -2038,10 +2039,14 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
       /*
        * Communication failure by device side.
        * Possibly, it was forcibly suspended and resumed.
+       *
+       * Only detect this kind of failure when interrupt transfer is
+       * not supported.  For card reader with interrupt transfer
+       * support removal is detected by intr_cb.
        */
-      DEBUGOUT ("CCID: card inactive/removed\n");
-      if (handle->transfer == NULL)
+      if (handle->ep_intr < 0)
         {
+          DEBUGOUT ("CCID: card inactive/removed\n");
           handle->powered_off = 1;
           scd_kick_the_loop ();
         }
@@ -2539,6 +2544,14 @@ ccid_get_atr (ccid_driver_t handle,
   if (statusbits == 2)
     return CCID_DRIVER_ERR_NO_CARD;
 
+  /*
+   * In the first invocation of ccid_slot_status, card reader may
+   * return CCID_DRIVER_ERR_CARD_INACTIVE and handle->powered_off may
+   * become 1.  Because inactive card is no problem (we are turning it
+   * ON here), clear the flag.
+   */
+  handle->powered_off = 0;
+
   /* For an inactive and also for an active card, issue the PowerOn
      command to get the ATR.  */
  again: