mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-28 22:49:59 +01:00
scd: Add INTERRUPT endp support to CCID driver.
* scd/app.c (scd_update_reader_status_file): Fix releas of APP. * scd/ccid-driver.c (struct ccid_driver_s): Add INTR_BUF. (intr_cb, ccid_setup_intr): New. (ccid_open_usb_reader): Call ccid_setup_intr. (ccid_slot_status): Return CCID_DRIVER_ERR_NO_READER when removed. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
3f4f20ee6e
commit
bb5ceb78c3
@ -1049,6 +1049,7 @@ scd_update_reader_status_file (void)
|
|||||||
{
|
{
|
||||||
log_debug ("Removal of a card: %d\n", a->slot);
|
log_debug ("Removal of a card: %d\n", a->slot);
|
||||||
apdu_close_reader (a->slot);
|
apdu_close_reader (a->slot);
|
||||||
|
release_application_internal (a);
|
||||||
deallocate_app (a);
|
deallocate_app (a);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -272,6 +272,8 @@ struct ccid_driver_s
|
|||||||
ccid_set_progress_cb. */
|
ccid_set_progress_cb. */
|
||||||
void (*progress_cb)(void *, const char *, int, int, int);
|
void (*progress_cb)(void *, const char *, int, int, int);
|
||||||
void *progress_cb_arg;
|
void *progress_cb_arg;
|
||||||
|
|
||||||
|
unsigned char intr_buf[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1753,6 +1755,64 @@ ccid_compare_BAI (ccid_driver_t handle, unsigned int bai)
|
|||||||
return handle->bai == bai;
|
return handle->bai == bai;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
intr_cb (struct libusb_transfer *transfer)
|
||||||
|
{
|
||||||
|
ccid_driver_t handle = transfer->user_data;
|
||||||
|
|
||||||
|
DEBUGOUT ("CCID: interrupt callback\n");
|
||||||
|
|
||||||
|
if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE)
|
||||||
|
{
|
||||||
|
device_removed:
|
||||||
|
DEBUGOUT ("CCID: device removed\n");
|
||||||
|
handle->powered_off = 1;
|
||||||
|
libusb_free_transfer (transfer);
|
||||||
|
}
|
||||||
|
else if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
|
||||||
|
{
|
||||||
|
if (transfer->actual_length == 2
|
||||||
|
&& transfer->buffer[0] == 0x50
|
||||||
|
&& (transfer->buffer[1] & 1) == 0)
|
||||||
|
{
|
||||||
|
DEBUGOUT ("CCID: card removed\n");
|
||||||
|
handle->powered_off = 1;
|
||||||
|
libusb_free_transfer (transfer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* Submit the URB again to keep watching the INTERRUPT transfer. */
|
||||||
|
err = libusb_submit_transfer (transfer);
|
||||||
|
if (err == LIBUSB_ERROR_NO_DEVICE)
|
||||||
|
goto device_removed;
|
||||||
|
|
||||||
|
DEBUGOUT_1 ("CCID submit transfer again %d", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ccid_setup_intr (ccid_driver_t handle)
|
||||||
|
{
|
||||||
|
struct libusb_transfer *transfer;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
transfer = libusb_alloc_transfer (0);
|
||||||
|
libusb_fill_interrupt_transfer (transfer, handle->idev, handle->ep_intr,
|
||||||
|
handle->intr_buf, sizeof (handle->intr_buf),
|
||||||
|
intr_cb, handle, 0);
|
||||||
|
err = libusb_submit_transfer (transfer);
|
||||||
|
DEBUGOUT_2 ("CCID submit transfer (%x): %d", handle->ep_intr, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ccid_open_usb_reader (const char *spec_reader_name,
|
ccid_open_usb_reader (const char *spec_reader_name,
|
||||||
int idx, struct ccid_dev_table *ccid_table,
|
int idx, struct ccid_dev_table *ccid_table,
|
||||||
@ -1847,6 +1907,9 @@ ccid_open_usb_reader (const char *spec_reader_name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((*handle)->ep_intr)
|
||||||
|
ccid_setup_intr (*handle);
|
||||||
|
|
||||||
rc = ccid_vendor_specific_init (*handle);
|
rc = ccid_vendor_specific_init (*handle);
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
@ -1871,8 +1934,8 @@ ccid_open_usb_reader (const char *spec_reader_name,
|
|||||||
/* Open the reader with the internal number READERNO and return a
|
/* Open the reader with the internal number READERNO and return a
|
||||||
pointer to be used as handle in HANDLE. Returns 0 on success. */
|
pointer to be used as handle in HANDLE. Returns 0 on success. */
|
||||||
int
|
int
|
||||||
ccid_open_reader (const char *spec_reader_name,
|
ccid_open_reader (const char *spec_reader_name, int idx,
|
||||||
int idx, struct ccid_dev_table *ccid_table,
|
struct ccid_dev_table *ccid_table,
|
||||||
ccid_driver_t *handle, char **rdrname_p)
|
ccid_driver_t *handle, char **rdrname_p)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
@ -2516,6 +2579,9 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits)
|
|||||||
unsigned char seqno;
|
unsigned char seqno;
|
||||||
int retries = 0;
|
int retries = 0;
|
||||||
|
|
||||||
|
if (handle->powered_off)
|
||||||
|
return CCID_DRIVER_ERR_NO_READER;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
msg[0] = PC_to_RDR_GetSlotStatus;
|
msg[0] = PC_to_RDR_GetSlotStatus;
|
||||||
msg[5] = 0; /* slot */
|
msg[5] = 0; /* slot */
|
||||||
@ -2546,8 +2612,7 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits)
|
|||||||
retries++;
|
retries++;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
if (rc && rc != CCID_DRIVER_ERR_NO_CARD
|
if (rc && rc != CCID_DRIVER_ERR_NO_CARD && rc != CCID_DRIVER_ERR_CARD_INACTIVE)
|
||||||
&& rc != CCID_DRIVER_ERR_CARD_INACTIVE)
|
|
||||||
return rc;
|
return rc;
|
||||||
*statusbits = (msg[7] & 3);
|
*statusbits = (msg[7] & 3);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user